Files
enterprise-addons/l10n_ch_hr_payroll/tests/common.py
T

160 lines
6.5 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
import logging
import pdb
from dateutil.relativedelta import relativedelta
from odoo.tests.common import tagged, TransactionCase
from odoo.tools import file_open
from odoo import Command
from odoo.tests import HttpCase, tagged, TransactionCase
import json
from datetime import datetime, date
from freezegun import freeze_time
from collections import defaultdict
from unittest.mock import patch
_logger = logging.getLogger(__name__)
@tagged('post_install_l10n', 'post_install', '-at_install', 'swissdec_payroll')
class TestSwissdecCommon(TransactionCase):
@classmethod
def _l10n_ch_generate_swissdec_demo_payslip(cls, contract, date_from, date_to, company, after_payment=False):
batch = cls.env['hr.payslip.run'].search(
[('date_start', '=', date_from), ('company_id', '=', company)])
vals = {
'name': f"Monthly Pay Batch - {date_from.year}-{date_from.month}",
'employee_id': contract.employee_id.id,
'version_id': contract.id,
'company_id': company,
'struct_id': cls.env.ref('l10n_ch_hr_payroll.hr_payroll_structure_ch_elm').id,
'date_from': date_from,
'date_to': date_to,
'l10n_ch_after_departure_payment': after_payment,
'payslip_run_id': batch.id,
}
payslip = cls.env['hr.payslip'].with_context(tracking_disable=True).create(vals)
cls.env.flush_all()
payslip.compute_sheet()
payslip.action_payslip_done()
return payslip
@classmethod
def _l10n_ch_compute_swissdec_demo_paylips(cls, company, date_from):
_logger.info('Created payslips for period %s-%s', date_from.year, date_from.month)
batch = cls._l10n_ch_create_batch(company, date_from.month, pay_13th=date_from.month == 12)
_logger.info('Computed payslips for period %s-%s', date_from.year, date_from.month)
return batch
@classmethod
def _l10n_ch_create_batch(cls, company, month, pay_13th=False):
cls.env.flush_all()
first_of_month = date.today().replace(day=1)
end_of_month = first_of_month + relativedelta(months=1, days=-1)
batch = cls.env['hr.payslip.run'].create({
"company_id": company.id,
"structure_id": cls.env.ref('l10n_ch_hr_payroll.hr_payroll_structure_ch_elm').id,
"l10n_ch_pay_13th_month": pay_13th,
"date_start": str(first_of_month),
"date_end": str(end_of_month)
})
batch.sudo().generate_payslips(batch.sudo()._get_valid_version_ids())
batch.sudo().action_validate()
cls.env.flush_all()
return batch
def _normalize_data(self, data):
"""
Recursively transform data so that the order of lists no longer matters.
"""
if isinstance(data, dict):
return {k: self._normalize_data(v) for k, v in sorted(data.items(), key=lambda d: str(d))}
elif isinstance(data, list):
return sorted([self._normalize_data(item) for item in data], key=lambda d: str(d))
else:
return data
def _get_truth_base_path(self):
return ""
def _compare_with_truth_base(self, declaration_type, identifier, generated_dict):
truth_base = json.load(file_open(f'{self._get_truth_base_path()}/{declaration_type}.json')),
truth_dict = truth_base[0].get(identifier)
json_formated = json.loads(json.dumps(generated_dict))
self.assertDictEqual(
self._normalize_data(json_formated),
self._normalize_data(truth_dict),
f"Mismatch in declaration '{identifier}'."
)
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.maxDiff = None
cls.env['res.company'].search([('name', '=', 'Muster AG')]).write({'name': 'Muster AG (Old)'})
cls.muster_ag_company = cls.env['res.company'].create({
'name': 'Muster AG',
'street': 'Bahnhofstrasse 1',
'zip': '6003',
'city': 'Luzern',
'country_id': cls.env.ref('base.ch').id,
'l10n_ch_uid': 'CHE-999.999.996',
'phone': '0412186532',
'l10n_ch_30_day_method': True,
'currency_id': cls.env.ref("base.CHF").id
})
cls.env.user.company_ids |= cls.muster_ag_company
cls.env = cls.env(context=dict(cls.env.context, allowed_company_ids=cls.muster_ag_company.ids))
# Load IS Rates
rates_to_load = [
('LU_N_A_0', 'LU_A0N.json'),
('LU_N_N_0', 'LU_N0N.json'),
('BE_N_A_0', 'BE_A0N.json'),
('BE_N_A_1', 'BE_A1N.json'),
('BE_N_B_0', 'BE_B0N.json'),
('BE_N_C_0', 'BE_C0N.json'),
('BE_N_B_1', 'BE_B1N.json'),
('BE_N_H_1', 'BE_H1N.json'),
('BE_N_L_0', 'BE_L0N.json'),
('BE_HE_N', 'BE_HEN.json'),
('BE_ME_N', 'BE_MEN.json'),
('LU_NO_N', 'LU_NON.json'),
('BE_SF_N', 'BE_SFN.json'),
('TI_N_A_0', 'TI_A0N.json'),
('TI_N_B_0', 'TI_B0N.json'),
('TI_N_B_1', 'TI_B1N.json'),
('TI_N_C_0', 'TI_C0N.json'),
('TI_N_F_0', 'TI_F0N.json'),
('TI_N_F_1', 'TI_F1N.json'),
('TI_N_R_0', 'TI_R0N.json'),
('TI_N_T_0', 'TI_T0N.json'),
('VD_N_A_0', 'VD_A0N.json'),
('VD_N_A_1', 'VD_A1N.json'),
('VD_N_A_2', 'VD_A2N.json'),
('VD_N_B_0', 'VD_B0N.json'),
]
rates_to_unlink = cls.env['hr.rule.parameter']
for xml_id, file_name in rates_to_load:
rates_to_unlink += cls.env['hr.rule.parameter'].search([('code', '=', f'l10n_ch_withholding_tax_rates_{xml_id}')])
if rates_to_unlink:
rates_to_unlink.unlink()
for xml_id, file_name in rates_to_load:
cls.env['hr.rule.parameter'].search([('code', '=', f'l10n_ch_withholding_tax_rates_{xml_id}')]).unlink()
rule_parameter = cls.env['hr.rule.parameter'].create({
'name': f'CH Withholding Tax: {xml_id}',
'code': f'l10n_ch_withholding_tax_rates_{xml_id}',
'country_id': cls.env.ref('base.ch').id,
})
cls.env['hr.rule.parameter.value'].create({
'parameter_value': json.load(file_open(f'l10n_ch_hr_payroll/tests/data/is_rates/{file_name}')),
'rule_parameter_id': rule_parameter.id,
'date_from': date(2021, 1, 1),
})