From 8b21ca2db917626d8392949a31d4e77766fa94c7 Mon Sep 17 00:00:00 2001 From: David Arnold Date: Sat, 14 Oct 2023 16:34:18 +0200 Subject: [PATCH] fixup! feat(payment): add advance payment status to advance payment doctypes to better track advance payments --- .../payment_request/payment_request.py | 37 +++++++++++++++++++ .../purchase_order/purchase_order_list.js | 4 +- .../purchase_order_analysis.js | 2 +- erpnext/controllers/status_updater.py | 16 ++++++-- .../doctype/sales_order/sales_order.json | 2 +- .../doctype/sales_order/sales_order_list.js | 4 +- .../payment_terms_status_for_sales_order.py | 2 +- .../sales_order_analysis.js | 2 +- 8 files changed, 59 insertions(+), 10 deletions(-) diff --git a/erpnext/accounts/doctype/payment_request/payment_request.py b/erpnext/accounts/doctype/payment_request/payment_request.py index e216d1476c..b690fed5b0 100644 --- a/erpnext/accounts/doctype/payment_request/payment_request.py +++ b/erpnext/accounts/doctype/payment_request/payment_request.py @@ -119,12 +119,16 @@ class PaymentRequest(Document): self.reference_doctype in ["Sales Order"] and ref_doc.advance_payment_status == "Not Requested" ): ref_doc.db_set("advance_payment_status", "Requested") + ref_doc.set_status(update=True) + ref_doc.notify_update() if ( self.reference_doctype in ["Purchase Order"] and ref_doc.advance_payment_status == "Not Initiated" ): ref_doc.db_set("advance_payment_status", "Initiated") + ref_doc.set_status(update=True) + ref_doc.notify_update() def request_phone_payment(self): controller = _get_payment_gateway_controller(self.payment_gateway) @@ -164,6 +168,39 @@ class PaymentRequest(Document): self.check_if_payment_entry_exists() self.set_as_cancelled() + if self.reference_doctype in ["Sales Order", "Purchase Order"]: + + ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name) + if self.reference_doctype in ["Sales Order"] and ref_doc.advance_payment_status == "Requested": + peer_pr = frappe.db.count( + "Payment Request", + { + "reference_doctype": self.reference_doctype, + "reference_name": self.reference_name, + "docstatus": 1, + }, + ) + if not peer_pr: + ref_doc.db_set("advance_payment_status", "Not Requested") + ref_doc.set_status(update=True) + ref_doc.notify_update() + + if ( + self.reference_doctype in ["Purchase Order"] and ref_doc.advance_payment_status == "Initiated" + ): + peer_pr = frappe.db.count( + "Payment Request", + { + "reference_doctype": self.reference_doctype, + "reference_name": self.reference_name, + "docstatus": 1, + }, + ) + if not peer_pr: + ref_doc.db_set("advance_payment_status", "Not Initiated") + ref_doc.set_status(update=True) + ref_doc.notify_update() + def make_invoice(self): ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name) if hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart": diff --git a/erpnext/buying/doctype/purchase_order/purchase_order_list.js b/erpnext/buying/doctype/purchase_order/purchase_order_list.js index 6594746cfc..d39d7f9213 100644 --- a/erpnext/buying/doctype/purchase_order/purchase_order_list.js +++ b/erpnext/buying/doctype/purchase_order/purchase_order_list.js @@ -1,6 +1,6 @@ frappe.listview_settings['Purchase Order'] = { add_fields: ["base_grand_total", "company", "currency", "supplier", - "supplier_name", "per_received", "per_billed", "status"], + "supplier_name", "per_received", "per_billed", "status", "advance_payment_status"], get_indicator: function (doc) { if (doc.status === "Closed") { return [__("Closed"), "green", "status,=,Closed"]; @@ -8,6 +8,8 @@ frappe.listview_settings['Purchase Order'] = { return [__("On Hold"), "orange", "status,=,On Hold"]; } else if (doc.status === "Delivered") { return [__("Delivered"), "green", "status,=,Closed"]; + } else if (doc.advance_payment_status == "Initiated") { + return [__("To Pay"), "gray", "advance_payment_status,=,Initiated"]; } else if (flt(doc.per_received, 2) < 100 && doc.status !== "Closed") { if (flt(doc.per_billed, 2) < 100) { return [__("To Receive and Bill"), "orange", diff --git a/erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.js b/erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.js index 91506c0ab3..3bf4f2bb29 100644 --- a/erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.js +++ b/erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.js @@ -54,7 +54,7 @@ frappe.query_reports["Purchase Order Analysis"] = { "fieldtype": "MultiSelectList", "width": "80", get_data: function(txt) { - let status = ["To Bill", "To Receive", "To Receive and Bill", "Completed"] + let status = ["To Pay", "To Bill", "To Receive", "To Receive and Bill", "Completed"] let options = [] for (let option of status){ options.push({ diff --git a/erpnext/controllers/status_updater.py b/erpnext/controllers/status_updater.py index 73a248fb53..2b79b895eb 100644 --- a/erpnext/controllers/status_updater.py +++ b/erpnext/controllers/status_updater.py @@ -53,6 +53,10 @@ status_map = { "To Deliver", "eval:self.per_delivered < 100 and self.per_billed == 100 and self.docstatus == 1 and not self.skip_delivery_note", ], + [ + "To Pay", + "eval:self.advance_payment_status == 'Requested' and self.docstatus == 1", + ], [ "Completed", "eval:(self.per_delivered == 100 or self.skip_delivery_note) and self.per_billed == 100 and self.docstatus == 1", @@ -63,15 +67,19 @@ status_map = { ], "Purchase Order": [ ["Draft", None], - [ - "To Receive and Bill", - "eval:self.per_received < 100 and self.per_billed < 100 and self.docstatus == 1", - ], ["To Bill", "eval:self.per_received >= 100 and self.per_billed < 100 and self.docstatus == 1"], [ "To Receive", "eval:self.per_received < 100 and self.per_billed == 100 and self.docstatus == 1", ], + [ + "To Receive and Bill", + "eval:self.per_received < 100 and self.per_billed < 100 and self.docstatus == 1", + ], + [ + "To Pay", + "eval:self.advance_payment_status == 'Initiated' and self.docstatus == 1", + ], [ "Completed", "eval:self.per_received >= 100 and self.per_billed == 100 and self.docstatus == 1", diff --git a/erpnext/selling/doctype/sales_order/sales_order.json b/erpnext/selling/doctype/sales_order/sales_order.json index 7fb49a9b67..084537eb4f 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.json +++ b/erpnext/selling/doctype/sales_order/sales_order.json @@ -1270,7 +1270,7 @@ "no_copy": 1, "oldfieldname": "status", "oldfieldtype": "Select", - "options": "\nDraft\nOn Hold\nTo Deliver and Bill\nTo Bill\nTo Deliver\nCompleted\nCancelled\nClosed", + "options": "\nDraft\nOn Hold\nTo Pay\nTo Deliver and Bill\nTo Bill\nTo Deliver\nCompleted\nCancelled\nClosed", "print_hide": 1, "read_only": 1, "reqd": 1, diff --git a/erpnext/selling/doctype/sales_order/sales_order_list.js b/erpnext/selling/doctype/sales_order/sales_order_list.js index 518f018726..37686a85c3 100644 --- a/erpnext/selling/doctype/sales_order/sales_order_list.js +++ b/erpnext/selling/doctype/sales_order/sales_order_list.js @@ -1,6 +1,6 @@ frappe.listview_settings['Sales Order'] = { add_fields: ["base_grand_total", "customer_name", "currency", "delivery_date", - "per_delivered", "per_billed", "status", "order_type", "name", "skip_delivery_note"], + "per_delivered", "per_billed", "status", "advance_payment_status", "order_type", "name", "skip_delivery_note"], get_indicator: function (doc) { if (doc.status === "Closed") { // Closed @@ -10,6 +10,8 @@ frappe.listview_settings['Sales Order'] = { return [__("On Hold"), "orange", "status,=,On Hold"]; } else if (doc.status === "Completed") { return [__("Completed"), "green", "status,=,Completed"]; + } else if (doc.advance_payment_status === "Requested") { + return [__("To Pay"), "gray", "advance_payment_status,=,Requested"]; } else if (!doc.skip_delivery_note && flt(doc.per_delivered, 2) < 100) { if (frappe.datetime.get_diff(doc.delivery_date) < 0) { // not delivered & overdue diff --git a/erpnext/selling/report/payment_terms_status_for_sales_order/payment_terms_status_for_sales_order.py b/erpnext/selling/report/payment_terms_status_for_sales_order/payment_terms_status_for_sales_order.py index 3682c5fd62..00acc803d5 100644 --- a/erpnext/selling/report/payment_terms_status_for_sales_order/payment_terms_status_for_sales_order.py +++ b/erpnext/selling/report/payment_terms_status_for_sales_order/payment_terms_status_for_sales_order.py @@ -209,7 +209,7 @@ def get_so_with_invoices(filters): ) .where( (so.docstatus == 1) - & (so.status.isin(["To Deliver and Bill", "To Bill"])) + & (so.status.isin(["To Deliver and Bill", "To Bill", "To Pay"])) & (so.payment_terms_template != "NULL") & (so.company == conditions.company) & (so.transaction_date[conditions.start_date : conditions.end_date]) diff --git a/erpnext/selling/report/sales_order_analysis/sales_order_analysis.js b/erpnext/selling/report/sales_order_analysis/sales_order_analysis.js index ac3d3dbf71..fc685e0fe9 100644 --- a/erpnext/selling/report/sales_order_analysis/sales_order_analysis.js +++ b/erpnext/selling/report/sales_order_analysis/sales_order_analysis.js @@ -56,7 +56,7 @@ frappe.query_reports["Sales Order Analysis"] = { "fieldtype": "MultiSelectList", "width": "80", get_data: function(txt) { - let status = ["To Bill", "To Deliver", "To Deliver and Bill", "Completed"] + let status = ["To Pay", "To Bill", "To Deliver", "To Deliver and Bill", "Completed"] let options = [] for (let option of status){ options.push({