You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

121 lines
5.6 KiB

# -*- coding: utf-8 -*-
from datetime import timedelta, datetime
from odoo import models, fields, api, _
class WorkedDayOvertime(models.Model):
_inherit = 'hr.payslip'
@api.model
def get_worked_day_lines(self, contract_ids, date_from, date_to):
"""
@param contract_ids: list of contract id
@return: returns a list of dict containing the input that should be applied for the given contract between date_from and date_to
"""
def was_on_leave_interval(employee_id, date_from, date_to):
date_from = fields.Datetime.to_string(date_from)
date_to = fields.Datetime.to_string(date_to)
return self.env['hr.holidays'].search([
('state', '=', 'validate'),
('employee_id', '=', employee_id),
('type', '=', 'remove'),
('date_from', '<=', date_from),
('date_to', '>=', date_to)
], limit=1)
res = []
normal_hours = 0
total_hours = 0
number_of_days = 0
contract_id = []
# fill only if the contract as a working schedule linked
uom_day = self.env.ref('product.product_uom_day', raise_if_not_found=False)
contract_id = []
for contract in self.env['hr.contract'].browse(contract_ids).filtered(lambda contract: contract.working_hours):
contract_val = contract
uom_hour = contract.employee_id.resource_id.calendar_id.uom_id or self.env.ref('product.product_uom_hour',
raise_if_not_found=False)
interval_data = []
holidays = self.env['hr.holidays']
attendances = {
'name': _("Normal Working Days paid at 100%"),
'sequence': 1,
'code': 'WORK100',
'number_of_days': 0.0,
'number_of_hours': 0.0,
'contract_id': contract.id,
}
leaves = {}
day_from = fields.Datetime.from_string(date_from)
day_to = fields.Datetime.from_string(date_to)
nb_of_days = (day_to - day_from).days + 1
# Gather all intervals and holidays
for day in range(0, nb_of_days):
working_intervals_on_day = contract.working_hours.get_working_intervals_of_day(
start_dt=day_from + timedelta(days=day))
for interval in working_intervals_on_day:
interval_data.append(
(interval, was_on_leave_interval(contract.employee_id.id, interval[0], interval[1])))
# Extract information from previous data. A working interval is considered:
# - as a leave if a hr.holiday completely covers the period
# - as a working period instead
for interval, holiday in interval_data:
holidays |= holiday
hours = (interval[1] - interval[0]).total_seconds() / 3600.0
if holiday:
# if he was on leave, fill the leaves dict
if holiday.holiday_status_id.name in leaves:
leaves[holiday.holiday_status_id.name]['number_of_hours'] += hours
else:
leaves[holiday.holiday_status_id.name] = {
'name': holiday.holiday_status_id.name,
'sequence': 5,
'code': holiday.holiday_status_id.name,
'number_of_days': 0.0,
'number_of_hours': hours,
'contract_id': contract.id,
}
else:
# add the input vals to tmp (increment if existing)
attendances['number_of_hours'] += hours
# Clean-up the results
leaves = [value for key, value in leaves.items()]
for data in [attendances] + leaves:
data['number_of_days'] = uom_hour._compute_quantity(data['number_of_hours'], uom_day) \
if uom_day and uom_hour \
else data['number_of_hours'] / 8.0
if data['name'] == 'Normal Working Days paid at 100%':
number_of_days = data['number_of_days']
normal_hours = data['number_of_hours']
contract_id = data['contract_id']
res.append(data)
date_from = fields.Datetime.from_string(date_from)
date_from += timedelta(days=-1)
date_from = str(date_from)
date_to = fields.Datetime.from_string(date_to)
date_to += timedelta(days=1)
date_to = str(date_to)
for attn_lines in self.env['hr.attendance'].search([('check_in', '>=', date_from),
('check_out', '<=', date_to),
('employee_id', '=', contract_val.employee_id.id)]):
check_in = datetime.strptime(attn_lines.check_in, '%Y-%m-%d %H:%M:%S')
check_out = datetime.strptime(attn_lines.check_out, '%Y-%m-%d %H:%M:%S')
time_diff = check_out - check_in
total_hours += ((time_diff.seconds / 60) / 60)
ovt_hours = total_hours - normal_hours
if ovt_hours > 0:
res.append({
'code': 'OVT',
'contract_id': contract_id,
'number_of_days': number_of_days,
'number_of_hours': ovt_hours,
'name': 'Overtime Hours',
})
return res