Files
odoo_source/addons/hr_payroll/models/resource.py
T
Lucas Lefèvre 75ef4686ff [IMP] hr_payroll: Add notion of full time/part time on resource calendar
Purpose
=======

In order to be able to manage payroll, we need to know if a resource calendar
is a full time or a part time. For instance, in belgium, 23h a week is a full
time for a teacher but in cp 200 it is 38h. In belgium every employee can take a
parental leave in part time but he cannot take it in part time if they are not full time.
Having a field indicating if the contract is full time or not is useful for computing
salary rules.

Specification
=============

On the calendar model
- Display a computed field with the number of hours in the calendar
- Display a field with the required number of hours to be full time
- Display a computed checkbox, ticked if full time or not

On the contract model
- Add a related on these fields, to ease the access on the salary rules computation.

closes odoo/odoo#30034
2019-01-15 16:04:21 +00:00

78 lines
3.5 KiB
Python

# -*- coding:utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import models, fields, api
from odoo.osv.expression import AND, OR
from odoo.tools import float_compare
class ResourceCalendar(models.Model):
_inherit = 'resource.calendar'
hours_per_week = fields.Float(compute="_compute_hours_per_week", string="Hours per Week")
full_time_required_hours = fields.Float(string="Fulltime Hours", help="Number of hours to work to be considered as fulltime.")
is_fulltime = fields.Boolean(compute='_compute_is_fulltime', string="Is Full Time")
# UI fields
normal_attendance_ids = fields.One2many(
'resource.calendar.attendance', 'calendar_id', 'Normal working Time',
domain=[('resource_id', '=', False)])
extra_attendance_ids = fields.One2many(
'resource.calendar.attendance', 'calendar_id', 'Employees working Time',
domain=[('resource_id', '!=', False)])
@api.depends('normal_attendance_ids.hour_from', 'normal_attendance_ids.hour_to')
def _compute_hours_per_week(self):
for calendar in self:
calendar.hours_per_week = sum((attendance.hour_to - attendance.hour_from) for attendance in calendar.normal_attendance_ids)
def _compute_is_fulltime(self):
for calendar in self:
calendar.is_fulltime = not float_compare(calendar.full_time_required_hours, calendar.hours_per_week, 3)
class ResourceCalendarAttendance(models.Model):
_inherit = 'resource.calendar.attendance'
def _default_benefit_type_id(self):
return self.env.ref('hr_payroll.benefit_type_attendance', raise_if_not_found=False)
benefit_type_id = fields.Many2one('hr.benefit.type', 'Benefit Type', default=_default_benefit_type_id)
class ResourceCalendarLeave(models.Model):
_inherit = 'resource.calendar.leaves'
benefit_type_id = fields.Many2one('hr.benefit.type', 'Benefit Type')
class ResourceMixin(models.AbstractModel):
_inherit = "resource.mixin"
def get_benefit_days_data(self, benefit_type, from_datetime, to_datetime, calendar=None):
"""
By default the resource calendar is used, but it can be
changed using the `calendar` argument.
Returns a dict {'days': n, 'hours': h} containing the number of leaves
expressed as days and as hours.
"""
resource = self.resource_id
calendar = calendar or self.resource_calendar_id
benefit_type_ids = benefit_type.ids
if benefit_type == self.env.ref('hr_payroll.benefit_type_attendance'): # special case for global attendances
benefit_type_ids += [False]# no benefit type = normal/global attendance
domain = [('benefit_type_id', 'in', benefit_type_ids)]
# naive datetimes are made explicit in UTC
from_datetime = self._timezone_datetime(from_datetime)
to_datetime = self._timezone_datetime(to_datetime)
day_total = self._get_day_total(from_datetime, to_datetime, calendar, resource)
# actual hours per day
if benefit_type.is_leave:
intervals = calendar._attendance_intervals(from_datetime, to_datetime, resource) & calendar._leave_intervals(from_datetime, to_datetime, resource, domain) # use domain to only retrieve leaves of this type
else:
intervals = calendar._attendance_intervals(from_datetime, to_datetime, resource, domain) - calendar._leave_intervals(from_datetime, to_datetime, resource)
return self._get_days_data(intervals, day_total)