From 05bb9848a25dfbef7feebe648983965ce6781b7d Mon Sep 17 00:00:00 2001 From: RomainLibert Date: Thu, 15 Feb 2018 11:36:10 +0100 Subject: [PATCH] [IMP] resource: add time_type field on resource.calendar.leaves We would like to have an overview of project forecast that include leaves, for this we need to implement several kind of 'leaves' directly in resource module. These kind of 'leaves' can be defined via the hr.leave.type model (only visible in base.group_no_one (choices currently are 'leave' and 'other') * Add field time_type on resource.calendar.leaves * Add a domain restriction that allows for filtering on this field * Add tests --- addons/hr_holidays/models/hr_leave.py | 3 +- addons/hr_holidays/models/hr_leave_type.py | 3 ++ addons/hr_holidays/tests/__init__.py | 1 + .../hr_holidays/tests/test_hr_leave_type.py | 41 +++++++++++++++++++ .../hr_holidays/views/hr_leave_type_views.xml | 1 + addons/resource/models/resource.py | 12 ++++-- addons/resource/tests/test_resource.py | 37 +++++++++++++++++ 7 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 addons/hr_holidays/tests/test_hr_leave_type.py diff --git a/addons/hr_holidays/models/hr_leave.py b/addons/hr_holidays/models/hr_leave.py index 69d578ff281..e3a56911a0e 100644 --- a/addons/hr_holidays/models/hr_leave.py +++ b/addons/hr_holidays/models/hr_leave.py @@ -283,7 +283,8 @@ class HolidaysRequest(models.Model): 'holiday_id': leave.id, 'date_to': leave.date_to, 'resource_id': leave.employee_id.resource_id.id, - 'calendar_id': leave.employee_id.resource_calendar_id.id + 'calendar_id': leave.employee_id.resource_calendar_id.id, + 'time_type': leave.holiday_status_id.time_type, }) return True diff --git a/addons/hr_holidays/models/hr_leave_type.py b/addons/hr_holidays/models/hr_leave_type.py index a7db3f2ff48..b70edf35fe6 100644 --- a/addons/hr_holidays/models/hr_leave_type.py +++ b/addons/hr_holidays/models/hr_leave_type.py @@ -77,6 +77,9 @@ class HolidaysType(models.Model): valid = fields.Boolean(compute='_compute_valid', search='_search_valid', help='This indicates if it is still possible to use this type of leave') + time_type = fields.Selection([('leave', 'Leave'), ('other', 'Other')], default='leave', string="Kind of Leave", + help="Whether this should be computed as a holiday or as work time (eg: formation)") + @api.multi @api.constrains('validity_start', 'validity_stop') def _check_validity_dates(self): diff --git a/addons/hr_holidays/tests/__init__.py b/addons/hr_holidays/tests/__init__.py index 06db7a9dca4..1300f22a091 100644 --- a/addons/hr_holidays/tests/__init__.py +++ b/addons/hr_holidays/tests/__init__.py @@ -2,3 +2,4 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from . import test_holidays_flow +from . import test_hr_leave_type diff --git a/addons/hr_holidays/tests/test_hr_leave_type.py b/addons/hr_holidays/tests/test_hr_leave_type.py new file mode 100644 index 00000000000..ebd2851ff60 --- /dev/null +++ b/addons/hr_holidays/tests/test_hr_leave_type.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from datetime import datetime +from dateutil.relativedelta import relativedelta + +from odoo.addons.hr_holidays.tests.common import TestHrHolidaysBase + + +class TestHrLeaveType(TestHrHolidaysBase): + def setUp(self): + super(TestHrLeaveType, self).setUp() + + LeaveType = self.env['hr.leave.type'] + + self.leave_leave = LeaveType.create({ + 'name': 'Legal Leaves', + 'limit': True, + 'time_type': 'leave', + }) + + def test_time_type(self): + Leave = self.env['hr.leave'] + RLeave = self.env['resource.calendar.leaves'] + + leave_1 = Leave.create({ + 'name': 'Doctor Appointment', + 'employee_id': self.employee_hruser_id, + 'holiday_status_id': self.leave_leave.id, + 'date_from': (datetime.today() - relativedelta(days=1)), + 'date_to': datetime.today(), + 'number_of_days_temp': 1, + }) + + leave_1.action_approve() + + self.assertEqual(RLeave.search([('holiday_id', '=', leave_1.id)]).time_type, 'leave') + + leave_1.action_refuse() + leave_1.action_draft() + + leave_1.unlink() diff --git a/addons/hr_holidays/views/hr_leave_type_views.xml b/addons/hr_holidays/views/hr_leave_type_views.xml index d5ae5093123..c100347b534 100644 --- a/addons/hr_holidays/views/hr_leave_type_views.xml +++ b/addons/hr_holidays/views/hr_leave_type_views.xml @@ -30,6 +30,7 @@ + diff --git a/addons/resource/models/resource.py b/addons/resource/models/resource.py index 6bba1a1911a..292d24c6a87 100644 --- a/addons/resource/models/resource.py +++ b/addons/resource/models/resource.py @@ -314,6 +314,8 @@ class ResourceCalendar(models.Model): search_domain += [('date_from', '<', fields.Datetime.to_string(end_datetime + timedelta(days=1)))] if domain: search_domain += domain + if domain is None: + search_domain += [('time_type', '=', 'leave')] leaves = self.env['resource.calendar.leaves'].search(search_domain + [('calendar_id', '=', self.id)]) filtered_leaves = self.env['resource.calendar.leaves'] @@ -591,9 +593,9 @@ class ResourceCalendar(models.Model): return intervals @api.multi - def plan_hours(self, hours, day_dt, compute_leaves=False, resource_id=None): + def plan_hours(self, hours, day_dt, compute_leaves=False, resource_id=None, domain=None): """ Return datetime after having planned hours """ - res = self._schedule_hours(hours, day_dt, compute_leaves, resource_id) + res = self._schedule_hours(hours, day_dt, compute_leaves, resource_id, domain) if res and hours < 0.0: return res[0][0] elif res: @@ -641,9 +643,9 @@ class ResourceCalendar(models.Model): return intervals @api.multi - def plan_days(self, days, day_dt, compute_leaves=False, resource_id=None): + def plan_days(self, days, day_dt, compute_leaves=False, resource_id=None, domain=None): """ Returns the datetime of a days scheduling. """ - res = self._schedule_days(days, day_dt, compute_leaves, resource_id) + res = self._schedule_days(days, day_dt, compute_leaves, resource_id, domain) return res and res[-1][1] or False @@ -762,6 +764,8 @@ class ResourceCalendarLeaves(models.Model): resource_id = fields.Many2one( "resource.resource", 'Resource', help="If empty, this is a generic holiday for the company. If a resource is set, the holiday/leave is only for this resource") + time_type = fields.Selection([('leave', 'Leave'), ('other', 'Other')], default='leave', + help="Whether this should be computed as a holiday or as work time (eg: formation)") @api.constrains('date_from', 'date_to') def check_dates(self): diff --git a/addons/resource/tests/test_resource.py b/addons/resource/tests/test_resource.py index ed1d81fd54f..8e8c5b8015d 100644 --- a/addons/resource/tests/test_resource.py +++ b/addons/resource/tests/test_resource.py @@ -810,3 +810,40 @@ class TestGlobalLeaves(TestResourceCommon): work_spec = [to_tuple(x) for x in self.calendar._get_day_leave_intervals(Date.from_string('2018-04-06'), time(0), time(23, 59, 59), self.resource1_id)] self.assertEqual(work_spec[0], (Datetime.from_string('2018-04-06 16:00:00'), Datetime.from_string('2018-04-06 21:00:00'))) + + +class TestTimeType(TestResourceCommon): + def setUp(self): + super(TestTimeType, self).setUp() + Leave = self.env['resource.calendar.leaves'] + + self.other1 = Leave.create({ + 'name': 'Formation', + 'calendar_id': self.calendar.id, + 'resource_id': self.resource1_id, + 'date_from': Datetime.from_string('2013-02-15 09:00:00'), + 'date_to': Datetime.from_string('2013-02-15 19:00:00'), + 'time_type': 'other', + }) + self.other2 = Leave.create({ + 'name': 'Homeworking', + 'calendar_id': self.calendar.id, + 'resource_id': self.resource1_id, + 'date_from': Datetime.from_string('2013-02-12 09:00:00'), + 'date_to': Datetime.from_string('2013-02-12 15:00:00'), + 'time_type': 'other', + }) + + def test_leaves_leaves(self): + # Here we test if setting the value to leave has the effect intended + leave = self.calendar._get_day_leave_intervals(Date.from_string('2013-02-26'), time(0), time(23, 59, 59), self.resource1_id, [('time_type', '=', 'leave')]) + self.assertEqual(len(leave), 1, "When asking for leave should compute the leaves") + leave = self.calendar._get_day_leave_intervals(Date.from_string('2013-02-15'), time(0), time(23, 59, 59), self.resource1_id, [('time_type', '=', 'leave')]) + self.assertEqual(len(leave), 0, "When asking for leave should ignore others") + + def test_leaves_other(self): + # Here we test if setting the value to other has the effect intended + leave = self.calendar._get_day_leave_intervals(Date.from_string('2013-02-26'), time(0), time(23, 59, 59), self.resource1_id, [('time_type', '=', 'other')]) + self.assertEqual(len(leave), 0, "When asking for other should ignore leaves") + leave = self.calendar._get_day_leave_intervals(Date.from_string('2013-02-15'), time(0), time(23, 59, 59), self.resource1_id, [('time_type', '=', 'other')]) + self.assertEqual(len(leave), 2, "When asking for other should compute others")