[UPDT] PAYROLL: Updated calculation method of employee contribution amount in deduction
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user