2
2
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
3
3
4
4
from datetime import datetime , time
5
+
5
6
from dateutil .relativedelta import relativedelta
6
7
from dateutil .rrule import MONTHLY , WEEKLY
7
- from pytz import timezone , UTC
8
+ from pytz import UTC , timezone
8
9
9
10
from odoo import api , fields , models
10
11
11
12
12
13
class HrTimesheetSheet (models .Model ):
13
- _inherit = ' hr_timesheet.sheet'
14
+ _inherit = " hr_timesheet.sheet"
14
15
15
16
def _get_subscribers (self ):
16
- """ Reviewers are going to be notified using activities """
17
+ """Reviewers are going to be notified using activities"""
17
18
res = super ()._get_subscribers ()
18
- res = res - self ._get_possible_reviewers ().mapped (' partner_id' )
19
+ res = res - self ._get_possible_reviewers ().mapped (" partner_id" )
19
20
return res
20
21
21
22
@api .multi
22
23
def write (self , vals ):
23
24
res = super ().write (vals )
24
25
25
- for sheet in self .filtered (lambda sheet : sheet .state == ' draft' ):
26
+ for sheet in self .filtered (lambda sheet : sheet .state == " draft" ):
26
27
# NOTE: user_id is written manually instead of using new_user_id
27
28
# in order to update only activities with different user_id
28
29
activities = sheet .activity_reschedule (
29
- [' hr_timesheet_sheet_activity.activity_sheet_resubmission' ],
30
+ [" hr_timesheet_sheet_activity.activity_sheet_resubmission" ],
30
31
)
31
32
for activity in activities :
32
33
if activity .user_id == sheet .user_id :
33
34
continue
34
35
if activity .user_id != self .env .user :
35
36
# NOTE: Only assigned user can update the activity
36
37
activity = activity .sudo ()
37
- activity .write ({
38
- 'user_id' : sheet .user_id .id ,
39
- })
38
+ activity .write (
39
+ {
40
+ "user_id" : sheet .user_id .id ,
41
+ }
42
+ )
40
43
if activities :
41
44
continue
42
45
@@ -45,20 +48,24 @@ def write(self, vals):
45
48
# NOTE: Instead of updating activities using activity_reschedule,
46
49
# manually update only needed fields
47
50
activities = sheet .activity_reschedule (
48
- [' hr_timesheet_sheet_activity.activity_sheet_submission' ],
51
+ [" hr_timesheet_sheet_activity.activity_sheet_submission" ],
49
52
)
50
53
for activity in activities :
51
54
values = {}
52
55
if activity .user_id != sheet .user_id :
53
- values .update ({
54
- 'user_id' : sheet .user_id .id ,
55
- })
56
+ values .update (
57
+ {
58
+ "user_id" : sheet .user_id .id ,
59
+ }
60
+ )
56
61
if activity .date_deadline != deadline :
57
- values .update ({
58
- # NOTE: user_id is set to trigger a notification
59
- 'user_id' : sheet .user_id .id ,
60
- 'date_deadline' : deadline ,
61
- })
62
+ values .update (
63
+ {
64
+ # NOTE: user_id is set to trigger a notification
65
+ "user_id" : sheet .user_id .id ,
66
+ "date_deadline" : deadline ,
67
+ }
68
+ )
62
69
if not values :
63
70
continue
64
71
@@ -76,7 +83,7 @@ def write(self, vals):
76
83
continue
77
84
78
85
sheet .activity_schedule (
79
- ' hr_timesheet_sheet_activity.activity_sheet_submission' ,
86
+ " hr_timesheet_sheet_activity.activity_sheet_submission" ,
80
87
date_deadline = deadline ,
81
88
user_id = sheet .user_id .id ,
82
89
)
@@ -87,7 +94,7 @@ def write(self, vals):
87
94
def action_timesheet_draft (self ):
88
95
for sheet in self :
89
96
sheet .activity_schedule (
90
- ' hr_timesheet_sheet_activity.activity_sheet_resubmission' ,
97
+ " hr_timesheet_sheet_activity.activity_sheet_resubmission" ,
91
98
date_deadline = sheet ._activity_sheet_resubmission_deadline (),
92
99
user_id = sheet .user_id .id ,
93
100
)
@@ -100,10 +107,12 @@ def action_timesheet_confirm(self):
100
107
101
108
# NOTE: activity_reschedule is used instead of activity_feedback
102
109
# to accomodate non-assigned-user completion
103
- activities = self .activity_reschedule ([
104
- 'hr_timesheet_sheet_activity.activity_sheet_submission' ,
105
- 'hr_timesheet_sheet_activity.activity_sheet_resubmission' ,
106
- ])
110
+ activities = self .activity_reschedule (
111
+ [
112
+ "hr_timesheet_sheet_activity.activity_sheet_submission" ,
113
+ "hr_timesheet_sheet_activity.activity_sheet_resubmission" ,
114
+ ]
115
+ )
107
116
for activity in activities :
108
117
if activity .user_id != self .env .user :
109
118
# NOTE: Only assigned user can update the activity
@@ -112,11 +121,9 @@ def action_timesheet_confirm(self):
112
121
113
122
for sheet in self :
114
123
for reviewer in sheet ._get_possible_reviewers ():
115
- deadline = sheet ._activity_sheet_review_deadline (
116
- reviewer
117
- )
124
+ deadline = sheet ._activity_sheet_review_deadline (reviewer )
118
125
sheet .activity_schedule (
119
- ' hr_timesheet_sheet_activity.activity_sheet_review' ,
126
+ " hr_timesheet_sheet_activity.activity_sheet_review" ,
120
127
date_deadline = deadline ,
121
128
user_id = reviewer .id ,
122
129
)
@@ -127,9 +134,11 @@ def action_timesheet_done(self):
127
134
128
135
# NOTE: activity_reschedule is used instead of activity_feedback
129
136
# to accomodate non-assigned-user completion
130
- activities = self .activity_reschedule ([
131
- 'hr_timesheet_sheet_activity.activity_sheet_review' ,
132
- ])
137
+ activities = self .activity_reschedule (
138
+ [
139
+ "hr_timesheet_sheet_activity.activity_sheet_review" ,
140
+ ]
141
+ )
133
142
for activity in activities :
134
143
if activity .user_id != self .env .user :
135
144
# NOTE: Only assigned user can update the activity
@@ -140,7 +149,7 @@ def action_timesheet_done(self):
140
149
def action_timesheet_refuse (self ):
141
150
for sheet in self :
142
151
sheet .activity_schedule (
143
- ' hr_timesheet_sheet_activity.activity_sheet_resubmission' ,
152
+ " hr_timesheet_sheet_activity.activity_sheet_resubmission" ,
144
153
date_deadline = sheet ._activity_sheet_resubmission_deadline (),
145
154
user_id = sheet .user_id .id ,
146
155
)
@@ -149,9 +158,11 @@ def action_timesheet_refuse(self):
149
158
150
159
# NOTE: activity_reschedule is used instead of activity_feedback
151
160
# to accomodate non-assigned-user completion
152
- activities = self .activity_reschedule ([
153
- 'hr_timesheet_sheet_activity.activity_sheet_review' ,
154
- ])
161
+ activities = self .activity_reschedule (
162
+ [
163
+ "hr_timesheet_sheet_activity.activity_sheet_review" ,
164
+ ]
165
+ )
155
166
for activity in activities :
156
167
if activity .user_id != self .env .user :
157
168
# NOTE: Only assigned user can update the activity
@@ -160,15 +171,16 @@ def action_timesheet_refuse(self):
160
171
161
172
@api .multi
162
173
def _activity_sheet_submission_deadline (self ):
163
- """ Hook for extensions """
174
+ """Hook for extensions"""
164
175
self .ensure_one ()
165
176
166
- employee_timezone = timezone (self .employee_id .tz or ' UTC' )
177
+ employee_timezone = timezone (self .employee_id .tz or " UTC" )
167
178
employee_today = self .env .context .get (
168
- 'hr_timesheet_sheet_activity_today' ,
169
- fields .Datetime .now ().replace (tzinfo = UTC ).astimezone (
170
- employee_timezone
171
- ).date ()
179
+ "hr_timesheet_sheet_activity_today" ,
180
+ fields .Datetime .now ()
181
+ .replace (tzinfo = UTC )
182
+ .astimezone (employee_timezone )
183
+ .date (),
172
184
)
173
185
174
186
# Get last workday of employee or last day of period (in user tz)
@@ -177,77 +189,69 @@ def _activity_sheet_submission_deadline(self):
177
189
time .min ,
178
190
).replace (tzinfo = employee_timezone )
179
191
datetime_end = datetime .combine (
180
- max (self .date_end , employee_today ),
181
- time .max
192
+ max (self .date_end , employee_today ), time .max
182
193
).replace (tzinfo = employee_timezone )
183
194
worktimes = self .employee_id .list_work_time_per_day (
184
195
datetime_start ,
185
196
datetime_end ,
186
197
)
187
- worktimes = list (filter (
188
- lambda worktime : worktime [1 ] > 0 ,
189
- worktimes
190
- ))
198
+ worktimes = list (filter (lambda worktime : worktime [1 ] > 0 , worktimes ))
191
199
if worktimes :
192
200
return worktimes [- 1 ][0 ] # Last workday of period
193
201
return datetime_end .date ()
194
202
195
203
@api .multi
196
204
def _activity_sheet_resubmission_deadline (self ):
197
- """ Hook for extensions """
205
+ """Hook for extensions"""
198
206
self .ensure_one ()
199
207
return None
200
208
201
209
@api .multi
202
210
def _activity_sheet_review_deadline (self , reviewer ):
203
- """ Hook for extensions """
211
+ """Hook for extensions"""
204
212
self .ensure_one ()
205
213
206
- employee_timezone = timezone (self .employee_id .tz or ' UTC' )
214
+ employee_timezone = timezone (self .employee_id .tz or " UTC" )
207
215
employee_today = self .env .context .get (
208
- 'hr_timesheet_sheet_activity_today' ,
209
- fields .Datetime .now ().replace (tzinfo = UTC ).astimezone (
210
- employee_timezone
211
- ).date ()
212
- )
213
- deadline = max (
214
- self .date_end + relativedelta (days = 1 ),
215
- employee_today
216
+ "hr_timesheet_sheet_activity_today" ,
217
+ fields .Datetime .now ()
218
+ .replace (tzinfo = UTC )
219
+ .astimezone (employee_timezone )
220
+ .date (),
216
221
)
222
+ deadline = max (self .date_end + relativedelta (days = 1 ), employee_today )
217
223
218
- reviewer_employee = self .env ['hr.employee' ].with_context (
219
- active_test = False ,
220
- ).search (
221
- [('user_id' , '=' , reviewer .id )],
222
- limit = 1 ,
224
+ reviewer_employee = (
225
+ self .env ["hr.employee" ]
226
+ .with_context (
227
+ active_test = False ,
228
+ )
229
+ .search (
230
+ [("user_id" , "=" , reviewer .id )],
231
+ limit = 1 ,
232
+ )
223
233
)
224
234
if not reviewer_employee :
225
235
return deadline
226
236
227
237
worktimes = reviewer_employee .list_work_time_per_day (
238
+ datetime .combine (deadline , time .min ).replace (tzinfo = employee_timezone ),
228
239
datetime .combine (
229
- deadline ,
230
- time .min
231
- ).replace (tzinfo = employee_timezone ),
232
- datetime .combine (
233
- deadline + self ._activity_sheet_review_max_period (),
234
- time .max
240
+ deadline + self ._activity_sheet_review_max_period (), time .max
235
241
).replace (tzinfo = employee_timezone ),
236
242
)
237
- worktimes = list (filter (
238
- lambda worktime : worktime [1 ] > 0 ,
239
- worktimes
240
- ))
243
+ worktimes = list (filter (lambda worktime : worktime [1 ] > 0 , worktimes ))
241
244
if worktimes :
242
245
return worktimes [0 ][0 ] # First workday of period
243
- return datetime .combine (deadline , time .max ).replace (
244
- tzinfo = employee_timezone
245
- ).astimezone (
246
- timezone (reviewer_employee .tz or 'UTC' )
247
- ).date ()
246
+ return (
247
+ datetime .combine (deadline , time .max )
248
+ .replace (tzinfo = employee_timezone )
249
+ .astimezone (timezone (reviewer_employee .tz or "UTC" ))
250
+ .date ()
251
+ )
248
252
249
253
def _activity_sheet_review_max_period (self ):
250
- """ Hook for extensions """
254
+ """Hook for extensions"""
251
255
self .ensure_one ()
252
256
r = self .company_id .sheet_range or WEEKLY
253
257
if r == WEEKLY :
0 commit comments