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

261 lines
12 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
from datetime import date
from dateutil.relativedelta import relativedelta
from odoo.tests.common import tagged
from odoo.addons.hr_payroll.tests.common import TestPayslipContractBase
@tagged('payslip_domain_condition')
class TestDomainCondition(TestPayslipContractBase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.company_2 = cls.env['res.company'].create({'name': 'Shrek Comp'})
cls.shrek_emp = cls.env['hr.employee'].create({
'name': 'Shrek',
'company_id': cls.company_2.id,
'date_version': date(2000, 4, 22),
'contract_date_start': date(2000, 4, 22),
'wage': 5000.33,
'structure_type_id': cls.structure_type.id,
})
cls.shrek_contract = cls.shrek_emp.version_id
cls.company_3 = cls.env['res.company'].create({'name': 'Donkey Comp'})
cls.donkey_emp = cls.env['hr.employee'].create({
'name': 'Donkey',
'company_id': cls.company_3.id,
'date_version': date(2000, 4, 22),
'contract_date_start': date(2000, 4, 22),
'wage': 5000.33,
'structure_type_id': cls.structure_type.id,
})
cls.donkey_contract = cls.donkey_emp.version_id
def _generate_payslip(self, date_from, struct, employee=None):
date_to = date_from + relativedelta(months=1, days=-1)
test_payslip = self.env['hr.payslip'].create({
'name': 'Payslip for domain condition tests - ' + str(date_from),
'employee_id': employee.id,
'company_id': employee.company_id.id,
'struct_id': struct.id,
'date_from': date_from,
'date_to': date_to,
})
test_payslip.compute_sheet()
test_payslip.action_payslip_done()
return test_payslip
def _assert_rule_applied(self, payslip, rule_code, expected_amount):
rule_line = payslip.line_ids.filtered(lambda l: l.code == rule_code) or 0
self.assertTrue(rule_line, f"Rule line {rule_code} not found in payslip.")
self.assertAlmostEqual(rule_line.total, expected_amount, delta=0.01,
msg=f"The total for {rule_code} should be {expected_amount} but is {rule_line.total}.")
def _assert_rule_not_applied(self, payslip, rule_code):
rule_line = payslip.line_ids.filtered(lambda l: l.code == rule_code)
self.assertEqual(len(rule_line), 0, f"Rule line {rule_code} should not be applied in payslip.")
def test_domain_01_basic(self):
domain_test_structure_01 = self.env['hr.payroll.structure'].create({
'name': 'Salary Structure for domain test 01',
'type_id': self.structure_type.id,
})
self.env['hr.salary.rule'].create({
'name': 'Always True Domain Rule',
'code': 'DOMTRUE',
'category_id': self.env.ref('hr_payroll.ALW').id,
'struct_id': domain_test_structure_01.id,
'condition_select': 'domain',
'condition_domain': "[]",
'amount_select': 'fix',
'amount_fix': 100.0,
})
self.env['hr.salary.rule'].create({
'name': 'Shrek Specific Domain Rule',
'code': 'DOMSHREK',
'category_id': self.env.ref('hr_payroll.ALW').id,
'struct_id': domain_test_structure_01.id,
'condition_select': 'domain',
'condition_domain': "[('employee_id.name', '=', 'Shrek')]",
'amount_select': 'fix',
'amount_fix': 200.0,
})
self.env['hr.salary.rule'].create({
'name': 'Always False Domain Rule',
'code': 'DOMFALSE',
'category_id': self.env.ref('hr_payroll.ALW').id,
'struct_id': domain_test_structure_01.id,
'condition_select': 'domain',
'condition_domain': "[('id', '=', 0)]",
'amount_select': 'fix',
'amount_fix': 300.0,
})
payslip_shrek = self._generate_payslip(date(2024, 1, 1), domain_test_structure_01, employee=self.shrek_emp)
payslip_donkey = self._generate_payslip(date(2024, 1, 1), domain_test_structure_01, employee=self.donkey_emp)
self._assert_rule_applied(payslip_shrek, 'DOMTRUE', 100.0)
self._assert_rule_applied(payslip_shrek, 'DOMSHREK', 200.0)
self._assert_rule_not_applied(payslip_shrek, 'DOMFALSE')
self._assert_rule_applied(payslip_donkey, 'DOMTRUE', 100.0)
self._assert_rule_not_applied(payslip_donkey, 'DOMSHREK')
self._assert_rule_not_applied(payslip_donkey, 'DOMFALSE')
def test_domain_02_dynamic_and_company_specific(self):
domain_test_structure_02 = self.env['hr.payroll.structure'].create({
'name': 'Salary Structure for domain test 02',
'type_id': self.structure_type.id,
})
self.env['hr.salary.rule'].create({
'name': 'Date Specific Domain Rule',
'code': 'DOMDATE',
'category_id': self.env.ref('hr_payroll.ALW').id,
'struct_id': domain_test_structure_02.id,
'condition_select': 'domain',
'condition_domain': '[("date_from", ">=", "2024-06-01")]',
'amount_select': 'fix',
'amount_fix': 150.0,
})
self.env['hr.salary.rule'].create({
'name': 'Company Specific Domain Rule',
'code': 'DOMCOMP',
'category_id': self.env.ref('hr_payroll.ALW').id,
'struct_id': domain_test_structure_02.id,
'condition_select': 'domain',
'condition_domain': '[("company_id.name", "=", "Donkey Comp")]',
'amount_select': 'fix',
'amount_fix': 250.0,
})
payslip_early = self._generate_payslip(date(2024, 5, 1), domain_test_structure_02, employee=self.shrek_emp)
self._assert_rule_not_applied(payslip_early, 'DOMDATE')
self._assert_rule_not_applied(payslip_early, 'DOMCOMP')
payslip_early = self._generate_payslip(date(2024, 5, 1), domain_test_structure_02, employee=self.donkey_emp)
self._assert_rule_not_applied(payslip_early, 'DOMDATE')
self._assert_rule_applied(payslip_early, 'DOMCOMP', 250.00)
payslip_june = self._generate_payslip(date(2024, 6, 1), domain_test_structure_02, employee=self.shrek_emp)
self._assert_rule_applied(payslip_june, 'DOMDATE', 150.0)
self._assert_rule_not_applied(payslip_june, 'DOMCOMP')
payslip_june = self._generate_payslip(date(2024, 6, 1), domain_test_structure_02, employee=self.donkey_emp)
self._assert_rule_applied(payslip_june, 'DOMDATE', 150.0)
self._assert_rule_applied(payslip_june, 'DOMCOMP', 250.00)
def test_domain_03_complex_and_dynamic_eval(self):
domain_test_structure_03 = self.env['hr.payroll.structure'].create({
'name': 'Salary Structure for domain test 03',
'type_id': self.structure_type.id,
})
self.env['hr.salary.rule'].create({
'name': 'Complex Domain Rule',
'code': 'DOMCOMPX',
'category_id': self.env.ref('hr_payroll.ALW').id,
'struct_id': domain_test_structure_03.id,
'condition_select': 'domain',
'condition_domain': "[('employee_id.name', 'in', ['Prince', 'Shrek']), ('date_from.year_number', '=', 2024)]",
'amount_select': 'fix',
'amount_fix': 300.0,
})
payslip_shrek_2024 = self._generate_payslip(date(2024, 1, 1), domain_test_structure_03, employee=self.shrek_emp)
payslip_donkey_2024 = self._generate_payslip(date(2024, 1, 1), domain_test_structure_03, employee=self.donkey_emp)
self._assert_rule_applied(payslip_shrek_2024, 'DOMCOMPX', 300.0)
self._assert_rule_not_applied(payslip_donkey_2024, 'DOMCOMPX')
payslip_shrek_2025 = self._generate_payslip(date(2025, 1, 1), domain_test_structure_03, employee=self.shrek_emp)
payslip_donkey_2025 = self._generate_payslip(date(2025, 1, 1), domain_test_structure_03, employee=self.donkey_emp)
self._assert_rule_not_applied(payslip_shrek_2025, 'DOMCOMPX')
self._assert_rule_not_applied(payslip_donkey_2025, 'DOMCOMPX')
def test_domain_04_complex_or_condition(self):
domain_test_structure_04 = self.env['hr.payroll.structure'].create({
'name': 'Salary Structure for domain test 03',
'type_id': self.structure_type.id,
})
self.env['hr.salary.rule'].create({
'name': 'Complex Domain Rule',
'code': 'DOMCOMPX',
'category_id': self.env.ref('hr_payroll.ALW').id,
'struct_id': domain_test_structure_04.id,
'condition_select': 'domain',
'condition_domain': "['|', ('employee_id.name', 'in', ['Prince', 'Shrek']), ('date_from.year_number', '=', 2024)]",
'amount_select': 'fix',
'amount_fix': 300.0,
})
payslip_shrek_2024 = self._generate_payslip(date(2024, 1, 1), domain_test_structure_04, employee=self.shrek_emp)
payslip_donkey_2024 = self._generate_payslip(date(2024, 1, 1), domain_test_structure_04, employee=self.donkey_emp)
self._assert_rule_applied(payslip_shrek_2024, 'DOMCOMPX', 300.0)
self._assert_rule_applied(payslip_donkey_2024, 'DOMCOMPX', 300.0)
payslip_shrek_2025 = self._generate_payslip(date(2025, 1, 1), domain_test_structure_04, employee=self.shrek_emp)
payslip_donkey_2025 = self._generate_payslip(date(2025, 1, 1), domain_test_structure_04, employee=self.donkey_emp)
self._assert_rule_applied(payslip_shrek_2025, 'DOMCOMPX', 300.0)
self._assert_rule_not_applied(payslip_donkey_2025, 'DOMCOMPX')
def test_domain_05_employee_properties(self):
domain_test_structure_05 = self.env['hr.payroll.structure'].create({
'name': 'Salary Structure for domain test 05',
'type_id': self.structure_type.id,
})
self.shrek_emp.write({'employee_properties': [
{
'name': 'payroll_property',
'type': 'char',
'definition_changed': True,
'value': 'Pomme'
}
]})
self.donkey_emp.write({'employee_properties': [
{
'name': 'payroll_property',
'type': 'char',
'definition_changed': True,
'value': 'Poire'
}
]})
self.env['hr.salary.rule'].create({
'name': 'Complex Domain Rule with property fields',
'code': 'DOMCOMPX',
'category_id': self.env.ref('hr_payroll.ALW').id,
'struct_id': domain_test_structure_05.id,
'condition_select': 'domain',
'condition_domain': "[('employee_id.employee_properties.payroll_property', '=', 'Pomme'), ('date_from.year_number', '=', 2024)]",
'amount_select': 'fix',
'amount_fix': 300.0,
})
payslip_shrek_2024 = self._generate_payslip(date(2024, 1, 1), domain_test_structure_05, employee=self.shrek_emp)
payslip_donkey_2024 = self._generate_payslip(date(2024, 1, 1), domain_test_structure_05, employee=self.donkey_emp)
self._assert_rule_applied(payslip_shrek_2024, 'DOMCOMPX', 300.0)
self._assert_rule_not_applied(payslip_donkey_2024, 'DOMCOMPX')
payslip_shrek_2025 = self._generate_payslip(date(2025, 1, 1), domain_test_structure_05, employee=self.shrek_emp)
payslip_donkey_2025 = self._generate_payslip(date(2025, 1, 1), domain_test_structure_05, employee=self.donkey_emp)
self._assert_rule_not_applied(payslip_shrek_2025, 'DOMCOMPX')
self._assert_rule_not_applied(payslip_donkey_2025, 'DOMCOMPX')