From 470674ead448c2d5a82381514a803e2a09b677df Mon Sep 17 00:00:00 2001 From: sofiagvaladze Date: Fri, 23 Sep 2022 07:39:31 +0000 Subject: [PATCH] [FIX] hr_holidays: correct the dashboard validity date Prior to this fix, closest_allocation_to_expire was the upcoming allocation regardless whether there were remaining leaves on it or not. That lead to misleading information on the dashboard. For example, let's say user has two allocations and used up the first allocation and has X days left on the second allocation. Still, the user will see that they have left X days (Valid until -- the first allocation expiration date --). Which is misleading, Instead they should see X days (Valid until -- the second allocation expiration date --). task - 2978789 closes odoo/odoo#103813 X-original-commit: dee3552659bec78fbbce4e8af155b3259e721dbd Signed-off-by: Kevin Baptiste --- addons/hr_holidays/models/hr_leave_type.py | 21 ++++++++++++------- .../hr_holidays/tests/test_leave_requests.py | 5 +++-- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/addons/hr_holidays/models/hr_leave_type.py b/addons/hr_holidays/models/hr_leave_type.py index e508922d678..14c698da5d1 100644 --- a/addons/hr_holidays/models/hr_leave_type.py +++ b/addons/hr_holidays/models/hr_leave_type.py @@ -315,8 +315,8 @@ class HolidaysType(models.Model): # Consume the allocations that are close to expiration first sorted_available_allocations = available_allocations.filtered('date_to').sorted(key='date_to') sorted_available_allocations += available_allocations.filtered(lambda allocation: not allocation.date_to) - allocations_days_consumed[employee_id][holiday_status_id][False]['closest_allocation_to_expire'] = sorted_available_allocations[0] if sorted_available_allocations else False leave_intervals = leaves_interval_by_status[holiday_status_id]._items + sorted_allocations_with_remaining_leaves = self.env['hr.leave.allocation'] for leave_interval in leave_intervals: leaves = leave_interval[2] for leave in leaves: @@ -336,6 +336,9 @@ class HolidaysType(models.Model): if leave.state == 'validate': days_consumed[available_allocation]['leaves_taken'] += max_leaves leave_duration -= max_leaves + # Check valid allocations with still availabe leaves on it + if days_consumed[available_allocation]['virtual_remaining_leaves'] > 0 and available_allocation.date_to and available_allocation.date_to > date: + sorted_allocations_with_remaining_leaves |= available_allocation if leave_duration > 0: # There are not enough allocation for the number of leaves days_consumed[False]['virtual_remaining_leaves'] -= leave_duration @@ -343,6 +346,8 @@ class HolidaysType(models.Model): days_consumed[False]['virtual_leaves_taken'] += leave_duration if leave.state == 'validate': days_consumed[False]['leaves_taken'] += leave_duration + # no need to sort the allocations again + allocations_days_consumed[employee_id][holiday_status_id][False]['closest_allocation_to_expire'] = sorted_allocations_with_remaining_leaves[0] if sorted_allocations_with_remaining_leaves else False # Future available leaves for employee_id, allocation_intervals_by_status in allocation_employees.items(): @@ -357,10 +362,7 @@ class HolidaysType(models.Model): closest_allocations = self.env['hr.leave.allocation'] for interval in intervals._items: closest_allocations |= interval[2] - allocations_of_that_type = closest_allocations.filtered(lambda a: a.date_to and a.state == 'validate' and a.date_to >= date) - allocations_sorted = sorted(allocations_of_that_type, key=lambda a: a.date_to) - allocation_closest = allocations_sorted[0] if allocations_sorted else False - allocations_days_consumed[employee_id][holiday_status_id][False]['closest_allocation_to_expire'] = allocation_closest + allocations_with_remaining_leaves = self.env['hr.leave.allocation'] for future_allocation_interval in future_allocation_intervals._items: if future_allocation_interval[0].date() > search_date: continue @@ -391,7 +393,11 @@ class HolidaysType(models.Model): days_consumed['remaining_leaves'] = days_consumed['max_leaves'] - days_consumed['leaves_taken'] if remaining_days_allocation >= quantity_available: break - + # Check valid allocations with still availabe leaves on it + if days_consumed['virtual_remaining_leaves'] > 0 and allocation.date_to and allocation.date_to > date: + allocations_with_remaining_leaves |= allocation + allocations_sorted = sorted(allocations_with_remaining_leaves, key=lambda a: a.date_to) + allocations_days_consumed[employee_id][holiday_status_id][False]['closest_allocation_to_expire'] = allocations_sorted[0] if allocations_sorted else False return allocations_days_consumed @@ -440,7 +446,8 @@ class HolidaysType(models.Model): def _get_days_request(self): self.ensure_one() - closest_allocation_remaining = (self.closest_allocation_to_expire.max_leaves - self.closest_allocation_to_expire.leaves_taken) if self.closest_allocation_to_expire else False + result = self._get_employees_days_per_allocation(self.closest_allocation_to_expire.employee_id.ids) + closest_allocation_remaining = result[self.closest_allocation_to_expire.employee_id.id][self][self.closest_allocation_to_expire]['virtual_remaining_leaves'] return (self.name, { 'remaining_leaves': ('%.2f' % self.remaining_leaves).rstrip('0').rstrip('.'), 'virtual_remaining_leaves': ('%.2f' % self.virtual_remaining_leaves).rstrip('0').rstrip('.'), diff --git a/addons/hr_holidays/tests/test_leave_requests.py b/addons/hr_holidays/tests/test_leave_requests.py index f21650ccef6..94db0ab8264 100644 --- a/addons/hr_holidays/tests/test_leave_requests.py +++ b/addons/hr_holidays/tests/test_leave_requests.py @@ -893,7 +893,7 @@ class TestLeaveRequests(TestHrHolidaysCommon): # Virtual remaining leave is equal to 1 because there is only one day remaining in the allocation based on its validity self._check_holidays_count( self.holidays_type_2.get_employees_days([self.employee_emp_id], date=date(2021, 12, 31))[self.employee_emp_id][self.holidays_type_2.id], - ml=10, lt=5, rl=5, vrl=1, vlt=5, closest_allocation=allocation_2021, + ml=10, lt=5, rl=5, vrl=1, vlt=5, closest_allocation=allocation_2022, ) leave_2022 = self.env['hr.leave'].with_user(self.user_employee_id).create({ @@ -922,9 +922,10 @@ class TestLeaveRequests(TestHrHolidaysCommon): # If the allocation is archived, the leaves taken are still counted on this allocation # but the max leaves and remaining leaves are not counted anymore + # If there are no virtual_remaining_leaves, then there is no upcoming allocation (closest_allocation_to_expire) to expire self._check_holidays_count( self.holidays_type_2.get_employees_days([self.employee_emp_id], date=date(2021, 12, 1))[self.employee_emp_id][self.holidays_type_2.id], - ml=0, lt=5, rl=0, vrl=0, vlt=5, closest_allocation=allocation_2021, + ml=0, lt=5, rl=0, vrl=0, vlt=5, closest_allocation=False, ) # The holidays count in 2022 is not affected by the archived allocation in 2021