feat: unreconcile on cancellation of bank transaction (#27109)

This commit is contained in:
Saqib 2021-08-25 16:25:51 +05:30 committed by GitHub
parent a65498dc61
commit 62114b226f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 13 deletions

View File

@ -22,6 +22,10 @@ class BankTransaction(StatusUpdater):
self.clear_linked_payment_entries() self.clear_linked_payment_entries()
self.set_status(update=True) self.set_status(update=True)
def on_cancel(self):
self.clear_linked_payment_entries(for_cancel=True)
self.set_status(update=True)
def update_allocations(self): def update_allocations(self):
if self.payment_entries: if self.payment_entries:
allocated_amount = reduce(lambda x, y: flt(x) + flt(y), [x.allocated_amount for x in self.payment_entries]) allocated_amount = reduce(lambda x, y: flt(x) + flt(y), [x.allocated_amount for x in self.payment_entries])
@ -42,20 +46,29 @@ class BankTransaction(StatusUpdater):
self.reload() self.reload()
def clear_linked_payment_entries(self): def clear_linked_payment_entries(self, for_cancel=False):
for payment_entry in self.payment_entries: for payment_entry in self.payment_entries:
if payment_entry.payment_document in ["Payment Entry", "Journal Entry", "Purchase Invoice", "Expense Claim"]: if payment_entry.payment_document in ["Payment Entry", "Journal Entry", "Purchase Invoice", "Expense Claim"]:
self.clear_simple_entry(payment_entry) self.clear_simple_entry(payment_entry, for_cancel=for_cancel)
elif payment_entry.payment_document == "Sales Invoice": elif payment_entry.payment_document == "Sales Invoice":
self.clear_sales_invoice(payment_entry) self.clear_sales_invoice(payment_entry, for_cancel=for_cancel)
def clear_simple_entry(self, payment_entry): def clear_simple_entry(self, payment_entry, for_cancel=False):
frappe.db.set_value(payment_entry.payment_document, payment_entry.payment_entry, "clearance_date", self.date) clearance_date = self.date if not for_cancel else None
frappe.db.set_value(
payment_entry.payment_document, payment_entry.payment_entry,
"clearance_date", clearance_date)
def clear_sales_invoice(self, payment_entry): def clear_sales_invoice(self, payment_entry, for_cancel=False):
frappe.db.set_value("Sales Invoice Payment", dict(parenttype=payment_entry.payment_document, clearance_date = self.date if not for_cancel else None
parent=payment_entry.payment_entry), "clearance_date", self.date) frappe.db.set_value(
"Sales Invoice Payment",
dict(
parenttype=payment_entry.payment_document,
parent=payment_entry.payment_entry
),
"clearance_date", clearance_date)
def get_total_allocated_amount(payment_entry): def get_total_allocated_amount(payment_entry):
return frappe.db.sql(""" return frappe.db.sql("""

View File

@ -4,10 +4,12 @@
frappe.listview_settings['Bank Transaction'] = { frappe.listview_settings['Bank Transaction'] = {
add_fields: ["unallocated_amount"], add_fields: ["unallocated_amount"],
get_indicator: function(doc) { get_indicator: function(doc) {
if(flt(doc.unallocated_amount)>0) { if(doc.docstatus == 2) {
return [__("Unreconciled"), "orange", "unallocated_amount,>,0"]; return [__("Cancelled"), "red", "docstatus,=,2"];
} else if(flt(doc.unallocated_amount)<=0) { } else if(flt(doc.unallocated_amount)<=0) {
return [__("Reconciled"), "green", "unallocated_amount,=,0"]; return [__("Reconciled"), "green", "unallocated_amount,=,0"];
} else if(flt(doc.unallocated_amount)>0) {
return [__("Unreconciled"), "orange", "unallocated_amount,>,0"];
} }
} }
}; };

View File

@ -25,6 +25,7 @@ class TestBankTransaction(unittest.TestCase):
def tearDownClass(cls): def tearDownClass(cls):
for bt in frappe.get_all("Bank Transaction"): for bt in frappe.get_all("Bank Transaction"):
doc = frappe.get_doc("Bank Transaction", bt.name) doc = frappe.get_doc("Bank Transaction", bt.name)
if doc.docstatus == 1:
doc.cancel() doc.cancel()
doc.delete() doc.delete()
@ -57,6 +58,12 @@ class TestBankTransaction(unittest.TestCase):
clearance_date = frappe.db.get_value("Payment Entry", payment.name, "clearance_date") clearance_date = frappe.db.get_value("Payment Entry", payment.name, "clearance_date")
self.assertTrue(clearance_date is not None) self.assertTrue(clearance_date is not None)
bank_transaction.reload()
bank_transaction.cancel()
clearance_date = frappe.db.get_value("Payment Entry", payment.name, "clearance_date")
self.assertFalse(clearance_date)
# Check if ERPNext can correctly filter a linked payments based on the debit/credit amount # Check if ERPNext can correctly filter a linked payments based on the debit/credit amount
def test_debit_credit_output(self): def test_debit_credit_output(self):
bank_transaction = frappe.get_doc("Bank Transaction", dict(description="Auszahlung Karte MC/000002916 AUTOMAT 698769 K002 27.10. 14:07")) bank_transaction = frappe.get_doc("Bank Transaction", dict(description="Auszahlung Karte MC/000002916 AUTOMAT 698769 K002 27.10. 14:07"))

View File

@ -86,7 +86,8 @@ status_map = {
], ],
"Bank Transaction": [ "Bank Transaction": [
["Unreconciled", "eval:self.docstatus == 1 and self.unallocated_amount>0"], ["Unreconciled", "eval:self.docstatus == 1 and self.unallocated_amount>0"],
["Reconciled", "eval:self.docstatus == 1 and self.unallocated_amount<=0"] ["Reconciled", "eval:self.docstatus == 1 and self.unallocated_amount<=0"],
["Cancelled", "eval:self.docstatus == 2"]
], ],
"POS Opening Entry": [ "POS Opening Entry": [
["Draft", None], ["Draft", None],