Files
enterprise-addons/hr_payroll/wizard/hr_payroll_payment_report_wizard.py
T

108 lines
4.7 KiB
Python

import base64
import csv
from io import StringIO
from odoo import api, fields, models, _
from odoo.exceptions import ValidationError
from odoo.tools.misc import format_amount, format_date
class HrPayrollPaymentReportWizard(models.TransientModel):
_name = 'hr.payroll.payment.report.wizard'
_description = 'HR Payroll Payment Report Wizard'
payslip_run_id = fields.Many2one('hr.payslip.run', check_company=True)
payslip_ids = fields.Many2many('hr.payslip', required=True, check_company=True)
export_format = fields.Selection([
('csv', 'CSV'),
], string='Export Format', required=True, default='csv')
company_id = fields.Many2one('res.company', compute="_compute_company_id")
effective_date = fields.Date(
string='Payment Date',
help='Payment Entry Date: the banking day on which you intend the payslip batch to be settled.',
default=fields.Date.context_today, required=True)
@api.depends('payslip_ids')
def _compute_company_id(self):
self.company_id = self.payslip_ids[0].company_id
def _create_csv_binary(self):
output = StringIO()
report_data = csv.writer(output)
report_data.writerow([_('Sequence'), _('Payment Date'), _('Report Date'), _('Payslip Period'), _('Employee name'), _('Bank account'), _('BIC'), _('Amount to pay')])
rows = []
index = 1
for slip in self.payslip_ids:
legal_name = slip.employee_id.legal_name
allocations = slip.compute_salary_allocations()
if not allocations:
continue
for ba in slip.employee_id.bank_account_ids:
amount = allocations[str(ba.id)]
if amount == 0:
continue
rows.append((
str(index),
format_date(self.env, self.effective_date),
format_date(self.env, fields.Date.today()),
format_date(self.env, slip.date_from) + ' - ' + format_date(self.env, slip.date_to),
legal_name,
ba.acc_number,
ba.bank_bic or '',
format_amount(self.env, amount, slip.currency_id)
))
index += 1
report_data.writerows(rows)
return base64.encodebytes(output.getvalue().encode())
def _write_file(self, payment_report, extension, filename=''):
if self.payslip_run_id:
batch_filename = filename or _('Payment Report - %(batch_name)s', batch_name=self.payslip_run_id.name)
self.payslip_run_id.write({
'payment_report': payment_report,
'payment_report_filename': batch_filename + extension,
'payment_report_format': dict(self._fields['export_format']._description_selection(self.env))[self.export_format],
'payment_report_date': fields.Date.today()})
for payslip in self.payslip_ids:
payslip_filename = filename or _('Payment Report - %(dates)s - %(employee_name)s',
dates=payslip._get_period_name({}),
employee_name=payslip.employee_id.legal_name)
payslip.write({
'payment_report': payment_report,
'payment_report_filename': payslip_filename + extension,
'payment_report_date': fields.Date.today()})
def _perform_checks(self):
"""
Extend this function and first call super()._perform_checks().
Then make condition(s) for the format(s) you added and corresponding checks.
The checks below are common to all payment reports.
"""
if not self.payslip_ids:
raise ValidationError(_('There should be at least one payslip to generate the file.'))
payslips = self.payslip_ids.filtered(lambda p: p.state == "validated" and p.net_wage > 0)
if not payslips:
raise ValidationError(_('There is no valid payslip (validated and net wage > 0) to generate the file.'))
def _write_payment_date(self):
self.payslip_ids.write({
'paid_date': self.effective_date
})
def generate_payment_report(self):
"""
Extend this function and first call super().generate_payment_report().
Then make condition(s) for the format(s) you added and corresponding methods.
"""
self.ensure_one()
if self.payslip_ids.filtered('error_count'):
raise ValidationError(self._get_error_message())
self._perform_checks()
self._write_payment_date()
if self.export_format == 'csv':
payment_report = self._create_csv_binary()
self._write_file(payment_report, '.csv')