Files
enterprise-addons/hr_payroll/tests/test_payment_report.py
T

193 lines
7.5 KiB
Python
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import base64
import csv
import io
from datetime import date
from odoo import Command, fields
from odoo.addons.hr_payroll.tests.common import TestPayslipBase
from odoo.tools.misc import format_date
class TestHrPayslipPaymentReport(TestPayslipBase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.partner_bank_account = cls.env['res.partner.bank'].create({
'acc_number': "9876543210",
'partner_id': cls.richard_emp.work_contact_id.id,
'acc_type': 'bank',
'allow_out_payment': True,
})
cls.richard_emp.bank_account_ids = [Command.link(cls.partner_bank_account.id)]
cls.payslip = cls.env['hr.payslip'].create({
'name': 'Test Payslip',
'employee_id': cls.richard_emp.id,
'date_from': date(2025, 1, 1),
'date_to': date(2025, 1, 31),
})
def test_payslip_payment_report_fields_and_attachment(self):
self.payslip.compute_sheet()
self.payslip.action_payslip_done()
wizard = self.env['hr.payroll.payment.report.wizard'].create({
'payslip_ids': [self.payslip.id],
'payslip_run_id': self.payslip.payslip_run_id.id,
'export_format': 'csv',
})
wizard.generate_payment_report()
attachment_count = self.env['ir.attachment'].search_count([
('res_model', '=', 'hr.payslip'),
('res_id', '=', self.payslip.id),
('res_field', '=', 'payment_report'),
])
self.assertTrue(self.payslip.payment_report, "Payment report should be set initially.")
self.assertTrue(self.payslip.payment_report_filename)
self.assertTrue(self.payslip.payment_report_date)
self.assertEqual(attachment_count, 1, "Attachment should exist before clearing.")
self.payslip.action_payslip_draft()
self.env.cr.flush()
attachment_count = self.env['ir.attachment'].search_count([
('res_model', '=', 'hr.payslip'),
('res_id', '=', self.payslip.id),
('res_field', '=', 'payment_report'),
])
self.assertFalse(self.payslip.payment_report, "Payment report should be cleared.")
self.assertFalse(self.payslip.payment_report_filename, "Filename should be cleared.")
self.assertFalse(self.payslip.payment_report_date, "Date should be cleared.")
self.assertEqual(attachment_count, 0, "Attachment should be deleted after clearing.")
class TestHrPayrunPaymentReport(TestHrPayslipPaymentReport):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.payslip_run = cls.env['hr.payslip.run'].create({
'name': 'Test Batch',
'date_start': date(2025, 1, 1),
'date_end': date(2025, 1, 31),
})
cls.payslip.payslip_run_id = cls.payslip_run
def test_payrun_payment_report_fields_and_attachment(self):
self.payslip_run.action_confirm()
self.payslip_run.action_validate()
wizard = self.env['hr.payroll.payment.report.wizard'].create({
'payslip_ids': [self.payslip.id],
'payslip_run_id': self.payslip.payslip_run_id.id,
'export_format': 'csv',
})
wizard.generate_payment_report()
attachment_count = self.env['ir.attachment'].search_count([
('res_model', '=', 'hr.payslip.run'),
('res_id', '=', self.payslip_run.id),
('res_field', '=', 'payment_report'),
])
self.assertTrue(self.payslip_run.payment_report, "Payrun payment report should be set initially.")
self.assertTrue(self.payslip_run.payment_report_filename)
self.assertTrue(self.payslip_run.payment_report_format)
self.assertTrue(self.payslip_run.payment_report_date)
self.assertEqual(attachment_count, 1, "Payrun report attachment should exist before clearing.")
self.payslip_run.action_draft()
self.env.cr.flush()
attachment_count = self.env['ir.attachment'].search_count([
('res_model', '=', 'hr.payslip.run'),
('res_id', '=', self.payslip_run.id),
('res_field', '=', 'payment_report'),
])
self.assertFalse(self.payslip_run.payment_report, "Payrun payment report should be cleared.")
self.assertFalse(self.payslip_run.payment_report_filename, "Payment report filename should be cleared.")
self.assertFalse(self.payslip_run.payment_report_format, "Payment report file format should be cleared")
self.assertFalse(self.payslip_run.payment_report_date, "Payment report date should be cleared.")
self.assertEqual(attachment_count, 0, "Payrun report attachment should be deleted after clearing.")
def test_payrun_payment_report_with_multiple_payslips(self):
self.payslip.compute_sheet()
self.payslip.action_payslip_done()
test_structure = self.env['hr.payroll.structure'].create({
'name': 'Test Salary Structure',
'type_id': self.structure_type.id,
})
net_salary_rule = test_structure.rule_ids.filtered(lambda r: r.code == "NET")
net_salary_rule.write({
'amount_select': 'fix',
'amount_fix': 0.0,
})
self.env['hr.payslip'].create({
'name': 'Test Payslip with 0.0 net salary',
'employee_id': self.richard_emp.id,
'date_from': date(2025, 1, 1),
'date_to': date(2025, 1, 31),
'payslip_run_id': self.payslip_run.id,
'struct_id': test_structure.id,
})
self.payslip_run.action_confirm()
self.payslip_run.action_validate()
wizard = self.env['hr.payroll.payment.report.wizard'].create({
'payslip_ids': self.payslip_run.slip_ids.ids,
'payslip_run_id': self.payslip_run.id,
'export_format': 'csv',
})
wizard.generate_payment_report()
attachment_count = self.env['ir.attachment'].search_count([
('res_model', '=', 'hr.payslip.run'),
('res_id', '=', self.payslip_run.id),
('res_field', '=', 'payment_report'),
])
self.assertTrue(self.payslip_run.payment_report, "Payrun payment report should be set.")
self.assertTrue(self.payslip_run.payment_report_filename)
self.assertTrue(self.payslip_run.payment_report_format)
self.assertTrue(self.payslip_run.payment_report_date)
self.assertEqual(attachment_count, 1, "Payrun report attachment should exist.")
csv_data = base64.b64decode(self.payslip_run.payment_report)
content = csv_data.decode('utf-8')
reader = csv.reader(io.StringIO(content), delimiter=',')
expected_values = [
# Header row
[
'Sequence', 'Payment Date', 'Report Date', 'Payslip Period',
'Employee name', 'Bank account', 'BIC', 'Amount to pay'
],
# First data row
[
'1',
format_date(wizard.env, wizard.effective_date),
format_date(wizard.env, fields.Date.today()),
format_date(wizard.env, self.payslip.date_from) + ' - ' + format_date(wizard.env, self.payslip.date_to),
'Richard',
'9876543210',
'',
'$ 7,205.42',
],
]
for idx, content in enumerate(reader):
self.assertSequenceEqual(expected_values[idx], content)