1
1
# Copyright 2015 Camptocamp SA - Guewen Baconnier
2
2
# Copyright 2017 Tecnativa, S.L. - Luis M. Ontalba
3
+ # Copyright 2024 Coop IT Easy SC - Carmen Bianca BAKKER
3
4
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
4
5
5
6
from datetime import timedelta
@@ -15,16 +16,14 @@ class AccountAnalyticLine(models.Model):
15
16
time_start = fields .Float (string = "Begin Hour" )
16
17
time_stop = fields .Float (string = "End Hour" )
17
18
18
- @api .constrains ("time_start" , "time_stop" , "unit_amount" )
19
- def _check_time_start_stop (self ):
20
- for line in self :
21
- value_to_html = self .env ["ir.qweb.field.float_time" ].value_to_html
22
- start = timedelta (hours = line .time_start )
23
- stop = timedelta (hours = line .time_stop )
24
- if stop < start :
25
- value_to_html (line .time_start , None )
26
- value_to_html (line .time_stop , None )
19
+ @api .onchange ("time_start" , "time_stop" )
20
+ def onchange_hours_start_stop (self ):
21
+ self .unit_amount = self .unit_amount_from_start_stop ()
27
22
23
+ def _validate_start_before_stop (self ):
24
+ value_to_html = self .env ["ir.qweb.field.float_time" ].value_to_html
25
+ for line in self :
26
+ if line .time_stop < line .time_start :
28
27
raise exceptions .ValidationError (
29
28
_ (
30
29
"The beginning hour (%(html_start)s) must "
@@ -35,7 +34,11 @@ def _check_time_start_stop(self):
35
34
"html_stop" : value_to_html (line .time_stop , None ),
36
35
}
37
36
)
38
- hours = (stop - start ).seconds / 3600
37
+
38
+ def _validate_unit_amount_equal_to_time_diff (self ):
39
+ value_to_html = self .env ["ir.qweb.field.float_time" ].value_to_html
40
+ for line in self :
41
+ hours = line .unit_amount_from_start_stop ()
39
42
rounding = self .env .ref ("uom.product_uom_hour" ).rounding
40
43
if hours and float_compare (
41
44
hours , line .unit_amount , precision_rounding = rounding
@@ -50,16 +53,21 @@ def _check_time_start_stop(self):
50
53
"html_hours" : value_to_html (hours , None ),
51
54
}
52
55
)
53
- # check if lines overlap
54
- others = self .search (
55
- [
56
- ("id" , "!=" , line .id ),
57
- ("employee_id" , "=" , line .employee_id .id ),
58
- ("date" , "=" , line .date ),
59
- ("time_start" , "<" , line .time_stop ),
60
- ("time_stop" , ">" , line .time_start ),
61
- ]
62
- )
56
+
57
+ def _overlap_domain (self ):
58
+ self .ensure_one ()
59
+ return [
60
+ ("id" , "!=" , self .id ),
61
+ ("employee_id" , "=" , self .employee_id .id ),
62
+ ("date" , "=" , self .date ),
63
+ ("time_start" , "<" , self .time_stop ),
64
+ ("time_stop" , ">" , self .time_start ),
65
+ ]
66
+
67
+ def _validate_no_overlap (self ):
68
+ value_to_html = self .env ["ir.qweb.field.float_time" ].value_to_html
69
+ for line in self :
70
+ others = self .search (line ._overlap_domain ())
63
71
if others :
64
72
message = _ ("Lines can't overlap:\n " )
65
73
message += "\n " .join (
@@ -74,13 +82,24 @@ def _check_time_start_stop(self):
74
82
)
75
83
raise exceptions .ValidationError (message )
76
84
77
- @api .onchange ("time_start" , "time_stop" )
78
- def onchange_hours_start_stop (self ):
79
- start = timedelta (hours = self .time_start )
80
- stop = timedelta (hours = self .time_stop )
85
+ @api .constrains ("time_start" , "time_stop" , "unit_amount" )
86
+ def _check_time_start_stop (self ):
87
+ self ._validate_start_before_stop ()
88
+ self ._validate_unit_amount_equal_to_time_diff ()
89
+ self ._validate_no_overlap ()
90
+
91
+ @api .model
92
+ def _hours_from_start_stop (self , time_start , time_stop ):
93
+ start = timedelta (hours = time_start )
94
+ stop = timedelta (hours = time_stop )
81
95
if stop < start :
82
- return
83
- self .unit_amount = (stop - start ).seconds / 3600
96
+ # Invalid case, but return something sensible.
97
+ return 0
98
+ return (stop - start ).seconds / 3600
99
+
100
+ def unit_amount_from_start_stop (self ):
101
+ self .ensure_one ()
102
+ return self ._hours_from_start_stop (self .time_start , self .time_stop )
84
103
85
104
def merge_timesheets (self ): # pragma: no cover
86
105
"""This method is needed in case hr_timesheet_sheet is installed"""
0 commit comments