From 898abe5bddc01fff2db4efbcfa232b7375bfb3ad Mon Sep 17 00:00:00 2001 From: Charles-Henri Decultot Date: Mon, 6 Jan 2025 13:39:22 +0100 Subject: [PATCH 1/3] fix: get mop from payment gateway --- .../payment_request/payment_request.py | 81 ++++++++++++++++++- .../patches/refactor_subscriptions_model.py | 10 +-- .../event_registration/event_registration.py | 5 +- 3 files changed, 85 insertions(+), 11 deletions(-) diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py index 9b2b3c8a82..372c240ba5 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.py +++ b/erpnext/accounts/doctype/payment_request/payment_request.py @@ -365,9 +365,7 @@ class PaymentRequest(Document): {"payment_gateway": self.payment_gateway, "customer_id": customer_id}, ) if not customer.mode_of_payment: - customer.mode_of_payment = frappe.get_cached_value( - "Mode of Payment", dict(payment_gateway=self.payment_gateway, enabled=True) - ) + customer.mode_of_payment = get_mode_of_payment_for_company(self.company, self.payment_gateway) customer.flags.ignore_permissions = True customer.save() @@ -1009,3 +1007,80 @@ def make_payment_order(source_name, target_doc=None): ) return doclist + + +def validate_payment(doc, method=None): + if doc.reference_doctype != "Payment Request" or ( + frappe.db.get_value(doc.reference_doctype, doc.reference_docname, "status") != "Paid" + ): + return + + frappe.throw( + _("The Payment Request {0} is already paid, cannot process payment twice").format( + doc.reference_docname + ) + ) + + +@frappe.whitelist() +def get_open_payment_requests_query(doctype, txt, searchfield, start, page_len, filters): + # permission checks in `get_list()` + filters = frappe._dict(filters) + + if not filters.reference_doctype or not filters.reference_name: + return [] + + if txt: + filters.name = ["like", f"%{txt}%"] + + open_payment_requests = frappe.get_list( + "Payment Request", + filters=filters, + fields=["name", "grand_total", "outstanding_amount"], + order_by="transaction_date ASC,creation ASC", + ) + + return [ + ( + pr.name, + _("Grand Total: {0}").format(pr.grand_total), + _("Outstanding Amount: {0}").format(pr.outstanding_amount), + ) + for pr in open_payment_requests + ] + + +def get_irequests_of_payment_request(doc: str | None = None) -> list: + res = [] + if doc: + res = frappe.db.get_all( + "Integration Request", + { + "reference_doctype": "Payment Request", + "reference_docname": doc, + "status": "Queued", + }, + ) + return res + + +def get_mode_of_payment_for_company(company, payment_gateway): + mode_of_payment = frappe.qb.DocType("Mode of Payment") + mode_of_payment_account = frappe.qb.DocType("Mode of Payment Account") + payment_gateway_dt = frappe.qb.DocType("Payment Gateway") + query = ( + frappe.qb.from_(mode_of_payment_account) + .left_join(mode_of_payment) + .on(mode_of_payment_account.parent == mode_of_payment.name) + .left_join(payment_gateway_dt) + .on(mode_of_payment_account.payment_gateway == payment_gateway_dt.name) + .select(mode_of_payment.name) + .where( + mode_of_payment.enabled + & (mode_of_payment_account.company == company) + & (mode_of_payment_account.payment_gateway == payment_gateway) + & (payment_gateway_dt.disabled == 0) + ) + ) + + return query.run(as_dict=True, pluck=True) diff --git a/erpnext/accounts/doctype/subscription/patches/refactor_subscriptions_model.py b/erpnext/accounts/doctype/subscription/patches/refactor_subscriptions_model.py index 619fe1fcc2..0fc76a62b2 100644 --- a/erpnext/accounts/doctype/subscription/patches/refactor_subscriptions_model.py +++ b/erpnext/accounts/doctype/subscription/patches/refactor_subscriptions_model.py @@ -3,6 +3,7 @@ from collections import defaultdict import frappe from frappe import _ +from erpnext.accounts.doctype.payment_request.payment_request import get_mode_of_payment_for_company from erpnext.setup.setup_wizard.operations.install_fixtures import create_recurrence_periods @@ -15,7 +16,6 @@ def execute(): frappe.reload_doc("selling", "doctype", "Recurrence Period") for dt in ["Subscription Template", "Subscription"]: - fields = [ "billing_interval", "billing_interval_count", @@ -134,9 +134,7 @@ def fix_new_orders_status(): if si := frappe.db.get_value( "Sales Invoice", - dict( - subscription=doc.name, from_date=doc.current_invoice_start, to_date=doc.current_invoice_end - ), + dict(subscription=doc.name, from_date=doc.current_invoice_start, to_date=doc.current_invoice_end), ): doc.set_state("sales_invoice", si) @@ -150,10 +148,10 @@ def fix_new_orders_status(): if prs := frappe.get_all( "Payment Request", filters=dict(subscription=doc.name, status="Paid"), - fields=["name", "payment_gateway"], + fields=["name", "payment_gateway", "company"], order_by="transaction_date DESC", ): - if mop := frappe.db.get_value("Mode of Payment", dict(payment_gateway=prs[0].payment_gateway)): + if mop := get_mode_of_payment_for_company(prs[0].company, prs[0].payment_gateway): doc.payment_gateway = mop doc.db_set("payment_gateway", mop) diff --git a/erpnext/venue/doctype/event_registration/event_registration.py b/erpnext/venue/doctype/event_registration/event_registration.py index b273249bd0..1436399324 100644 --- a/erpnext/venue/doctype/event_registration/event_registration.py +++ b/erpnext/venue/doctype/event_registration/event_registration.py @@ -8,6 +8,7 @@ from frappe import _ from frappe.model.document import Document from frappe.utils import cint, is_desk +from erpnext.accounts.doctype.payment_request.payment_request import get_mode_of_payment_for_company from erpnext.utilities import webshop_app_import_guard @@ -425,8 +426,8 @@ class EventRegistration(Document): fee_amount = 0.0 # exchange_rate = 1.0 # TODO - mode_of_payment = mode_of_payment or frappe.db.get_value( - "Mode of Payment", dict(payment_gateway=payment_gateway.name, enabled=1) + mode_of_payment = mode_of_payment or get_mode_of_payment_for_company( + details.company, payment_gateway.name ) -- GitLab From 2d07ec759a3b278e23cfe0749ff8bfb8e3bd163d Mon Sep 17 00:00:00 2001 From: Charles-Henri Decultot Date: Mon, 6 Jan 2025 13:40:58 +0100 Subject: [PATCH 2/3] fix: handle if mode of payment doesn't exist --- erpnext/accounts/doctype/payment_request/payment_request.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py index 372c240ba5..7a53b70d58 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.py +++ b/erpnext/accounts/doctype/payment_request/payment_request.py @@ -1083,4 +1083,6 @@ def get_mode_of_payment_for_company(company, payment_gateway): ) ) - return query.run(as_dict=True, pluck=True) + mode_of_payments = query.run(as_dict=True, pluck=True) + + return mode_of_payments[0] if mode_of_payments else None -- GitLab From 226e3832e24e716e4d0f1bf1205bfa8be2278dcf Mon Sep 17 00:00:00 2001 From: Charles-Henri Decultot Date: Wed, 22 Jan 2025 15:28:25 +0000 Subject: [PATCH 3/3] fix: remove v5 functions --- .../payment_request/payment_request.py | 56 ------------------- 1 file changed, 56 deletions(-) diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py index 7a53b70d58..32020b8877 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.py +++ b/erpnext/accounts/doctype/payment_request/payment_request.py @@ -1008,62 +1008,6 @@ def make_payment_order(source_name, target_doc=None): return doclist - -def validate_payment(doc, method=None): - if doc.reference_doctype != "Payment Request" or ( - frappe.db.get_value(doc.reference_doctype, doc.reference_docname, "status") != "Paid" - ): - return - - frappe.throw( - _("The Payment Request {0} is already paid, cannot process payment twice").format( - doc.reference_docname - ) - ) - - -@frappe.whitelist() -def get_open_payment_requests_query(doctype, txt, searchfield, start, page_len, filters): - # permission checks in `get_list()` - filters = frappe._dict(filters) - - if not filters.reference_doctype or not filters.reference_name: - return [] - - if txt: - filters.name = ["like", f"%{txt}%"] - - open_payment_requests = frappe.get_list( - "Payment Request", - filters=filters, - fields=["name", "grand_total", "outstanding_amount"], - order_by="transaction_date ASC,creation ASC", - ) - - return [ - ( - pr.name, - _("Grand Total: {0}").format(pr.grand_total), - _("Outstanding Amount: {0}").format(pr.outstanding_amount), - ) - for pr in open_payment_requests - ] - - -def get_irequests_of_payment_request(doc: str | None = None) -> list: - res = [] - if doc: - res = frappe.db.get_all( - "Integration Request", - { - "reference_doctype": "Payment Request", - "reference_docname": doc, - "status": "Queued", - }, - ) - return res - - def get_mode_of_payment_for_company(company, payment_gateway): mode_of_payment = frappe.qb.DocType("Mode of Payment") mode_of_payment_account = frappe.qb.DocType("Mode of Payment Account") -- GitLab