From 16860c228da0a3452fa89dcae6fe169698c6ddbe Mon Sep 17 00:00:00 2001 From: barredterra <14891507+barredterra@users.noreply.github.com> Date: Wed, 27 Dec 2023 23:05:37 +0100 Subject: [PATCH 1/3] fix: unreconcile Bank Transaction on cancel of payment voucher (cherry picked from commit 0a95b38166e36946f89286d39081b0f529e88cb6) # Conflicts: # erpnext/accounts/doctype/bank_transaction/bank_transaction.py # erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js # erpnext/accounts/doctype/sales_invoice/sales_invoice.js --- .../bank_transaction/bank_transaction.py | 22 +++++++++++++++++++ .../doctype/journal_entry/journal_entry.js | 2 +- .../doctype/payment_entry/payment_entry.js | 2 +- .../purchase_invoice/purchase_invoice.js | 4 ++++ .../doctype/sales_invoice/sales_invoice.js | 4 ++++ erpnext/controllers/accounts_controller.py | 5 +++++ 6 files changed, 37 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py index 1d6cb8e2c0..26047b7afb 100644 --- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py +++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py @@ -3,7 +3,11 @@ import frappe from frappe import _ +<<<<<<< HEAD from frappe.model.document import Document +======= +from frappe.model.docstatus import DocStatus +>>>>>>> 0a95b38166 (fix: unreconcile Bank Transaction on cancel of payment voucher) from frappe.utils import flt @@ -415,3 +419,21 @@ def unclear_reference_payment(doctype, docname, bt_name): bt = frappe.get_doc("Bank Transaction", bt_name) set_voucher_clearance(doctype, docname, None, bt) return docname + + +def remove_from_bank_transaction(doctype, docname): + """Remove a (cancelled) voucher from all Bank Transactions.""" + for bt_name in get_reconciled_bank_transactions(doctype, docname): + bt = frappe.get_doc("Bank Transaction", bt_name) + if bt.docstatus == DocStatus.cancelled(): + continue + + modified = False + + for pe in bt.payment_entries: + if pe.payment_document == doctype and pe.payment_entry == docname: + bt.remove(pe) + modified = True + + if modified: + bt.save() diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.js b/erpnext/accounts/doctype/journal_entry/journal_entry.js index 266154d87f..07fb5e857c 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.js +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.js @@ -8,7 +8,7 @@ frappe.provide("erpnext.journal_entry"); frappe.ui.form.on("Journal Entry", { setup: function(frm) { frm.add_fetch("bank_account", "account", "account"); - frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', 'Journal Entry', "Repost Payment Ledger", 'Asset', 'Asset Movement', 'Asset Depreciation Schedule', "Repost Accounting Ledger", "Unreconcile Payment", "Unreconcile Payment Entries"]; + frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', 'Journal Entry', "Repost Payment Ledger", 'Asset', 'Asset Movement', 'Asset Depreciation Schedule', "Repost Accounting Ledger", "Unreconcile Payment", "Unreconcile Payment Entries", "Bank Transaction"]; }, refresh: function(frm) { diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js index 81ffee3f6e..9402e3da09 100644 --- a/erpnext/accounts/doctype/payment_entry/payment_entry.js +++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js @@ -9,7 +9,7 @@ erpnext.accounts.taxes.setup_tax_filters("Advance Taxes and Charges"); frappe.ui.form.on('Payment Entry', { onload: function(frm) { - frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', 'Journal Entry', 'Repost Payment Ledger','Repost Accounting Ledger', 'Unreconcile Payment', 'Unreconcile Payment Entries']; + frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', 'Journal Entry', 'Repost Payment Ledger','Repost Accounting Ledger', 'Unreconcile Payment', 'Unreconcile Payment Entries', "Bank Transaction"]; if(frm.doc.__islocal) { if (!frm.doc.paid_from) frm.set_value("paid_from_account_currency", null); diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js index 44d4d81643..f1f815a1cd 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js @@ -35,7 +35,11 @@ erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying. super.onload(); // Ignore linked advances +<<<<<<< HEAD this.frm.ignore_doctypes_on_cancel_all = ['Journal Entry', 'Payment Entry', 'Purchase Invoice', "Repost Payment Ledger", "Repost Accounting Ledger", "Unreconcile Payment", "Unreconcile Payment Entries", "Serial and Batch Bundle"]; +======= + this.frm.ignore_doctypes_on_cancel_all = ['Journal Entry', 'Payment Entry', 'Purchase Invoice', "Repost Payment Ledger", "Repost Accounting Ledger", "Unreconcile Payment", "Unreconcile Payment Entries", "Bank Transaction"]; +>>>>>>> 0a95b38166 (fix: unreconcile Bank Transaction on cancel of payment voucher) if(!this.frm.doc.__islocal) { // show credit_to in print format diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index ba2cd82516..c6487e360a 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -37,9 +37,13 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends e super.onload(); this.frm.ignore_doctypes_on_cancel_all = ['POS Invoice', 'Timesheet', 'POS Invoice Merge Log', +<<<<<<< HEAD 'POS Closing Entry', 'Journal Entry', 'Payment Entry', "Repost Payment Ledger", "Repost Accounting Ledger", "Unreconcile Payment", "Unreconcile Payment Entries", 'Serial and Batch Bundle' ]; +======= + 'POS Closing Entry', 'Journal Entry', 'Payment Entry', "Repost Payment Ledger", "Repost Accounting Ledger", "Unreconcile Payment", "Unreconcile Payment Entries", "Bank Transaction"]; +>>>>>>> 0a95b38166 (fix: unreconcile Bank Transaction on cancel of payment voucher) if(!this.frm.doc.__islocal && !this.frm.doc.customer && this.frm.doc.debit_to) { // show debit_to in print format diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index 9a6044f8d7..6b1be396d2 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -1414,11 +1414,16 @@ class AccountsController(TransactionBase): reconcile_against_document(lst) def on_cancel(self): + from erpnext.accounts.doctype.bank_transaction.bank_transaction import ( + remove_from_bank_transaction, + ) from erpnext.accounts.utils import ( cancel_exchange_gain_loss_journal, unlink_ref_doc_from_payment_entries, ) + remove_from_bank_transaction(self.doctype, self.name) + if self.doctype in ["Sales Invoice", "Purchase Invoice", "Payment Entry", "Journal Entry"]: # Cancel Exchange Gain/Loss Journal before unlinking cancel_exchange_gain_loss_journal(self) From b2fc5e49888286746c4eaf5fa02b585ddb860af2 Mon Sep 17 00:00:00 2001 From: barredterra <14891507+barredterra@users.noreply.github.com> Date: Thu, 28 Dec 2023 00:00:04 +0100 Subject: [PATCH 2/3] test: cancel voucher linked to Bank Transaction (cherry picked from commit 517bedeb7ee68d7794d09a5f49b97ab64f652abf) --- .../bank_transaction/test_bank_transaction.py | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/bank_transaction/test_bank_transaction.py b/erpnext/accounts/doctype/bank_transaction/test_bank_transaction.py index 4a6491d086..7bb3f4183b 100644 --- a/erpnext/accounts/doctype/bank_transaction/test_bank_transaction.py +++ b/erpnext/accounts/doctype/bank_transaction/test_bank_transaction.py @@ -2,10 +2,10 @@ # See license.txt import json -import unittest import frappe from frappe import utils +from frappe.model.docstatus import DocStatus from frappe.tests.utils import FrappeTestCase from erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool import ( @@ -81,6 +81,29 @@ class TestBankTransaction(FrappeTestCase): clearance_date = frappe.db.get_value("Payment Entry", payment.name, "clearance_date") self.assertFalse(clearance_date) + def test_cancel_voucher(self): + bank_transaction = frappe.get_doc( + "Bank Transaction", + dict(description="1512567 BG/000003025 OPSKATTUZWXXX AT776000000098709849 Herr G"), + ) + payment = frappe.get_doc("Payment Entry", dict(party="Mr G", paid_amount=1700)) + vouchers = json.dumps( + [ + { + "payment_doctype": "Payment Entry", + "payment_name": payment.name, + "amount": bank_transaction.unallocated_amount, + } + ] + ) + reconcile_vouchers(bank_transaction.name, vouchers) + payment.reload() + payment.cancel() + bank_transaction.reload() + self.assertEqual(bank_transaction.docstatus, DocStatus.submitted()) + self.assertEqual(bank_transaction.unallocated_amount, 1700) + self.assertEqual(bank_transaction.payment_entries, []) + # Check if ERPNext can correctly filter a linked payments based on the debit/credit amount def test_debit_credit_output(self): bank_transaction = frappe.get_doc( From 6b2e3503d9790ffb1c863ce1189530b19543f91d Mon Sep 17 00:00:00 2001 From: barredterra <14891507+barredterra@users.noreply.github.com> Date: Thu, 11 Jan 2024 14:56:20 +0100 Subject: [PATCH 3/3] chore: resolve merge confilcts --- .../bank_transaction/bank_transaction.py | 5 +---- .../purchase_invoice/purchase_invoice.js | 16 ++++++++++----- .../doctype/sales_invoice/sales_invoice.js | 20 ++++++++++++------- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py index 26047b7afb..c38d27355f 100644 --- a/erpnext/accounts/doctype/bank_transaction/bank_transaction.py +++ b/erpnext/accounts/doctype/bank_transaction/bank_transaction.py @@ -3,11 +3,8 @@ import frappe from frappe import _ -<<<<<<< HEAD -from frappe.model.document import Document -======= from frappe.model.docstatus import DocStatus ->>>>>>> 0a95b38166 (fix: unreconcile Bank Transaction on cancel of payment voucher) +from frappe.model.document import Document from frappe.utils import flt diff --git a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js index f1f815a1cd..a2d210dc54 100644 --- a/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js +++ b/erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js @@ -35,11 +35,17 @@ erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying. super.onload(); // Ignore linked advances -<<<<<<< HEAD - this.frm.ignore_doctypes_on_cancel_all = ['Journal Entry', 'Payment Entry', 'Purchase Invoice', "Repost Payment Ledger", "Repost Accounting Ledger", "Unreconcile Payment", "Unreconcile Payment Entries", "Serial and Batch Bundle"]; -======= - this.frm.ignore_doctypes_on_cancel_all = ['Journal Entry', 'Payment Entry', 'Purchase Invoice', "Repost Payment Ledger", "Repost Accounting Ledger", "Unreconcile Payment", "Unreconcile Payment Entries", "Bank Transaction"]; ->>>>>>> 0a95b38166 (fix: unreconcile Bank Transaction on cancel of payment voucher) + this.frm.ignore_doctypes_on_cancel_all = [ + "Journal Entry", + "Payment Entry", + "Purchase Invoice", + "Repost Payment Ledger", + "Repost Accounting Ledger", + "Unreconcile Payment", + "Unreconcile Payment Entries", + "Serial and Batch Bundle", + "Bank Transaction", + ]; if(!this.frm.doc.__islocal) { // show credit_to in print format diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js index c6487e360a..7cda11addc 100644 --- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js +++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js @@ -36,14 +36,20 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends e var me = this; super.onload(); - this.frm.ignore_doctypes_on_cancel_all = ['POS Invoice', 'Timesheet', 'POS Invoice Merge Log', -<<<<<<< HEAD - 'POS Closing Entry', 'Journal Entry', 'Payment Entry', "Repost Payment Ledger", "Repost Accounting Ledger", "Unreconcile Payment", "Unreconcile Payment Entries", - 'Serial and Batch Bundle' + this.frm.ignore_doctypes_on_cancel_all = [ + "POS Invoice", + "Timesheet", + "POS Invoice Merge Log", + "POS Closing Entry", + "Journal Entry", + "Payment Entry", + "Repost Payment Ledger", + "Repost Accounting Ledger", + "Unreconcile Payment", + "Unreconcile Payment Entries", + "Serial and Batch Bundle", + "Bank Transaction", ]; -======= - 'POS Closing Entry', 'Journal Entry', 'Payment Entry', "Repost Payment Ledger", "Repost Accounting Ledger", "Unreconcile Payment", "Unreconcile Payment Entries", "Bank Transaction"]; ->>>>>>> 0a95b38166 (fix: unreconcile Bank Transaction on cancel of payment voucher) if(!this.frm.doc.__islocal && !this.frm.doc.customer && this.frm.doc.debit_to) { // show debit_to in print format