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