bug fix
This commit is contained in:
parent
5b47d06eec
commit
68c3d7d8a9
|
|
@ -1,6 +1,18 @@
|
|||
import json
|
||||
|
||||
import frappe
|
||||
from frappe.utils import cint, flt
|
||||
|
||||
|
||||
def _extract_messages(message_log):
|
||||
"""Extract plain text from frappe.local.message_log entries."""
|
||||
parts = []
|
||||
for m in message_log:
|
||||
if isinstance(m, dict):
|
||||
parts.append(m.get("message") or m.get("msg") or "")
|
||||
else:
|
||||
parts.append(str(m))
|
||||
return " | ".join(p for p in parts if p)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
|
|
@ -291,6 +303,8 @@ def _create_and_reconcile_doc(txn, paid_from, paid_to, document_type, multi_curr
|
|||
return {"success": True, "doc_name": doc_name, "reconciled": False, "error": str(re)}
|
||||
|
||||
except Exception as e:
|
||||
frappe.db.rollback()
|
||||
frappe.local.message_log = []
|
||||
frappe.log_error(
|
||||
f"_create_and_reconcile_doc failed for {bank_transaction_name}: {e}\n{frappe.get_traceback()}",
|
||||
"Kapital Bank Mapping",
|
||||
|
|
@ -320,11 +334,22 @@ def _create_payment_entry_for_brt(txn, paid_from, paid_to, bank_txn):
|
|||
if party_type and party:
|
||||
pe.party_type = party_type
|
||||
pe.party = party
|
||||
|
||||
frappe.local.message_log = []
|
||||
pe.insert(ignore_permissions=True)
|
||||
pe.submit()
|
||||
|
||||
if frappe.local.message_log:
|
||||
msgs = _extract_messages(frappe.local.message_log)
|
||||
frappe.local.message_log = []
|
||||
frappe.db.rollback()
|
||||
return {"success": False, "error": msgs}
|
||||
|
||||
return {"success": True, "doc_name": pe.name}
|
||||
|
||||
except Exception as e:
|
||||
frappe.db.rollback()
|
||||
frappe.local.message_log = []
|
||||
frappe.log_error(
|
||||
f"_create_payment_entry_for_brt failed: {e}\n{frappe.get_traceback()}",
|
||||
"Kapital Bank Mapping",
|
||||
|
|
@ -335,6 +360,9 @@ def _create_payment_entry_for_brt(txn, paid_from, paid_to, bank_txn):
|
|||
def _create_journal_entry_for_brt(txn, paid_from, paid_to, bank_txn, multi_currency=False):
|
||||
"""Create and submit a Journal Entry for a BRT transaction."""
|
||||
try:
|
||||
import erpnext
|
||||
from erpnext.setup.utils import get_exchange_rate
|
||||
|
||||
amount = abs(float(txn.get("amount") or 0))
|
||||
party_type = (txn.get("party_type") or "").strip()
|
||||
party = (txn.get("party") or "").strip()
|
||||
|
|
@ -342,9 +370,47 @@ def _create_journal_entry_for_brt(txn, paid_from, paid_to, bank_txn, multi_curre
|
|||
posting_date = bank_txn.date or txn.get("date")
|
||||
ref_no = bank_txn.reference_number or txn.get("reference_number") or ""
|
||||
|
||||
# Determine account types to assign party to the right row
|
||||
paid_from_type = frappe.db.get_value("Account", paid_from, "account_type") or ""
|
||||
paid_to_type = frappe.db.get_value("Account", paid_to, "account_type") or ""
|
||||
company_currency = erpnext.get_company_currency(bank_txn.company)
|
||||
|
||||
# Get account currencies and types
|
||||
from_account = frappe.get_cached_value("Account", paid_from, ["account_type", "account_currency"], as_dict=True) or {}
|
||||
to_account = frappe.get_cached_value("Account", paid_to, ["account_type", "account_currency"], as_dict=True) or {}
|
||||
paid_from_type = from_account.get("account_type") or ""
|
||||
paid_to_type = to_account.get("account_type") or ""
|
||||
from_currency = from_account.get("account_currency") or company_currency
|
||||
to_currency = to_account.get("account_currency") or company_currency
|
||||
|
||||
# Auto-enable multi_currency if any account is in a foreign currency
|
||||
is_multi = from_currency != company_currency or to_currency != company_currency
|
||||
|
||||
# Frappe rounds debit_in_account_currency to field precision BEFORE multiplying
|
||||
# by exchange_rate to get debit (company currency).
|
||||
# Strategy: keep the original amount on the company-currency row, then compute
|
||||
# an exact exchange rate for the foreign row so that:
|
||||
# flt(foreign_amount * exact_rate, P) == flt(amount, P)
|
||||
# This mirrors what Frappe UI does when the user types the AZN amount first.
|
||||
currency_precision = cint(frappe.db.get_single_value("System Settings", "currency_precision") or 2)
|
||||
|
||||
if from_currency == company_currency and to_currency != company_currency:
|
||||
to_rate = get_exchange_rate(to_currency, company_currency, posting_date)
|
||||
to_amount = flt(amount / to_rate, currency_precision)
|
||||
exact_to_rate = (amount / to_amount) if to_amount else to_rate
|
||||
from_rate = 1
|
||||
from_amount = amount
|
||||
to_rate = exact_to_rate
|
||||
elif to_currency == company_currency and from_currency != company_currency:
|
||||
from_rate = get_exchange_rate(from_currency, company_currency, posting_date)
|
||||
from_amount = flt(amount / from_rate, currency_precision)
|
||||
exact_from_rate = (amount / from_amount) if from_amount else from_rate
|
||||
to_rate = 1
|
||||
to_amount = amount
|
||||
from_rate = exact_from_rate
|
||||
else:
|
||||
# Both same currency OR both foreign (rare)
|
||||
from_rate = 1 if from_currency == company_currency else get_exchange_rate(from_currency, company_currency, posting_date)
|
||||
to_rate = 1 if to_currency == company_currency else get_exchange_rate(to_currency, company_currency, posting_date)
|
||||
from_amount = flt(amount / from_rate, currency_precision)
|
||||
to_amount = flt(amount / to_rate, currency_precision)
|
||||
|
||||
je = frappe.new_doc("Journal Entry")
|
||||
je.voucher_type = "Bank Entry"
|
||||
|
|
@ -353,27 +419,37 @@ def _create_journal_entry_for_brt(txn, paid_from, paid_to, bank_txn, multi_curre
|
|||
je.cheque_no = ref_no
|
||||
je.cheque_date = posting_date
|
||||
je.user_remark = bank_txn.description or txn.get("purpose") or ""
|
||||
if multi_currency:
|
||||
if is_multi:
|
||||
je.multi_currency = 1
|
||||
|
||||
# Pay: paid_from credit, paid_to debit
|
||||
# Receive: paid_from debit, paid_to credit
|
||||
# Only set *_in_account_currency + exchange_rate; Frappe computes debit/credit itself.
|
||||
if is_pay:
|
||||
from_credit, from_debit = amount, 0
|
||||
to_credit, to_debit = 0, amount
|
||||
else:
|
||||
from_credit, from_debit = 0, amount
|
||||
to_credit, to_debit = amount, 0
|
||||
|
||||
from_row = {
|
||||
"account": paid_from,
|
||||
"credit_in_account_currency": from_credit,
|
||||
"debit_in_account_currency": from_debit,
|
||||
"exchange_rate": from_rate,
|
||||
"credit_in_account_currency": from_amount,
|
||||
"debit_in_account_currency": 0,
|
||||
}
|
||||
to_row = {
|
||||
"account": paid_to,
|
||||
"credit_in_account_currency": to_credit,
|
||||
"debit_in_account_currency": to_debit,
|
||||
"exchange_rate": to_rate,
|
||||
"debit_in_account_currency": to_amount,
|
||||
"credit_in_account_currency": 0,
|
||||
}
|
||||
else:
|
||||
from_row = {
|
||||
"account": paid_from,
|
||||
"exchange_rate": from_rate,
|
||||
"debit_in_account_currency": from_amount,
|
||||
"credit_in_account_currency": 0,
|
||||
}
|
||||
to_row = {
|
||||
"account": paid_to,
|
||||
"exchange_rate": to_rate,
|
||||
"credit_in_account_currency": to_amount,
|
||||
"debit_in_account_currency": 0,
|
||||
}
|
||||
|
||||
if party_type and party:
|
||||
|
|
@ -386,11 +462,22 @@ def _create_journal_entry_for_brt(txn, paid_from, paid_to, bank_txn, multi_curre
|
|||
|
||||
je.append("accounts", from_row)
|
||||
je.append("accounts", to_row)
|
||||
|
||||
frappe.local.message_log = []
|
||||
je.insert(ignore_permissions=True)
|
||||
je.submit()
|
||||
|
||||
if frappe.local.message_log:
|
||||
msgs = _extract_messages(frappe.local.message_log)
|
||||
frappe.local.message_log = []
|
||||
frappe.db.rollback()
|
||||
return {"success": False, "error": msgs}
|
||||
|
||||
return {"success": True, "doc_name": je.name}
|
||||
|
||||
except Exception as e:
|
||||
frappe.db.rollback()
|
||||
frappe.local.message_log = []
|
||||
frappe.log_error(
|
||||
f"_create_journal_entry_for_brt failed: {e}\n{frappe.get_traceback()}",
|
||||
"Kapital Bank Mapping",
|
||||
|
|
|
|||
Loading…
Reference in New Issue