1
+ import time
2
+
3
+ import pytz
1
4
from django .conf import settings
2
5
from rest_framework import serializers
3
6
9
12
from apps .oss_installation .utils import cloud_user_identity_status
10
13
from apps .twilioapp .utils import check_phone_number_is_valid
11
14
from apps .user_management .models import User
15
+ from apps .user_management .models .user import default_working_hours
12
16
from common .api_helpers .custom_fields import TeamPrimaryKeyRelatedField
13
17
from common .api_helpers .mixins import EagerLoadingMixin
14
18
from common .constants .role import Role
@@ -29,6 +33,7 @@ class UserSerializer(DynamicFieldsModelSerializer, EagerLoadingMixin):
29
33
organization = FastOrganizationSerializer (read_only = True )
30
34
current_team = TeamPrimaryKeyRelatedField (allow_null = True , required = False )
31
35
36
+ timezone = serializers .CharField (allow_null = True , required = False )
32
37
avatar = serializers .URLField (source = "avatar_url" , read_only = True )
33
38
34
39
permissions = serializers .SerializerMethodField ()
@@ -47,6 +52,8 @@ class Meta:
47
52
"username" ,
48
53
"role" ,
49
54
"avatar" ,
55
+ "timezone" ,
56
+ "working_hours" ,
50
57
"unverified_phone_number" ,
51
58
"verified_phone_number" ,
52
59
"slack_user_identity" ,
@@ -63,6 +70,52 @@ class Meta:
63
70
"verified_phone_number" ,
64
71
]
65
72
73
+ def validate_timezone (self , tz ):
74
+ if tz is None :
75
+ return tz
76
+
77
+ try :
78
+ pytz .timezone (tz )
79
+ except pytz .UnknownTimeZoneError :
80
+ raise serializers .ValidationError ("not a valid timezone" )
81
+
82
+ return tz
83
+
84
+ def validate_working_hours (self , working_hours ):
85
+ if not isinstance (working_hours , dict ):
86
+ raise serializers .ValidationError ("must be dict" )
87
+
88
+ # check that all days are present
89
+ if sorted (working_hours .keys ()) != sorted (default_working_hours ().keys ()):
90
+ raise serializers .ValidationError ("missing some days" )
91
+
92
+ for day in working_hours :
93
+ periods = working_hours [day ]
94
+
95
+ if not isinstance (periods , list ):
96
+ raise serializers .ValidationError ("periods must be list" )
97
+
98
+ for period in periods :
99
+ if not isinstance (period , dict ):
100
+ raise serializers .ValidationError ("period must be dict" )
101
+
102
+ if sorted (period .keys ()) != sorted (["start" , "end" ]):
103
+ raise serializers .ValidationError ("'start' and 'end' fields must be present" )
104
+
105
+ if not isinstance (period ["start" ], str ) or not isinstance (period ["end" ], str ):
106
+ raise serializers .ValidationError ("'start' and 'end' fields must be str" )
107
+
108
+ try :
109
+ start = time .strptime (period ["start" ], "%H:%M:%S" )
110
+ end = time .strptime (period ["end" ], "%H:%M:%S" )
111
+ except ValueError :
112
+ raise serializers .ValidationError ("'start' and 'end' fields must be in '%H:%M:%S' format" )
113
+
114
+ if start >= end :
115
+ raise serializers .ValidationError ("'start' must be less than 'end'" )
116
+
117
+ return working_hours
118
+
66
119
def validate_unverified_phone_number (self , value ):
67
120
if value :
68
121
if check_phone_number_is_valid (value ):
@@ -110,6 +163,8 @@ class UserHiddenFieldsSerializer(UserSerializer):
110
163
"current_team" ,
111
164
"username" ,
112
165
"avatar" ,
166
+ "timezone" ,
167
+ "working_hours" ,
113
168
"notification_chain_verbal" ,
114
169
"permissions" ,
115
170
]
0 commit comments