|
2 | 2 | # Copyright 2022-2023 Tecnativa - Víctor Martínez
|
3 | 3 | # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
4 | 4 |
|
| 5 | +from datetime import date |
| 6 | + |
5 | 7 | from odoo import _, api, fields, models
|
6 | 8 | from odoo.exceptions import UserError
|
7 | 9 | from odoo.tools import config
|
@@ -58,6 +60,43 @@ def default_get(self, fields):
|
58 | 60 | ]
|
59 | 61 | return vals
|
60 | 62 |
|
| 63 | + def _get_current_hours_per_day(self): |
| 64 | + """ |
| 65 | + Checks all calendars and uses the most specific first (date_start and date_end are set). |
| 66 | + If no calendar matches it checks for calendars where no date_end is set. |
| 67 | + If no calendar matches it checks for calendars where no date_start is set. |
| 68 | + If no calendar matches it checks for calenders with neither date_start nor date_end. |
| 69 | + It returns the hours_per_day of the first matching resource calendar. |
| 70 | + If no calendar matches or no calendar exists -1 is returned. |
| 71 | + :return: the current valid hours per day |
| 72 | + """ |
| 73 | + if not self.calendar_ids: |
| 74 | + return -1 |
| 75 | + today = date.today() |
| 76 | + relevant_calendars = self.calendar_ids.filtered( |
| 77 | + lambda x: x.date_start |
| 78 | + and x.date_end |
| 79 | + and x.date_start <= today <= x.date_end |
| 80 | + ) |
| 81 | + if relevant_calendars: |
| 82 | + return relevant_calendars[0].calendar_id.hours_per_day |
| 83 | + relevant_calendars = self.calendar_ids.filtered( |
| 84 | + lambda x: x.date_start and not x.date_end and x.date_start <= today |
| 85 | + ) |
| 86 | + if relevant_calendars: |
| 87 | + return relevant_calendars[0].calendar_id.hours_per_day |
| 88 | + relevant_calendars = self.calendar_ids.filtered( |
| 89 | + lambda x: not x.date_start and x.date_end and today <= x.date_end |
| 90 | + ) |
| 91 | + if relevant_calendars: |
| 92 | + return relevant_calendars[0].calendar_id.hours_per_day |
| 93 | + relevant_calendars = self.calendar_ids.filtered( |
| 94 | + lambda x: not x.date_start and not x.date_end |
| 95 | + ) |
| 96 | + if relevant_calendars: |
| 97 | + return relevant_calendars[0].calendar_id.hours_per_day |
| 98 | + return -1 |
| 99 | + |
61 | 100 | def _regenerate_calendar(self):
|
62 | 101 | self.ensure_one()
|
63 | 102 | vals_list = []
|
@@ -115,11 +154,11 @@ def _regenerate_calendar(self):
|
115 | 154 | )
|
116 | 155 | else:
|
117 | 156 | self.resource_calendar_id.attendance_ids = vals_list
|
118 |
| - # Set the hours per day to the last (top date end) calendar line to apply |
| 157 | + # Set the hours per day to the value of the current resource calendar |
| 158 | + current_hours_per_day = self._get_current_hours_per_day() |
| 159 | + if current_hours_per_day >= 0: |
| 160 | + self.resource_id.calendar_id.hours_per_day = current_hours_per_day |
119 | 161 | if self.calendar_ids:
|
120 |
| - self.resource_id.calendar_id.hours_per_day = self.calendar_ids[ |
121 |
| - 0 |
122 |
| - ].calendar_id.hours_per_day |
123 | 162 | # set global leaves
|
124 | 163 | self.copy_global_leaves()
|
125 | 164 |
|
@@ -162,6 +201,13 @@ def copy_global_leaves(self):
|
162 | 201 | to_unlink.unlink()
|
163 | 202 | return self.env["resource.calendar.leaves"].create(new_vals).ids
|
164 | 203 |
|
| 204 | + def cron_recompute_hours_per_day(self): |
| 205 | + employees = self.search([]) |
| 206 | + for employee in employees: |
| 207 | + current_hours_per_day = employee._get_current_hours_per_day() |
| 208 | + if current_hours_per_day >= 0: |
| 209 | + employee.resource_id.calendar_id.hours_per_day = current_hours_per_day |
| 210 | + |
165 | 211 | def regenerate_calendar(self):
|
166 | 212 | for item in self:
|
167 | 213 | item._regenerate_calendar()
|
|
0 commit comments