refactor: split make_exchage_gain_loss_journal into smaller function
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 40432f7..6bf9d29 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -968,6 +968,78 @@
d.exchange_gain_loss = difference
+ def create_gain_loss_journal(
+ self,
+ party_type,
+ party,
+ party_account,
+ gain_loss_account,
+ exc_gain_loss,
+ dr_or_cr,
+ reverse_dr_or_cr,
+ ref1_dt,
+ ref1_dn,
+ ref1_detail_no,
+ ref2_dt,
+ ref2_dn,
+ ref2_detail_no,
+ ) -> str:
+ journal_entry = frappe.new_doc("Journal Entry")
+ journal_entry.voucher_type = "Exchange Gain Or Loss"
+ journal_entry.company = self.company
+ journal_entry.posting_date = nowdate()
+ journal_entry.multi_currency = 1
+
+ party_account_currency = frappe.get_cached_value("Account", party_account, "account_currency")
+
+ if not gain_loss_account:
+ frappe.throw(
+ _("Please set default Exchange Gain/Loss Account in Company {}").format(self.get("company"))
+ )
+ gain_loss_account_currency = get_account_currency(gain_loss_account)
+ company_currency = frappe.get_cached_value("Company", self.company, "default_currency")
+
+ if gain_loss_account_currency != self.company_currency:
+ frappe.throw(_("Currency for {0} must be {1}").format(gain_loss_account, company_currency))
+
+ journal_account = frappe._dict(
+ {
+ "account": party_account,
+ "party_type": party_type,
+ "party": party,
+ "account_currency": party_account_currency,
+ "exchange_rate": 0,
+ "cost_center": erpnext.get_default_cost_center(self.company),
+ "reference_type": ref1_dt,
+ "reference_name": ref1_dn,
+ "reference_detail_no": ref1_detail_no,
+ dr_or_cr: abs(exc_gain_loss),
+ dr_or_cr + "_in_account_currency": 0,
+ }
+ )
+
+ journal_entry.append("accounts", journal_account)
+
+ journal_account = frappe._dict(
+ {
+ "account": gain_loss_account,
+ "account_currency": gain_loss_account_currency,
+ "exchange_rate": 1,
+ "cost_center": erpnext.get_default_cost_center(self.company),
+ "reference_type": ref2_dt,
+ "reference_name": ref2_dn,
+ "reference_detail_no": ref2_detail_no,
+ reverse_dr_or_cr + "_in_account_currency": 0,
+ reverse_dr_or_cr: abs(exc_gain_loss),
+ }
+ )
+
+ journal_entry.append("accounts", journal_account)
+
+ journal_entry.save()
+ journal_entry.submit()
+ return journal_entry.name
+
def make_exchange_gain_loss_journal(self, args: dict = None) -> None:
"""
Make Exchange Gain/Loss journal for Invoices and Payments
@@ -978,23 +1050,16 @@
if self.get("doctype") == "Journal Entry":
# 'args' is populated with exchange gain/loss account and the amount to be booked.
# These are generated by Sales/Purchase Invoice during reconciliation and advance allocation.
+ # and below logic is only for such scenarios
if args:
for arg in args:
# Advance section uses `exchange_gain_loss` and reconciliation uses `difference_amount`
if (
arg.get("difference_amount", 0) != 0 or arg.get("exchange_gain_loss", 0) != 0
) and arg.get("difference_account"):
- journal_entry = frappe.new_doc("Journal Entry")
- journal_entry.voucher_type = "Exchange Gain Or Loss"
- journal_entry.company = self.company
- journal_entry.posting_date = nowdate()
- journal_entry.multi_currency = 1
party_account = arg.get("account")
- party_account_currency = frappe.get_cached_value(
- "Account", party_account, "account_currency"
- )
-
+ gain_loss_account = arg.get("difference_account")
difference_amount = arg.get("difference_amount") or arg.get("exchange_gain_loss")
if difference_amount > 0:
dr_or_cr = "debit" if arg.get("party_type") == "Customer" else "credit"
@@ -1003,60 +1068,22 @@
reverse_dr_or_cr = "debit" if dr_or_cr == "credit" else "credit"
- gain_loss_account = arg.get("difference_account")
- if not gain_loss_account:
- frappe.throw(
- _("Please set default Exchange Gain/Loss Account in Company {}").format(
- self.get("company")
- )
- )
-
- gain_loss_account_currency = get_account_currency(gain_loss_account)
- if gain_loss_account_currency != self.company_currency:
- frappe.throw(
- _("Currency for {0} must be {1}").format(gain_loss_account, self.company_currency)
- )
-
- journal_account = frappe._dict(
- {
- "account": party_account,
- "party_type": arg.get("party_type"),
- "party": arg.get("party"),
- "account_currency": party_account_currency,
- "exchange_rate": 0,
- "cost_center": erpnext.get_default_cost_center(self.company),
- "reference_type": arg.get("against_voucher_type"),
- "reference_name": arg.get("against_voucher"),
- "reference_detail_no": arg.get("idx"),
- dr_or_cr: abs(difference_amount),
- dr_or_cr + "_in_account_currency": 0,
- }
+ self.create_gain_loss_journal(
+ arg.get("party_type"),
+ arg.get("party"),
+ party_account,
+ gain_loss_account,
+ difference_amount,
+ dr_or_cr,
+ reverse_dr_or_cr,
+ arg.get("against_voucher_type"),
+ arg.get("against_voucher"),
+ arg.get("idx"),
+ self.doctype,
+ self.name,
+ arg.get("idx"),
)
- journal_entry.append("accounts", journal_account)
-
- journal_account = frappe._dict(
- {
- "account": gain_loss_account,
- "account_currency": gain_loss_account_currency,
- "exchange_rate": 1,
- "cost_center": erpnext.get_default_cost_center(self.company),
- # TODO: figure out a way to pass reference
- # TODO: add reference_detail_no field in payment ledger
- # throws 'Journal Entry doesn't have {account} or doesn't have matched account'
- "reference_type": self.doctype,
- "reference_name": self.name,
- "reference_detail_no": arg.idx,
- reverse_dr_or_cr: abs(difference_amount),
- reverse_dr_or_cr + "_in_account_currency": 0,
- }
- )
-
- journal_entry.append("accounts", journal_account)
-
- journal_entry.save()
- journal_entry.submit()
-
if self.get("doctype") == "Payment Entry":
# For Payment Entry, exchange_gain_loss field in the `references` table is the trigger for journal creation
gain_loss_to_book = [x for x in self.references if x.exchange_gain_loss != 0]
@@ -1093,23 +1120,15 @@
)
for d in gain_loss_to_book:
+ # Filter out References for which Gain/Loss is already booked
if d.exchange_gain_loss and (
(d.reference_doctype, d.reference_name, str(d.idx)) not in booked
):
- journal_entry = frappe.new_doc("Journal Entry")
- journal_entry.voucher_type = "Exchange Gain Or Loss"
- journal_entry.company = self.company
- journal_entry.posting_date = nowdate()
- journal_entry.multi_currency = 1
-
if self.payment_type == "Receive":
party_account = self.paid_from
elif self.payment_type == "Pay":
party_account = self.paid_to
- party_account_currency = frappe.get_cached_value(
- "Account", party_account, "account_currency"
- )
dr_or_cr = "debit" if d.exchange_gain_loss > 0 else "credit"
if d.reference_doctype == "Purchase Invoice":
@@ -1120,54 +1139,22 @@
gain_loss_account = frappe.get_cached_value(
"Company", self.company, "exchange_gain_loss_account"
)
- if not gain_loss_account:
- frappe.throw(
- _("Please set default Exchange Gain/Loss Account in Company {}").format(
- self.get("company")
- )
- )
- gain_loss_account_currency = get_account_currency(gain_loss_account)
- if gain_loss_account_currency != self.company_currency:
- frappe.throw(
- _("Currency for {0} must be {1}").format(gain_loss_account, self.company_currency)
- )
- journal_account = frappe._dict(
- {
- "account": party_account,
- "party_type": self.party_type,
- "party": self.party,
- "account_currency": party_account_currency,
- "exchange_rate": 0,
- "cost_center": erpnext.get_default_cost_center(self.company),
- "reference_type": d.reference_doctype,
- "reference_name": d.reference_name,
- "reference_detail_no": d.idx,
- dr_or_cr: abs(d.exchange_gain_loss),
- dr_or_cr + "_in_account_currency": 0,
- }
+ self.create_gain_loss_journal(
+ self.party_type,
+ self.party,
+ party_account,
+ gain_loss_account,
+ d.exchange_gain_loss,
+ dr_or_cr,
+ reverse_dr_or_cr,
+ d.reference_doctype,
+ d.reference_name,
+ d.idx,
+ self.doctype,
+ self.name,
+ d.idx,
)
-
- journal_entry.append("accounts", journal_account)
-
- journal_account = frappe._dict(
- {
- "account": gain_loss_account,
- "account_currency": gain_loss_account_currency,
- "exchange_rate": 1,
- "cost_center": erpnext.get_default_cost_center(self.company),
- "reference_type": self.doctype,
- "reference_name": self.name,
- "reference_detail_no": d.idx,
- reverse_dr_or_cr + "_in_account_currency": 0,
- reverse_dr_or_cr: abs(d.exchange_gain_loss),
- }
- )
-
- journal_entry.append("accounts", journal_account)
-
- journal_entry.save()
- journal_entry.submit()
# frappe.throw("stopping...")
def update_against_document_in_jv(self):