fix: tax calculation on salary slip for the first month (#24272)
* fix: tax calculation on salary slip for the first month
* fix: net pay precision issue
* fix: net pay precision issue
Co-authored-by: Anurag Mishra <32095923+Anurag810@users.noreply.github.com>
diff --git a/erpnext/hr/doctype/employee/employee.json b/erpnext/hr/doctype/employee/employee.json
index 4f1c04f..dc2aaa4 100644
--- a/erpnext/hr/doctype/employee/employee.json
+++ b/erpnext/hr/doctype/employee/employee.json
@@ -813,7 +813,7 @@
"idx": 24,
"image_field": "image",
"links": [],
- "modified": "2020-10-16 15:02:04.283657",
+ "modified": "2021-01-01 16:54:33.477439",
"modified_by": "Administrator",
"module": "HR",
"name": "Employee",
@@ -855,7 +855,6 @@
"write": 1
}
],
- "quick_entry": 1,
"search_fields": "employee_name",
"show_name_in_global_search": 1,
"sort_field": "modified",
diff --git a/erpnext/payroll/doctype/salary_slip/salary_slip.js b/erpnext/payroll/doctype/salary_slip/salary_slip.js
index 8e05bb2..51fb359 100644
--- a/erpnext/payroll/doctype/salary_slip/salary_slip.js
+++ b/erpnext/payroll/doctype/salary_slip/salary_slip.js
@@ -151,7 +151,6 @@
var salary_detail_fields = ["formula", "abbr", "statistical_component", "variable_based_on_taxable_salary"];
frm.fields_dict['earnings'].grid.set_column_disp(salary_detail_fields, false);
frm.fields_dict['deductions'].grid.set_column_disp(salary_detail_fields, false);
- calculate_totals(frm);
frm.trigger("set_dynamic_labels");
},
diff --git a/erpnext/payroll/doctype/salary_slip/salary_slip.py b/erpnext/payroll/doctype/salary_slip/salary_slip.py
index 3bb1f62..d725f68 100644
--- a/erpnext/payroll/doctype/salary_slip/salary_slip.py
+++ b/erpnext/payroll/doctype/salary_slip/salary_slip.py
@@ -143,8 +143,8 @@
self.salary_slip_based_on_timesheet = self._salary_structure_doc.salary_slip_based_on_timesheet or 0
self.set_time_sheet()
self.pull_sal_struct()
- payroll_based_on, consider_unmarked_attendance_as = frappe.db.get_value("Payroll Settings", None, ["payroll_based_on","consider_unmarked_attendance_as"])
- return [payroll_based_on, consider_unmarked_attendance_as]
+ ps = frappe.db.get_value("Payroll Settings", None, ["payroll_based_on","consider_unmarked_attendance_as"], as_dict=1)
+ return [ps.payroll_based_on, ps.consider_unmarked_attendance_as]
def set_time_sheet(self):
if self.salary_slip_based_on_timesheet:
@@ -424,16 +424,19 @@
def calculate_net_pay(self):
if self.salary_structure:
self.calculate_component_amounts("earnings")
- self.gross_pay = self.get_component_totals("earnings")
+ self.gross_pay = self.get_component_totals("earnings", depends_on_payment_days=1)
self.base_gross_pay = flt(flt(self.gross_pay) * flt(self.exchange_rate), self.precision('base_gross_pay'))
if self.salary_structure:
self.calculate_component_amounts("deductions")
+
+ self.set_loan_repayment()
+ self.set_component_amounts_based_on_payment_days()
+ self.set_net_pay()
+
+ def set_net_pay(self):
self.total_deduction = self.get_component_totals("deductions")
self.base_total_deduction = flt(flt(self.total_deduction) * flt(self.exchange_rate), self.precision('base_total_deduction'))
-
- self.set_loan_repayment()
-
self.net_pay = flt(self.gross_pay) - (flt(self.total_deduction) + flt(self.total_loan_repayment))
self.rounded_total = rounded(self.net_pay)
self.base_net_pay = flt(flt(self.net_pay) * flt(self.exchange_rate), self.precision('base_net_pay'))
@@ -455,8 +458,6 @@
else:
self.add_tax_components(payroll_period)
- self.set_component_amounts_based_on_payment_days(component_type)
-
def add_structure_components(self, component_type):
data = self.get_data_for_eval()
for struct_row in self._salary_structure_doc.get(component_type):
@@ -813,7 +814,7 @@
cint(row.depends_on_payment_days) and cint(self.total_working_days) and
(not self.salary_slip_based_on_timesheet or
getdate(self.start_date) < joining_date or
- getdate(self.end_date) > relieving_date
+ (relieving_date and getdate(self.end_date) > relieving_date)
)):
additional_amount = flt((flt(row.additional_amount) * flt(self.payment_days)
/ cint(self.total_working_days)), row.precision("additional_amount"))
@@ -946,15 +947,21 @@
struct_row['variable_based_on_taxable_salary'] = component.variable_based_on_taxable_salary
return struct_row
- def get_component_totals(self, component_type):
+ def get_component_totals(self, component_type, depends_on_payment_days=0):
+ joining_date, relieving_date = frappe.get_cached_value("Employee", self.employee,
+ ["date_of_joining", "relieving_date"])
+
total = 0.0
for d in self.get(component_type):
if not d.do_not_include_in_total:
- d.amount = flt(d.amount, d.precision("amount"))
- total += d.amount
+ if depends_on_payment_days:
+ amount = self.get_amount_based_on_payment_days(d, joining_date, relieving_date)[0]
+ else:
+ amount = flt(d.amount, d.precision("amount"))
+ total += amount
return total
- def set_component_amounts_based_on_payment_days(self, component_type):
+ def set_component_amounts_based_on_payment_days(self):
joining_date, relieving_date = frappe.get_cached_value("Employee", self.employee,
["date_of_joining", "relieving_date"])
@@ -964,8 +971,9 @@
if not joining_date:
frappe.throw(_("Please set the Date Of Joining for employee {0}").format(frappe.bold(self.employee_name)))
- for d in self.get(component_type):
- d.amount = self.get_amount_based_on_payment_days(d, joining_date, relieving_date)[0]
+ for component_type in ("earnings", "deductions"):
+ for d in self.get(component_type):
+ d.amount = flt(self.get_amount_based_on_payment_days(d, joining_date, relieving_date)[0], d.precision("amount"))
def set_loan_repayment(self):
self.total_loan_repayment = 0
@@ -1089,17 +1097,17 @@
self.calculate_net_pay()
def set_totals(self):
- self.gross_pay = 0
+ self.gross_pay = 0.0
if self.salary_slip_based_on_timesheet == 1:
self.calculate_total_for_salary_slip_based_on_timesheet()
else:
- self.total_deduction = 0
+ self.total_deduction = 0.0
if self.earnings:
for earning in self.earnings:
- self.gross_pay += flt(earning.amount)
+ self.gross_pay += flt(earning.amount, earning.precision("amount"))
if self.deductions:
for deduction in self.deductions:
- self.total_deduction += flt(deduction.amount)
+ self.total_deduction += flt(deduction.amount, deduction.precision("amount"))
self.net_pay = flt(self.gross_pay) - flt(self.total_deduction) - flt(self.total_loan_repayment)
self.set_base_totals()
diff --git a/erpnext/payroll/doctype/salary_slip/test_salary_slip.py b/erpnext/payroll/doctype/salary_slip/test_salary_slip.py
index d6fb419..4368c03 100644
--- a/erpnext/payroll/doctype/salary_slip/test_salary_slip.py
+++ b/erpnext/payroll/doctype/salary_slip/test_salary_slip.py
@@ -318,7 +318,7 @@
year_to_date = 0
for slip in salary_slips:
- year_to_date += slip.net_pay
+ year_to_date += flt(slip.net_pay)
self.assertEqual(slip.year_to_date, year_to_date)
def test_tax_for_payroll_period(self):