Files
enterprise-addons/hr_work_entry_planning_attendance/models/hr_version.py
T

70 lines
3.2 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
from collections import defaultdict
from datetime import datetime
from dateutil.relativedelta import relativedelta
from odoo import models
from odoo.tools.intervals import Intervals
class HrOvertimeRule(models.Model):
_inherit = 'hr.attendance.overtime.rule'
_name = 'hr.attendance.overtime.rule'
def _get_expected_hours_from_contract(self, date, version, period='day'):
if version.work_entry_source == 'planning' and version.overtime_from_attendance:
date_start = date
date_end = date
if period == 'week':
date_start = date_start - relativedelta(days=date_start.weekday()) # Set to Monday
date_end = date_start + relativedelta(days=6) # Set to Sunday
start_dt = datetime.combine(date_start, datetime.min.time())
end_dt = datetime.combine(date_end, datetime.max.time())
search_domain = [
('employee_id', '=', version.employee_id.id),
('state', '=', 'published'),
('start_datetime', '<', end_dt.replace(tzinfo=None)),
('end_datetime', '>', start_dt.replace(tzinfo=None)),
]
planning_slots = self.env['planning.slot'].sudo().search(search_domain)
expected_hours = sum(planning_slots.mapped('duration'))
return expected_hours
return super()._get_expected_hours_from_contract(date, version, period)
class HrVersion(models.Model):
_inherit = 'hr.version'
_name = 'hr.version'
def _get_attendance_intervals(self, start_dt, end_dt):
##################################
# PLANNING BASED CONTRACTS WITH ATTENDANCE OVERTIME #
##################################
mapped_intervals = super()._get_attendance_intervals(start_dt, end_dt)
planning_based_contracts = self.filtered(lambda c: c.work_entry_source == 'planning' and c.overtime_from_attendance)
attendances = self.env['hr.attendance'].sudo().search([
('employee_id', 'in', planning_based_contracts.employee_id.ids),
('check_in', '<=', end_dt.replace(tzinfo=None)),
('check_out', '>=', start_dt.replace(tzinfo=None)), # We ignore attendances which don't have a check_out
])
overtime_intervals = {r: Intervals(keep_distinct=True) for r in mapped_intervals}
overtime_intervals.update(planning_based_contracts._get_overtime_intervals(start_dt, end_dt))
planning_based_contracts._set_real_overtime_intervals(start_dt, end_dt, attendances, mapped_intervals, overtime_intervals)
work_entry_overtime_intervals = defaultdict(list)
for r, intervals in overtime_intervals.items():
for start, end, overtime in intervals:
if not (overtime.rule_ids.work_entry_type_id and overtime.status == 'approved'):
continue
work_entry_overtime_intervals[r].extend([
(start, end, overtime)
])
result = {
r: (mapped_intervals[r] - overtime_intervals[r])
| Intervals(work_entry_overtime_intervals[r], keep_distinct=True)
for r in mapped_intervals
}
return result