fix: skip mapping creation if document creation fails in Both mode
In "Both" mode, mappings were saved before documents were created, so a failed document still produced a mapping entry. Now for "Both" mode: document is created first, and the mapping row is added only on success. Settings are saved once after all transactions. "Mappings Only" and "Documents & Reconcile" modes are unaffected. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
3b44f5a694
commit
2f10fb4aa0
|
|
@ -21,7 +21,7 @@ def create_purpose_mappings(transactions, paid_from=None, paid_to=None, document
|
||||||
try:
|
try:
|
||||||
txn_list = json.loads(transactions) if isinstance(transactions, str) else transactions
|
txn_list = json.loads(transactions) if isinstance(transactions, str) else transactions
|
||||||
|
|
||||||
do_mappings = mode in ("Both", "Mappings Only")
|
do_mappings = mode == "Mappings Only"
|
||||||
do_documents = mode in ("Both", "Documents & Reconcile")
|
do_documents = mode in ("Both", "Documents & Reconcile")
|
||||||
|
|
||||||
created_mappings = 0
|
created_mappings = 0
|
||||||
|
|
@ -31,11 +31,11 @@ def create_purpose_mappings(transactions, paid_from=None, paid_to=None, document
|
||||||
reconciled = 0
|
reconciled = 0
|
||||||
errors = []
|
errors = []
|
||||||
|
|
||||||
needs_settings = do_mappings or mode == "Documents & Reconcile"
|
needs_settings = do_mappings or do_documents
|
||||||
if needs_settings:
|
if needs_settings:
|
||||||
settings = frappe.get_single("Kapital Bank Settings")
|
settings = frappe.get_single("Kapital Bank Settings")
|
||||||
|
|
||||||
if do_mappings:
|
if mode in ("Both", "Mappings Only"):
|
||||||
existing_purpose = {
|
existing_purpose = {
|
||||||
(row.purpose_keyword, row.payment_type, (row.currency or "").upper())
|
(row.purpose_keyword, row.payment_type, (row.currency or "").upper())
|
||||||
for row in settings.transaction_mappings
|
for row in settings.transaction_mappings
|
||||||
|
|
@ -47,6 +47,7 @@ def create_purpose_mappings(transactions, paid_from=None, paid_to=None, document
|
||||||
if not row.purpose_keyword and row.counterparty and row.payment_type
|
if not row.purpose_keyword and row.counterparty and row.payment_type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if do_mappings:
|
||||||
# Deduplicate within batch; first occurrence wins for party info
|
# Deduplicate within batch; first occurrence wins for party info
|
||||||
unique_purposes = {}
|
unique_purposes = {}
|
||||||
unique_parties = {}
|
unique_parties = {}
|
||||||
|
|
@ -190,12 +191,62 @@ def create_purpose_mappings(transactions, paid_from=None, paid_to=None, document
|
||||||
"reference_number": txn.get("reference_number") or "",
|
"reference_number": txn.get("reference_number") or "",
|
||||||
"message": result.get("error"),
|
"message": result.get("error"),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# In "Both" mode: add mapping only after successful document creation
|
||||||
|
if mode == "Both":
|
||||||
|
purpose = (txn.get("purpose") or "").strip()
|
||||||
|
party_type = (txn.get("party_type") or "").strip()
|
||||||
|
party = (txn.get("party") or "").strip()
|
||||||
|
payment_type = "Pay" if txn.get("drcr") == "D" else "Receive"
|
||||||
|
bt_name = txn.get("bank_transaction_name")
|
||||||
|
kb_currency = (frappe.db.get_value("Bank Transaction", bt_name, "kb_currency") or "").strip().upper() if bt_name else ""
|
||||||
|
is_foreign = kb_currency and kb_currency != "AZN"
|
||||||
|
|
||||||
|
if purpose:
|
||||||
|
purpose_name = _ensure_purpose(purpose)
|
||||||
|
key = (purpose_name, payment_type, kb_currency)
|
||||||
|
if key not in existing_purpose:
|
||||||
|
settings.append("transaction_mappings", {
|
||||||
|
"purpose_keyword": purpose_name,
|
||||||
|
"payment_type": payment_type,
|
||||||
|
"paid_from": paid_from,
|
||||||
|
"paid_to": paid_to,
|
||||||
|
"document_type": document_type,
|
||||||
|
"counterparty_type": party_type or None,
|
||||||
|
"counterparty": party or None,
|
||||||
|
"currency": kb_currency or None,
|
||||||
|
"multi_currency": 1 if is_foreign else 0,
|
||||||
|
})
|
||||||
|
existing_purpose.add(key)
|
||||||
|
created_mappings += 1
|
||||||
|
elif party:
|
||||||
|
key = (party_type, party, payment_type, kb_currency)
|
||||||
|
if key not in existing_party_only:
|
||||||
|
settings.append("transaction_mappings", {
|
||||||
|
"purpose_keyword": None,
|
||||||
|
"payment_type": payment_type,
|
||||||
|
"paid_from": paid_from,
|
||||||
|
"paid_to": paid_to,
|
||||||
|
"document_type": document_type,
|
||||||
|
"counterparty_type": party_type or None,
|
||||||
|
"counterparty": party or None,
|
||||||
|
"currency": kb_currency or None,
|
||||||
|
"multi_currency": 1 if is_foreign else 0,
|
||||||
|
})
|
||||||
|
existing_party_only.add(key)
|
||||||
|
created_mappings += 1
|
||||||
|
else:
|
||||||
|
skipped_no_data += 1
|
||||||
else:
|
else:
|
||||||
errors.append({
|
errors.append({
|
||||||
"reference_number": txn.get("reference_number") or "",
|
"reference_number": txn.get("reference_number") or "",
|
||||||
"message": result.get("error") or "Unknown error",
|
"message": result.get("error") or "Unknown error",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if mode == "Both" and created_mappings > 0:
|
||||||
|
settings.save(ignore_permissions=True)
|
||||||
|
frappe.db.commit()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"success": True,
|
"success": True,
|
||||||
"created_mappings": created_mappings,
|
"created_mappings": created_mappings,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue