diff --git a/addons/hr_holidays/data/hr_holidays_data.xml b/addons/hr_holidays/data/hr_holidays_data.xml index f50089606e0..4dca005bc63 100644 --- a/addons/hr_holidays/data/hr_holidays_data.xml +++ b/addons/hr_holidays/data/hr_holidays_data.xml @@ -260,7 +260,7 @@ officer - + 2 @@ -270,7 +270,7 @@ Sick Time Off no - + True 3 @@ -285,7 +285,7 @@ officer hour - + 4 @@ -299,7 +299,7 @@ hour - + 5 diff --git a/addons/hr_holidays/data/hr_holidays_demo.xml b/addons/hr_holidays/data/hr_holidays_demo.xml index b6ee5595449..fbb236edbf5 100644 --- a/addons/hr_holidays/data/hr_holidays_demo.xml +++ b/addons/hr_holidays/data/hr_holidays_demo.xml @@ -13,7 +13,7 @@ no both officer - + @@ -22,7 +22,7 @@ no both officer - + diff --git a/addons/hr_holidays/data/mail_activity_type_data.xml b/addons/hr_holidays/data/mail_activity_type_data.xml index b5bac396e0d..19858334853 100644 --- a/addons/hr_holidays/data/mail_activity_type_data.xml +++ b/addons/hr_holidays/data/mail_activity_type_data.xml @@ -19,10 +19,5 @@ fa-sun-o hr.leave.allocation - - Allocation Second Approve - fa-sun-o - hr.leave.allocation - diff --git a/addons/hr_holidays/models/hr_leave.py b/addons/hr_holidays/models/hr_leave.py index bbe9a79a2b2..eb7e62ed38f 100644 --- a/addons/hr_holidays/models/hr_leave.py +++ b/addons/hr_holidays/models/hr_leave.py @@ -987,7 +987,7 @@ class HolidaysRequest(models.Model): if holiday.validation_type == 'no_validation': # Automatic validation should be done in sudo, because user might not have the rights to do it by himself holiday_sudo.action_validate() - holiday_sudo.message_subscribe(partner_ids=[holiday._get_responsible_for_approval().partner_id.id]) + holiday_sudo.message_subscribe(partner_ids=holiday._get_responsible_for_approval().partner_id.ids) holiday_sudo.message_post(body=_("The time off has been automatically approved"), subtype_xmlid="mail.mt_comment") # Message from OdooBot (sudo) elif not self._context.get('import_file'): holiday_sudo.activity_update() @@ -1425,11 +1425,11 @@ class HolidaysRequest(models.Model): responsibles = leave.employee_id.leave_manager_id.partner_id # officer elif leave.holiday_status_id.leave_validation_type == 'hr' and leave.state == 'validate': - responsibles = leave.holiday_status_id.responsible_id.partner_id + responsibles = leave.holiday_status_id.responsible_ids.partner_id # both elif leave.holiday_status_id.leave_validation_type == 'both' and leave.state == 'validate': responsibles = leave.employee_id.leave_manager_id.partner_id - responsibles |= leave.holiday_status_id.responsible_id.partner_id + responsibles |= leave.holiday_status_id.responsible_ids.partner_id if responsibles: leave_name = list(filter(lambda h: leave.id in h, leave_names))[0][1] @@ -1572,13 +1572,15 @@ class HolidaysRequest(models.Model): elif self.employee_id.parent_id.user_id: responsible = self.employee_id.parent_id.user_id elif self.validation_type == 'hr' or (self.validation_type == 'both' and self.state == 'validate1'): - if self.holiday_status_id.responsible_id: - responsible = self.holiday_status_id.responsible_id - + if self.holiday_status_id.responsible_ids: + responsible = self.holiday_status_id.responsible_ids + else: + responsible = self.env.ref('hr_holidays.group_hr_holidays_user').users.filtered(lambda u: self.holiday_status_id.company_id in u.company_ids) return responsible def activity_update(self): to_clean, to_do = self.env['hr.leave'], self.env['hr.leave'] + activity_vals = [] for holiday in self: note = _( 'New %(leave_type)s Request created by %(user)s', @@ -1588,16 +1590,16 @@ class HolidaysRequest(models.Model): if holiday.state == 'draft': to_clean |= holiday elif holiday.state == 'confirm': - holiday.activity_schedule( - 'hr_holidays.mail_act_leave_approval', - note=note, - user_id=holiday.sudo()._get_responsible_for_approval().id or self.env.user.id) - elif holiday.state == 'validate1': - holiday.activity_feedback(['hr_holidays.mail_act_leave_approval']) - holiday.activity_schedule( - 'hr_holidays.mail_act_leave_second_approval', - note=note, - user_id=holiday.sudo()._get_responsible_for_approval().id or self.env.user.id) + user_ids = holiday.sudo()._get_responsible_for_approval().ids or self.env.user.ids + for user_id in user_ids: + activity_vals.append({ + 'activity_type_id': self.env.ref('hr_holidays.mail_act_leave_approval').id, + 'automated': True, + 'note': note, + 'user_id': user_id, + 'res_id': holiday.id, + 'res_model_id': self.env.ref('hr_holidays.model_hr_leave').id, + }) elif holiday.state == 'validate': to_do |= holiday elif holiday.state == 'refuse': @@ -1606,6 +1608,7 @@ class HolidaysRequest(models.Model): to_clean.activity_unlink(['hr_holidays.mail_act_leave_approval', 'hr_holidays.mail_act_leave_second_approval']) if to_do: to_do.activity_feedback(['hr_holidays.mail_act_leave_approval', 'hr_holidays.mail_act_leave_second_approval']) + self.env['mail.activity'].create(activity_vals) #################################################### # Messaging methods diff --git a/addons/hr_holidays/models/hr_leave_allocation.py b/addons/hr_holidays/models/hr_leave_allocation.py index ba4420f7bf8..ac1c5cf4ad0 100644 --- a/addons/hr_holidays/models/hr_leave_allocation.py +++ b/addons/hr_holidays/models/hr_leave_allocation.py @@ -737,13 +737,16 @@ class HolidaysAllocation(models.Model): responsible = self.env.user if self.validation_type == 'officer' or self.validation_type == 'set': - if self.holiday_status_id.responsible_id: - responsible = self.holiday_status_id.responsible_id + if self.holiday_status_id.responsible_ids: + responsible = self.holiday_status_id.responsible_ids + else: + responsible = self.env.ref('hr_holidays.group_hr_holidays_user').users.filtered(lambda u: self.holiday_status_id.company_id in u.company_ids) return responsible def activity_update(self): to_clean, to_do = self.env['hr.leave.allocation'], self.env['hr.leave.allocation'] + activity_vals = [] for allocation in self: if allocation.validation_type != 'no': note = _( @@ -755,24 +758,25 @@ class HolidaysAllocation(models.Model): if allocation.state == 'draft': to_clean |= allocation elif allocation.state == 'confirm': - allocation.activity_schedule( - 'hr_holidays.mail_act_leave_allocation_approval', - note=note, - user_id=allocation.sudo()._get_responsible_for_approval().id or self.env.user.id) - elif allocation.state == 'validate1': - allocation.activity_feedback(['hr_holidays.mail_act_leave_allocation_approval']) - allocation.activity_schedule( - 'hr_holidays.mail_act_leave_allocation_second_approval', - note=note, - user_id=allocation.sudo()._get_responsible_for_approval().id or self.env.user.id) + user_ids = allocation.sudo()._get_responsible_for_approval().ids or self.env.user.ids + for user_id in user_ids: + activity_vals.append({ + 'activity_type_id': self.env.ref('hr_holidays.mail_act_leave_allocation_approval').id, + 'automated': True, + 'note': note, + 'user_id': user_id, + 'res_id': allocation.id, + 'res_model_id': self.env.ref('hr_holidays.model_hr_leave_allocation').id, + }) elif allocation.state == 'validate': to_do |= allocation elif allocation.state == 'refuse': to_clean |= allocation + self.env['mail.activity'].create(activity_vals) if to_clean: - to_clean.activity_unlink(['hr_holidays.mail_act_leave_allocation_approval', 'hr_holidays.mail_act_leave_allocation_second_approval']) + to_clean.activity_unlink(['hr_holidays.mail_act_leave_allocation_approval']) if to_do: - to_do.activity_feedback(['hr_holidays.mail_act_leave_allocation_approval', 'hr_holidays.mail_act_leave_allocation_second_approval']) + to_do.activity_feedback(['hr_holidays.mail_act_leave_allocation_approval']) #################################################### # Messaging methods @@ -813,7 +817,7 @@ class HolidaysAllocation(models.Model): def message_subscribe(self, partner_ids=None, subtype_ids=None): # due to record rule can not allow to add follower and mention on validated leave so subscribe through sudo - if self.state in ['validate', 'validate1']: + if any(state in ['validate', 'validate1'] for state in self.mapped('state')): self.check_access_rights('read') self.check_access_rule('read') return super(HolidaysAllocation, self.sudo()).message_subscribe(partner_ids=partner_ids, subtype_ids=subtype_ids) diff --git a/addons/hr_holidays/models/hr_leave_type.py b/addons/hr_holidays/models/hr_leave_type.py index 30829f15c05..676e5a7503a 100644 --- a/addons/hr_holidays/models/hr_leave_type.py +++ b/addons/hr_holidays/models/hr_leave_type.py @@ -58,11 +58,12 @@ class HolidaysType(models.Model): group_days_leave = fields.Float( compute='_compute_group_days_leave', string='Group Time Off') company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.company) - responsible_id = fields.Many2one( - 'res.users', 'Responsible Time Off Officer', + responsible_ids = fields.Many2many( + 'res.users', 'hr_leave_type_res_users_rel', 'hr_leave_type_id', 'res_users_id', string='Responsible Time Off Officer', domain=lambda self: [('groups_id', 'in', self.env.ref('hr_holidays.group_hr_holidays_user').id), ('share', '=', False), ('company_ids', 'in', self.env.company.id)], + auto_join=True, help="Choose the Time Off Officer who will be notified to approve allocation or Time Off request") leave_validation_type = fields.Selection([ ('no_validation', 'No Validation'), diff --git a/addons/hr_holidays/tests/test_accrual_allocations.py b/addons/hr_holidays/tests/test_accrual_allocations.py index b3a0138a33c..856c9648f3c 100644 --- a/addons/hr_holidays/tests/test_accrual_allocations.py +++ b/addons/hr_holidays/tests/test_accrual_allocations.py @@ -4,6 +4,7 @@ import datetime from freezegun import freeze_time from dateutil.relativedelta import relativedelta +from odoo import Command from odoo.tests import tagged from odoo.addons.hr_holidays.tests.common import TestHrHolidaysCommon @@ -354,7 +355,7 @@ class TestAccrualAllocations(TestHrHolidaysCommon): holiday_type = self.env['hr.leave.type'].create({ 'name': 'Paid Time Off', 'requires_allocation': 'no', - 'responsible_id': self.user_hrmanager_id, + 'responsible_ids': [Command.link(self.user_hrmanager_id)], 'time_type': 'leave', }) leave = self.env['hr.leave'].create({ diff --git a/addons/hr_holidays/tests/test_company_leave.py b/addons/hr_holidays/tests/test_company_leave.py index b83572b9196..f13e296981d 100644 --- a/addons/hr_holidays/tests/test_company_leave.py +++ b/addons/hr_holidays/tests/test_company_leave.py @@ -3,6 +3,7 @@ from datetime import date, datetime +from odoo import Command from odoo.tests import tagged from odoo.tests.common import TransactionCase @@ -18,7 +19,7 @@ class TestCompanyLeave(TransactionCase): cls.bank_holiday = cls.env['hr.leave.type'].create({ 'name': 'Bank Holiday', - 'responsible_id': cls.env.user.id, + 'responsible_ids': [Command.link(cls.env.ref('base.user_admin').id)], 'company_id': cls.company.id, 'requires_allocation': 'no', }) diff --git a/addons/hr_holidays/tests/test_holidays_flow.py b/addons/hr_holidays/tests/test_holidays_flow.py index 8200c981fdf..d613f9c3f46 100644 --- a/addons/hr_holidays/tests/test_holidays_flow.py +++ b/addons/hr_holidays/tests/test_holidays_flow.py @@ -7,7 +7,7 @@ from dateutil.relativedelta import relativedelta from freezegun import freeze_time from psycopg2 import IntegrityError -from odoo import fields +from odoo import Command from odoo.exceptions import AccessError, ValidationError, UserError from odoo.tools import mute_logger, test_reports @@ -90,7 +90,7 @@ class TestHolidaysFlow(TestHrHolidaysCommon): 'employee_requests': 'no', 'allocation_validation_type': 'officer', 'leave_validation_type': 'both', - 'responsible_id': self.env.ref('base.user_admin').id, + 'responsible_ids': [Command.link(self.env.ref('base.user_admin').id)], }) self.env['hr.leave.allocation'].create([ @@ -244,7 +244,7 @@ class TestHolidaysFlow(TestHrHolidaysCommon): 'employee_requests': 'no', 'allocation_validation_type': 'officer', 'leave_validation_type': 'both', - 'responsible_id': self.env.ref('base.user_admin').id, + 'responsible_ids': [Command.link(self.env.ref('base.user_admin').id)], }) self.env['hr.leave.allocation'].create({ diff --git a/addons/hr_holidays/views/hr_leave_type_views.xml b/addons/hr_holidays/views/hr_leave_type_views.xml index e9a1672c2de..8249b626ce6 100644 --- a/addons/hr_holidays/views/hr_leave_type_views.xml +++ b/addons/hr_holidays/views/hr_leave_type_views.xml @@ -63,10 +63,10 @@ - + 'invisible': [('leave_validation_type', 'in', ['no_validation', 'manager']), '|', ('requires_allocation', '=', 'no'), ('allocation_validation_type', '!=', 'officer')]}"/> diff --git a/addons/hr_work_entry_holidays/tests/common.py b/addons/hr_work_entry_holidays/tests/common.py index 3c53e1e0914..fa95484e904 100644 --- a/addons/hr_work_entry_holidays/tests/common.py +++ b/addons/hr_work_entry_holidays/tests/common.py @@ -3,6 +3,7 @@ from datetime import datetime from dateutil.relativedelta import relativedelta +from odoo import Command from odoo.fields import Datetime from odoo.addons.hr_work_entry_contract.tests.common import TestWorkEntryBase @@ -17,8 +18,10 @@ class TestWorkEntryHolidaysBase(TestWorkEntryBase): 'name': 'Legal Leaves', 'time_type': 'leave', 'requires_allocation': 'no', + 'responsible_ids': [Command.link(cls.env.ref('base.user_admin').id)], 'work_entry_type_id': cls.work_entry_type_leave.id }) + cls.env.ref('base.user_admin').notification_type = 'inbox' # I create a new employee "Jules" cls.jules_emp = cls.env['hr.employee'].create({ diff --git a/addons/hr_work_entry_holidays/tests/test_performance.py b/addons/hr_work_entry_holidays/tests/test_performance.py index 996b7b2e336..2b1844012ae 100644 --- a/addons/hr_work_entry_holidays/tests/test_performance.py +++ b/addons/hr_work_entry_holidays/tests/test_performance.py @@ -32,7 +32,7 @@ class TestWorkEntryHolidaysPerformance(TestWorkEntryHolidaysBase): self.richard_emp.generate_work_entries(date(2018, 1, 1), date(2018, 1, 2)) leave = self.create_leave(datetime(2018, 1, 1, 7, 0), datetime(2018, 1, 1, 18, 0)) - with self.assertQueryCount(__system__=79, admin=81): + with self.assertQueryCount(__system__=91, admin=93): leave.action_validate() leave.action_refuse() @@ -48,7 +48,7 @@ class TestWorkEntryHolidaysPerformance(TestWorkEntryHolidaysBase): @users('__system__', 'admin') @warmup def test_performance_leave_create(self): - with self.assertQueryCount(__system__=29, admin=30): + with self.assertQueryCount(__system__=44, admin=44): leave = self.create_leave(datetime(2018, 1, 1, 7, 0), datetime(2018, 1, 1, 18, 0)) leave.action_refuse() @@ -57,7 +57,7 @@ class TestWorkEntryHolidaysPerformance(TestWorkEntryHolidaysBase): def test_performance_leave_confirm(self): leave = self.create_leave(datetime(2018, 1, 1, 7, 0), datetime(2018, 1, 1, 18, 0)) leave.action_draft() - with self.assertQueryCount(__system__=25, admin=26): + with self.assertQueryCount(__system__=40, admin=40): leave.action_confirm() leave.state = 'refuse'