Skip to content

Commit

Permalink
feat: get addtional slary for employee
Browse files Browse the repository at this point in the history
  • Loading branch information
saurabh6790 committed Feb 17, 2023
1 parent 6aa6699 commit 5bf6e1b
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 58 deletions.
20 changes: 11 additions & 9 deletions hrms/payroll/doctype/payroll_period/payroll_period.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,17 @@ def get_payroll_period_days(start_date, end_date, employee, company=None):


def get_payroll_period(from_date, to_date, company):
payroll_period = frappe.db.sql(
"""
select name, start_date, end_date
from `tabPayroll Period`
where start_date<=%s and end_date>= %s and company=%s
""",
(from_date, to_date, company),
as_dict=1,
)
Payroll_Period = frappe.qb.DocType("Payroll Period")

payroll_period = (
frappe.qb.from_(Payroll_Period)
.select(Payroll_Period.name, Payroll_Period.start_date, Payroll_Period.end_date)
.where(
(Payroll_Period.start_date <= from_date)
& (Payroll_Period.end_date >= to_date)
& (Payroll_Period.company == company)
)
).run(as_dict=1)

return payroll_period[0] if payroll_period else None

Expand Down
13 changes: 9 additions & 4 deletions hrms/payroll/doctype/salary_slip/salary_slip.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,12 @@
"ctc",
"income_from_other_sources",
"total_earnings",
"non_taxable_earnings",
"column_break_0rsw",
"deductions_before_tax_calculation",
"tax_exemption_declaration",
"non_taxable_earnings",
"standard_tax_exemption_amount",
"tax_exemption_declaration",
"column_break_35wb",
"deductions_before_tax_calculation",
"annual_taxable_amount",
"income_tax_deducted_till_date",
"section_break_75",
Expand Down Expand Up @@ -699,13 +700,17 @@
"fieldname": "salary_details_tab",
"fieldtype": "Tab Break",
"label": "Salary Details"
},
{
"fieldname": "column_break_35wb",
"fieldtype": "Column Break"
}
],
"icon": "fa fa-file-text",
"idx": 9,
"is_submittable": 1,
"links": [],
"modified": "2023-01-17 13:11:34.478357",
"modified": "2023-01-17 13:32:29.592558",
"modified_by": "Administrator",
"module": "Payroll",
"name": "Salary Slip",
Expand Down
84 changes: 39 additions & 45 deletions hrms/payroll/doctype/salary_slip/salary_slip.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ def validate(self):
self.compute_month_to_date()
self.compute_component_wise_year_to_date()
self.add_leave_balances()
self.compute_income_tax_breakup()

if frappe.db.get_single_value("Payroll Settings", "max_working_hours_against_timesheet"):
max_working_hours = frappe.db.get_single_value(
Expand Down Expand Up @@ -610,11 +611,10 @@ def set_net_pay(self):
flt(self.hour_rate) * flt(self.exchange_rate), self.precision("base_hour_rate")
)
self.set_net_total_in_words()
self.set_income_tax_breakup()

def set_income_tax_breakup(self):
def compute_income_tax_breakup(self):
self.ctc = self.base_gross_pay * 12
self.income_from_other_sources = self.income_from_other_sources
self.income_from_other_sources = self.get_income_form_other_sources()
self.total_earnings = self.ctc + self.income_from_other_sources
self.non_taxable_earnings = 0
self.deductions_before_tax_calculation = 0
Expand All @@ -627,14 +627,14 @@ def calculate_component_amounts(self, component_type):
if not getattr(self, "_salary_structure_doc", None):
self._salary_structure_doc = frappe.get_doc("Salary Structure", self.salary_structure)

payroll_period = get_payroll_period(self.start_date, self.end_date, self.company)
self.payroll_period = get_payroll_period(self.start_date, self.end_date, self.company)

self.add_structure_components(component_type)
self.add_additional_salary_components(component_type)
if component_type == "earnings":
self.add_employee_benefits(payroll_period)
self.add_employee_benefits()
else:
self.add_tax_components(payroll_period)
self.add_tax_components()

def add_structure_components(self, component_type):
data, default_data = self.get_data_for_eval()
Expand Down Expand Up @@ -756,7 +756,7 @@ def eval_condition_and_formula(self, d, data):
)
raise

def add_employee_benefits(self, payroll_period):
def add_employee_benefits(self):
for struct_row in self._salary_structure_doc.get("earnings"):
if struct_row.is_flexible_benefit == 1:
if (
Expand All @@ -772,7 +772,7 @@ def add_employee_benefits(self, payroll_period):
struct_row.salary_component,
self._salary_structure_doc,
self.payroll_frequency,
payroll_period,
self.payroll_period,
)
if benefit_component_amount:
self.update_component_row(struct_row, benefit_component_amount, "earnings")
Expand All @@ -783,7 +783,7 @@ def add_employee_benefits(self, payroll_period):
if benefit_claim_amount:
self.update_component_row(struct_row, benefit_claim_amount, "earnings")

self.adjust_benefits_in_last_payroll_period(payroll_period)
self.adjust_benefits_in_last_payroll_period(self.payroll_period)

def adjust_benefits_in_last_payroll_period(self, payroll_period):
if payroll_period:
Expand Down Expand Up @@ -811,7 +811,7 @@ def add_additional_salary_components(self, component_type):
is_recurring=additional_salary.is_recurring,
)

def add_tax_components(self, payroll_period):
def add_tax_components(self):
# Calculate variable_based_on_taxable_salary after all components updated in salary slip
tax_components, other_deduction_components = [], []
for d in self._salary_structure_doc.get("deductions"):
Expand All @@ -828,7 +828,7 @@ def add_tax_components(self, payroll_period):
]

for d in tax_components:
tax_amount = self.calculate_variable_based_on_taxable_salary(d, payroll_period)
tax_amount = self.calculate_variable_based_on_taxable_salary(d)
tax_row = get_salary_component_data(d)
self.update_component_row(tax_row, tax_amount, "deductions")

Expand Down Expand Up @@ -927,8 +927,8 @@ def set_precision_for_component_amounts(self):
for component_row in self.get(component_type):
component_row.amount = flt(component_row.amount, component_row.precision("amount"))

def calculate_variable_based_on_taxable_salary(self, tax_component, payroll_period):
if not payroll_period:
def calculate_variable_based_on_taxable_salary(self, tax_component):
if not self.payroll_period:
frappe.msgprint(
_("Start and end dates not in a valid Payroll Period, cannot calculate {0}.").format(
tax_component
Expand All @@ -937,40 +937,38 @@ def calculate_variable_based_on_taxable_salary(self, tax_component, payroll_peri
return

# Deduct taxes forcefully for unsubmitted tax exemption proof and unclaimed benefits in the last period
if payroll_period.end_date <= getdate(self.end_date):
if self.payroll_period.end_date <= getdate(self.end_date):
self.deduct_tax_for_unsubmitted_tax_exemption_proof = 1
self.deduct_tax_for_unclaimed_employee_benefits = 1

return self.calculate_variable_tax(payroll_period, tax_component)
return self.calculate_variable_tax(tax_component)

def calculate_variable_tax(self, payroll_period, tax_component):
def calculate_variable_tax(self, tax_component):
# get Tax slab from salary structure assignment for the employee and payroll period
tax_slab = self.get_income_tax_slabs(payroll_period)
tax_slab = self.get_income_tax_slabs(self.payroll_period)

# get remaining numbers of sub-period (period for which one salary is processed)
remaining_sub_periods = get_period_factor(
self.employee, self.start_date, self.end_date, self.payroll_frequency, payroll_period
self.employee, self.start_date, self.end_date, self.payroll_frequency, self.payroll_period
)[1]

# get taxable_earnings, opening_taxable_earning, paid_taxes for previous period
previous_taxable_earnings = self.get_taxable_earnings_for_prev_period(
payroll_period.start_date, self.start_date, tax_slab.allow_tax_exemption
self.payroll_period.start_date, self.start_date, tax_slab.allow_tax_exemption
)
previous_total_paid_taxes = self.get_tax_paid_in_period(
payroll_period.start_date, self.start_date, tax_component
self.payroll_period.start_date, self.start_date, tax_component
)

# get taxable_earnings for current period (all days)
current_taxable_earnings = self.get_taxable_earnings(
tax_slab.allow_tax_exemption, payroll_period=payroll_period
)
current_taxable_earnings = self.get_taxable_earnings(tax_slab.allow_tax_exemption)
future_structured_taxable_earnings = current_taxable_earnings.taxable_earnings * (
math.ceil(remaining_sub_periods) - 1
)

# get taxable_earnings, addition_earnings for current actual payment days
current_taxable_earnings_for_payment_days = self.get_taxable_earnings(
tax_slab.allow_tax_exemption, based_on_payment_days=1, payroll_period=payroll_period
tax_slab.allow_tax_exemption, based_on_payment_days=1
)
current_structured_taxable_earnings = current_taxable_earnings_for_payment_days.taxable_earnings
current_additional_earnings = current_taxable_earnings_for_payment_days.additional_income
Expand All @@ -981,14 +979,14 @@ def calculate_variable_tax(self, payroll_period, tax_component):
# Get taxable unclaimed benefits
unclaimed_taxable_benefits = 0
if self.deduct_tax_for_unclaimed_employee_benefits:
unclaimed_taxable_benefits = self.calculate_unclaimed_taxable_benefits(payroll_period)
unclaimed_taxable_benefits = self.calculate_unclaimed_taxable_benefits()
unclaimed_taxable_benefits += current_taxable_earnings_for_payment_days.flexi_benefits

# Total exemption amount based on tax exemption declaration
total_exemption_amount = self.get_total_exemption_amount(payroll_period, tax_slab)
total_exemption_amount = self.get_total_exemption_amount(tax_slab)

# Employee Other Incomes
other_incomes = self.get_income_form_other_sources(payroll_period) or 0.0
other_incomes = self.get_income_form_other_sources() or 0.0

# Total taxable earnings including additional and other incomes
total_taxable_earnings = (
Expand Down Expand Up @@ -1148,9 +1146,7 @@ def get_tax_paid_in_period(self, start_date, end_date, tax_component):

return total_tax_paid + tax_deducted_till_date

def get_taxable_earnings(
self, allow_tax_exemption=False, based_on_payment_days=0, payroll_period=None
):
def get_taxable_earnings(self, allow_tax_exemption=False, based_on_payment_days=0):
joining_date, relieving_date = self.get_joining_and_relieving_dates()

taxable_earnings = 0
Expand Down Expand Up @@ -1179,7 +1175,7 @@ def get_taxable_earnings(
# Get additional amount based on future recurring additional salary
if additional_amount and earning.is_recurring_additional_salary:
additional_income += self.get_future_recurring_additional_amount(
earning.additional_salary, earning.additional_amount, payroll_period
earning.additional_salary, earning.additional_amount
) # Used earning.additional_amount to consider the amount for the full month

if earning.deduct_full_tax_on_selected_payroll_date:
Expand All @@ -1199,7 +1195,7 @@ def get_taxable_earnings(

if additional_amount and ded.is_recurring_additional_salary:
additional_income -= self.get_future_recurring_additional_amount(
ded.additional_salary, ded.additional_amount, payroll_period
ded.additional_salary, ded.additional_amount
) # Used ded.additional_amount to consider the amount for the full month

return frappe._dict(
Expand All @@ -1211,9 +1207,7 @@ def get_taxable_earnings(
}
)

def get_future_recurring_additional_amount(
self, additional_salary, monthly_additional_amount, payroll_period
):
def get_future_recurring_additional_amount(self, additional_salary, monthly_additional_amount):
future_recurring_additional_amount = 0
to_date = frappe.db.get_value("Additional Salary", additional_salary, "to_date")

Expand All @@ -1222,8 +1216,8 @@ def get_future_recurring_additional_amount(

# If recurring period end date is beyond the payroll period,
# last day of payroll period should be considered for recurring period calculation
if getdate(to_date) > getdate(payroll_period.end_date):
to_date = getdate(payroll_period.end_date)
if getdate(to_date) > getdate(self.payroll_period.end_date):
to_date = getdate(self.payroll_period.end_date)

future_recurring_period = ((to_date.year - from_date.year) * 12) + (
to_date.month - from_date.month
Expand Down Expand Up @@ -1283,7 +1277,7 @@ def get_amount_based_on_payment_days(self, row, joining_date, relieving_date):

return amount, additional_amount

def calculate_unclaimed_taxable_benefits(self, payroll_period):
def calculate_unclaimed_taxable_benefits(self):
# get total sum of benefits paid
total_benefits_paid = flt(
frappe.db.sql(
Expand All @@ -1301,7 +1295,7 @@ def calculate_unclaimed_taxable_benefits(self, payroll_period):
""",
{
"employee": self.employee,
"start_date": payroll_period.start_date,
"start_date": self.payroll_period.start_date,
"end_date": self.start_date,
},
)[0][0]
Expand All @@ -1318,27 +1312,27 @@ def calculate_unclaimed_taxable_benefits(self, payroll_period):
and employee=%s
and claim_date between %s and %s
""",
(self.employee, payroll_period.start_date, self.end_date),
(self.employee, self.payroll_period.start_date, self.end_date),
)[0][0]
)

return total_benefits_paid - total_benefits_claimed

def get_total_exemption_amount(self, payroll_period, tax_slab):
def get_total_exemption_amount(self, tax_slab):
total_exemption_amount = 0
if tax_slab.allow_tax_exemption:
if self.deduct_tax_for_unsubmitted_tax_exemption_proof:
exemption_proof = frappe.db.get_value(
"Employee Tax Exemption Proof Submission",
{"employee": self.employee, "payroll_period": payroll_period.name, "docstatus": 1},
{"employee": self.employee, "payroll_period": self.payroll_period.name, "docstatus": 1},
["exemption_amount"],
)
if exemption_proof:
total_exemption_amount = exemption_proof
else:
declaration = frappe.db.get_value(
"Employee Tax Exemption Declaration",
{"employee": self.employee, "payroll_period": payroll_period.name, "docstatus": 1},
{"employee": self.employee, "payroll_period": self.payroll_period.name, "docstatus": 1},
["total_exemption_amount"],
)
if declaration:
Expand All @@ -1348,12 +1342,12 @@ def get_total_exemption_amount(self, payroll_period, tax_slab):

return total_exemption_amount

def get_income_form_other_sources(self, payroll_period):
def get_income_form_other_sources(self):
return frappe.get_all(
"Employee Other Income",
filters={
"employee": self.employee,
"payroll_period": payroll_period.name,
"payroll_period": self.payroll_period.name,
"company": self.company,
"docstatus": 1,
},
Expand Down

0 comments on commit 5bf6e1b

Please sign in to comment.