Skip to content

Commit

Permalink
Merge pull request #43689 from ruthra-kumar/allow_multiple_payment_re…
Browse files Browse the repository at this point in the history
…quests

refactor: allow multiple payment requests through customer portal
  • Loading branch information
ruthra-kumar authored Nov 7, 2024
2 parents 44832c3 + 18c13a2 commit a10b38e
Showing 1 changed file with 77 additions and 6 deletions.
83 changes: 77 additions & 6 deletions erpnext/accounts/doctype/payment_request/payment_request.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import json

import frappe
from frappe import _
from frappe import _, qb
from frappe.model.document import Document
from frappe.query_builder.functions import Sum
from frappe.utils import flt, nowdate
Expand Down Expand Up @@ -563,11 +563,24 @@ def make_payment_request(**args):
# fetches existing payment request `grand_total` amount
existing_payment_request_amount = get_existing_payment_request_amount(ref_doc.doctype, ref_doc.name)

if existing_payment_request_amount:
def validate_and_calculate_grand_total(grand_total, existing_payment_request_amount):
grand_total -= existing_payment_request_amount

if not grand_total:
frappe.throw(_("Payment Request is already created"))
return grand_total

if existing_payment_request_amount:
if args.order_type == "Shopping Cart":
# If Payment Request is in an advanced stage, then create for remaining amount.
if get_existing_payment_request_amount(
ref_doc.doctype, ref_doc.name, ["Initiated", "Partially Paid", "Payment Ordered", "Paid"]
):
grand_total = validate_and_calculate_grand_total(grand_total, existing_payment_request_amount)
else:
# If PR's are processed, cancel all of them.
cancel_old_payment_requests(ref_doc.doctype, ref_doc.name)
else:
grand_total = validate_and_calculate_grand_total(grand_total, existing_payment_request_amount)

if draft_payment_request:
frappe.db.set_value(
Expand Down Expand Up @@ -683,21 +696,65 @@ def get_amount(ref_doc, payment_account=None):
frappe.throw(_("Payment Entry is already created"))


def get_existing_payment_request_amount(ref_dt, ref_dn):
def get_irequest_status(payment_requests: None | list = None) -> list:
IR = frappe.qb.DocType("Integration Request")
res = []
if payment_requests:
res = (
frappe.qb.from_(IR)
.select(IR.name)
.where(IR.reference_doctype.eq("Payment Request"))
.where(IR.reference_docname.isin(payment_requests))
.where(IR.status.isin(["Authorized", "Completed"]))
.run(as_dict=True)
)
return res


def cancel_old_payment_requests(ref_dt, ref_dn):
PR = frappe.qb.DocType("Payment Request")

if res := (
frappe.qb.from_(PR)
.select(PR.name)
.where(PR.reference_doctype == ref_dt)
.where(PR.reference_name == ref_dn)
.where(PR.docstatus == 1)
.where(PR.status.isin(["Draft", "Requested"]))
.run(as_dict=True)
):
if get_irequest_status([x.name for x in res]):
frappe.throw(_("Another Payment Request is already processed"))
else:
for x in res:
doc = frappe.get_doc("Payment Request", x.name)
doc.flags.ignore_permissions = True
doc.cancel()

if ireqs := get_irequests_of_payment_request(doc.name):
for ireq in ireqs:
frappe.db.set_value("Integration Request", ireq.name, "status", "Cancelled")


def get_existing_payment_request_amount(ref_dt, ref_dn, statuses: list | None = None) -> list:
"""
Return the total amount of Payment Requests against a reference document.
"""
PR = frappe.qb.DocType("Payment Request")

response = (
query = (
frappe.qb.from_(PR)
.select(Sum(PR.grand_total))
.where(PR.reference_doctype == ref_dt)
.where(PR.reference_name == ref_dn)
.where(PR.docstatus == 1)
.run()
)

if statuses:
query = query.where(PR.status.isin(statuses))

response = query.run()

return response[0][0] if response[0] else 0


Expand Down Expand Up @@ -915,3 +972,17 @@ def get_open_payment_requests_query(doctype, txt, searchfield, start, page_len,
)
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

0 comments on commit a10b38e

Please sign in to comment.