mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-26 08:24:47 +00:00
Merge pull request #31521 from ruchamahabal/fix-salary-calc-pd
fix: components in the same table don't get updated value of prev payment-days based component
This commit is contained in:
@@ -626,7 +626,7 @@ class SalarySlip(TransactionBase):
|
|||||||
for struct_row in self._salary_structure_doc.get(component_type):
|
for struct_row in self._salary_structure_doc.get(component_type):
|
||||||
amount = self.eval_condition_and_formula(struct_row, data)
|
amount = self.eval_condition_and_formula(struct_row, data)
|
||||||
if amount is not None and struct_row.statistical_component == 0:
|
if amount is not None and struct_row.statistical_component == 0:
|
||||||
self.update_component_row(struct_row, amount, component_type)
|
self.update_component_row(struct_row, amount, component_type, data=data)
|
||||||
|
|
||||||
def get_data_for_eval(self):
|
def get_data_for_eval(self):
|
||||||
"""Returns data for evaluating formula"""
|
"""Returns data for evaluating formula"""
|
||||||
@@ -780,7 +780,7 @@ class SalarySlip(TransactionBase):
|
|||||||
self.update_component_row(tax_row, tax_amount, "deductions")
|
self.update_component_row(tax_row, tax_amount, "deductions")
|
||||||
|
|
||||||
def update_component_row(
|
def update_component_row(
|
||||||
self, component_data, amount, component_type, additional_salary=None, is_recurring=0
|
self, component_data, amount, component_type, additional_salary=None, is_recurring=0, data=None
|
||||||
):
|
):
|
||||||
component_row = None
|
component_row = None
|
||||||
for d in self.get(component_type):
|
for d in self.get(component_type):
|
||||||
@@ -850,6 +850,8 @@ class SalarySlip(TransactionBase):
|
|||||||
component_row.amount = amount
|
component_row.amount = amount
|
||||||
|
|
||||||
self.update_component_amount_based_on_payment_days(component_row)
|
self.update_component_amount_based_on_payment_days(component_row)
|
||||||
|
if data:
|
||||||
|
data[component_row.abbr] = component_row.amount
|
||||||
|
|
||||||
def update_component_amount_based_on_payment_days(self, component_row):
|
def update_component_amount_based_on_payment_days(self, component_row):
|
||||||
joining_date, relieving_date = self.get_joining_and_relieving_dates()
|
joining_date, relieving_date = self.get_joining_and_relieving_dates()
|
||||||
|
|||||||
@@ -1119,6 +1119,7 @@ def make_earning_salary_component(
|
|||||||
"formula": "BS*.5",
|
"formula": "BS*.5",
|
||||||
"type": "Earning",
|
"type": "Earning",
|
||||||
"amount_based_on_formula": 1,
|
"amount_based_on_formula": 1,
|
||||||
|
"depends_on_payment_days": 0,
|
||||||
},
|
},
|
||||||
{"salary_component": "Leave Encashment", "abbr": "LE", "type": "Earning"},
|
{"salary_component": "Leave Encashment", "abbr": "LE", "type": "Earning"},
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||||
# License: GNU General Public License v3. See license.txt
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
@@ -18,6 +19,7 @@ class SalaryStructure(Document):
|
|||||||
self.strip_condition_and_formula_fields()
|
self.strip_condition_and_formula_fields()
|
||||||
self.validate_max_benefits_with_flexi()
|
self.validate_max_benefits_with_flexi()
|
||||||
self.validate_component_based_on_tax_slab()
|
self.validate_component_based_on_tax_slab()
|
||||||
|
self.validate_payment_days_based_dependent_component()
|
||||||
|
|
||||||
def set_missing_values(self):
|
def set_missing_values(self):
|
||||||
overwritten_fields = [
|
overwritten_fields = [
|
||||||
@@ -58,6 +60,35 @@ class SalaryStructure(Document):
|
|||||||
if flt(self.net_pay) < 0 and self.salary_slip_based_on_timesheet:
|
if flt(self.net_pay) < 0 and self.salary_slip_based_on_timesheet:
|
||||||
frappe.throw(_("Net pay cannot be negative"))
|
frappe.throw(_("Net pay cannot be negative"))
|
||||||
|
|
||||||
|
def validate_payment_days_based_dependent_component(self):
|
||||||
|
abbreviations = self.get_component_abbreviations()
|
||||||
|
for component_type in ("earnings", "deductions"):
|
||||||
|
for row in self.get(component_type):
|
||||||
|
if (
|
||||||
|
row.formula
|
||||||
|
and row.depends_on_payment_days
|
||||||
|
# check if the formula contains any of the payment days components
|
||||||
|
and any(re.search(r"\b" + abbr + r"\b", row.formula) for abbr in abbreviations)
|
||||||
|
):
|
||||||
|
message = _("Row #{0}: The {1} Component has the options {2} and {3} enabled.").format(
|
||||||
|
row.idx,
|
||||||
|
frappe.bold(row.salary_component),
|
||||||
|
frappe.bold("Amount based on formula"),
|
||||||
|
frappe.bold("Depends On Payment Days"),
|
||||||
|
)
|
||||||
|
message += "<br><br>" + _(
|
||||||
|
"Disable {0} for the {1} component, to prevent the amount from being deducted twice, as its formula already uses a payment-days-based component."
|
||||||
|
).format(
|
||||||
|
frappe.bold("Depends On Payment Days"), frappe.bold(row.salary_component)
|
||||||
|
)
|
||||||
|
frappe.throw(message, title=_("Payment Days Dependency"))
|
||||||
|
|
||||||
|
def get_component_abbreviations(self):
|
||||||
|
abbr = [d.abbr for d in self.earnings if d.depends_on_payment_days]
|
||||||
|
abbr += [d.abbr for d in self.deductions if d.depends_on_payment_days]
|
||||||
|
|
||||||
|
return abbr
|
||||||
|
|
||||||
def strip_condition_and_formula_fields(self):
|
def strip_condition_and_formula_fields(self):
|
||||||
# remove whitespaces from condition and formula fields
|
# remove whitespaces from condition and formula fields
|
||||||
for row in self.earnings:
|
for row in self.earnings:
|
||||||
|
|||||||
Reference in New Issue
Block a user