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:
parent
37c1331aba
commit
27ce789023
@ -1,8 +1,10 @@
|
|||||||
// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
// frappe.ui.form.on("Bank Party Mapper", {
|
frappe.ui.form.on("Bank Party Mapper", {
|
||||||
// refresh(frm) {
|
refresh(frm) {
|
||||||
|
if (!frm.is_new()) {
|
||||||
// },
|
frm.set_intro(__("Please avoid editing unless you are absolutely certain."));
|
||||||
// });
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
"party_type",
|
"party_type",
|
||||||
"party",
|
"party",
|
||||||
"column_break_wbna",
|
"column_break_wbna",
|
||||||
"bank_party_name_desc",
|
"bank_party_name",
|
||||||
"bank_party_account_number",
|
"bank_party_account_number",
|
||||||
"bank_party_iban"
|
"bank_party_iban"
|
||||||
],
|
],
|
||||||
@ -47,14 +47,14 @@
|
|||||||
"options": "party_type"
|
"options": "party_type"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "bank_party_name_desc",
|
"fieldname": "bank_party_name",
|
||||||
"fieldtype": "Small Text",
|
"fieldtype": "Data",
|
||||||
"label": "Party Name/Desc (Bank Statement)"
|
"label": "Party Name (Bank Statement)"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-04-03 10:11:31.384383",
|
"modified": "2023-04-04 14:27:23.450456",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Bank Party Mapper",
|
"name": "Bank Party Mapper",
|
||||||
|
@ -1,9 +1,24 @@
|
|||||||
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
|
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
# import frappe
|
import frappe
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
|
||||||
|
|
||||||
class BankPartyMapper(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()
|
||||||
|
@ -49,11 +49,11 @@ class AutoMatchbyAccountIBAN:
|
|||||||
result = frappe.db.get_value(
|
result = frappe.db.get_value(
|
||||||
"Bank Party Mapper",
|
"Bank Party Mapper",
|
||||||
filters={filter_field: self.get(filter_field)},
|
filters={filter_field: self.get(filter_field)},
|
||||||
fieldname=["party_type", "party"],
|
fieldname=["party_type", "party", "name"],
|
||||||
)
|
)
|
||||||
if result:
|
if result:
|
||||||
party_type, party = result
|
party_type, party, mapper_name = result
|
||||||
return (party_type, party, None)
|
return (party_type, party, {"mapper_name": mapper_name})
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@ -89,33 +89,29 @@ class AutoMatchbyPartyDescription:
|
|||||||
|
|
||||||
def match(self):
|
def match(self):
|
||||||
# Match by Customer, Supplier or Employee Name
|
# 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
|
# fuzzy search by customer/supplier & employee
|
||||||
if not (self.bank_party_name or self.description):
|
if not (self.bank_party_name or self.description):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
result = self.match_party_name_desc_in_bank_party_mapper()
|
result = self.match_party_name_in_bank_party_mapper()
|
||||||
|
|
||||||
if not result:
|
if not result:
|
||||||
result = self.match_party_name_desc_in_party()
|
result = self.match_party_name_desc_in_party()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def match_party_name_desc_in_bank_party_mapper(self):
|
def match_party_name_in_bank_party_mapper(self):
|
||||||
"""Check if match exists for party name or description in Bank Party Mapper"""
|
"""Check if match exists for party name in Bank Party Mapper"""
|
||||||
result = None
|
result = None
|
||||||
or_filters = []
|
|
||||||
|
|
||||||
if self.bank_party_name:
|
if not self.bank_party_name:
|
||||||
or_filters.append({"bank_party_name_desc": self.bank_party_name})
|
return
|
||||||
|
|
||||||
if self.description:
|
|
||||||
or_filters.append({"bank_party_name_desc": self.description})
|
|
||||||
|
|
||||||
mapper_res = frappe.get_all(
|
mapper_res = frappe.get_all(
|
||||||
"Bank Party Mapper",
|
"Bank Party Mapper",
|
||||||
or_filters=or_filters,
|
filters={"bank_party_name": self.bank_party_name},
|
||||||
fields=["party_type", "party"],
|
fields=["party_type", "party", "name"],
|
||||||
limit_page_length=1,
|
limit_page_length=1,
|
||||||
)
|
)
|
||||||
if mapper_res:
|
if mapper_res:
|
||||||
@ -123,7 +119,7 @@ class AutoMatchbyPartyDescription:
|
|||||||
result = (
|
result = (
|
||||||
mapper_res["party_type"],
|
mapper_res["party_type"],
|
||||||
mapper_res["party"],
|
mapper_res["party"],
|
||||||
None,
|
{"mapper_name": mapper_res["name"]},
|
||||||
)
|
)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@ -157,7 +153,7 @@ class AutoMatchbyPartyDescription:
|
|||||||
party_name, score, index = result
|
party_name, score, index = result
|
||||||
if score > 75:
|
if score > 75:
|
||||||
# Dont set description as a key in Bank Party Mapper due to its volatility
|
# 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 (
|
return (
|
||||||
party,
|
party,
|
||||||
party_name,
|
party_name,
|
||||||
|
@ -37,7 +37,8 @@
|
|||||||
"column_break_3czf",
|
"column_break_3czf",
|
||||||
"bank_party_name",
|
"bank_party_name",
|
||||||
"bank_party_account_number",
|
"bank_party_account_number",
|
||||||
"bank_party_iban"
|
"bank_party_iban",
|
||||||
|
"bank_party_mapper"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@ -214,7 +215,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "bank_party_name",
|
"fieldname": "bank_party_name",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Party Name (Bank Statement)"
|
"label": "Party Name/Account Holder (Bank Statement)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "bank_party_iban",
|
"fieldname": "bank_party_iban",
|
||||||
@ -225,11 +226,19 @@
|
|||||||
"fieldname": "bank_party_account_number",
|
"fieldname": "bank_party_account_number",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Party Account No. (Bank Statement)"
|
"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,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2023-03-31 10:45:30.671309",
|
"modified": "2023-04-04 15:47:20.620006",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Bank Transaction",
|
"name": "Bank Transaction",
|
||||||
|
@ -35,6 +35,8 @@ class BankTransaction(StatusUpdater):
|
|||||||
self.update_allocations()
|
self.update_allocations()
|
||||||
self._saving_flag = False
|
self._saving_flag = False
|
||||||
|
|
||||||
|
self.set_in_bank_party_mapper()
|
||||||
|
|
||||||
def on_cancel(self):
|
def on_cancel(self):
|
||||||
self.clear_linked_payment_entries(for_cancel=True)
|
self.clear_linked_payment_entries(for_cancel=True)
|
||||||
self.set_status(update=True)
|
self.set_status(update=True)
|
||||||
@ -176,11 +178,28 @@ class BankTransaction(StatusUpdater):
|
|||||||
if not mapper:
|
if not mapper:
|
||||||
return
|
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(
|
mapper_doc = frappe.get_doc(
|
||||||
{"doctype": "Bank Party Mapper", "party_type": self.party_type, "party": self.party}
|
{"doctype": "Bank Party Mapper", "party_type": self.party_type, "party": self.party}
|
||||||
)
|
)
|
||||||
mapper_doc.update(mapper)
|
mapper_doc.update(mapper)
|
||||||
mapper_doc.insert()
|
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()
|
@frappe.whitelist()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user