261 lines
12 KiB
Python
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')
|