From 5862d5168382f6df755be1fe40f9392b184dc33e Mon Sep 17 00:00:00 2001 From: Jared Kipe Date: Wed, 27 Jul 2022 20:09:41 +0000 Subject: [PATCH] [IMP] l10n_pe_hr_payroll: implement salary struct for gratif --- l10n_pe_hr_payroll/__manifest__.py | 2 +- l10n_pe_hr_payroll/data/base.xml | 10 +++ l10n_pe_hr_payroll/data/ir_5ta_cat_rules.xml | 47 ++++++++++++++ l10n_pe_hr_payroll/i18n/es.po | 9 +-- l10n_pe_hr_payroll/models/hr_payslip.py | 61 +++++++++++++++++++ .../models/pe_payroll_config.py | 2 - l10n_pe_hr_payroll/models/rules/ir_5ta_cat.py | 4 +- l10n_pe_hr_payroll/tests/common.py | 3 +- .../views/pe_payroll_config_views.xml | 2 - 9 files changed, 124 insertions(+), 16 deletions(-) diff --git a/l10n_pe_hr_payroll/__manifest__.py b/l10n_pe_hr_payroll/__manifest__.py index 3c5d4cd3..2c3d8f99 100644 --- a/l10n_pe_hr_payroll/__manifest__.py +++ b/l10n_pe_hr_payroll/__manifest__.py @@ -3,7 +3,7 @@ { 'name': 'Peru - Payroll', 'author': 'Hibou Corp. ', - 'version': '15.0.2022.1.0', + 'version': '15.0.2022.2.0', 'category': 'Payroll Localization', 'depends': [ 'hr_payroll_hibou', diff --git a/l10n_pe_hr_payroll/data/base.xml b/l10n_pe_hr_payroll/data/base.xml index cdea1281..bb664c89 100644 --- a/l10n_pe_hr_payroll/data/base.xml +++ b/l10n_pe_hr_payroll/data/base.xml @@ -17,6 +17,7 @@ Peru Employee (5ta Cat.) + PE5 + + July/December Gratuity (5ta Cat.) + PE5GRATIF + + + + + + Peru Employee (4ta Cat.) diff --git a/l10n_pe_hr_payroll/data/ir_5ta_cat_rules.xml b/l10n_pe_hr_payroll/data/ir_5ta_cat_rules.xml index 5341acc7..123dbb5f 100644 --- a/l10n_pe_hr_payroll/data/ir_5ta_cat_rules.xml +++ b/l10n_pe_hr_payroll/data/ir_5ta_cat_rules.xml @@ -58,4 +58,51 @@ + + + Gratif Full Months + MONTHS + + + + + + + + + Gratif + ALW_GRATIF + none + code + result = payslip.paid_amount + + + + + + + + Gratif Bonifextra + ALW_GRATIF_BONIFEXTRA + python + result = categories.ALW + code + result, result_rate = categories.ALW, payslip.rule_parameter('er_essalud') + + + + + + + + Net Gratif + NET + none + code + result = categories.BASIC + categories.ALW + categories.DED + + + diff --git a/l10n_pe_hr_payroll/i18n/es.po b/l10n_pe_hr_payroll/i18n/es.po index a00ae657..4ec71b08 100644 --- a/l10n_pe_hr_payroll/i18n/es.po +++ b/l10n_pe_hr_payroll/i18n/es.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 15.0+e\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-06-30 16:24+0000\n" -"PO-Revision-Date: 2022-06-30 16:24+0000\n" +"POT-Creation-Date: 2022-07-27 20:00+0000\n" +"PO-Revision-Date: 2022-07-27 20:00+0000\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -70,11 +70,6 @@ msgstr "Creado Por" msgid "Created on" msgstr "Creado En" -#. module: l10n_pe_hr_payroll -#: model:ir.model.fields,field_description:l10n_pe_hr_payroll.field_hr_contract_pe_payroll_config__date_hired -msgid "Date Hired" -msgstr "Fecha de Contratación" - #. module: l10n_pe_hr_payroll #: model:ir.model.fields,field_description:l10n_pe_hr_payroll.field_hr_contract_pe_payroll_config__name msgid "Description" diff --git a/l10n_pe_hr_payroll/models/hr_payslip.py b/l10n_pe_hr_payroll/models/hr_payslip.py index df66de83..dd5ed325 100644 --- a/l10n_pe_hr_payroll/models/hr_payslip.py +++ b/l10n_pe_hr_payroll/models/hr_payslip.py @@ -1,5 +1,7 @@ # Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. +from datetime import date + from odoo import api, fields, models from .rules.general import _general_rate from .rules.ir_4ta_cat import ir_4ta_cat @@ -8,6 +10,48 @@ from .rules.ir_5ta_cat import ir_5ta_cat class HRPayslip(models.Model): _inherit = 'hr.payslip' + + @api.model_create_multi + def create(self, vals_list): + payslips = super().create(vals_list) + draft_slips = payslips.filtered(lambda p: p.employee_id and p.state == 'draft') + if not draft_slips: + return payslips + + for slip in draft_slips.filtered(lambda s: s.struct_id.code == 'PE5GRATIF'): + slip._pe_5thcat_gratif_update_input_line() + + return payslips + + def _pe_5thcat_gratif_update_input_line(self): + full_months_type = self.env.ref('l10n_pe_hr_payroll.input_type_gratif_months', raise_if_not_found=False) + if not full_months_type: + return + for payslip in self: + # compute full months, for now I'll hard code to 6 + amount = payslip._pe_5thcat_gratif_months() + lines_to_remove = payslip.input_line_ids.filtered(lambda x: x.input_type_id == full_months_type) + input_lines_vals = [(2, line.id, False) for line in lines_to_remove] + input_lines_vals.append((0, 0, { + 'amount': amount, + 'input_type_id': full_months_type.id + })) + payslip.update({'input_line_ids': input_lines_vals}) + + def _pe_5thcat_gratif_months(self): + full_months = 0 + # are we in July or December? + # brute force, but this algorithm should be very very fast + date_hire = self.contract_id.first_contract_date + if self.date_to.month == 7: + for i in range(1, 7): + if date_hire < date(self.date_to.year, i, 15): + full_months += 1 + else: + for i in range(7, 13): + if date_hire < date(self.date_to.year-1, i, 15): + full_months += 1 + return full_months def _get_base_local_dict(self): res = super()._get_base_local_dict() @@ -17,3 +61,20 @@ class HRPayslip(models.Model): 'ir_5ta_cat': ir_5ta_cat, }) return res + + def _get_paid_amount(self): + if self.struct_id.code == 'PE5GRATIF': + return self._pe_5thcat_gratif() + return super()._get_paid_amount() + + def _pe_5thcat_gratif(self): + if self.contract_id.structure_type_id != self.struct_id.type_id: + return 0.0 + + # TODO hourly averages daily hours to compute from wage + basic = self.contract_id._get_contract_wage() + month_line = self.input_line_ids.filtered(lambda l: l.code == 'MONTHS') + if not basic or not month_line: + return 0.0 + # normalize to 6 months + return basic * (1.0 / 6.0) * month_line.amount diff --git a/l10n_pe_hr_payroll/models/pe_payroll_config.py b/l10n_pe_hr_payroll/models/pe_payroll_config.py index 7ec13f85..97d58319 100644 --- a/l10n_pe_hr_payroll/models/pe_payroll_config.py +++ b/l10n_pe_hr_payroll/models/pe_payroll_config.py @@ -9,8 +9,6 @@ class HRContractPEPayrollConfig(models.Model): name = fields.Char(string="Description") employee_id = fields.Many2one('hr.employee', string="Employee", required=True) - date_hired = fields.Date(string='Date Hired', required=True, default=fields.Date.today, - help='For calculations like IR 5TH CAT.') ee_5ta_cat_exempt = fields.Boolean(string='Exempt from 5th Cat. withholding.') diff --git a/l10n_pe_hr_payroll/models/rules/ir_5ta_cat.py b/l10n_pe_hr_payroll/models/rules/ir_5ta_cat.py index ffac865c..a5acbd2e 100644 --- a/l10n_pe_hr_payroll/models/rules/ir_5ta_cat.py +++ b/l10n_pe_hr_payroll/models/rules/ir_5ta_cat.py @@ -31,9 +31,9 @@ def ir_5ta_cat(payslip, categories, worked_days, inputs): wage_year = (basic_wage * pay_periods_at_current) + prior_wage_year - # IF employee's `date_hired` is in current year + # IF employee's `first_contract_date` is in current year # THEN we can pro-rate the period (reduce withholding) - date_hired = payslip.dict.contract_id.pe_payroll_config_value('date_hired') + date_hired = payslip.dict.contract_id.first_contract_date payslip_date_end = payslip.dict.date_to hired_in_year = date_hired.year == payslip_date_end.year periods_in_year_eligible = pay_periods_in_year diff --git a/l10n_pe_hr_payroll/tests/common.py b/l10n_pe_hr_payroll/tests/common.py index e8b128f1..f6f45697 100755 --- a/l10n_pe_hr_payroll/tests/common.py +++ b/l10n_pe_hr_payroll/tests/common.py @@ -12,6 +12,7 @@ class TestPePayslip(common.TestPayslip): super().setUp() self.structure_type = self.env.ref('l10n_pe_hr_payroll.structure_type_employee') self.structure = self.env.ref('l10n_pe_hr_payroll.hr_payroll_structure') + self.structure_gratif = self.env.ref('l10n_pe_hr_payroll.hr_payroll_structure_gratif') self.structure_type.default_struct_id = self.structure # self.debug = True self._log('PE structue_type %s %s and structure %s %s' % (self.structure_type, self.structure_type.name, self.structure, self.structure.name)) @@ -52,8 +53,6 @@ class TestPePayslip(common.TestPayslip): self._logger.warning('cannot locate attribute names "%s" on hr.contract().' % (key, )) # PE Payroll Config Defaults Should be set on the Model - if 'date_hired' not in config_values: - config_values['date_hired'] = '2016-01-01' config = config_model.create(config_values) contract_values['pe_payroll_config_id'] = config.id diff --git a/l10n_pe_hr_payroll/views/pe_payroll_config_views.xml b/l10n_pe_hr_payroll/views/pe_payroll_config_views.xml index 38ec9bda..3cb941f4 100644 --- a/l10n_pe_hr_payroll/views/pe_payroll_config_views.xml +++ b/l10n_pe_hr_payroll/views/pe_payroll_config_views.xml @@ -8,7 +8,6 @@ - @@ -24,7 +23,6 @@ -