[UPDT] PAYROLL: Updated calculation method of employee contribution amount in deduction

This commit is contained in:
Horilla
2024-03-15 11:45:51 +05:30
parent 54c30761c3
commit 052bd46023
3 changed files with 149 additions and 37 deletions

View File

@@ -12,7 +12,7 @@ from dateutil.relativedelta import relativedelta
from base.methods import get_pagination from base.methods import get_pagination
from leave.models import Holiday, CompanyLeave from leave.models import Holiday, CompanyLeave
from attendance.models import Attendance from attendance.models import Attendance
from payroll.models.models import Contract, Payslip from payroll.models.models import Contract, Deduction, Payslip
def get_holiday_dates(range_start: date, range_end: date) -> list: def get_holiday_dates(range_start: date, range_end: date) -> list:
@@ -579,6 +579,40 @@ def paginator_qry(qryset, page_number):
return qryset return qryset
def calculate_employer_contribution(data):
"""
This method is used to calculate the employer contribution
"""
pay_head_data = data["pay_data"]
deductions_to_process = [
pay_head_data.get("pretax_deductions"),
pay_head_data.get("post_tax_deductions"),
pay_head_data.get("tax_deductions"),
pay_head_data.get("net_deductions"),
]
for deductions in deductions_to_process:
if deductions:
for deduction in deductions:
if (
deduction.get("deduction_id")
and deduction.get("employer_contribution_rate", 0) > 0
):
object = Deduction.objects.filter(
id=deduction.get("deduction_id")
).first()
if object:
amount = pay_head_data.get(object.based_on)
employer_contribution_amount = (
amount * object.employer_rate
) / 100
deduction["based_on"] = object.based_on
deduction["employer_contribution_amount"] = (
employer_contribution_amount
)
return data
def save_payslip(**kwargs): def save_payslip(**kwargs):
""" """
This method is used to save the generated payslip This method is used to save the generated payslip

View File

@@ -62,14 +62,110 @@ filter_mapping = {
} }
def calculate_employer_contribution(deduction: Deduction, amount: float):
"""
This method is used to calculate the employer contribution
""" tets = {
employer_contribution_amount = 0 "net_pay": 35140.905000000006,
if max(0, deduction.employer_rate): "employee": 1,
employer_contribution_amount = (amount * deduction.employer_rate) / 100 "allowances": [
return employer_contribution_amount {
"allowance_id": 5,
"title": "Low Basic Pay Assistance",
"is_taxable": True,
"amount": 0,
},
{
"allowance_id": 13,
"title": "Bonus point Redeem for Adam Luis ",
"is_taxable": True,
"amount": 75.0,
},
{
"allowance_id": 17,
"title": "Motorcycle",
"is_taxable": True,
"amount": 5000.0,
},
{
"allowance_id": 2,
"title": "Meal Allowance",
"is_taxable": False,
"amount": 800.0,
},
],
"gross_pay": 39284.09090909091,
"contract_wage": 35000.0,
"basic_pay": 33409.09090909091,
"paid_days": 21.0,
"unpaid_days": 1.0,
"taxable_gross_pay": {"taxable_gross_pay": 35848.47727272727},
"basic_pay_deductions": [],
"gross_pay_deductions": [],
"pretax_deductions": [
{
"deduction_id": 1,
"title": "Social Security (FICA)",
"is_pretax": True,
"amount": 2435.6136363636365,
"employer_contribution_rate": 6.2,
},
{
"deduction_id": 62,
"title": "Late Come penalty",
"is_pretax": True,
"amount": 200.0,
"employer_contribution_rate": 0.0,
},
],
"post_tax_deductions": [
{
"deduction_id": 2,
"title": "Medicare tax",
"is_pretax": False,
"amount": 484.43181818181824,
"employer_contribution_rate": 1.45,
},
{
"deduction_id": 55,
"title": "ESI",
"is_pretax": False,
"amount": 0,
"employer_contribution_rate": 3.25,
},
{
"deduction_id": 73,
"title": "Test",
"is_pretax": False,
"amount": 0.0,
"employer_contribution_rate": 0.0,
},
],
"tax_deductions": [
{
"deduction_id": 75,
"title": "test tax netpay",
"is_tax": True,
"amount": 668.1818181818182,
"employer_contribution_rate": 3.0,
}
],
"net_deductions": [
{
"deduction_id": 74,
"title": "Test Netpay",
"is_pretax": False,
"amount": 354.9586363636364,
"employer_contribution_rate": 2.0,
}
],
"total_deductions": 3788.227272727273,
"loss_of_pay": 1590.909090909091,
"federal_tax": 0,
"start_date": "2024-02-01",
"end_date": "2024-02-29",
"range": "Feb 01 2024 - Feb 29 2024",
}
def dynamic_attr(obj, attribute_path): def dynamic_attr(obj, attribute_path):
@@ -357,16 +453,12 @@ def calculate_tax_deduction(*_args, **kwargs):
amount = if_condition_on(**kwargs) amount = if_condition_on(**kwargs)
deductions_amt.append(amount) deductions_amt.append(amount)
for deduction, amount in zip(deductions, deductions_amt): for deduction, amount in zip(deductions, deductions_amt):
employer_contribution_amount = calculate_employer_contribution(
deduction, kwargs[deduction.based_on]
)
serialized_deduction = { serialized_deduction = {
"deduction_id": deduction.id, "deduction_id": deduction.id,
"title": deduction.title, "title": deduction.title,
"is_tax": deduction.is_tax, "is_tax": deduction.is_tax,
"amount": amount, "amount": amount,
"employer_contribution_rate": deduction.employer_rate, "employer_contribution_rate": deduction.employer_rate,
"employer_contribution_amount": employer_contribution_amount,
} }
serialized_deductions.append(serialized_deduction) serialized_deductions.append(serialized_deduction)
return {"tax_deductions": serialized_deductions} return {"tax_deductions": serialized_deductions}
@@ -466,16 +558,12 @@ def calculate_pre_tax_deduction(*_args, **kwargs):
kwargs["component"] = deduction kwargs["component"] = deduction
pre_tax_deductions_amt.append(if_condition_on(**kwargs)) pre_tax_deductions_amt.append(if_condition_on(**kwargs))
for deduction, amount in zip(pre_tax_deductions, pre_tax_deductions_amt): for deduction, amount in zip(pre_tax_deductions, pre_tax_deductions_amt):
employer_contribution_amount = calculate_employer_contribution(
deduction, kwargs[deduction.based_on]
)
serialized_deduction = { serialized_deduction = {
"deduction_id": deduction.id, "deduction_id": deduction.id,
"title": deduction.title, "title": deduction.title,
"is_pretax": deduction.is_pretax, "is_pretax": deduction.is_pretax,
"amount": amount, "amount": amount,
"employer_contribution_rate": deduction.employer_rate, "employer_contribution_rate": deduction.employer_rate,
"employer_contribution_amount": employer_contribution_amount,
} }
serialized_deductions.append(serialized_deduction) serialized_deductions.append(serialized_deduction)
return {"pretax_deductions": serialized_deductions, "installments": installments} return {"pretax_deductions": serialized_deductions, "installments": installments}
@@ -548,7 +636,7 @@ def calculate_post_tax_deduction(*_args, **kwargs):
else: else:
if deduction.based_on != "net_pay": if deduction.based_on != "net_pay":
calculation_function = calculation_mapping.get(deduction.based_on) calculation_function = calculation_mapping.get(deduction.based_on)
amount, taxable_gross_pay = calculation_function( amount = calculation_function(
**{ **{
"employee": employee, "employee": employee,
"start_date": start_date, "start_date": start_date,
@@ -558,7 +646,6 @@ def calculate_post_tax_deduction(*_args, **kwargs):
"total_allowance": total_allowance, "total_allowance": total_allowance,
"basic_pay": basic_pay, "basic_pay": basic_pay,
"day_dict": day_dict, "day_dict": day_dict,
"taxable_deduction": True,
} }
) )
kwargs["amount"] = amount kwargs["amount"] = amount
@@ -567,16 +654,12 @@ def calculate_post_tax_deduction(*_args, **kwargs):
post_tax_deductions_amt.append(amount) post_tax_deductions_amt.append(amount)
for deduction, amount in zip(post_tax_deductions, post_tax_deductions_amt): for deduction, amount in zip(post_tax_deductions, post_tax_deductions_amt):
employer_contribution_amount = calculate_employer_contribution(
deduction, taxable_gross_pay
)
serialized_deduction = { serialized_deduction = {
"deduction_id": deduction.id, "deduction_id": deduction.id,
"title": deduction.title, "title": deduction.title,
"is_pretax": deduction.is_pretax, "is_pretax": deduction.is_pretax,
"amount": amount, "amount": amount,
"employer_contribution_rate": deduction.employer_rate, "employer_contribution_rate": deduction.employer_rate,
"employer_contribution_amount": employer_contribution_amount,
} }
serialized_deductions.append(serialized_deduction) serialized_deductions.append(serialized_deduction)
for deduction in post_tax_deductions: for deduction in post_tax_deductions:
@@ -614,16 +697,12 @@ def calculate_net_pay_deduction(net_pay, net_pay_deductions, **kwargs):
deduction_amt.append(amount) deduction_amt.append(amount)
net_deduction = 0 net_deduction = 0
for deduction, amount in zip(deductions, deduction_amt): for deduction, amount in zip(deductions, deduction_amt):
employer_contribution_amount = calculate_employer_contribution(
deduction, net_pay
)
serialized_deduction = { serialized_deduction = {
"deduction_id": deduction.id, "deduction_id": deduction.id,
"title": deduction.title, "title": deduction.title,
"is_pretax": deduction.is_pretax, "is_pretax": deduction.is_pretax,
"amount": amount, "amount": amount,
"employer_contribution_rate": deduction.employer_rate, "employer_contribution_rate": deduction.employer_rate,
"employer_contribution_amount": employer_contribution_amount,
} }
net_deduction = amount + net_deduction net_deduction = amount + net_deduction
serialized_net_pay_deductions.append(serialized_deduction) serialized_net_pay_deductions.append(serialized_deduction)
@@ -734,10 +813,7 @@ def calculate_based_on_taxable_gross_pay(*_args, **kwargs):
taxable_gross_pay = taxable_gross_pay["taxable_gross_pay"] taxable_gross_pay = taxable_gross_pay["taxable_gross_pay"]
rate = component.rate rate = component.rate
amount = taxable_gross_pay * rate / 100 amount = taxable_gross_pay * rate / 100
if kwargs["taxable_deduction"]: return amount
return amount, taxable_gross_pay
else:
return amount
def calculate_based_on_net_pay(component, net_pay, day_dict): def calculate_based_on_net_pay(component, net_pay, day_dict):

View File

@@ -58,6 +58,7 @@ from payroll.methods.payslip_calc import (
) )
from payroll.methods.tax_calc import calculate_taxable_amount from payroll.methods.tax_calc import calculate_taxable_amount
from payroll.methods.methods import ( from payroll.methods.methods import (
calculate_employer_contribution,
compute_salary_on_period, compute_salary_on_period,
paginator_qry, paginator_qry,
save_payslip, save_payslip,
@@ -196,15 +197,15 @@ def payroll_calculation(employee, start_date, end_date):
net_pay_deduction_list.append(deduction) net_pay_deduction_list.append(deduction)
net_pay = net_pay - net_pay_deductions["net_deduction"] net_pay = net_pay - net_pay_deductions["net_deduction"]
payslip_data = { payslip_data = {
"net_pay": net_pay,
"employee": employee, "employee": employee,
"allowances": allowances["allowances"],
"gross_pay": gross_pay,
"contract_wage": contract_wage, "contract_wage": contract_wage,
"basic_pay": basic_pay, "basic_pay": basic_pay,
"gross_pay": gross_pay,
"taxable_gross_pay": taxable_gross_pay["taxable_gross_pay"],
"net_pay": net_pay,
"allowances": allowances["allowances"],
"paid_days": paid_days, "paid_days": paid_days,
"unpaid_days": unpaid_days, "unpaid_days": unpaid_days,
"taxable_gross_pay": taxable_gross_pay,
"basic_pay_deductions": basic_pay_deductions, "basic_pay_deductions": basic_pay_deductions,
"gross_pay_deductions": gross_pay_deductions, "gross_pay_deductions": gross_pay_deductions,
"pretax_deductions": pretax_deductions["pretax_deductions"], "pretax_deductions": pretax_deductions["pretax_deductions"],
@@ -613,6 +614,7 @@ def create_payslip(request, new_post_data=None):
data["deduction"] = payslip_data["total_deductions"] data["deduction"] = payslip_data["total_deductions"]
data["net_pay"] = payslip_data["net_pay"] data["net_pay"] = payslip_data["net_pay"]
data["pay_data"] = json.loads(payslip_data["json_data"]) data["pay_data"] = json.loads(payslip_data["json_data"])
calculate_employer_contribution(data)
data["installments"] = payslip_data["installments"] data["installments"] = payslip_data["installments"]
payslip_data["instance"] = save_payslip(**data) payslip_data["instance"] = save_payslip(**data)
form = forms.PayslipForm() form = forms.PayslipForm()
@@ -1440,9 +1442,9 @@ def get_contribution_report(request):
for deduction_id, group in grouped_deductions.items(): for deduction_id, group in grouped_deductions.items():
title = group[0]["title"] title = group[0]["title"]
employee_contribution = sum(item["amount"] for item in group) employee_contribution = sum(item.get("amount",0) for item in group)
employer_contribution = sum( employer_contribution = sum(
item["employer_contribution_amount"] for item in group item.get("employer_contribution_amount",0) for item in group
) )
total_contribution = employee_contribution + employer_contribution total_contribution = employee_contribution + employer_contribution
if employer_contribution > 0: if employer_contribution > 0: