From 8b808bb86b1de78e987a83312ae12f001b03a89e Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Mon, 9 Oct 2023 20:13:29 +0530 Subject: [PATCH 1/2] fix(Expense Claim): respect system precision for rounding (cherry picked from commit fcbbb4dc06481b3f5ef08977f86e13c06c146809) --- .../hr/doctype/expense_claim/expense_claim.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/hrms/hr/doctype/expense_claim/expense_claim.py b/hrms/hr/doctype/expense_claim/expense_claim.py index c776aca256..5e53d6d8b5 100644 --- a/hrms/hr/doctype/expense_claim/expense_claim.py +++ b/hrms/hr/doctype/expense_claim/expense_claim.py @@ -268,32 +268,48 @@ def validate_account_details(self): def calculate_total_amount(self): self.total_claimed_amount = 0 self.total_sanctioned_amount = 0 + for d in self.get("expenses"): + self.round_floats_in(d) + if self.approval_status == "Rejected": d.sanctioned_amount = 0.0 self.total_claimed_amount += flt(d.amount) self.total_sanctioned_amount += flt(d.sanctioned_amount) + self.round_floats_in(self, ["total_claimed_amount", "total_sanctioned_amount"]) + @frappe.whitelist() def calculate_taxes(self): self.total_taxes_and_charges = 0 for tax in self.taxes: + self.round_floats_in(tax) + if tax.rate: - tax.tax_amount = flt(self.total_sanctioned_amount) * flt(tax.rate / 100) + tax.tax_amount = flt( + flt(self.total_sanctioned_amount) * flt(tax.rate / 100), + tax.precision("tax_amount"), + ) tax.total = flt(tax.tax_amount) + flt(self.total_sanctioned_amount) self.total_taxes_and_charges += flt(tax.tax_amount) + self.round_floats_in(self, ["total_taxes_and_charges"]) + self.grand_total = ( flt(self.total_sanctioned_amount) + flt(self.total_taxes_and_charges) - flt(self.total_advance_amount) ) + self.round_floats_in(self, ["grand_total"]) def validate_advances(self): self.total_advance_amount = 0 + for d in self.get("advances"): + self.round_floats_in(d) + ref_doc = frappe.db.get_value( "Employee Advance", d.employee_advance, @@ -315,6 +331,7 @@ def validate_advances(self): self.total_advance_amount += flt(d.allocated_amount) if self.total_advance_amount: + self.round_floats_in(self, ["total_advance_amount"]) precision = self.precision("total_advance_amount") amount_with_taxes = flt( (flt(self.total_sanctioned_amount, precision) + flt(self.total_taxes_and_charges, precision)), From f13eaaa6400ce9eaa67998428a94c1eadaf8390c Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Mon, 9 Oct 2023 20:13:37 +0530 Subject: [PATCH 2/2] test: rounding in claims (cherry picked from commit 05d756b642181bd7d085ea733fa5344247ca049c) --- .../expense_claim/test_expense_claim.py | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/hrms/hr/doctype/expense_claim/test_expense_claim.py b/hrms/hr/doctype/expense_claim/test_expense_claim.py index c61520919e..6fd9959ec1 100644 --- a/hrms/hr/doctype/expense_claim/test_expense_claim.py +++ b/hrms/hr/doctype/expense_claim/test_expense_claim.py @@ -491,12 +491,37 @@ def test_accounting_dimension_mapping(self): self.assertEqual(dimensions.project, project) self.assertEqual(dimensions.cost_center, expense_claim.cost_center) + def test_rounding(self): + payable_account = get_payable_account(company_name) + taxes = generate_taxes(rate=7) + expense_claim = make_expense_claim( + payable_account, + 130.84, + 130.84, + company_name, + "Travel Expenses - _TC3", + taxes=taxes, + ) + + self.assertEqual(expense_claim.total_sanctioned_amount, 130.84) + self.assertEqual(expense_claim.total_taxes_and_charges, 9.16) + self.assertEqual(expense_claim.grand_total, 140) + + pe = make_payment_entry(expense_claim, 140) + + expense_claim.reload() + self.assertEqual(expense_claim.status, "Paid") + + pe.cancel() + expense_claim.reload() + self.assertEqual(expense_claim.status, "Unpaid") + def get_payable_account(company): return frappe.get_cached_value("Company", company, "default_payable_account") -def generate_taxes(company=None): +def generate_taxes(company=None, rate=None) -> dict: company = company or company_name parent_account = frappe.db.get_value( "Account", filters={"account_name": "Duties and Taxes", "company": company} @@ -515,10 +540,8 @@ def generate_taxes(company=None): { "account_head": account, "cost_center": cost_center, - "rate": 9, + "rate": rate or 9, "description": "CGST", - "tax_amount": 10, - "total": 210, } ] }