diff --git a/addons/hr_holidays/models/hr_employee.py b/addons/hr_holidays/models/hr_employee.py index db3390b7c08..4bc7630c685 100644 --- a/addons/hr_holidays/models/hr_employee.py +++ b/addons/hr_holidays/models/hr_employee.py @@ -5,6 +5,7 @@ import datetime from dateutil.relativedelta import relativedelta from odoo import _, api, fields, models +from odoo.exceptions import UserError from odoo.tools.float_utils import float_round from odoo.addons.resource.models.utils import HOURS_PER_DAY @@ -129,7 +130,7 @@ class HrEmployeeBase(models.AbstractModel): ('employee_id', 'in', self.ids), ('date_from', '<=', fields.Datetime.now()), ('date_to', '>=', fields.Datetime.now()), - ('state', 'not in', ('cancel', 'refuse')) + ('state', '=', 'validate'), ]) leave_data = {} for holiday in holidays: @@ -163,6 +164,8 @@ class HrEmployeeBase(models.AbstractModel): employee.show_leaves = False def _search_absent_employee(self, operator, value): + if operator not in ('=', '!=') or not isinstance(value, bool): + raise UserError(_('Operation not supported')) # This search is only used for the 'Absent Today' filter however # this only returns employees that are absent right now. today_date = datetime.datetime.utcnow().date() @@ -170,14 +173,12 @@ class HrEmployeeBase(models.AbstractModel): today_end = fields.Datetime.to_string(today_date + relativedelta(hours=23, minutes=59, seconds=59)) holidays = self.env['hr.leave'].sudo().search([ ('employee_id', '!=', False), - ('state', 'not in', ['cancel', 'refuse']), + ('state', '=', 'validate'), ('date_from', '<=', today_end), ('date_to', '>=', today_start), ]) - op = 'not in' - if (operator == '=' and value) or (operator == '!=' and not value): - op = 'in' - return [('id', op, holidays.mapped('employee_id').ids)] + operator = ['in', 'not in'][(operator == '=') != value] + return [('id', operator, holidays.mapped('employee_id').ids)] @api.model_create_multi def create(self, vals_list): @@ -242,7 +243,7 @@ class HrEmployee(models.Model): ('employee_id', 'in', self.ids), ('date_from', '<=', fields.Datetime.now()), ('date_to', '>=', fields.Datetime.now()), - ('state', 'not in', ('cancel', 'refuse')) + ('state', '=', 'validate'), ]) for holiday in holidays: employee = self.filtered(lambda e: e.id == holiday.employee_id.id) diff --git a/addons/hr_holidays/models/res_users.py b/addons/hr_holidays/models/res_users.py index 557bf2285e6..c9ee752a082 100644 --- a/addons/hr_holidays/models/res_users.py +++ b/addons/hr_holidays/models/res_users.py @@ -51,7 +51,7 @@ class User(models.Model): self.env['hr.leave'].flush_model(['user_id', 'state', 'date_from', 'date_to']) self.env.cr.execute('''SELECT res_users.%s FROM res_users JOIN hr_leave ON hr_leave.user_id = res_users.id - AND state in ('validate') + AND state = 'validate' AND hr_leave.active = 't' AND res_users.active = 't' AND date_from <= %%s AND date_to >= %%s''' % field, (now, now)) diff --git a/addons/hr_holidays/tests/test_leave_requests.py b/addons/hr_holidays/tests/test_leave_requests.py index ad8cc846985..840e8b9b766 100644 --- a/addons/hr_holidays/tests/test_leave_requests.py +++ b/addons/hr_holidays/tests/test_leave_requests.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from datetime import datetime, date +from datetime import datetime, date, timedelta import time from dateutil.relativedelta import relativedelta from freezegun import freeze_time @@ -1057,3 +1057,48 @@ class TestLeaveRequests(TestHrHolidaysCommon): with self.assertRaises(ValidationError): self.env['hr.leave'].with_user(self.user_employee_id).create(trigger_error_leave) + + def test_current_leave_status(self): + types = ('no_validation', 'manager', 'hr', 'both') + employee = self.employee_emp + + def run_validation_flow(leave_validation_type): + LeaveType = self.env['hr.leave.type'].with_user(self.user_hrmanager_id) + leave_type = LeaveType.with_context(tracking_disable=True).create({ + 'name': leave_validation_type.capitalize(), + 'leave_validation_type': leave_validation_type, + 'requires_allocation': 'no', + }) + current_leave = self.env['hr.leave'].with_user(self.user_employee_id).create({ + 'name': 'Holiday Request', + 'holiday_type': 'employee', + 'employee_id': employee.id, + 'holiday_status_id': leave_type.id, + 'date_from': datetime.today() - timedelta(days=1), + 'date_to': datetime.today() + timedelta(days=1), + }) + + if leave_validation_type in ('manager', 'both'): + self.assertFalse(employee.is_absent) + self.assertFalse(employee.current_leave_id) + self.assertEqual(employee.filtered_domain([('is_absent', '=', False)]), employee) + self.assertFalse(employee.filtered_domain([('is_absent', '=', True)])) + current_leave.with_user(self.user_hruser_id).action_approve() + + if leave_validation_type in ('hr', 'both'): + self.assertFalse(employee.is_absent) + self.assertFalse(employee.current_leave_id) + self.assertEqual(employee.filtered_domain([('is_absent', '=', False)]), employee) + self.assertFalse(employee.filtered_domain([('is_absent', '=', True)])) + current_leave.with_user(self.user_hrmanager_id).action_validate() + + self.assertTrue(employee.is_absent) + self.assertEqual(employee.current_leave_id, current_leave.holiday_status_id) + self.assertFalse(employee.filtered_domain([('is_absent', '=', False)])) + self.assertEqual(employee.filtered_domain([('is_absent', '=', True)]), employee) + + raise RuntimeError() + + for leave_validation_type in types: + with self.assertRaises(RuntimeError), self.env.cr.savepoint(): + run_validation_flow(leave_validation_type) diff --git a/addons/hr_holidays/tests/test_out_of_office.py b/addons/hr_holidays/tests/test_out_of_office.py index 8914be78cd2..0ae1b31cb42 100644 --- a/addons/hr_holidays/tests/test_out_of_office.py +++ b/addons/hr_holidays/tests/test_out_of_office.py @@ -105,12 +105,12 @@ class TestOutOfOfficePerformance(TestHrHolidaysCommon, TransactionCaseWithUserDe self.assertEqual(self.hr_partner.im_status, 'leave_offline') def test_search_absent_employee(self): - present_employees = self.env['hr.employee'].search([('is_absent', '!=', 'True')]) - absent_employees = self.env['hr.employee'].search([('is_absent', '=', 'True')]) + present_employees = self.env['hr.employee'].search([('is_absent', '!=', True)]) + absent_employees = self.env['hr.employee'].search([('is_absent', '=', True)]) today_date = datetime.utcnow().date() holidays = self.env['hr.leave'].sudo().search([ ('employee_id', '!=', False), - ('state', 'not in', ['cancel', 'refuse']), + ('state', '=', 'validate'), ('date_from', '<=', today_date), ('date_to', '>=', today_date), ]) diff --git a/addons/project_timesheet_holidays/models/resource_calendar_leaves.py b/addons/project_timesheet_holidays/models/resource_calendar_leaves.py index 7b320cfe4d4..6739f2087c7 100644 --- a/addons/project_timesheet_holidays/models/resource_calendar_leaves.py +++ b/addons/project_timesheet_holidays/models/resource_calendar_leaves.py @@ -119,7 +119,7 @@ class ResourceCalendarLeaves(models.Model): ('employee_id', 'in', employee_ids_all), ('date_from', '<=', max_date), ('date_to', '>=', min_date), - ('state', 'not in', ('cancel', 'refuse')), + ('state', '=', 'validate'), ], ['employee_id'], ['date_from:array_agg', 'date_to:array_agg']) holidays_by_employee = { employee.id: [