From c4dba4bdf2da96966277348da2ec77222a92c3b1 Mon Sep 17 00:00:00 2001 From: Charles-Henri Decultot Date: Thu, 11 Apr 2024 16:58:07 +0200 Subject: [PATCH 1/4] feat: Generate a Payment order directly from purchase invoices --- .../doctype/payment_order/payment_order.js | 38 ++++++++++++- .../doctype/payment_order/payment_order.json | 4 +- .../doctype/payment_order/payment_order.py | 2 +- .../purchase_invoice/purchase_invoice.json | 55 ++++++------------- .../purchase_invoice/purchase_invoice.py | 38 ++++++++++++- 5 files changed, 93 insertions(+), 44 deletions(-) diff --git a/erpnext/accounts/doctype/payment_order/payment_order.js b/erpnext/accounts/doctype/payment_order/payment_order.js index e2d65423e87..d64ba9a370b 100644 --- a/erpnext/accounts/doctype/payment_order/payment_order.js +++ b/erpnext/accounts/doctype/payment_order/payment_order.js @@ -11,6 +11,16 @@ frappe.ui.form.on('Payment Order', { } }); + frm.set_query("bank_account", "references", function(doc, cdt, cdn) { + const row = locals[cdt][cdn] + return { + filters: { + "party_type": "Supplier", + "party": row.supplier + } + } + }); + frm.set_df_property('references', 'cannot_add_rows', true); }, refresh: function(frm) { @@ -23,11 +33,15 @@ frappe.ui.form.on('Payment Order', { frm.trigger("get_from_payment_entry"); }, __("Get Payments from")); + frm.add_custom_button(__('Purchase Invoice'), function() { + frm.trigger("get_from_purchase_invoice"); + }, __("Get Payments from")); + frm.trigger('remove_button'); } // payment Entry - if (frm.doc.docstatus===1 && frm.doc.payment_order_type==='Payment Request') { + if (frm.doc.docstatus===1 && ["Payment Request", "Purchase Invoice"].includes(frm.doc.payment_order_type)) { frm.add_custom_button(__('Journal entries for one supplier'), function() { frm.trigger("make_payment_records"); }, __("Create")); @@ -123,6 +137,28 @@ frappe.ui.form.on('Payment Order', { }); }, + get_from_purchase_invoice: function(frm) { + frm.trigger("remove_row_if_empty"); + erpnext.utils.map_current_doc({ + method: "erpnext.accounts.doctype.purchase_invoice.purchase_invoice.make_payment_order", + source_doctype: "Purchase Invoice", + target: frm, + date_field: "due_date", + setters: { + supplier: frm.doc.supplier || "", + posting_date: null, + due_date: null, + company: frm.doc.company, + status: "Overdue", + outstanding_amount: null, + }, + get_query_filters: { + docstatus: 1, + outstanding_amount: (">", 0.0) + } + }); + }, + make_payment_records: function(frm){ var dialog = new frappe.ui.Dialog({ title: __("For Supplier"), diff --git a/erpnext/accounts/doctype/payment_order/payment_order.json b/erpnext/accounts/doctype/payment_order/payment_order.json index 88776bc5aec..a1f6768bd89 100644 --- a/erpnext/accounts/doctype/payment_order/payment_order.json +++ b/erpnext/accounts/doctype/payment_order/payment_order.json @@ -79,7 +79,7 @@ "fieldname": "payment_order_type", "fieldtype": "Select", "label": "Payment Order Type", - "options": "\nPayment Request\nPayment Entry", + "options": "\nPayment Request\nPayment Entry\nPurchase Invoice", "read_only": 1, "reqd": 1 }, @@ -115,7 +115,7 @@ "link_fieldname": "payment_order" } ], - "modified": "2023-11-27 17:19:23.959658", + "modified": "2024-04-11 16:51:34.723794", "modified_by": "Administrator", "module": "Accounts", "name": "Payment Order", diff --git a/erpnext/accounts/doctype/payment_order/payment_order.py b/erpnext/accounts/doctype/payment_order/payment_order.py index ac1800977f3..6ff59dd3582 100644 --- a/erpnext/accounts/doctype/payment_order/payment_order.py +++ b/erpnext/accounts/doctype/payment_order/payment_order.py @@ -31,7 +31,7 @@ class PaymentOrder(Document): company_bank_account: DF.Link naming_series: DF.Literal["PMO-"] party: DF.Link | None - payment_order_type: DF.Literal["", "Payment Request", "Payment Entry"] + payment_order_type: DF.Literal["", "Payment Request", "Payment Entry", "Purchase Invoice"] posting_date: DF.Date | None references: DF.Table[PaymentOrderReference] # end: auto-generated types diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json index 7a4a73c98f7..0d4a9137abd 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json @@ -24,9 +24,6 @@ "is_paid", "is_return", "return_against", - "update_outstanding_for_self", - "update_billed_amount_in_purchase_order", - "update_billed_amount_in_purchase_receipt", "apply_tds", "tax_withholding_category", "amended_from", @@ -196,6 +193,7 @@ "is_internal_supplier", "represents_company", "supplier_group", + "payment_order_status", "column_break_147", "inter_company_invoice_reference", "is_old_subcontracting_flow", @@ -424,20 +422,6 @@ "read_only": 1, "search_index": 1 }, - { - "default": "0", - "depends_on": "eval: doc.is_return", - "fieldname": "update_billed_amount_in_purchase_order", - "fieldtype": "Check", - "label": "Update Billed Amount in Purchase Order" - }, - { - "default": "1", - "depends_on": "eval: doc.is_return", - "fieldname": "update_billed_amount_in_purchase_receipt", - "fieldtype": "Check", - "label": "Update Billed Amount in Purchase Receipt" - }, { "fieldname": "section_addresses", "fieldtype": "Section Break", @@ -1296,8 +1280,7 @@ "in_standard_filter": 1, "label": "Status", "no_copy": 1, - "options": "\nDraft\nReturn\nDebit Note Issued\nSubmitted\nPaid\nPartly Paid\nUnpaid\nOverdue\nCancelled\nInternal Transfer", - "print_hide": 1 + "options": "\nDraft\nReturn\nDebit Note Issued\nSubmitted\nPaid\nPartly Paid\nUnpaid\nOverdue\nCancelled\nInternal Transfer" }, { "fieldname": "inter_company_invoice_reference", @@ -1661,19 +1644,17 @@ "options": "Supplier Group" }, { - "default": "0", - "depends_on": "eval:!doc.is_return", - "fieldname": "is_down_payment_invoice", - "fieldtype": "Check", - "label": "Is Down Payment Invoice" - }, - { - "default": "1", - "depends_on": "eval: doc.is_return && doc.return_against", - "description": "Debit Note will update it's own outstanding amount, even if \"Return Against\" is specified.", - "fieldname": "update_outstanding_for_self", + "default": "0", + "depends_on": "eval:!doc.is_return", + "fieldname": "is_down_payment_invoice", "fieldtype": "Check", - "label": "Update Outstanding for Self" + "label": "Is Down Payment Invoice" + }, + { + "fieldname": "payment_order_status", + "fieldtype": "Data", + "label": "Payment Order Status", + "read_only": 1 } ], "icon": "uil uil-file-alt", @@ -1681,13 +1662,13 @@ "is_sealed": 1, "is_submittable": 1, "links": [ - { - "group": "Payment Request", - "link_doctype": "Payment Request", - "link_fieldname": "reference_name" - } + { + "group": "Payment Request", + "link_doctype": "Payment Request", + "link_fieldname": "reference_name" + } ], - "modified": "2024-03-22 16:15:09.099187", + "modified": "2024-04-11 16:50:59.350520", "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice", diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index f86545d89bf..fda51fc533c 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -153,6 +153,7 @@ class PurchaseInvoice(BuyingController): outstanding_amount: DF.Currency paid_amount: DF.Currency party_account_currency: DF.Link | None + payment_order_status: DF.Data | None payment_schedule: DF.Table[PaymentSchedule] payment_terms_template: DF.Link | None per_received: DF.Percent @@ -216,9 +217,7 @@ class PurchaseInvoice(BuyingController): total_qty: DF.Float total_taxes_and_charges: DF.Currency unrealized_profit_loss_account: DF.Link | None - update_billed_amount_in_purchase_order: DF.Check - update_billed_amount_in_purchase_receipt: DF.Check - update_outstanding_for_self: DF.Check + unreconciled_amount: DF.Currency update_stock: DF.Check use_company_roundoff_cost_center: DF.Check use_transaction_date_exchange_rate: DF.Check @@ -1999,3 +1998,36 @@ def make_purchase_receipt(source_name, target_doc=None): ) return doc + + +@frappe.whitelist() +def make_payment_order(source_name, target_doc=None): + from frappe.model.mapper import get_mapped_doc + + def set_missing_values(source, target): + target.payment_order_type = "Purchase Invoice" + bank_account = frappe.db.get_value("Supplier", source.supplier, "default_bank_account") + target.append( + "references", + { + "reference_doctype": source.doctype, + "reference_name": source.name, + "amount": source.outstanding_amount, + "supplier": source.supplier, + "bank_account": bank_account, + }, + ) + + doclist = get_mapped_doc( + "Purchase Invoice", + source_name, + { + "Purchase Invoice": { + "doctype": "Payment Order", + } + }, + target_doc, + set_missing_values, + ) + + return doclist -- GitLab From 65a82151eb19e53638bd62b429100ed671cb6b2f Mon Sep 17 00:00:00 2001 From: Charles-Henri Decultot Date: Thu, 11 Apr 2024 17:05:07 +0200 Subject: [PATCH 2/4] fix: merge conflict --- .../purchase_invoice/purchase_invoice.json | 25 +++++++++++++++++++ .../purchase_invoice/purchase_invoice.py | 3 +++ 2 files changed, 28 insertions(+) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json index 0d4a9137abd..38948b8c884 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json @@ -24,6 +24,9 @@ "is_paid", "is_return", "return_against", + "update_outstanding_for_self", + "update_billed_amount_in_purchase_order", + "update_billed_amount_in_purchase_receipt", "apply_tds", "tax_withholding_category", "amended_from", @@ -422,6 +425,20 @@ "read_only": 1, "search_index": 1 }, + { + "default": "0", + "depends_on": "eval: doc.is_return", + "fieldname": "update_billed_amount_in_purchase_order", + "fieldtype": "Check", + "label": "Update Billed Amount in Purchase Order" + }, + { + "default": "1", + "depends_on": "eval: doc.is_return", + "fieldname": "update_billed_amount_in_purchase_receipt", + "fieldtype": "Check", + "label": "Update Billed Amount in Purchase Receipt" + }, { "fieldname": "section_addresses", "fieldtype": "Section Break", @@ -1650,6 +1667,14 @@ "fieldtype": "Check", "label": "Is Down Payment Invoice" }, + { + "default": "1", + "depends_on": "eval: doc.is_return && doc.return_against", + "description": "Debit Note will update it's own outstanding amount, even if \"Return Against\" is specified.", + "fieldname": "update_outstanding_for_self", + "fieldtype": "Check", + "label": "Update Outstanding for Self" + }, { "fieldname": "payment_order_status", "fieldtype": "Data", diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index fda51fc533c..5931bd7897b 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -218,6 +218,9 @@ class PurchaseInvoice(BuyingController): total_taxes_and_charges: DF.Currency unrealized_profit_loss_account: DF.Link | None unreconciled_amount: DF.Currency + update_billed_amount_in_purchase_order: DF.Check + update_billed_amount_in_purchase_receipt: DF.Check + update_outstanding_for_self: DF.Check update_stock: DF.Check use_company_roundoff_cost_center: DF.Check use_transaction_date_exchange_rate: DF.Check -- GitLab From 5628770cfccf8d61a17cb5d6a761f6e59f785937 Mon Sep 17 00:00:00 2001 From: Charles-Henri Decultot Date: Thu, 11 Apr 2024 17:06:21 +0200 Subject: [PATCH 3/4] fix: merge conflict --- .../accounts/doctype/purchase_invoice/purchase_invoice.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json index 38948b8c884..d481116d9d9 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json @@ -1297,7 +1297,8 @@ "in_standard_filter": 1, "label": "Status", "no_copy": 1, - "options": "\nDraft\nReturn\nDebit Note Issued\nSubmitted\nPaid\nPartly Paid\nUnpaid\nOverdue\nCancelled\nInternal Transfer" + "options": "\nDraft\nReturn\nDebit Note Issued\nSubmitted\nPaid\nPartly Paid\nUnpaid\nOverdue\nCancelled\nInternal Transfer", + "print_hide": 1 }, { "fieldname": "inter_company_invoice_reference", -- GitLab From 7cd77ab5d5c64db422d1ad09a0590d7fcffe1900 Mon Sep 17 00:00:00 2001 From: Charles-Henri Decultot Date: Thu, 11 Apr 2024 17:14:18 +0200 Subject: [PATCH 4/4] fix: Set payment order status as Select field --- .../accounts/doctype/purchase_invoice/purchase_invoice.json | 5 +++-- .../accounts/doctype/purchase_invoice/purchase_invoice.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json index d481116d9d9..8e7c3107fed 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json @@ -1678,8 +1678,9 @@ }, { "fieldname": "payment_order_status", - "fieldtype": "Data", + "fieldtype": "Select", "label": "Payment Order Status", + "options": "Initiated\nPayment Ordered", "read_only": 1 } ], @@ -1694,7 +1695,7 @@ "link_fieldname": "reference_name" } ], - "modified": "2024-04-11 16:50:59.350520", + "modified": "2024-04-11 17:13:37.934789", "modified_by": "Administrator", "module": "Accounts", "name": "Purchase Invoice", diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py index 5931bd7897b..a9e64a96b40 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py @@ -153,7 +153,7 @@ class PurchaseInvoice(BuyingController): outstanding_amount: DF.Currency paid_amount: DF.Currency party_account_currency: DF.Link | None - payment_order_status: DF.Data | None + payment_order_status: DF.Literal["Initiated", "Payment Ordered"] payment_schedule: DF.Table[PaymentSchedule] payment_terms_template: DF.Link | None per_received: DF.Percent -- GitLab