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")