odoo18/addons_extensions/hr_payroll/models/hr_payslip_run.py

119 lines
4.7 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
from datetime import date, datetime
from dateutil.relativedelta import relativedelta
from odoo import api, fields, models, _
from odoo.exceptions import UserError, ValidationError
class HrPayslipRun(models.Model):
_name = 'hr.payslip.run'
_inherit = ['mail.thread', 'mail.activity.mixin']
_description = 'Payslip Batches'
_order = 'date_end desc'
name = fields.Char(required=True)
slip_ids = fields.One2many('hr.payslip', 'payslip_run_id', string='Payslips')
state = fields.Selection([
('draft', 'New'),
('verify', 'Confirmed'),
('close', 'Done'),
('paid', 'Paid'),
], string='Status', index=True, readonly=True, copy=False, default='draft', store=True, compute='_compute_state_change')
date_start = fields.Date(string='Date From', required=True, default=lambda self: fields.Date.to_string(date.today().replace(day=1)))
date_end = fields.Date(string='Date To', required=True,
default=lambda self: fields.Date.to_string((datetime.now() + relativedelta(months=+1, day=1, days=-1)).date()))
payslip_count = fields.Integer(compute='_compute_payslip_count')
company_id = fields.Many2one('res.company', string='Company', readonly=True, required=True,
default=lambda self: self.env.company)
country_id = fields.Many2one(
'res.country', string='Country',
related='company_id.country_id', readonly=True
)
country_code = fields.Char(related='country_id.code', depends=['country_id'], readonly=True)
currency_id = fields.Many2one(related="company_id.currency_id")
payment_report = fields.Binary(
string='Payment Report',
help="Export .csv file related to this batch",
readonly=True)
payment_report_filename = fields.Char(readonly=True)
payment_report_date = fields.Date(readonly=True)
def _compute_payslip_count(self):
for payslip_run in self:
payslip_run.payslip_count = len(payslip_run.slip_ids)
@api.depends('slip_ids', 'state')
def _compute_state_change(self):
for payslip_run in self:
if payslip_run.state == 'draft' and payslip_run.slip_ids:
payslip_run.update({'state': 'verify'})
def action_draft(self):
if self.slip_ids.filtered(lambda s: s.state == 'paid'):
raise ValidationError(_('You cannot reset a batch to draft if some of the payslips have already been paid.'))
self.write({'state': 'draft'})
self.slip_ids.write({'state': 'draft'})
def action_open(self):
self.write({'state': 'verify'})
def action_close(self):
if self._are_payslips_ready():
self.write({'state' : 'close'})
def action_payment_report(self, export_format='csv'):
self.ensure_one()
self.env['hr.payroll.payment.report.wizard'].create({
'payslip_ids': self.slip_ids.ids,
'payslip_run_id': self.id,
'export_format': export_format
}).generate_payment_report()
def action_paid(self):
self.mapped('slip_ids').action_payslip_paid()
self.write({'state': 'paid'})
def action_validate(self):
payslip_done_result = self.mapped('slip_ids').filtered(lambda slip: slip.state not in ['draft', 'cancel']).action_payslip_done()
self.action_close()
return payslip_done_result
def action_confirm(self):
self.slip_ids.write({'state': 'verify'})
self.write({'state': 'verify'})
def action_open_payslips(self):
self.ensure_one()
return {
"type": "ir.actions.act_window",
"res_model": "hr.payslip",
"views": [[False, "list"], [False, "form"]],
"domain": [['id', 'in', self.slip_ids.ids]],
"context": {'default_payslip_run_id': self.id},
"name": "Payslips",
}
def action_open_payslip_run_form(self):
self.ensure_one()
return {
'type': 'ir.actions.act_window',
'res_model': 'hr.payslip.run',
'views': [[False, 'form']],
'res_id': self.id,
}
def _generate_payslips(self):
action = self.env["ir.actions.actions"]._for_xml_id("hr_payroll.action_hr_payslip_by_employees")
action['context'] = repr(self.env.context)
return action
@api.ondelete(at_uninstall=False)
def _unlink_if_draft_or_cancel(self):
if any(self.mapped('slip_ids').filtered(lambda payslip: payslip.state not in ('draft', 'cancel'))):
raise UserError(_("You can't delete a batch with payslips if they are not draft or cancelled."))
def _are_payslips_ready(self):
return all(slip.state in ['done', 'cancel'] for slip in self.mapped('slip_ids'))