From e8623a009a269e1b40348d0203239f8f62ce7060 Mon Sep 17 00:00:00 2001 From: jmra-odoo Date: Mon, 17 Mar 2025 13:18:22 +0530 Subject: [PATCH 1/2] [ADD] l10n_in_hr_payroll_extension: Indian l10n modification for hr_payroll With This Commit ======================================================== - Added default configurations for deductions and allowances in setting. - Added salary components and deductions section in `hr_contract`. - Implemented dynamic percentage-based calculations for payroll allowances. - Added computation logic to ensure real-time updates based on wage. - Improved salary structure display in payroll & employee contracts. --- l10n_in_hr_payroll_extension/__init__.py | 1 + l10n_in_hr_payroll_extension/__manifest__.py | 10 ++ .../models/__init__.py | 3 + .../models/hr_contract.py | 118 +++++++++++++ .../models/res_company.py | 27 +++ .../models/res_config_settings.py | 36 ++++ .../views/hr_contract_views.xml | 146 ++++++++++++++++ .../views/res_config_settings_views.xml | 163 ++++++++++++++++++ 8 files changed, 504 insertions(+) create mode 100644 l10n_in_hr_payroll_extension/__init__.py create mode 100644 l10n_in_hr_payroll_extension/__manifest__.py create mode 100644 l10n_in_hr_payroll_extension/models/__init__.py create mode 100644 l10n_in_hr_payroll_extension/models/hr_contract.py create mode 100644 l10n_in_hr_payroll_extension/models/res_company.py create mode 100644 l10n_in_hr_payroll_extension/models/res_config_settings.py create mode 100644 l10n_in_hr_payroll_extension/views/hr_contract_views.xml create mode 100644 l10n_in_hr_payroll_extension/views/res_config_settings_views.xml diff --git a/l10n_in_hr_payroll_extension/__init__.py b/l10n_in_hr_payroll_extension/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/l10n_in_hr_payroll_extension/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/l10n_in_hr_payroll_extension/__manifest__.py b/l10n_in_hr_payroll_extension/__manifest__.py new file mode 100644 index 00000000000..1e4175e4ae9 --- /dev/null +++ b/l10n_in_hr_payroll_extension/__manifest__.py @@ -0,0 +1,10 @@ +{ + 'name': "Indian Payroll Extension", + 'depends': ['l10n_in_hr_payroll'], + 'installable': True, + 'license': 'LGPL-3', + 'data': [ + 'views/res_config_settings_views.xml', + 'views/hr_contract_views.xml', + ], +} diff --git a/l10n_in_hr_payroll_extension/models/__init__.py b/l10n_in_hr_payroll_extension/models/__init__.py new file mode 100644 index 00000000000..880e048d29b --- /dev/null +++ b/l10n_in_hr_payroll_extension/models/__init__.py @@ -0,0 +1,3 @@ +from . import res_company +from . import res_config_settings +from . import hr_contract diff --git a/l10n_in_hr_payroll_extension/models/hr_contract.py b/l10n_in_hr_payroll_extension/models/hr_contract.py new file mode 100644 index 00000000000..025d95d27b1 --- /dev/null +++ b/l10n_in_hr_payroll_extension/models/hr_contract.py @@ -0,0 +1,118 @@ +from odoo import api, fields, models + + +class HrContract(models.Model): + _inherit = 'hr.contract' + + l10n_in_basic_salary = fields.Float(string="Basic Salary", help="Basic salary calculated from the wage", compute="_compute_l10n_in_basic_salary", inverse="_inverse_l10n_in_basic_salary") + l10n_in_house_rent_allowance = fields.Float(string="House Rent Allowance", compute="_compute_l10n_in_house_rent_allowance", inverse="_inverse_l10n_in_house_rent_allowance") + l10n_in_standard_allowance = fields.Float(string="Standard Allowance", default=4167) + l10n_in_performance_bonus = fields.Float(string="Performance Bonus", compute="_compute_l10n_in_performance_bonus", inverse="_inverse_l10n_in_performance_bonus") + l10n_in_leave_travel_allowance = fields.Float(string="Leave Travel Allowance", compute="_compute_l10n_in_leave_travel_allowance", inverse="_inverse_l10n_in_leave_travel_allowance") + l10n_in_leave_allowance = fields.Float(string="Leave Allowance", compute="_compute_leave_allowance", inverse="_inverse_leave_allowance") + l10n_in_leave_days = fields.Float(string="Leave Days", default=1) + l10n_in_gratuity = fields.Float(string="Gratuity", default=0) + l10n_in_supplementary_allowance = fields.Float(string="Supplementary Allowance", compute="_compute_l10n_in_supplementary_allowance", inverse="_inverse_l10n_in_supplementary_allowance", default=0) + + l10n_in_basic_salary_percent = fields.Float(string="Basic Salary Percentage", help="basic salary percentage of wage", default=50) + l10n_in_house_rent_allowance_percent = fields.Float(string="House Rent Allowance Percentage", help="this is the percentage of basic salary", default=50) + l10n_in_standard_allowance_percent = fields.Float(string="Standard Allowance Percentage", compute="_compute_l10n_in_standard_allowance_percent", inverse="_inverse_l10n_in_standard_allowance_percent") + l10n_in_performance_bonus_percent = fields.Float(string="Performance Bonus Percentage", default=20) + l10n_in_leave_travel_allowance_percent = fields.Float(string="Leave Travel Allowance Percentage", default=20) + l10n_in_leave_allowance_per_day_percent = fields.Float(string="Leave allowance per day percentage") + l10n_in_leave_allowance_percent = fields.Float(string="Leave Allowance Percentage") + l10n_in_gratuity_percent = fields.Float(string="Gratuity Percentage", compute="_compute_l10n_in_gratuity_percent", inverse="_inverse_l10n_in_gratuity_percent") + l10n_in_supplementary_allowance_percent = fields.Float(string="Supplementary Allowance Percentage") + + l10n_in_pf_employee_contribution = fields.Float(related="company_id.l10n_in_pf_employee_contribution", readonly=False) + l10n_in_pf_employer_contribution = fields.Float(related="company_id.l10n_in_pf_employer_contribution", readonly=False) + l10n_in_professional_tax = fields.Float(string="Professional Tax", default=200) + l10n_in_esic_employee_contribution = fields.Float(related="company_id.l10n_in_esic_employee_contribution", readonly=False) + l10n_in_esic_employer_contribution = fields.Float(related="company_id.l10n_in_esic_employer_contribution", readonly=False) + l10n_in_lwf_employee_contribution = fields.Float(related="company_id.l10n_in_lwf_employee_contribution", readonly=False) + l10n_in_lwf_employer_contribution = fields.Float(related="company_id.l10n_in_lwf_employer_contribution", readonly=False) + l10n_in_other_deduction = fields.Float(string="Other Deduction") + + @api.depends("l10n_in_basic_salary_percent", "wage") + def _compute_l10n_in_basic_salary(self): + for record in self: + record.l10n_in_basic_salary = record.wage * (record.l10n_in_basic_salary_percent / 100) + + def _inverse_l10n_in_basic_salary(self): + for record in self: + record.l10n_in_basic_salary_percent = (record.l10n_in_basic_salary * 100) / record.wage if record.wage else 0 + + @api.depends("l10n_in_basic_salary", "l10n_in_house_rent_allowance_percent") + def _compute_l10n_in_house_rent_allowance(self): + for record in self: + record.l10n_in_house_rent_allowance = record.l10n_in_basic_salary * (record.l10n_in_house_rent_allowance_percent / 100) + + def _inverse_l10n_in_house_rent_allowance(self): + for record in self: + record.l10n_in_house_rent_allowance_percent = (record.l10n_in_house_rent_allowance * 100) / record.l10n_in_basic_salary if record.l10n_in_basic_salary else 0 + + @api.depends("l10n_in_standard_allowance", "wage") + def _compute_l10n_in_standard_allowance_percent(self): + for record in self: + record.l10n_in_standard_allowance_percent = (record.l10n_in_standard_allowance * 100) / record.wage if record.wage else 0 + + def _inverse_l10n_in_standard_allowance_percent(self): + for record in self: + record.l10n_in_standard_allowance = (record.l10n_in_standard_allowance_percent * record.wage) / 100 + + @api.depends("l10n_in_performance_bonus_percent", "l10n_in_basic_salary") + def _compute_l10n_in_performance_bonus(self): + for record in self: + record.l10n_in_performance_bonus = record.l10n_in_basic_salary * (record.l10n_in_performance_bonus_percent / 100) + + def _inverse_l10n_in_performance_bonus(self): + for record in self: + record.l10n_in_performance_bonus_percent = (record.l10n_in_performance_bonus * 100) / record.l10n_in_basic_salary if record.l10n_in_basic_salary else 0 + + @api.depends("l10n_in_leave_travel_allowance_percent", "l10n_in_basic_salary") + def _compute_l10n_in_leave_travel_allowance(self): + for record in self: + record.l10n_in_leave_travel_allowance = record.l10n_in_basic_salary * (record.l10n_in_leave_travel_allowance_percent / 100) + + def _inverse_l10n_in_leave_travel_allowance(self): + for record in self: + record.l10n_in_leave_travel_allowance_percent = record.l10n_in_leave_days * ((record.l10n_in_leave_allowance * 100) / record.wage if record.wage else 0) + + @api.depends('wage', 'l10n_in_leave_allowance_per_day_percent', 'l10n_in_leave_days') + def _compute_leave_allowance(self): + for record in self: + record.l10n_in_leave_allowance = (record.wage * (record.l10n_in_leave_allowance_per_day_percent/100) * record.l10n_in_leave_days) + + def _inverse_leave_allowance(self): + for record in self: + if record.l10n_in_basic_salary and record.l10n_in_leave_days: + record.l10n_in_leave_allowance_percent = record.l10n_in_leave_allowance * 100 / record.wage if record.wage else 0 + record.l10n_in_leave_allowance_per_day_percent = (record.l10n_in_leave_allowance * 100 / (record.wage * record.l10n_in_leave_days)) if record.wage else 0 + + @api.depends("l10n_in_gratuity", "l10n_in_basic_salary") + def _compute_l10n_in_gratuity_percent(self): + for record in self: + record.l10n_in_gratuity_percent = (record.l10n_in_gratuity * 100) / record.l10n_in_basic_salary if record.l10n_in_basic_salary else 0 + + def _inverse_l10n_in_gratuity_percent(self): + for record in self: + record.l10n_in_gratuity = record.l10n_in_basic_salary * (record.l10n_in_gratuity_percent / 100) + + @api.depends("wage", "l10n_in_basic_salary", "l10n_in_house_rent_allowance", "l10n_in_standard_allowance", "l10n_in_performance_bonus", "l10n_in_leave_travel_allowance", "l10n_in_leave_allowance", "l10n_in_gratuity") + def _compute_l10n_in_supplementary_allowance(self): + for record in self: + total_allowance = sum([ + record.l10n_in_basic_salary, + record.l10n_in_house_rent_allowance, + record.l10n_in_standard_allowance, + record.l10n_in_performance_bonus, + record.l10n_in_leave_travel_allowance, + record.l10n_in_leave_allowance, + record.l10n_in_gratuity + ]) + if record.wage: + record.l10n_in_supplementary_allowance = record.wage - total_allowance + + def _inverse_l10n_in_supplementary_allowance(self): + for record in self: + record.l10n_in_supplementary_allowance_percent = (record.l10n_in_supplementary_allowance * 100) / record.wage if record.wage else 0 diff --git a/l10n_in_hr_payroll_extension/models/res_company.py b/l10n_in_hr_payroll_extension/models/res_company.py new file mode 100644 index 00000000000..04ccd22ee86 --- /dev/null +++ b/l10n_in_hr_payroll_extension/models/res_company.py @@ -0,0 +1,27 @@ +from odoo import fields, models + + +class ResCompany(models.Model): + _inherit = 'res.company' + + l10n_in_org_pan_number = fields.Char(string="PAN Number") + l10n_in_org_tan_number = fields.Char(string="TAN Number") + l10n_in_org_tds_circle = fields.Char(string="TDS Circle/AO Code") + l10n_in_org_tax_details = fields.Boolean(string="Organisation Tax Details") + + l10n_in_is_provident_fund = fields.Boolean(string="Employee's Provident Fund") + l10n_in_employer_identification = fields.Char(string="Employer Identification") + l10n_in_pf_employee_contribution = fields.Float(string="Employee Contribution") + l10n_in_pf_employer_contribution = fields.Float(string="Employer Contribution") + + l10n_in_is_professional_tax = fields.Boolean(string="Professional Tax") + l10n_in_professional_tax_number = fields.Char(string="Professional Tax Number") + + l10n_in_is_esic = fields.Boolean(string="Employee's State Insurance Corporation") + l10n_in_esic_ip = fields.Char(string="ESIC IP") + l10n_in_esic_employee_contribution = fields.Float(string="Employee Contribution") + l10n_in_esic_employer_contribution = fields.Float(string="Employer Contribution") + + l10n_in_is_lwf = fields.Boolean(string="Labour Welfare Fund") + l10n_in_lwf_employee_contribution = fields.Float(string="Employee Contribution") + l10n_in_lwf_employer_contribution = fields.Float(string="Employer Contribution") diff --git a/l10n_in_hr_payroll_extension/models/res_config_settings.py b/l10n_in_hr_payroll_extension/models/res_config_settings.py new file mode 100644 index 00000000000..6914f6567ab --- /dev/null +++ b/l10n_in_hr_payroll_extension/models/res_config_settings.py @@ -0,0 +1,36 @@ +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = 'res.config.settings' + + l10n_in_org_pan_number = fields.Char(related='company_id.l10n_in_org_pan_number', readonly=False) + l10n_in_org_tan_number = fields.Char(related='company_id.l10n_in_org_tan_number', readonly=False) + l10n_in_org_tds_circle = fields.Char(related='company_id.l10n_in_org_tds_circle', readonly=False) + l10n_in_org_tax_details = fields.Boolean(related='company_id.l10n_in_org_tax_details', readonly=False) + + l10n_in_is_provident_fund = fields.Boolean(related='company_id.l10n_in_is_provident_fund', readonly=False, default=True) + l10n_in_employer_identification = fields.Char(related='company_id.l10n_in_employer_identification', readonly=False) + l10n_in_pf_employee_contribution = fields.Float(related='company_id.l10n_in_pf_employee_contribution', readonly=False, default=12) + l10n_in_pf_employer_contribution = fields.Float(related='company_id.l10n_in_pf_employer_contribution', readonly=False, default=12) + + l10n_in_is_professional_tax = fields.Boolean(related='company_id.l10n_in_is_professional_tax', readonly=False, default=True) + l10n_in_professional_tax_number = fields.Char(related='company_id.l10n_in_professional_tax_number', readonly=False) + + l10n_in_is_esic = fields.Boolean(related='company_id.l10n_in_is_esic', readonly=False, default=True) + l10n_in_esic_ip = fields.Char(related='company_id.l10n_in_esic_ip', readonly=False) + l10n_in_esic_employee_contribution = fields.Float(related='company_id.l10n_in_esic_employee_contribution', readonly=False, default=0.75) + l10n_in_esic_employer_contribution = fields.Float(related='company_id.l10n_in_esic_employer_contribution', readonly=False, default=3.25) + + l10n_in_is_lwf = fields.Boolean(related='company_id.l10n_in_is_lwf', readonly=False, default=True) + l10n_in_lwf_employee_contribution = fields.Float(related='company_id.l10n_in_lwf_employee_contribution', readonly=False, default=6) + l10n_in_lwf_employer_contribution = fields.Float(related='company_id.l10n_in_lwf_employer_contribution', readonly=False, default=12) + + default_l10n_in_basic_salary_percent = fields.Float(string="Basic Salary", help="You can define the % of the salary from company cost to compute the basic salary based on your wages (Including D4).", default_model="hr.contract", default=50) + default_l10n_in_house_rent_allowance_percent = fields.Float(string="House Rent Allowance", help="You can define 50% for metro city and 40% for non-metro city.", default_model="hr.contract", default=50) + default_l10n_in_standard_allowance = fields.Float(string="Standard Allowance", default_model="hr.contract", default=4167) + default_l10n_in_performance_bonus_percent = fields.Float(string="Performance Bonus", default_model="hr.contract", default=20) + default_l10n_in_leave_travel_allowance_percent = fields.Float(string="Leave Travel Allowance", default_model="hr.contract", default=20) + default_l10n_in_leave_days = fields.Float(string="Leave Days", default_model="hr.contract", default=1) + default_l10n_in_gratuity = fields.Float(string="Gratuity", default_model="hr.contract") + default_l10n_in_supplementary_allowance = fields.Float(string="Supplementary Allowance", default_model="hr.contract") diff --git a/l10n_in_hr_payroll_extension/views/hr_contract_views.xml b/l10n_in_hr_payroll_extension/views/hr_contract_views.xml new file mode 100644 index 00000000000..510307702e2 --- /dev/null +++ b/l10n_in_hr_payroll_extension/views/hr_contract_views.xml @@ -0,0 +1,146 @@ + + + hr.contract.form.in.inherit + hr.contract + + + + 1 + + + 1 + + + + +
+ + + + +
+
+
+
+
diff --git a/l10n_in_hr_payroll_extension/views/res_config_settings_views.xml b/l10n_in_hr_payroll_extension/views/res_config_settings_views.xml new file mode 100644 index 00000000000..6646c5cb7d3 --- /dev/null +++ b/l10n_in_hr_payroll_extension/views/res_config_settings_views.xml @@ -0,0 +1,163 @@ + + + res.config.settings.view.form.inherited.l10n_in_hr_payroll + res.config.settings + + + + + + + + + + + + + +
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+ Salary Components + + +
+
+
+
+
+
+
From 946edf8fdc6c13196bb71b2d8e58a174121e81ab Mon Sep 17 00:00:00 2001 From: jmra-odoo Date: Thu, 20 Mar 2025 14:11:39 +0530 Subject: [PATCH 2/2] [IMP] l10n_in_hr_payroll_extension: test cases and monetary fields With This Commit ======================================================== - Added Test Cases for salary component calculations - Modified some fields to make them monetary - Minor changes in views according above changes --- .../models/hr_contract.py | 26 ++++++++--------- .../models/res_company.py | 4 +-- .../models/res_config_settings.py | 6 ++-- .../tests/__init__.py | 1 + .../tests/test_hr_contract.py | 29 +++++++++++++++++++ .../views/hr_contract_views.xml | 24 +++++++-------- .../views/res_config_settings_views.xml | 2 +- 7 files changed, 62 insertions(+), 30 deletions(-) create mode 100644 l10n_in_hr_payroll_extension/tests/__init__.py create mode 100644 l10n_in_hr_payroll_extension/tests/test_hr_contract.py diff --git a/l10n_in_hr_payroll_extension/models/hr_contract.py b/l10n_in_hr_payroll_extension/models/hr_contract.py index 025d95d27b1..1202582d9f6 100644 --- a/l10n_in_hr_payroll_extension/models/hr_contract.py +++ b/l10n_in_hr_payroll_extension/models/hr_contract.py @@ -4,15 +4,15 @@ class HrContract(models.Model): _inherit = 'hr.contract' - l10n_in_basic_salary = fields.Float(string="Basic Salary", help="Basic salary calculated from the wage", compute="_compute_l10n_in_basic_salary", inverse="_inverse_l10n_in_basic_salary") - l10n_in_house_rent_allowance = fields.Float(string="House Rent Allowance", compute="_compute_l10n_in_house_rent_allowance", inverse="_inverse_l10n_in_house_rent_allowance") - l10n_in_standard_allowance = fields.Float(string="Standard Allowance", default=4167) - l10n_in_performance_bonus = fields.Float(string="Performance Bonus", compute="_compute_l10n_in_performance_bonus", inverse="_inverse_l10n_in_performance_bonus") - l10n_in_leave_travel_allowance = fields.Float(string="Leave Travel Allowance", compute="_compute_l10n_in_leave_travel_allowance", inverse="_inverse_l10n_in_leave_travel_allowance") - l10n_in_leave_allowance = fields.Float(string="Leave Allowance", compute="_compute_leave_allowance", inverse="_inverse_leave_allowance") + l10n_in_basic_salary = fields.Monetary(string="Basic Salary", help="Basic salary calculated from the wage", compute="_compute_l10n_in_basic_salary", inverse="_inverse_l10n_in_basic_salary", currency_field="currency_id") + l10n_in_house_rent_allowance = fields.Monetary(string="House Rent Allowance", compute="_compute_l10n_in_house_rent_allowance", inverse="_inverse_l10n_in_house_rent_allowance", currency_field="currency_id") + l10n_in_standard_allowance = fields.Monetary(string="Standard Allowance", default=4167, currency_field="currency_id") + l10n_in_performance_bonus = fields.Monetary(string="Performance Bonus", compute="_compute_l10n_in_performance_bonus", inverse="_inverse_l10n_in_performance_bonus", currency_field="currency_id") + l10n_in_leave_travel_allowance = fields.Monetary(string="Leave Travel Allowance", compute="_compute_l10n_in_leave_travel_allowance", inverse="_inverse_l10n_in_leave_travel_allowance", currency_field="currency_id") + l10n_in_leave_allowance = fields.Monetary(string="Leave Allowance", compute="_compute_leave_allowance", inverse="_inverse_leave_allowance", currency_field="currency_id") l10n_in_leave_days = fields.Float(string="Leave Days", default=1) - l10n_in_gratuity = fields.Float(string="Gratuity", default=0) - l10n_in_supplementary_allowance = fields.Float(string="Supplementary Allowance", compute="_compute_l10n_in_supplementary_allowance", inverse="_inverse_l10n_in_supplementary_allowance", default=0) + l10n_in_gratuity = fields.Monetary(string="Gratuity", currency_field="currency_id") + l10n_in_supplementary_allowance = fields.Monetary(string="Supplementary Allowance", compute="_compute_l10n_in_supplementary_allowance", inverse="_inverse_l10n_in_supplementary_allowance", currency_field="currency_id") l10n_in_basic_salary_percent = fields.Float(string="Basic Salary Percentage", help="basic salary percentage of wage", default=50) l10n_in_house_rent_allowance_percent = fields.Float(string="House Rent Allowance Percentage", help="this is the percentage of basic salary", default=50) @@ -26,12 +26,12 @@ class HrContract(models.Model): l10n_in_pf_employee_contribution = fields.Float(related="company_id.l10n_in_pf_employee_contribution", readonly=False) l10n_in_pf_employer_contribution = fields.Float(related="company_id.l10n_in_pf_employer_contribution", readonly=False) - l10n_in_professional_tax = fields.Float(string="Professional Tax", default=200) + l10n_in_professional_tax = fields.Monetary(string="Professional Tax", default=200) l10n_in_esic_employee_contribution = fields.Float(related="company_id.l10n_in_esic_employee_contribution", readonly=False) l10n_in_esic_employer_contribution = fields.Float(related="company_id.l10n_in_esic_employer_contribution", readonly=False) - l10n_in_lwf_employee_contribution = fields.Float(related="company_id.l10n_in_lwf_employee_contribution", readonly=False) - l10n_in_lwf_employer_contribution = fields.Float(related="company_id.l10n_in_lwf_employer_contribution", readonly=False) - l10n_in_other_deduction = fields.Float(string="Other Deduction") + l10n_in_lwf_employee_contribution = fields.Monetary(related="company_id.l10n_in_lwf_employee_contribution", readonly=False, currency_field="currency_id") + l10n_in_lwf_employer_contribution = fields.Monetary(related="company_id.l10n_in_lwf_employer_contribution", readonly=False, currency_field="currency_id") + l10n_in_other_deduction = fields.Monetary(string="Other Deduction", currency_field="currency_id") @api.depends("l10n_in_basic_salary_percent", "wage") def _compute_l10n_in_basic_salary(self): @@ -76,7 +76,7 @@ def _compute_l10n_in_leave_travel_allowance(self): def _inverse_l10n_in_leave_travel_allowance(self): for record in self: - record.l10n_in_leave_travel_allowance_percent = record.l10n_in_leave_days * ((record.l10n_in_leave_allowance * 100) / record.wage if record.wage else 0) + record.l10n_in_leave_travel_allowance_percent = (record.l10n_in_leave_travel_allowance * 100) / record.l10n_in_basic_salary if record.l10n_in_basic_salary else 0 @api.depends('wage', 'l10n_in_leave_allowance_per_day_percent', 'l10n_in_leave_days') def _compute_leave_allowance(self): diff --git a/l10n_in_hr_payroll_extension/models/res_company.py b/l10n_in_hr_payroll_extension/models/res_company.py index 04ccd22ee86..68216c49bb4 100644 --- a/l10n_in_hr_payroll_extension/models/res_company.py +++ b/l10n_in_hr_payroll_extension/models/res_company.py @@ -23,5 +23,5 @@ class ResCompany(models.Model): l10n_in_esic_employer_contribution = fields.Float(string="Employer Contribution") l10n_in_is_lwf = fields.Boolean(string="Labour Welfare Fund") - l10n_in_lwf_employee_contribution = fields.Float(string="Employee Contribution") - l10n_in_lwf_employer_contribution = fields.Float(string="Employer Contribution") + l10n_in_lwf_employee_contribution = fields.Monetary(string="Employee Contribution", currency_field="currency_id") + l10n_in_lwf_employer_contribution = fields.Monetary(string="Employer Contribution", currency_field="currency_id") diff --git a/l10n_in_hr_payroll_extension/models/res_config_settings.py b/l10n_in_hr_payroll_extension/models/res_config_settings.py index 6914f6567ab..20c25f7ffcf 100644 --- a/l10n_in_hr_payroll_extension/models/res_config_settings.py +++ b/l10n_in_hr_payroll_extension/models/res_config_settings.py @@ -4,6 +4,8 @@ class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' + currency_id = fields.Many2one("res.currency", default=lambda self: self.env.company.currency_id) + l10n_in_org_pan_number = fields.Char(related='company_id.l10n_in_org_pan_number', readonly=False) l10n_in_org_tan_number = fields.Char(related='company_id.l10n_in_org_tan_number', readonly=False) l10n_in_org_tds_circle = fields.Char(related='company_id.l10n_in_org_tds_circle', readonly=False) @@ -23,8 +25,8 @@ class ResConfigSettings(models.TransientModel): l10n_in_esic_employer_contribution = fields.Float(related='company_id.l10n_in_esic_employer_contribution', readonly=False, default=3.25) l10n_in_is_lwf = fields.Boolean(related='company_id.l10n_in_is_lwf', readonly=False, default=True) - l10n_in_lwf_employee_contribution = fields.Float(related='company_id.l10n_in_lwf_employee_contribution', readonly=False, default=6) - l10n_in_lwf_employer_contribution = fields.Float(related='company_id.l10n_in_lwf_employer_contribution', readonly=False, default=12) + l10n_in_lwf_employee_contribution = fields.Monetary(related='company_id.l10n_in_lwf_employee_contribution', readonly=False, default=6, currency_field="currency_id") + l10n_in_lwf_employer_contribution = fields.Monetary(related='company_id.l10n_in_lwf_employer_contribution', readonly=False, default=12, currency_field="currency_id") default_l10n_in_basic_salary_percent = fields.Float(string="Basic Salary", help="You can define the % of the salary from company cost to compute the basic salary based on your wages (Including D4).", default_model="hr.contract", default=50) default_l10n_in_house_rent_allowance_percent = fields.Float(string="House Rent Allowance", help="You can define 50% for metro city and 40% for non-metro city.", default_model="hr.contract", default=50) diff --git a/l10n_in_hr_payroll_extension/tests/__init__.py b/l10n_in_hr_payroll_extension/tests/__init__.py new file mode 100644 index 00000000000..0894c057839 --- /dev/null +++ b/l10n_in_hr_payroll_extension/tests/__init__.py @@ -0,0 +1 @@ +from . import test_hr_contract diff --git a/l10n_in_hr_payroll_extension/tests/test_hr_contract.py b/l10n_in_hr_payroll_extension/tests/test_hr_contract.py new file mode 100644 index 00000000000..f5ac424a95f --- /dev/null +++ b/l10n_in_hr_payroll_extension/tests/test_hr_contract.py @@ -0,0 +1,29 @@ +from odoo.tests.common import TransactionCase +from odoo.tests import tagged + + +@tagged('post_install', '-at_install') +class TestHrContract(TransactionCase): + @classmethod + def setUpClass(cls): + super(TestHrContract, cls).setUpClass() + + cls.contract = cls.env['hr.contract'].create({ + 'name': "Test Contract", + 'wage': 100000, + 'l10n_in_basic_salary_percent': 50, + 'l10n_in_house_rent_allowance_percent': 50, + 'l10n_in_standard_allowance': 4167, + 'l10n_in_performance_bonus_percent': 20, + 'l10n_in_leave_travel_allowance_percent': 20, + 'l10n_in_gratuity': 250, + }) + + def test_salary_component_amounts(self): + self.assertEqual(self.contract.l10n_in_basic_salary, 50000, "50% of 100000 should be 50000") + self.assertEqual(self.contract.l10n_in_house_rent_allowance, 25000, "50% of 50000(Basic Salary) should be 25000") + self.assertEqual(self.contract.l10n_in_standard_allowance_percent, 4.167, "4167 is a 4.17% of 100000(Wage)") + self.assertEqual(self.contract.l10n_in_performance_bonus, 10000, "20% of 50000(Basic Salary) should be 10000") + self.assertEqual(self.contract.l10n_in_leave_travel_allowance, 10000, "20% of 50000(Basic Salary) should be 10000") + self.assertEqual(self.contract.l10n_in_gratuity_percent, 0.50, "250 is a 0.50% of 50000(Basic Salary)") + self.assertEqual(self.contract.l10n_in_supplementary_allowance, 583, "supplementary should be remaining amount from wage") diff --git a/l10n_in_hr_payroll_extension/views/hr_contract_views.xml b/l10n_in_hr_payroll_extension/views/hr_contract_views.xml index 510307702e2..44c2540f827 100644 --- a/l10n_in_hr_payroll_extension/views/hr_contract_views.xml +++ b/l10n_in_hr_payroll_extension/views/hr_contract_views.xml @@ -15,7 +15,7 @@