[FIX] hr_holidays : deduct correct # days on allocation

Steps :
Create, confirm and validate 2 overlapping leave allocations :
	> Type : T
	> Duration : 5 days
Create, confirm and approve a time off request in the overlapping period :
	> Type : T
	> Duration : 10 days
Go to the allocations.

Issue :
They have respectively 0 and 10 days taken.

Cause :
hr_leave.holiday_allocation_id is m2o, so 2 allocations cannot be
attributed to the same leave request.
_compute_from_holiday_status_id() sets the first valid (in terms of
validity dates) allocation to this field, without comparing the
number of leave days of the allocation and the request.

Fix :
Compare it. If no allocation has sufficient number of days, but their
sum is enough, ask the user to split them.

opw-2781530

closes odoo/odoo#87468

X-original-commit: a0ff3fc5888d8b6a794d40d32b2a546761dfa791
Signed-off-by: Kevin Baptiste <kba@odoo.com>
This commit is contained in:
Audric Onockx (auon)
2022-03-29 20:21:37 +02:00
parent 348e731a13
commit 3d24aacb4d
3 changed files with 61 additions and 1 deletions
+8
View File
@@ -4058,6 +4058,14 @@ msgid ""
"You don't have the rights to apply second approval on a time off request"
msgstr ""
#. module: hr_holidays
#: code:addons/hr_holidays/models/hr_leave.py:0
#, python-format
msgid ""
"You have several allocations for those type and period.\n"
"Please split your request to fit in their number of days."
msgstr ""
#. module: hr_holidays
#: code:addons/hr_holidays/models/hr_leave.py:0
#, python-format
+7 -1
View File
@@ -302,6 +302,12 @@ class HolidaysRequest(models.Model):
for leave in self:
leave.all_employee_ids = leave.employee_id | leave.employee_ids
@api.constrains('holiday_status_id', 'number_of_days')
def _check_allocation_duration(self):
for holiday in self:
if holiday.holiday_status_id.requires_allocation == 'yes' and holiday.number_of_days > holiday.holiday_allocation_id.number_of_days:
raise ValidationError(_("You have several allocations for those type and period.\nPlease split your request to fit in their number of days."))
@api.depends_context('uid')
def _compute_description(self):
self.check_access_rights('read')
@@ -355,7 +361,7 @@ class HolidaysRequest(models.Model):
'&',
('date_to', '=', False),
('date_from', '<=', max(self.mapped('date_from'))),
], ['id', 'date_from', 'date_to', 'holiday_status_id', 'employee_id'], order="date_to, id"
], ['id', 'date_from', 'date_to', 'holiday_status_id', 'employee_id', 'number_of_days'], order="number_of_days desc, date_to, id"
)
allocations_dict = defaultdict(lambda: [])
for allocation in allocations:
@@ -583,3 +583,49 @@ class TestLeaveRequests(TestHrHolidaysCommon):
'date_to': datetime(2022, 3, 11, 23, 59, 59),
})
self.assertEqual(leave.number_of_days, 1)
def test_several_allocations(self):
allocation_vals = {
'name': 'Allocation',
'employee_id': self.employee_emp_id,
'holiday_status_id': self.holidays_type_2.id,
'number_of_days': 5,
'state': 'confirm',
'date_from': '2022-01-01',
'date_to': '2022-12-31',
}
allocation1 = self.env['hr.leave.allocation'].create(allocation_vals)
allocation2 = self.env['hr.leave.allocation'].create(allocation_vals)
allocation1.action_validate()
allocation2.action_validate()
# Neither allocation has enough days
with self.assertRaises(ValidationError):
self.env['hr.leave'].with_user(self.user_employee_id).create({
'name': 'Holiday Request',
'employee_id': self.employee_emp_id,
'holiday_status_id': self.holidays_type_2.id,
'date_from': '2022-01-01',
'date_to': '2022-01-15',
'number_of_days': 10,
})
allocation_vals.update({'number_of_days': 10})
allocation3 = self.env['hr.leave.allocation'].create(allocation_vals)
allocation3.action_validate()
# The 3rd allocation has enough days, so it should be picked
holiday = self.env['hr.leave'].with_user(self.user_employee_id).create({
'name': 'Holiday Request',
'employee_id': self.employee_emp_id,
'holiday_status_id': self.holidays_type_2.id,
'date_from': '2022-01-01',
'date_to': '2022-01-15',
'number_of_days': 10,
})
holiday.sudo().action_validate()
self.assertEqual(allocation1.leaves_taken, 0.0, 'As this allocation does not have enough days, it should not be affected')
self.assertEqual(allocation2.leaves_taken, 0.0, 'As this allocation does not have enough days, it should not be affected')
self.assertEqual(allocation3.leaves_taken, 10.0, 'As this allocation has enough days, the leave days should be taken')