From cf7252d3e732759d8d160335e501fdb0972856ad Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Fri, 2 Feb 2024 21:57:45 +0530 Subject: [PATCH 1/4] fix: check payments against orders for getting request amount (cherry picked from commit f7face43cdcc9ef4e9d7a8cd90b0de8fc567d4e3) # Conflicts: # erpnext/accounts/doctype/payment_request/payment_request.py --- .../payment_request/payment_request.py | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py index 4f6205a2445..317090e7547 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.py +++ b/erpnext/accounts/doctype/payment_request/payment_request.py @@ -3,7 +3,11 @@ import json import frappe from frappe import _, qb from frappe.model.document import Document +<<<<<<< HEAD from frappe.query_builder.functions import Abs, Sum +======= +from frappe.query_builder.functions import Sum +>>>>>>> f7face43cd (fix: check payments against orders for getting request amount) from frappe.utils import flt, nowdate from frappe.utils.background_jobs import enqueue @@ -127,6 +131,8 @@ class PaymentRequest(Document): ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name) if not hasattr(ref_doc, "order_type") or ref_doc.order_type != "Shopping Cart": ref_amount = get_amount(ref_doc, self.payment_account) + if not ref_amount: + frappe.throw(_("Payment Entry is already created")) if existing_payment_request_amount + flt(self.grand_total) > ref_amount: frappe.throw( @@ -544,6 +550,8 @@ def make_payment_request(**args): gateway_account = get_gateway_details(args) or frappe._dict() grand_total = get_amount(ref_doc, gateway_account.get("payment_account")) + if not grand_total: + frappe.throw(_("Payment Entry is already created")) if args.loyalty_points and args.dt == "Sales Order": from erpnext.accounts.doctype.loyalty_program.loyalty_program import validate_loyalty_points @@ -678,6 +686,7 @@ def get_amount(ref_doc, payment_account=None): dt = ref_doc.doctype if dt in ["Sales Order", "Purchase Order"]: grand_total = flt(ref_doc.rounded_total) or flt(ref_doc.grand_total) + grand_total -= get_paid_amount_against_order(dt, ref_doc.name) elif dt in ["Sales Invoice", "Purchase Invoice"]: if not ref_doc.get("is_pos"): if ref_doc.party_account_currency == ref_doc.currency: @@ -699,10 +708,14 @@ def get_amount(ref_doc, payment_account=None): elif dt == "Fees": grand_total = ref_doc.outstanding_amount +<<<<<<< HEAD if grand_total > 0: return flt(grand_total, get_currency_precision()) else: frappe.throw(_("Payment Entry is already created")) +======= + return grand_total +>>>>>>> f7face43cd (fix: check payments against orders for getting request amount) def get_irequest_status(payment_requests: None | list = None) -> list: @@ -992,6 +1005,7 @@ def validate_payment(doc, method=None): ) +<<<<<<< HEAD @frappe.whitelist() def get_open_payment_requests_query(doctype, txt, searchfield, start, page_len, filters): # permission checks in `get_list()` @@ -1032,3 +1046,27 @@ def get_irequests_of_payment_request(doc: str | None = None) -> list: }, ) return res +======= +def get_paid_amount_against_order(dt, dn): + pe_ref = frappe.qb.DocType("Payment Entry Reference") + if dt == "Sales Order": + inv_dt, inv_field = "Sales Invoice Item", "sales_order" + else: + inv_dt, inv_field = "Purchase Invoice Item", "purchase_order" + inv_item = frappe.qb.DocType(inv_dt) + return ( + frappe.qb.from_(pe_ref) + .select( + Sum(pe_ref.allocated_amount), + ) + .where( + (pe_ref.docstatus == 1) + & ( + (pe_ref.reference_name == dn) + | pe_ref.reference_name.isin( + frappe.qb.from_(inv_item).select(inv_item.parent).where(inv_item[inv_field] == dn).distinct() + ) + ) + ) + ).run()[0][0] or 0 +>>>>>>> f7face43cd (fix: check payments against orders for getting request amount) From b0302d71b7a001e1298f3cc5c43c793c6525da32 Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Fri, 2 Feb 2024 21:59:53 +0530 Subject: [PATCH 2/4] fix(portal): payment amount for orders (cherry picked from commit c18ff5bd253878da2f71690f194e8fedd07b2a87) # Conflicts: # erpnext/templates/pages/order.py --- erpnext/templates/pages/order.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/erpnext/templates/pages/order.py b/erpnext/templates/pages/order.py index dca5a0c7497..dff982ed838 100644 --- a/erpnext/templates/pages/order.py +++ b/erpnext/templates/pages/order.py @@ -4,9 +4,13 @@ import frappe from frappe import _ +<<<<<<< HEAD from erpnext.accounts.doctype.payment_request.payment_request import ( ALLOWED_DOCTYPES_FOR_PAYMENT_REQUEST, ) +======= +from erpnext.accounts.doctype.payment_request.payment_request import get_amount +>>>>>>> c18ff5bd25 (fix(portal): payment amount for orders) def get_context(context): @@ -50,11 +54,15 @@ def get_context(context): ) context.available_loyalty_points = int(loyalty_program_details.get("loyalty_points")) +<<<<<<< HEAD context.show_pay_button = ( "payments" in frappe.get_installed_apps() and frappe.db.get_single_value("Buying Settings", "show_pay_button") and context.doc.doctype in ALLOWED_DOCTYPES_FOR_PAYMENT_REQUEST ) +======= + context.show_pay_button, context.pay_amount = get_payment_details(context.doc) +>>>>>>> c18ff5bd25 (fix(portal): payment amount for orders) context.show_make_pi_button = False if context.doc.get("supplier"): # show Make Purchase Invoice button based on permission @@ -67,3 +75,14 @@ def get_attachments(dt, dn): fields=["name", "file_name", "file_url", "is_private"], filters={"attached_to_name": dn, "attached_to_doctype": dt, "is_private": 0}, ) + + +def get_payment_details(doc): + show_pay_button, amount = ( + "payments" in frappe.get_installed_apps() + and frappe.db.get_single_value("Buying Settings", "show_pay_button") + ), 0 + if not show_pay_button: + return show_pay_button, amount + amount = get_amount(doc) + return bool(amount), amount From b7ae17aaaf18be38be8ac53c826ff4f9a73a9058 Mon Sep 17 00:00:00 2001 From: Gursheen Anand Date: Fri, 2 Feb 2024 22:01:42 +0530 Subject: [PATCH 3/4] fix(portal): context pay_amount for button (cherry picked from commit 7efb5a8cb5d581d2ddfcc728f600bf5ba9649ad5) # Conflicts: # erpnext/templates/pages/order.html --- erpnext/templates/pages/order.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/erpnext/templates/pages/order.html b/erpnext/templates/pages/order.html index 315478fc649..f5e7dadde7f 100644 --- a/erpnext/templates/pages/order.html +++ b/erpnext/templates/pages/order.html @@ -40,7 +40,11 @@

+<<<<<<< HEAD {{ _("Pay", null, "Amount") }} {{doc.get_formatted("grand_total") }} +======= + {{ _("Pay") }} {{ pay_amount }} +>>>>>>> 7efb5a8cb5 (fix(portal): context pay_amount for button)

From 4d8984e4e962562c768227d72f36326eff8f8fe0 Mon Sep 17 00:00:00 2001 From: ljain112 Date: Tue, 8 Apr 2025 15:54:44 +0530 Subject: [PATCH 4/4] fix: resolve conflicts --- .../payment_request/payment_request.py | 34 ------------------- erpnext/templates/pages/order.html | 6 +--- erpnext/templates/pages/order.py | 24 +++++-------- 3 files changed, 10 insertions(+), 54 deletions(-) diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py index 317090e7547..8cb9eb6b5d9 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.py +++ b/erpnext/accounts/doctype/payment_request/payment_request.py @@ -3,11 +3,7 @@ import json import frappe from frappe import _, qb from frappe.model.document import Document -<<<<<<< HEAD from frappe.query_builder.functions import Abs, Sum -======= -from frappe.query_builder.functions import Sum ->>>>>>> f7face43cd (fix: check payments against orders for getting request amount) from frappe.utils import flt, nowdate from frappe.utils.background_jobs import enqueue @@ -686,7 +682,6 @@ def get_amount(ref_doc, payment_account=None): dt = ref_doc.doctype if dt in ["Sales Order", "Purchase Order"]: grand_total = flt(ref_doc.rounded_total) or flt(ref_doc.grand_total) - grand_total -= get_paid_amount_against_order(dt, ref_doc.name) elif dt in ["Sales Invoice", "Purchase Invoice"]: if not ref_doc.get("is_pos"): if ref_doc.party_account_currency == ref_doc.currency: @@ -708,14 +703,10 @@ def get_amount(ref_doc, payment_account=None): elif dt == "Fees": grand_total = ref_doc.outstanding_amount -<<<<<<< HEAD if grand_total > 0: return flt(grand_total, get_currency_precision()) else: frappe.throw(_("Payment Entry is already created")) -======= - return grand_total ->>>>>>> f7face43cd (fix: check payments against orders for getting request amount) def get_irequest_status(payment_requests: None | list = None) -> list: @@ -1005,7 +996,6 @@ def validate_payment(doc, method=None): ) -<<<<<<< HEAD @frappe.whitelist() def get_open_payment_requests_query(doctype, txt, searchfield, start, page_len, filters): # permission checks in `get_list()` @@ -1046,27 +1036,3 @@ def get_irequests_of_payment_request(doc: str | None = None) -> list: }, ) return res -======= -def get_paid_amount_against_order(dt, dn): - pe_ref = frappe.qb.DocType("Payment Entry Reference") - if dt == "Sales Order": - inv_dt, inv_field = "Sales Invoice Item", "sales_order" - else: - inv_dt, inv_field = "Purchase Invoice Item", "purchase_order" - inv_item = frappe.qb.DocType(inv_dt) - return ( - frappe.qb.from_(pe_ref) - .select( - Sum(pe_ref.allocated_amount), - ) - .where( - (pe_ref.docstatus == 1) - & ( - (pe_ref.reference_name == dn) - | pe_ref.reference_name.isin( - frappe.qb.from_(inv_item).select(inv_item.parent).where(inv_item[inv_field] == dn).distinct() - ) - ) - ) - ).run()[0][0] or 0 ->>>>>>> f7face43cd (fix: check payments against orders for getting request amount) diff --git a/erpnext/templates/pages/order.html b/erpnext/templates/pages/order.html index f5e7dadde7f..0805a32ae33 100644 --- a/erpnext/templates/pages/order.html +++ b/erpnext/templates/pages/order.html @@ -40,11 +40,7 @@

-<<<<<<< HEAD - {{ _("Pay", null, "Amount") }} {{doc.get_formatted("grand_total") }} -======= - {{ _("Pay") }} {{ pay_amount }} ->>>>>>> 7efb5a8cb5 (fix(portal): context pay_amount for button) + {{ _("Pay", null, "Amount") }} {{ pay_amount }}

diff --git a/erpnext/templates/pages/order.py b/erpnext/templates/pages/order.py index dff982ed838..dcf3b046722 100644 --- a/erpnext/templates/pages/order.py +++ b/erpnext/templates/pages/order.py @@ -4,13 +4,10 @@ import frappe from frappe import _ -<<<<<<< HEAD from erpnext.accounts.doctype.payment_request.payment_request import ( ALLOWED_DOCTYPES_FOR_PAYMENT_REQUEST, + get_amount, ) -======= -from erpnext.accounts.doctype.payment_request.payment_request import get_amount ->>>>>>> c18ff5bd25 (fix(portal): payment amount for orders) def get_context(context): @@ -54,15 +51,7 @@ def get_context(context): ) context.available_loyalty_points = int(loyalty_program_details.get("loyalty_points")) -<<<<<<< HEAD - context.show_pay_button = ( - "payments" in frappe.get_installed_apps() - and frappe.db.get_single_value("Buying Settings", "show_pay_button") - and context.doc.doctype in ALLOWED_DOCTYPES_FOR_PAYMENT_REQUEST - ) -======= context.show_pay_button, context.pay_amount = get_payment_details(context.doc) ->>>>>>> c18ff5bd25 (fix(portal): payment amount for orders) context.show_make_pi_button = False if context.doc.get("supplier"): # show Make Purchase Invoice button based on permission @@ -79,10 +68,15 @@ def get_attachments(dt, dn): def get_payment_details(doc): show_pay_button, amount = ( - "payments" in frappe.get_installed_apps() - and frappe.db.get_single_value("Buying Settings", "show_pay_button") - ), 0 + ( + "payments" in frappe.get_installed_apps() + and frappe.db.get_single_value("Buying Settings", "show_pay_button") + and doc.doctype in ALLOWED_DOCTYPES_FOR_PAYMENT_REQUEST + ), + 0, + ) if not show_pay_button: return show_pay_button, amount + amount = get_amount(doc) return bool(amount), amount