From 541b29af11682db9786dd377883af2183602f5e8 Mon Sep 17 00:00:00 2001 From: Sugesh393 Date: Tue, 11 Mar 2025 11:49:35 +0530 Subject: [PATCH 1/3] fix: add base_outstanding and base_paid_amount in payment schedule table --- .../doctype/payment_entry/payment_entry.py | 42 +++++++++++++++++-- .../payment_schedule/payment_schedule.json | 22 +++++++++- .../payment_schedule/payment_schedule.py | 28 +++++++++++++ .../accounts_receivable.py | 26 +++++++----- erpnext/controllers/accounts_controller.py | 3 ++ 5 files changed, 104 insertions(+), 17 deletions(-) diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.py b/erpnext/accounts/doctype/payment_entry/payment_entry.py index d6efad1d19e..03e2dd6c926 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.py +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.py @@ -7,6 +7,7 @@ from functools import reduce import frappe from frappe import ValidationError, _, qb, scrub, throw +from frappe.model.meta import get_field_precision from frappe.query_builder import Tuple from frappe.query_builder.functions import Count from frappe.utils import cint, comma_or, flt, getdate, nowdate @@ -864,16 +865,39 @@ class PaymentEntry(AccountsController): outstanding = flt(invoice_paid_amount_map.get(key, {}).get("outstanding")) discounted_amt = flt(invoice_paid_amount_map.get(key, {}).get("discounted_amt")) + conversion_rate = frappe.db.get_value(key[2], {"name": key[1]}, "conversion_rate") + base_paid_amount_precision = get_field_precision( + frappe.get_meta("Payment Schedule").get_field("base_paid_amount") + ) + base_outstanding_precision = get_field_precision( + frappe.get_meta("Payment Schedule").get_field("base_outstanding") + ) + + base_paid_amount = flt( + (allocated_amount - discounted_amt) * conversion_rate, base_paid_amount_precision + ) + base_outstanding = flt(allocated_amount * conversion_rate, base_outstanding_precision) + if cancel: frappe.db.sql( """ UPDATE `tabPayment Schedule` SET paid_amount = `paid_amount` - %s, + base_paid_amount = `base_paid_amount` - %s, discounted_amount = `discounted_amount` - %s, - outstanding = `outstanding` + %s + outstanding = `outstanding` + %s, + base_outstanding = `base_outstanding` - %s WHERE parent = %s and payment_term = %s""", - (allocated_amount - discounted_amt, discounted_amt, allocated_amount, key[1], key[0]), + ( + allocated_amount - discounted_amt, + base_paid_amount, + discounted_amt, + allocated_amount, + base_outstanding, + key[1], + key[0], + ), ) else: if allocated_amount > outstanding: @@ -889,10 +913,20 @@ class PaymentEntry(AccountsController): UPDATE `tabPayment Schedule` SET paid_amount = `paid_amount` + %s, + base_paid_amount = `base_paid_amount` + %s, discounted_amount = `discounted_amount` + %s, - outstanding = `outstanding` - %s + outstanding = `outstanding` - %s, + base_outstanding = `base_outstanding` - %s WHERE parent = %s and payment_term = %s""", - (allocated_amount - discounted_amt, discounted_amt, allocated_amount, key[1], key[0]), + ( + allocated_amount - discounted_amt, + base_paid_amount, + discounted_amt, + allocated_amount, + base_outstanding, + key[1], + key[0], + ), ) def get_allocated_amount_in_transaction_currency( diff --git a/erpnext/accounts/doctype/payment_schedule/payment_schedule.json b/erpnext/accounts/doctype/payment_schedule/payment_schedule.json index 098972196b3..6b8166a8b98 100644 --- a/erpnext/accounts/doctype/payment_schedule/payment_schedule.json +++ b/erpnext/accounts/doctype/payment_schedule/payment_schedule.json @@ -24,7 +24,9 @@ "paid_amount", "discounted_amount", "column_break_3", - "base_payment_amount" + "base_payment_amount", + "base_outstanding", + "base_paid_amount" ], "fields": [ { @@ -155,18 +157,34 @@ "fieldtype": "Currency", "label": "Payment Amount (Company Currency)", "options": "Company:company:default_currency" + }, + { + "fieldname": "base_outstanding", + "fieldtype": "Currency", + "label": "Outstanding (Company Currency)", + "options": "Company:company:default_currency", + "read_only": 1 + }, + { + "depends_on": "base_paid_amount", + "fieldname": "base_paid_amount", + "fieldtype": "Currency", + "label": "Paid Amount (Company Currency)", + "options": "Company:company:default_currency", + "read_only": 1 } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2024-03-27 13:10:11.356171", + "modified": "2025-03-11 11:06:51.792982", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Schedule", "owner": "Administrator", "permissions": [], "quick_entry": 1, + "row_format": "Dynamic", "sort_field": "creation", "sort_order": "DESC", "states": [], diff --git a/erpnext/accounts/doctype/payment_schedule/payment_schedule.py b/erpnext/accounts/doctype/payment_schedule/payment_schedule.py index 33e261f0efd..a3d1dbe5564 100644 --- a/erpnext/accounts/doctype/payment_schedule/payment_schedule.py +++ b/erpnext/accounts/doctype/payment_schedule/payment_schedule.py @@ -6,4 +6,32 @@ from frappe.model.document import Document class PaymentSchedule(Document): + # begin: auto-generated types + # This code is auto-generated. Do not modify anything in this block. + + from typing import TYPE_CHECKING + + if TYPE_CHECKING: + from frappe.types import DF + + base_outstanding: DF.Currency + base_paid_amount: DF.Currency + base_payment_amount: DF.Currency + description: DF.SmallText | None + discount: DF.Float + discount_date: DF.Date | None + discount_type: DF.Literal["Percentage", "Amount"] + discounted_amount: DF.Currency + due_date: DF.Date + invoice_portion: DF.Percent + mode_of_payment: DF.Link | None + outstanding: DF.Currency + paid_amount: DF.Currency + parent: DF.Data + parentfield: DF.Data + parenttype: DF.Data + payment_amount: DF.Currency + payment_term: DF.Link | None + # end: auto-generated types + pass diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py index 046aff0271d..973b7eede66 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.py +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.py @@ -517,7 +517,7 @@ class ReceivablePayableReport: select si.name, si.party_account_currency, si.currency, si.conversion_rate, si.total_advance, ps.due_date, ps.payment_term, ps.payment_amount, ps.base_payment_amount, - ps.description, ps.paid_amount, ps.discounted_amount + ps.description, ps.paid_amount, ps.base_paid_amount, ps.discounted_amount from `tab{row.voucher_type}` si, `tabPayment Schedule` ps where si.name = ps.parent and ps.parenttype = '{row.voucher_type}' and @@ -540,20 +540,24 @@ class ReceivablePayableReport: # Deduct that from paid amount pre allocation row.paid -= flt(payment_terms_details[0].total_advance) + company_currency = frappe.get_value("Company", self.filters.get("company"), "default_currency") + # If single payment terms, no need to split the row if len(payment_terms_details) == 1 and payment_terms_details[0].payment_term: - self.append_payment_term(row, payment_terms_details[0], original_row) + self.append_payment_term(row, payment_terms_details[0], original_row, company_currency) return for d in payment_terms_details: term = frappe._dict(original_row) - self.append_payment_term(row, d, term) + self.append_payment_term(row, d, term, company_currency) + + def append_payment_term(self, row, d, term, company_currency): + invoiced = d.base_payment_amount + paid_amount = d.base_paid_amount - def append_payment_term(self, row, d, term): - if d.currency == d.party_account_currency: + if company_currency == d.party_account_currency or self.filters.get("in_party_currency"): invoiced = d.payment_amount - else: - invoiced = d.base_payment_amount + paid_amount = d.paid_amount row.payment_terms.append( term.update( @@ -562,15 +566,15 @@ class ReceivablePayableReport: "invoiced": invoiced, "invoice_grand_total": row.invoiced, "payment_term": d.description or d.payment_term, - "paid": d.paid_amount + d.discounted_amount, + "paid": paid_amount + d.discounted_amount, "credit_note": 0.0, - "outstanding": invoiced - d.paid_amount - d.discounted_amount, + "outstanding": invoiced - paid_amount - d.discounted_amount, } ) ) - if d.paid_amount: - row["paid"] -= d.paid_amount + d.discounted_amount + if paid_amount: + row["paid"] -= paid_amount + d.discounted_amount def allocate_closing_to_term(self, row, term, key): if row[key]: diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 146fc2ba0ba..3d364b038ac 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -2488,6 +2488,9 @@ class AccountsController(TransactionBase): base_grand_total * flt(d.invoice_portion) / 100, d.precision("base_payment_amount") ) d.outstanding = d.payment_amount + d.base_outstanding = flt( + d.payment_amount * self.get("conversion_rate"), d.precision("base_outstanding") + ) elif not d.invoice_portion: d.base_payment_amount = flt( d.payment_amount * self.get("conversion_rate"), d.precision("base_payment_amount") -- GitLab From 35c386656b805982ff530ce5537ae60090597136 Mon Sep 17 00:00:00 2001 From: Sugesh393 Date: Tue, 11 Mar 2025 11:52:42 +0530 Subject: [PATCH 2/3] fix: add patch to update base_outstanding and base_paid_amount --- erpnext/patches.txt | 2 +- ...date_payment_schedule_fields_in_invoices.py | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 erpnext/patches/v15_0/update_payment_schedule_fields_in_invoices.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index c71f0886554..cdbb15163d0 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -441,4 +441,4 @@ erpnext.patches.v15_0.rename_field_from_rate_difference_to_amount_difference erpnext.patches.v15_0.recalculate_amount_difference_field #2025-03-18 erpnext.stock.doctype.stock_ledger_entry.patches.ensure_sle_indexes erpnext.patches.v15_0.set_purchase_receipt_row_item_to_capitalization_stock_item -erpnext.patches.v15_0.rename_sla_fields +erpnext.patches.v15_0.update_payment_schedule_fields_in_invoices diff --git a/erpnext/patches/v15_0/update_payment_schedule_fields_in_invoices.py b/erpnext/patches/v15_0/update_payment_schedule_fields_in_invoices.py new file mode 100644 index 00000000000..74d8ac38f72 --- /dev/null +++ b/erpnext/patches/v15_0/update_payment_schedule_fields_in_invoices.py @@ -0,0 +1,18 @@ +import frappe +from frappe.query_builder import DocType + + +def execute(): + invoice_types = ["Sales Invoice", "Purchase Invoice"] + for invoice_type in invoice_types: + invoice = DocType(invoice_type) + invoice_details = frappe.qb.from_(invoice).select(invoice.conversion_rate, invoice.name) + update_payment_schedule(invoice_details) + + +def update_payment_schedule(invoice_details): + ps = DocType("Payment Schedule") + + frappe.qb.update(ps).join(invoice_details).on(ps.parent == invoice_details.name).set( + ps.base_paid_amount, ps.paid_amount * invoice_details.conversion_rate + ).set(ps.base_outstanding, ps.outstanding * invoice_details.conversion_rate).run() -- GitLab From 1fcfd5c766e40f8d3c334d63ff9a3ddf59940374 Mon Sep 17 00:00:00 2001 From: Charles-Henri Decultot Date: Mon, 24 Mar 2025 13:51:10 +0100 Subject: [PATCH 3/3] fix: merge conflict --- erpnext/patches.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index cdbb15163d0..26ad8e0d8e0 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -441,4 +441,5 @@ erpnext.patches.v15_0.rename_field_from_rate_difference_to_amount_difference erpnext.patches.v15_0.recalculate_amount_difference_field #2025-03-18 erpnext.stock.doctype.stock_ledger_entry.patches.ensure_sle_indexes erpnext.patches.v15_0.set_purchase_receipt_row_item_to_capitalization_stock_item +erpnext.patches.v15_0.rename_sla_fields erpnext.patches.v15_0.update_payment_schedule_fields_in_invoices -- GitLab