157 lines
6.1 KiB
Python
157 lines
6.1 KiB
Python
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
from datetime import datetime, date
|
|
import base64
|
|
|
|
from odoo.exceptions import ValidationError
|
|
from odoo.tests.common import TransactionCase
|
|
from odoo.tests import tagged
|
|
|
|
|
|
@tagged('post_install', '-at_install', 'post_install_l10n')
|
|
class TestHrPayrollPayrollAcerta(TransactionCase):
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
|
|
cls.belgium = cls.env.ref('base.be')
|
|
cls.company = cls.env['res.company'].create({
|
|
'name': 'Test Belgium Company',
|
|
'country_id': cls.belgium.id,
|
|
'acerta_code': '1234567',
|
|
})
|
|
|
|
cls.employee = cls.env['hr.employee'].create({
|
|
'name': 'Test Employee',
|
|
'company_id': cls.company.id,
|
|
})
|
|
|
|
cls.version = cls.env['hr.version'].create({
|
|
'name': 'Test Version',
|
|
'employee_id': cls.employee.id,
|
|
'company_id': cls.company.id,
|
|
'contract_date_start': datetime(2024, 10, 1),
|
|
'contract_date_end': datetime(2024, 10, 31),
|
|
'acerta_code': '12345678901234567',
|
|
'wage': 3000,
|
|
'date_version': datetime(2024, 10, 1).date(),
|
|
})
|
|
|
|
cls.work_entry_type = cls.env['hr.work.entry.type'].create({
|
|
'name': 'Test Work Entry Type',
|
|
'code': 'WORKTEST',
|
|
'acerta_code': '1234',
|
|
})
|
|
|
|
cls.sick_work_entry_type = cls.env['hr.work.entry.type'].create({
|
|
'name': 'Sick time off',
|
|
'code': 'SICK110',
|
|
'acerta_code': '050',
|
|
})
|
|
|
|
cls.sick_time_off_type = cls.env['hr.leave.type'].create({
|
|
'name': 'Sick Time Off',
|
|
'requires_allocation': False,
|
|
'work_entry_type_id': cls.sick_work_entry_type.id,
|
|
})
|
|
|
|
def test_hr_version_acerta_code_zfill(self):
|
|
"""Test hr.version acerta_code shorter than 20 chars is zero-padded"""
|
|
self.version.write({'acerta_code': '12345'})
|
|
self.assertEqual(len(self.version.acerta_code), 17)
|
|
self.assertTrue(self.version.acerta_code.endswith('12345'))
|
|
|
|
def test_work_entry_type_acerta_code_validation(self):
|
|
"""Test hr.work.entry.type acerta_code validation (must be 3-6 characters)"""
|
|
with self.assertRaises(ValidationError):
|
|
self.work_entry_type.write({'acerta_code': '12'})
|
|
with self.assertRaises(ValidationError):
|
|
self.work_entry_type.write({'acerta_code': '1234567'})
|
|
self.work_entry_type.write({'acerta_code': '4321'})
|
|
self.assertEqual(
|
|
self.work_entry_type.acerta_code,
|
|
'4321',
|
|
"Acerta code should be valid when between 3 and 6 characters long"
|
|
)
|
|
|
|
def test_company_acerta_code_validation(self):
|
|
"""Test res.company acerta_code validation (must be exactly 7 characters)"""
|
|
with self.assertRaises(ValidationError):
|
|
self.company.write({'acerta_code': '1234'})
|
|
with self.assertRaises(ValidationError):
|
|
self.company.write({'acerta_code': '12345678'})
|
|
|
|
self.company.write({'acerta_code': '7654321'})
|
|
self.assertEqual(
|
|
self.company.acerta_code,
|
|
'7654321',
|
|
"Acerta code should be valid when exactly 7 characters long"
|
|
)
|
|
|
|
def test_full_acerta_export_flow(self):
|
|
"""Test creating an Acerta export, populating, and generating the export file without errors"""
|
|
work_entry = self.env['hr.work.entry'].create({
|
|
'name': 'Work Entry',
|
|
'company_id': self.company.id,
|
|
'employee_id': self.employee.id,
|
|
'work_entry_type_id': self.work_entry_type.id,
|
|
'date': self.version.contract_date_start,
|
|
'version_id': self.version.id,
|
|
})
|
|
work_entry.action_validate()
|
|
|
|
export = self.env['l10n.be.hr.payroll.export.acerta'].with_company(self.company.id).create({
|
|
'company_id': self.company.id,
|
|
'reference_month': '10',
|
|
'reference_year': 2024,
|
|
})
|
|
export.action_populate()
|
|
|
|
self.assertTrue(export.eligible_employee_line_ids)
|
|
self.assertIn(self.employee, export.eligible_employee_line_ids.employee_id)
|
|
|
|
export.action_export_file()
|
|
self.assertTrue(export.export_file)
|
|
|
|
def test_acerta_sick_time_off_overlapping_weekend(self):
|
|
current_version = self.env['hr.version'].create({
|
|
'name': 'Test Version',
|
|
'employee_id': self.employee.id,
|
|
'company_id': self.company.id,
|
|
'contract_date_start': datetime(2026, 1, 1),
|
|
'contract_date_end': datetime(2026, 12, 31),
|
|
'acerta_code': '3344',
|
|
'wage': 3000,
|
|
'date_version': datetime(2026, 1, 1).date(),
|
|
})
|
|
self.employee.version_id = current_version
|
|
self.employee.resource_calendar_id.company_id = self.company
|
|
self.env['hr.leave'].create({
|
|
'name': 'Sick time off',
|
|
'employee_id': self.employee.id,
|
|
'holiday_status_id': self.sick_time_off_type.id,
|
|
'request_date_from': '2026-08-07',
|
|
'request_date_to': '2026-08-10',
|
|
}).action_approve()
|
|
|
|
self.employee.version_id._generate_work_entries(datetime(2026, 8, 7, 0, 0, 0),
|
|
datetime(2026, 8, 10, 23, 59, 59))
|
|
|
|
acerta_report = self.env['l10n.be.hr.payroll.export.acerta'].create({
|
|
'company_id': self.company.id,
|
|
'period_start': date(2026, 8, 1),
|
|
'period_stop': date(2026, 8, 31),
|
|
'reference_month': '8',
|
|
'reference_year': 2026,
|
|
})
|
|
|
|
acerta_report.with_company(self.company).action_populate()
|
|
acerta_report.action_export_file()
|
|
content = base64.b64decode(acerta_report.export_file).decode('utf-8')
|
|
|
|
expected_line_sat = 'KLX1123456700000000000003344 08/08/2026 0050 0000'
|
|
expected_line_sun = 'KLX1123456700000000000003344 09/08/2026 0050 0000'
|
|
|
|
self.assertIn(expected_line_sat, content)
|
|
self.assertIn(expected_line_sun, content)
|