From e3e7166c608b7ee73c2a5d2c4d1d908095d962a9 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Thu, 5 Sep 2024 14:11:27 +0530 Subject: [PATCH] revert: fix(Salary Structure Assignment: Preview Salary Slip): Calculation of earnings whose formula is dependent on deductions and so on (#2161) (cherry picked from commit 7260edf708c5548cba207df2a4af57b6f877165d) --- .../doctype/salary_slip/salary_slip.py | 30 +-------- .../doctype/salary_slip/test_salary_slip.py | 63 ------------------- 2 files changed, 2 insertions(+), 91 deletions(-) diff --git a/hrms/payroll/doctype/salary_slip/salary_slip.py b/hrms/payroll/doctype/salary_slip/salary_slip.py index 10e267e786..c26b9a9d01 100644 --- a/hrms/payroll/doctype/salary_slip/salary_slip.py +++ b/hrms/payroll/doctype/salary_slip/salary_slip.py @@ -2,7 +2,6 @@ # License: GNU General Public License v3. See license.txt -import ast import unicodedata from datetime import date @@ -792,33 +791,12 @@ def set_gross_pay_and_base_gross_pay(): if self.salary_structure: self.calculate_component_amounts("deductions") - deduction_abbrs = [d.abbr for d in self.deductions] - self.update_dependent_components_recursively("earnings", deduction_abbrs) - - set_gross_pay_and_base_gross_pay() - self.update_dependent_components_recursively("deductions", ["gross_pay", "base_gross_pay"]) - set_loan_repayment(self) self.set_precision_for_component_amounts() self.set_net_pay() self.compute_income_tax_breakup() - def update_dependent_components_recursively( - self, component_type: str, updated_var: str | list[str] - ) -> None: - def is_var_updated(var: str | list[str]) -> bool: - return var == updated_var if isinstance(updated_var, str) else var in updated_var - - other_component_type = "deductions" if component_type == "earnings" else "earnings" - - for d in self._salary_structure_doc.get(component_type): - if d.amount_based_on_formula and d.formula: - for var in get_variables_from_formula(d.formula): - if is_var_updated(var): - self.add_structure_component(d, component_type) - self.update_dependent_components_recursively(other_component_type, d.abbr) - def set_net_pay(self): self.total_deduction = self.get_component_totals("deductions") self.base_total_deduction = flt( @@ -2308,6 +2286,8 @@ def _safe_eval(code: str, eval_globals: dict | None = None, eval_locals: dict | def _check_attributes(code: str) -> None: + import ast + from frappe.utils.safe_exec import UNSAFE_ATTRIBUTES unsafe_attrs = set(UNSAFE_ATTRIBUTES).union(["__"]) - {"format"} @@ -2346,9 +2326,3 @@ def email_salary_slips(names) -> None: for name in names: salary_slip = frappe.get_doc("Salary Slip", name) salary_slip.email_salary_slip() - - -def get_variables_from_formula(formula: str) -> list[str]: - # compile expects a string - formula = cstr(formula) - return [node.id for node in ast.walk(ast.parse(formula, mode="eval")) if isinstance(node, ast.Name)] diff --git a/hrms/payroll/doctype/salary_slip/test_salary_slip.py b/hrms/payroll/doctype/salary_slip/test_salary_slip.py index e24d5002cf..c214e19021 100644 --- a/hrms/payroll/doctype/salary_slip/test_salary_slip.py +++ b/hrms/payroll/doctype/salary_slip/test_salary_slip.py @@ -1634,69 +1634,6 @@ def test_variable_tax_component(self): self.assertEqual(test_tds.accounts[0].company, salary_slip.company) self.assertListEqual(tax_component, ["_Test TDS"]) - def test_circular_dependency_in_formula(self): - from hrms.payroll.doctype.salary_structure.test_salary_structure import ( - create_salary_structure_assignment, - ) - - earnings = [ - { - "salary_component": "Dependent Earning", - "abbr": "DE", - "type": "Earning", - "depends_on_payment_days": 0, - "amount_based_on_formula": 1, - "formula": "ID * 10", - }, - ] - make_salary_component(earnings, False, company_list=[]) - - deductions = [ - { - "salary_component": "Independent Deduction", - "abbr": "ID", - "type": "Deduction", - "amount": 500, - }, - { - "salary_component": "Dependent Deduction", - "abbr": "DD", - "type": "Deduction", - "amount_based_on_formula": 1, - "formula": "DE / 5\nif DE > 0\n else 0", - }, - ] - make_salary_component(deductions, False, company_list=[]) - - details = { - "doctype": "Salary Structure", - "name": "Test Salary Structure for Circular Dependency", - "company": "_Test Company", - "payroll_frequency": "Monthly", - "payment_account": get_random("Account", filters={"account_currency": "USD"}), - "currency": "INR", - } - salary_structure = frappe.get_doc(details) - - for entry in earnings: - salary_structure.append("earnings", entry) - for entry in deductions: - salary_structure.append("deductions", entry) - - salary_structure.insert() - salary_structure.submit() - - emp = make_employee("test_circ_dep@salary.com", company="_Test Company") - - create_salary_structure_assignment(emp, salary_structure.name, currency="INR") - salary_slip = make_salary_slip( - salary_structure.name, employee=emp, posting_date=getdate(), for_preview=1 - ) - - self.assertEqual(salary_slip.gross_pay, 5000) - self.assertEqual(salary_slip.earnings[0].amount, 5000) - self.assertEqual(salary_slip.deductions[1].amount, 1000) - class TestSalarySlipSafeEval(FrappeTestCase): def test_safe_eval_for_salary_slip(self):