|
| 1 | +# SPDX-FileCopyrightText: 2026 Coop IT Easy SC |
| 2 | +# |
| 3 | +# SPDX-License-Identifier: AGPL-3.0-or-later |
| 4 | + |
1 | 5 | from datetime import datetime, timedelta |
2 | 6 |
|
3 | 7 | from odoo import _, api, fields, models |
@@ -32,50 +36,112 @@ def create(self, vals_list): |
32 | 36 | to the old shift and subscribe him/her to the new one |
33 | 37 | """ |
34 | 38 | res = super().create(vals_list) |
35 | | - res._unsubscribe_old_shift() |
36 | 39 | res._subscribe_new_shift() |
| 40 | + res._unsubscribe_old_shift() |
37 | 41 | return res |
38 | 42 |
|
39 | 43 | def _unsubscribe_old_shift(self): |
40 | 44 | """ |
41 | 45 | Unsubscribe self.worker_id from old_shift |
42 | | - Return True is unsubscription is successful. |
43 | | - :return: Boolean |
| 46 | + Raise error if not possible. |
44 | 47 | """ |
45 | | - if ( |
46 | | - self.old_shift_id.worker_id |
47 | | - and self.old_shift_id.worker_id == self.worker_id |
48 | | - ): |
49 | | - self.old_shift_id.worker_id = False |
50 | | - else: |
51 | | - raise ValidationError(_("You can't change shift that your are not worker.")) |
| 48 | + self._check_old_shift(self.old_shift_id, self.worker_id) |
| 49 | + self.old_shift_id.write( |
| 50 | + { |
| 51 | + "worker_id": False, |
| 52 | + "is_regular": False, |
| 53 | + "is_compensation": False, |
| 54 | + } |
| 55 | + ) |
52 | 56 |
|
53 | 57 | def _subscribe_new_shift(self): |
54 | 58 | """ |
55 | 59 | Subscribe self.worker_id to the new shift |
56 | | - Return True is subscription is successful. |
57 | | - :return: Boolean |
| 60 | + Raise error if not possible. |
58 | 61 | """ |
| 62 | + self._check_new_shift(self.new_shift_id) |
| 63 | + self.new_shift_id.write( |
| 64 | + { |
| 65 | + "worker_id": self.worker_id.id, |
| 66 | + "is_regular": self.old_shift_id.is_regular, |
| 67 | + "is_compensation": self.old_shift_id.is_compensation, |
| 68 | + } |
| 69 | + ) |
| 70 | + |
| 71 | + @api.model |
| 72 | + def _check_old_shift(self, old_shift_id, worker_id): |
| 73 | + """Check if old shift can be changed""" |
| 74 | + try: |
| 75 | + hour_limit_change = int( |
| 76 | + self.env["ir.config_parameter"].get_param( |
| 77 | + "shift_change.hour_limit_change" |
| 78 | + ) |
| 79 | + ) |
| 80 | + except ValueError: |
| 81 | + # fall back to a default value |
| 82 | + hour_limit_change = 0 |
| 83 | + if not old_shift_id.worker_id or old_shift_id.worker_id != worker_id: |
| 84 | + raise ValidationError(_("You can't change shift that your are not worker.")) |
| 85 | + if old_shift_id.start_time <= datetime.now(): |
| 86 | + raise ValidationError(_("You can't change shift that is in the past.")) |
| 87 | + if old_shift_id.start_time <= datetime.now() + timedelta( |
| 88 | + hours=hour_limit_change |
| 89 | + ): |
| 90 | + raise ValidationError(_("You can't change a shift so close in the futur.")) |
| 91 | + try: |
| 92 | + same_shift_change_max = int( |
| 93 | + self.env["ir.config_parameter"].get_param( |
| 94 | + "shift_change.same_shift_change_max" |
| 95 | + ) |
| 96 | + ) |
| 97 | + except ValueError: |
| 98 | + # fall back to a default value |
| 99 | + same_shift_change_max = 0 |
| 100 | + if same_shift_change_max: |
| 101 | + same_shift_change_nb = 0 |
| 102 | + tmp_old_shift_id = old_shift_id |
| 103 | + while tmp_old_shift_id: |
| 104 | + change = self.search( |
| 105 | + [ |
| 106 | + ("new_shift_id", "=", tmp_old_shift_id.id), |
| 107 | + ("worker_id", "=", worker_id.id), |
| 108 | + ], |
| 109 | + limit=1, |
| 110 | + ) |
| 111 | + if change: |
| 112 | + same_shift_change_nb += 1 |
| 113 | + tmp_old_shift_id = change.old_shift_id |
| 114 | + else: |
| 115 | + tmp_old_shift_id = None |
| 116 | + if same_shift_change_nb >= same_shift_change_max: |
| 117 | + raise ValidationError( |
| 118 | + _( |
| 119 | + "You can't change the same shift more than" |
| 120 | + f"{same_shift_change_max} times." |
| 121 | + ) |
| 122 | + ) |
| 123 | + |
| 124 | + @api.model |
| 125 | + def _check_new_shift(self, new_shift_id): |
| 126 | + """Check if shift can be changed or not""" |
59 | 127 | try: |
60 | 128 | hour_limit_change = int( |
61 | 129 | self.env["ir.config_parameter"].get_param( |
62 | 130 | "shift_change.hour_limit_change" |
63 | 131 | ) |
64 | 132 | ) |
65 | 133 | except ValueError: |
66 | | - # Fall back to a default value |
| 134 | + # fall back to a default value |
67 | 135 | hour_limit_change = 0 |
68 | | - if self.new_shift_id.worker_id: |
| 136 | + if new_shift_id.worker_id: |
69 | 137 | raise ValidationError( |
70 | 138 | _("You can't subscribe to a shift assigned to someone else.") |
71 | 139 | ) |
72 | | - elif self.new_shift_id.start_time <= datetime.now(): |
| 140 | + if new_shift_id.start_time <= datetime.now(): |
73 | 141 | raise ValidationError(_("You can't subscribe to a shift in the past.")) |
74 | | - elif self.new_shift_id.start_time <= datetime.now() + timedelta( |
| 142 | + if new_shift_id.start_time <= datetime.now() + timedelta( |
75 | 143 | hours=hour_limit_change |
76 | 144 | ): |
77 | 145 | raise ValidationError( |
78 | 146 | _("You can't subscribe to a shift so close in the futur.") |
79 | 147 | ) |
80 | | - else: |
81 | | - self.new_shift_id.worker_id = self.worker_id |
|
0 commit comments