-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Indian l10n modification for hr_payroll #649
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 18.0
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -127,3 +127,4 @@ dmypy.json | |
|
||
# Pyre type checker | ||
.pyre/ | ||
.vscode |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import models |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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', | ||
], | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from . import res_company | ||
from . import res_config_settings | ||
from . import hr_contract |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,118 @@ | ||||||
from odoo import api, fields, models | ||||||
|
||||||
|
||||||
class HrContract(models.Model): | ||||||
_inherit = 'hr.contract' | ||||||
|
||||||
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.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) | ||||||
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(string="Employee Contribution", default=12) | ||||||
l10n_in_pf_employer_contribution = fields.Float(string="Employer Contribution", default=12) | ||||||
l10n_in_professional_tax = fields.Monetary(string="Professional Tax", default=200) | ||||||
l10n_in_esic_employee_contribution = fields.Float(string="Employee Contribution", default=0.75) | ||||||
l10n_in_esic_employer_contribution = fields.Float(string="Employer Contribution", default=3.25) | ||||||
l10n_in_lwf_employee_contribution = fields.Monetary(string="Employee Contribution", currency_field="currency_id", default=6) | ||||||
l10n_in_lwf_employer_contribution = fields.Monetary(string="Employer Contribution", currency_field="currency_id", default=12) | ||||||
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): | ||||||
for record in self: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done! |
||||||
record.l10n_in_basic_salary = record.wage * (record.l10n_in_basic_salary_percent / 100) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have you checked percentage widget to avoid percentage logic on backend? Also what if there is an hourly wage instead of a fixed wage on contract? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. checked percentage widget how it works and also implemented it. |
||||||
|
||||||
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_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): | ||||||
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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
from odoo import fields, models | ||
|
||
|
||
class ResCompany(models.Model): | ||
_inherit = 'res.company' | ||
|
||
l10n_in_org_tax_details = fields.Boolean(string="Organisation Tax Details") | ||
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_employer_identification = fields.Char(string="Employer Identification") | ||
l10n_in_professional_tax_number = fields.Char(string="Professional Tax Number") | ||
l10n_in_esic_ip = fields.Char(string="ESIC IP") |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did you check those fields that are not related to multi-company environment each company has different value in it. so those fields should be company dependant. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, they were not working with multiple company with different values. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
from odoo import fields, models | ||
|
||
|
||
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_tax_details = fields.Boolean(related='company_id.l10n_in_org_tax_details', readonly=False) | ||
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_is_provident_fund = fields.Boolean(string="Employee's Provident Fund", default=True) | ||
l10n_in_employer_identification = fields.Char(related='company_id.l10n_in_employer_identification', readonly=False) | ||
default_l10n_in_pf_employee_contribution = fields.Float(string="Employee Contribution", default_model="hr.contract", default=12) | ||
default_l10n_in_pf_employer_contribution = fields.Float(string="Employer Contribution", default_model="hr.contract", default=12) | ||
|
||
l10n_in_is_professional_tax = fields.Boolean(string="Professional Tax", 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(string="Employee's State Insurance Corporation", default=True) | ||
l10n_in_esic_ip = fields.Char(related='company_id.l10n_in_esic_ip', readonly=False) | ||
default_l10n_in_esic_employee_contribution = fields.Float(string="Employee Contribution", default_model="hr.contract", default=0.75) | ||
default_l10n_in_esic_employer_contribution = fields.Float(string="Employer Contribution", default_model="hr.contract", default=3.25) | ||
|
||
l10n_in_is_lwf = fields.Boolean(string="Labour Welfare Fund", default=True) | ||
default_l10n_in_lwf_employee_contribution = fields.Monetary(string="Employee Contribution", currency_field="currency_id", default_model="hr.contract", default=6) | ||
default_l10n_in_lwf_employer_contribution = fields.Monetary(string="Employer Contribution", currency_field="currency_id", default_model="hr.contract", 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") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import test_hr_contract |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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().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") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make code more readable so avoid using record instead of use contract
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I will take care of it from now.