feat: Manually Update/Correct Party in Bank Transaction

- On updating bank trans.n party after submit, the corresponding mapper doc will be updated too
- The mapper doc in turn will update all linked bank transactions that do not have this updated value
- Added Bank Party Mapper hidden link in Bank Transaction
- Rename field in BPM to `Party Name` as it does not hold description data
- If a BT matches with a BPM record, link that record in the BT
This commit is contained in:
marination 2023-04-04 19:27:01 +05:30
parent 37c1331aba
commit 27ce789023
6 changed files with 73 additions and 32 deletions

View File

@ -1,8 +1,10 @@
// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
// frappe.ui.form.on("Bank Party Mapper", {
// refresh(frm) {
// },
// });
frappe.ui.form.on("Bank Party Mapper", {
refresh(frm) {
if (!frm.is_new()) {
frm.set_intro(__("Please avoid editing unless you are absolutely certain."));
}
},
});

View File

@ -9,7 +9,7 @@
"party_type",
"party",
"column_break_wbna",
"bank_party_name_desc",
"bank_party_name",
"bank_party_account_number",
"bank_party_iban"
],
@ -47,14 +47,14 @@
"options": "party_type"
},
{
"fieldname": "bank_party_name_desc",
"fieldtype": "Small Text",
"label": "Party Name/Desc (Bank Statement)"
"fieldname": "bank_party_name",
"fieldtype": "Data",
"label": "Party Name (Bank Statement)"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2023-04-03 10:11:31.384383",
"modified": "2023-04-04 14:27:23.450456",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Bank Party Mapper",

View File

@ -1,9 +1,24 @@
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
# import frappe
import frappe
from frappe.model.document import Document
class BankPartyMapper(Document):
pass
def on_update(self):
self.update_party_in_linked_transactions()
def update_party_in_linked_transactions(self):
if self.is_new():
return
# Set updated party values in other linked bank transactions
bank_transaction = frappe.qb.DocType("Bank Transaction")
frappe.qb.update(bank_transaction).set("party_type", self.party_type).set(
"party", self.party
).where(
(bank_transaction.bank_party_mapper == self.name)
& ((bank_transaction.party_type != self.party_type) | (bank_transaction.party != self.party))
).run()

View File

@ -49,11 +49,11 @@ class AutoMatchbyAccountIBAN:
result = frappe.db.get_value(
"Bank Party Mapper",
filters={filter_field: self.get(filter_field)},
fieldname=["party_type", "party"],
fieldname=["party_type", "party", "name"],
)
if result:
party_type, party = result
return (party_type, party, None)
party_type, party, mapper_name = result
return (party_type, party, {"mapper_name": mapper_name})
return result
@ -89,33 +89,29 @@ class AutoMatchbyPartyDescription:
def match(self):
# Match by Customer, Supplier or Employee Name
# search bank party mapper by party and then description
# search bank party mapper by party
# fuzzy search by customer/supplier & employee
if not (self.bank_party_name or self.description):
return None
result = self.match_party_name_desc_in_bank_party_mapper()
result = self.match_party_name_in_bank_party_mapper()
if not result:
result = self.match_party_name_desc_in_party()
return result
def match_party_name_desc_in_bank_party_mapper(self):
"""Check if match exists for party name or description in Bank Party Mapper"""
def match_party_name_in_bank_party_mapper(self):
"""Check if match exists for party name in Bank Party Mapper"""
result = None
or_filters = []
if self.bank_party_name:
or_filters.append({"bank_party_name_desc": self.bank_party_name})
if self.description:
or_filters.append({"bank_party_name_desc": self.description})
if not self.bank_party_name:
return
mapper_res = frappe.get_all(
"Bank Party Mapper",
or_filters=or_filters,
fields=["party_type", "party"],
filters={"bank_party_name": self.bank_party_name},
fields=["party_type", "party", "name"],
limit_page_length=1,
)
if mapper_res:
@ -123,7 +119,7 @@ class AutoMatchbyPartyDescription:
result = (
mapper_res["party_type"],
mapper_res["party"],
None,
{"mapper_name": mapper_res["name"]},
)
return result
@ -157,7 +153,7 @@ class AutoMatchbyPartyDescription:
party_name, score, index = result
if score > 75:
# Dont set description as a key in Bank Party Mapper due to its volatility
mapper = {"bank_party_name_desc": self.get(field)} if field == "bank_party_name" else None
mapper = {"bank_party_name": self.get(field)} if field == "bank_party_name" else None
return (
party,
party_name,

View File

@ -37,7 +37,8 @@
"column_break_3czf",
"bank_party_name",
"bank_party_account_number",
"bank_party_iban"
"bank_party_iban",
"bank_party_mapper"
],
"fields": [
{
@ -214,7 +215,7 @@
{
"fieldname": "bank_party_name",
"fieldtype": "Data",
"label": "Party Name (Bank Statement)"
"label": "Party Name/Account Holder (Bank Statement)"
},
{
"fieldname": "bank_party_iban",
@ -225,11 +226,19 @@
"fieldname": "bank_party_account_number",
"fieldtype": "Data",
"label": "Party Account No. (Bank Statement)"
},
{
"fieldname": "bank_party_mapper",
"fieldtype": "Link",
"hidden": 1,
"label": "Bank Party Mapper",
"options": "Bank Party Mapper",
"read_only": 1
}
],
"is_submittable": 1,
"links": [],
"modified": "2023-03-31 10:45:30.671309",
"modified": "2023-04-04 15:47:20.620006",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Bank Transaction",

View File

@ -35,6 +35,8 @@ class BankTransaction(StatusUpdater):
self.update_allocations()
self._saving_flag = False
self.set_in_bank_party_mapper()
def on_cancel(self):
self.clear_linked_payment_entries(for_cancel=True)
self.set_status(update=True)
@ -176,11 +178,28 @@ class BankTransaction(StatusUpdater):
if not mapper:
return
if mapper.get("mapper_name"):
# Transaction matched with a Bank party Mapper record
self.bank_party_mapper = mapper.get("mapper_name") # Link mapper to Bank Transaction
return
mapper_doc = frappe.get_doc(
{"doctype": "Bank Party Mapper", "party_type": self.party_type, "party": self.party}
)
mapper_doc.update(mapper)
mapper_doc.insert()
self.bank_party_mapper = mapper_doc.name # Link mapper to Bank Transaction
def set_in_bank_party_mapper(self):
"""Set in Bank Party Mapper if Party Type & Party are manually changed after submit."""
doc_before_update = self.get_doc_before_save()
party_type_changed = self.party_type and (doc_before_update.party_type != self.party_type)
party_changed = self.party and (doc_before_update.party != self.party)
if (party_type_changed or party_changed) and self.bank_party_mapper:
mapper_doc = frappe.get_doc("Bank Party Mapper", self.bank_party_mapper)
mapper_doc.update({"party_type": self.party_type, "party": self.party})
mapper_doc.save()
@frappe.whitelist()