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.
 
 
 
 
 

109 lines
5.2 KiB

# -*- coding: utf-8 -*-
###################################################################################
# A part of OpenHrms Project <https://www.openhrms.com>
#
# Cybrosys Technologies Pvt. Ltd.
# Copyright (C) 2018-TODAY Cybrosys Technologies (<https://www.cybrosys.com>).
# Author: Saritha Sahadevan (<https://www.cybrosys.com>)
#
# This program is free software: you can modify
# it under the terms of the GNU Affero General Public License (AGPL) as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
###################################################################################
from datetime import datetime, timedelta
from odoo import models, fields, api, _, tools
class HrPayroll(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 = []
# fill only if the contract as a working schedule linked
uom_day = self.env.ref('product.product_uom_day', raise_if_not_found=False)
for contract in self.env['hr.contract'].browse(contract_ids).filtered(lambda contract: 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 = {}
# Gather all intervals and holidays
for days in contract.shift_schedule:
start_date = datetime.strptime(days.start_date, tools.DEFAULT_SERVER_DATE_FORMAT)
end_date = datetime.strptime(days.end_date, tools.DEFAULT_SERVER_DATE_FORMAT)
nb_of_days = (end_date - start_date).days + 1
for day in range(0, nb_of_days):
working_intervals_on_day = days.hr_shift.get_working_intervals_of_day(
start_dt=start_date + 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
res.append(data)
return res