refactor: split make_exchage_gain_loss_journal into smaller function

This commit is contained in:
ruthra kumar 2023-07-25 10:51:58 +05:30
parent c87332d5da
commit c0b3b069b5

View File

@ -968,67 +968,52 @@ class AccountsController(TransactionBase):
d.exchange_gain_loss = difference d.exchange_gain_loss = difference
def make_exchange_gain_loss_journal(self, args: dict = None) -> None: def create_gain_loss_journal(
""" self,
Make Exchange Gain/Loss journal for Invoices and Payments party_type,
""" party,
# Cancelling existing exchange gain/loss journals is handled during the `on_cancel` event. party_account,
# see accounts/utils.py:cancel_exchange_gain_loss_journal() gain_loss_account,
if self.docstatus == 1: exc_gain_loss,
if self.get("doctype") == "Journal Entry": dr_or_cr,
# 'args' is populated with exchange gain/loss account and the amount to be booked. reverse_dr_or_cr,
# These are generated by Sales/Purchase Invoice during reconciliation and advance allocation. ref1_dt,
if args: ref1_dn,
for arg in args: ref1_detail_no,
# Advance section uses `exchange_gain_loss` and reconciliation uses `difference_amount` ref2_dt,
if ( ref2_dn,
arg.get("difference_amount", 0) != 0 or arg.get("exchange_gain_loss", 0) != 0 ref2_detail_no,
) and arg.get("difference_account"): ) -> str:
journal_entry = frappe.new_doc("Journal Entry") journal_entry = frappe.new_doc("Journal Entry")
journal_entry.voucher_type = "Exchange Gain Or Loss" journal_entry.voucher_type = "Exchange Gain Or Loss"
journal_entry.company = self.company journal_entry.company = self.company
journal_entry.posting_date = nowdate() journal_entry.posting_date = nowdate()
journal_entry.multi_currency = 1 journal_entry.multi_currency = 1
party_account = arg.get("account") party_account_currency = frappe.get_cached_value("Account", party_account, "account_currency")
party_account_currency = frappe.get_cached_value(
"Account", party_account, "account_currency"
)
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"
else:
dr_or_cr = "credit" if arg.get("party_type") == "Customer" else "debit"
reverse_dr_or_cr = "debit" if dr_or_cr == "credit" else "credit"
gain_loss_account = arg.get("difference_account")
if not gain_loss_account: if not gain_loss_account:
frappe.throw( frappe.throw(
_("Please set default Exchange Gain/Loss Account in Company {}").format( _("Please set default Exchange Gain/Loss Account in Company {}").format(self.get("company"))
self.get("company")
) )
)
gain_loss_account_currency = get_account_currency(gain_loss_account) 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: if gain_loss_account_currency != self.company_currency:
frappe.throw( frappe.throw(_("Currency for {0} must be {1}").format(gain_loss_account, company_currency))
_("Currency for {0} must be {1}").format(gain_loss_account, self.company_currency)
)
journal_account = frappe._dict( journal_account = frappe._dict(
{ {
"account": party_account, "account": party_account,
"party_type": arg.get("party_type"), "party_type": party_type,
"party": arg.get("party"), "party": party,
"account_currency": party_account_currency, "account_currency": party_account_currency,
"exchange_rate": 0, "exchange_rate": 0,
"cost_center": erpnext.get_default_cost_center(self.company), "cost_center": erpnext.get_default_cost_center(self.company),
"reference_type": arg.get("against_voucher_type"), "reference_type": ref1_dt,
"reference_name": arg.get("against_voucher"), "reference_name": ref1_dn,
"reference_detail_no": arg.get("idx"), "reference_detail_no": ref1_detail_no,
dr_or_cr: abs(difference_amount), dr_or_cr: abs(exc_gain_loss),
dr_or_cr + "_in_account_currency": 0, dr_or_cr + "_in_account_currency": 0,
} }
) )
@ -1041,14 +1026,11 @@ class AccountsController(TransactionBase):
"account_currency": gain_loss_account_currency, "account_currency": gain_loss_account_currency,
"exchange_rate": 1, "exchange_rate": 1,
"cost_center": erpnext.get_default_cost_center(self.company), "cost_center": erpnext.get_default_cost_center(self.company),
# TODO: figure out a way to pass reference "reference_type": ref2_dt,
# TODO: add reference_detail_no field in payment ledger "reference_name": ref2_dn,
# throws 'Journal Entry doesn't have {account} or doesn't have matched account' "reference_detail_no": ref2_detail_no,
"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, reverse_dr_or_cr + "_in_account_currency": 0,
reverse_dr_or_cr: abs(exc_gain_loss),
} }
) )
@ -1056,6 +1038,51 @@ class AccountsController(TransactionBase):
journal_entry.save() journal_entry.save()
journal_entry.submit() 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
"""
# Cancelling existing exchange gain/loss journals is handled during the `on_cancel` event.
# see accounts/utils.py:cancel_exchange_gain_loss_journal()
if self.docstatus == 1:
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"):
party_account = arg.get("account")
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"
else:
dr_or_cr = "credit" if arg.get("party_type") == "Customer" else "debit"
reverse_dr_or_cr = "debit" if dr_or_cr == "credit" else "credit"
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"),
)
if self.get("doctype") == "Payment Entry": if self.get("doctype") == "Payment Entry":
# For Payment Entry, exchange_gain_loss field in the `references` table is the trigger for journal creation # For Payment Entry, exchange_gain_loss field in the `references` table is the trigger for journal creation
@ -1093,23 +1120,15 @@ class AccountsController(TransactionBase):
) )
for d in gain_loss_to_book: for d in gain_loss_to_book:
# Filter out References for which Gain/Loss is already booked
if d.exchange_gain_loss and ( if d.exchange_gain_loss and (
(d.reference_doctype, d.reference_name, str(d.idx)) not in booked (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": if self.payment_type == "Receive":
party_account = self.paid_from party_account = self.paid_from
elif self.payment_type == "Pay": elif self.payment_type == "Pay":
party_account = self.paid_to 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" dr_or_cr = "debit" if d.exchange_gain_loss > 0 else "credit"
if d.reference_doctype == "Purchase Invoice": if d.reference_doctype == "Purchase Invoice":
@ -1120,54 +1139,22 @@ class AccountsController(TransactionBase):
gain_loss_account = frappe.get_cached_value( gain_loss_account = frappe.get_cached_value(
"Company", self.company, "exchange_gain_loss_account" "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( self.create_gain_loss_journal(
{ self.party_type,
"account": party_account, self.party,
"party_type": self.party_type, party_account,
"party": self.party, gain_loss_account,
"account_currency": party_account_currency, d.exchange_gain_loss,
"exchange_rate": 0, dr_or_cr,
"cost_center": erpnext.get_default_cost_center(self.company), reverse_dr_or_cr,
"reference_type": d.reference_doctype, d.reference_doctype,
"reference_name": d.reference_name, d.reference_name,
"reference_detail_no": d.idx, d.idx,
dr_or_cr: abs(d.exchange_gain_loss), self.doctype,
dr_or_cr + "_in_account_currency": 0, 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...") # frappe.throw("stopping...")
def update_against_document_in_jv(self): def update_against_document_in_jv(self):