forked from Mapan/odoo17e
82 lines
4.6 KiB
Python
82 lines
4.6 KiB
Python
# -*- coding:utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from odoo import api, fields, models, _
|
|
from odoo.tools import float_round
|
|
|
|
|
|
class HrPayslipWorkedDays(models.Model):
|
|
_name = 'hr.payslip.worked_days'
|
|
_description = 'Payslip Worked Days'
|
|
_order = 'payslip_id, sequence'
|
|
|
|
name = fields.Char(compute='_compute_name', store=True, string='Description', readonly=False)
|
|
payslip_id = fields.Many2one('hr.payslip', string='Pay Slip', required=True, ondelete='cascade', index=True)
|
|
sequence = fields.Integer(required=True, index=True, default=10)
|
|
code = fields.Char(string='Code', related='work_entry_type_id.code')
|
|
work_entry_type_id = fields.Many2one('hr.work.entry.type', string='Type', required=True, help="The code that can be used in the salary rules")
|
|
number_of_days = fields.Float(string='Number of Days')
|
|
number_of_hours = fields.Float(string='Number of Hours')
|
|
is_paid = fields.Boolean(compute='_compute_is_paid', store=True)
|
|
amount = fields.Monetary(string='Amount', compute='_compute_amount', store=True, copy=True)
|
|
contract_id = fields.Many2one(related='payslip_id.contract_id', string='Contract',
|
|
help="The contract this worked days should be applied to")
|
|
currency_id = fields.Many2one('res.currency', related='payslip_id.currency_id')
|
|
is_credit_time = fields.Boolean(string='Credit Time')
|
|
|
|
@api.depends(
|
|
'work_entry_type_id', 'payslip_id', 'payslip_id.struct_id',
|
|
'payslip_id.employee_id', 'payslip_id.contract_id', 'payslip_id.struct_id', 'payslip_id.date_from', 'payslip_id.date_to')
|
|
def _compute_is_paid(self):
|
|
unpaid = {struct.id: struct.unpaid_work_entry_type_ids.ids for struct in self.mapped('payslip_id.struct_id')}
|
|
for worked_days in self:
|
|
worked_days.is_paid = (worked_days.work_entry_type_id.id not in unpaid[worked_days.payslip_id.struct_id.id]) if worked_days.payslip_id.struct_id.id in unpaid else False
|
|
|
|
@api.depends('is_paid', 'is_credit_time', 'number_of_hours', 'payslip_id', 'contract_id.wage', 'payslip_id.sum_worked_hours')
|
|
def _compute_amount(self):
|
|
for worked_days in self:
|
|
if worked_days.payslip_id.edited or worked_days.payslip_id.state not in ['draft', 'verify']:
|
|
continue
|
|
if not worked_days.contract_id or worked_days.code == 'OUT' or worked_days.is_credit_time:
|
|
worked_days.amount = 0
|
|
continue
|
|
if worked_days.payslip_id.wage_type == "hourly":
|
|
worked_days.amount = worked_days.payslip_id.contract_id.hourly_wage * worked_days.number_of_hours if worked_days.is_paid else 0
|
|
else:
|
|
worked_days.amount = worked_days.payslip_id.contract_id.contract_wage * worked_days.number_of_hours / (worked_days.payslip_id.sum_worked_hours or 1) if worked_days.is_paid else 0
|
|
|
|
def _is_half_day(self):
|
|
self.ensure_one()
|
|
work_hours = self.payslip_id._get_worked_day_lines_hours_per_day()
|
|
# For refunds number of days is negative
|
|
return abs(self.number_of_days) < 1 or float_round(self.number_of_hours / self.number_of_days, 2) < work_hours
|
|
|
|
@api.depends('work_entry_type_id', 'number_of_days', 'number_of_hours', 'payslip_id')
|
|
def _compute_name(self):
|
|
to_check_public_holiday = {
|
|
res[0]: res[1]
|
|
for res in self.env['resource.calendar.leaves']._read_group(
|
|
[
|
|
('resource_id', '=', False),
|
|
('work_entry_type_id', 'in', self.mapped('work_entry_type_id').ids),
|
|
('date_from', '<=', max(self.payslip_id.mapped('date_to'))),
|
|
('date_to', '>=', min(self.payslip_id.mapped('date_from'))),
|
|
],
|
|
['work_entry_type_id'],
|
|
['id:recordset']
|
|
)
|
|
}
|
|
for worked_days in self:
|
|
public_holidays = to_check_public_holiday.get(worked_days.work_entry_type_id, '')
|
|
holidays = public_holidays and public_holidays.filtered(lambda p:
|
|
(p.calendar_id.id == worked_days.payslip_id.contract_id.resource_calendar_id.id or not p.calendar_id.id)
|
|
and p.date_from.date() <= worked_days.payslip_id.date_to
|
|
and p.date_to.date() >= worked_days.payslip_id.date_from
|
|
and p.company_id == worked_days.payslip_id.company_id)
|
|
half_day = worked_days._is_half_day()
|
|
if holidays:
|
|
name = (', '.join(holidays.mapped('name')))
|
|
else:
|
|
name = worked_days.work_entry_type_id.name
|
|
worked_days.name = name + (_(' (Half-Day)') if half_day else '')
|