Skip to content

Commit

Permalink
Merge pull request #33461 from frappe/mergify/bp/version-14-hotfix/pr…
Browse files Browse the repository at this point in the history
…-33380

fix: ERR journals should be reported in AR/AP (backport #33380)
  • Loading branch information
ruthra-kumar authored Dec 28, 2022
2 parents 73c9820 + 1f40d9b commit 123493b
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ def get_data(self):
# Get return entries
self.get_return_entries()

# Get Exchange Rate Revaluations
self.get_exchange_rate_revaluations()

self.data = []

for ple in self.ple_entries:
Expand Down Expand Up @@ -251,7 +254,8 @@ def build_data(self):
row.invoice_grand_total = row.invoiced

if (abs(row.outstanding) > 1.0 / 10**self.currency_precision) and (
abs(row.outstanding_in_account_currency) > 1.0 / 10**self.currency_precision
(abs(row.outstanding_in_account_currency) > 1.0 / 10**self.currency_precision)
or (row.voucher_no in self.err_journals)
):

# non-zero oustanding, we must consider this row
Expand Down Expand Up @@ -1028,3 +1032,17 @@ def get_chart_data(self):
"data": {"labels": self.ageing_column_labels, "datasets": rows},
"type": "percentage",
}

def get_exchange_rate_revaluations(self):
je = qb.DocType("Journal Entry")
results = (
qb.from_(je)
.select(je.name)
.where(
(je.company == self.filters.company)
& (je.posting_date.lte(self.filters.report_date))
& (je.voucher_type == "Exchange Rate Revaluation")
)
.run()
)
self.err_journals = [x[0] for x in results] if results else []
134 changes: 116 additions & 18 deletions erpnext/accounts/report/accounts_receivable/test_accounts_receivable.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import unittest

import frappe
from frappe.tests.utils import FrappeTestCase
from frappe.utils import add_days, getdate, today
from frappe.tests.utils import FrappeTestCase, change_settings
from frappe.utils import add_days, flt, getdate, today

from erpnext import get_default_cost_center
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
from erpnext.accounts.report.accounts_receivable.accounts_receivable import execute
Expand All @@ -17,10 +18,37 @@ def setUp(self):
frappe.db.sql("delete from `tabPayment Entry` where company='_Test Company 2'")
frappe.db.sql("delete from `tabGL Entry` where company='_Test Company 2'")
frappe.db.sql("delete from `tabPayment Ledger Entry` where company='_Test Company 2'")
frappe.db.sql("delete from `tabJournal Entry` where company='_Test Company 2'")
frappe.db.sql("delete from `tabExchange Rate Revaluation` where company='_Test Company 2'")

self.create_usd_account()

def tearDown(self):
frappe.db.rollback()

def create_usd_account(self):
name = "Debtors USD"
exists = frappe.db.get_list(
"Account", filters={"company": "_Test Company 2", "account_name": "Debtors USD"}
)
if exists:
self.debtors_usd = exists[0].name
else:
debtors = frappe.get_doc(
"Account",
frappe.db.get_list(
"Account", filters={"company": "_Test Company 2", "account_name": "Debtors"}
)[0].name,
)

debtors_usd = frappe.new_doc("Account")
debtors_usd.company = debtors.company
debtors_usd.account_name = "Debtors USD"
debtors_usd.account_currency = "USD"
debtors_usd.parent_account = debtors.parent_account
debtors_usd.account_type = debtors.account_type
self.debtors_usd = debtors_usd.save().name

def test_accounts_receivable(self):
filters = {
"company": "_Test Company 2",
Expand All @@ -33,7 +61,7 @@ def test_accounts_receivable(self):
}

# check invoice grand total and invoiced column's value for 3 payment terms
name = make_sales_invoice()
name = make_sales_invoice().name
report = execute(filters)

expected_data = [[100, 30], [100, 50], [100, 20]]
Expand Down Expand Up @@ -118,8 +146,74 @@ def test_payment_againt_po_in_receivable_report(self):
],
)

@change_settings(
"Accounts Settings", {"allow_multi_currency_invoices_against_single_party_account": 1}
)
def test_exchange_revaluation_for_party(self):
"""
Exchange Revaluation for party on Receivable/Payable shoule be included
"""

company = "_Test Company 2"
customer = "_Test Customer 2"

# Using Exchange Gain/Loss account for unrealized as well.
company_doc = frappe.get_doc("Company", company)
company_doc.unrealized_exchange_gain_loss_account = company_doc.exchange_gain_loss_account
company_doc.save()

si = make_sales_invoice(no_payment_schedule=True, do_not_submit=True)
si.currency = "USD"
si.conversion_rate = 0.90
si.debit_to = self.debtors_usd
si = si.save().submit()

# Exchange Revaluation
err = frappe.new_doc("Exchange Rate Revaluation")
err.company = company
err.posting_date = today()
accounts = err.get_accounts_data()
err.extend("accounts", accounts)
err.accounts[0].new_exchange_rate = 0.95
row = err.accounts[0]
row.new_balance_in_base_currency = flt(
row.new_exchange_rate * flt(row.balance_in_account_currency)
)
row.gain_loss = row.new_balance_in_base_currency - flt(row.balance_in_base_currency)
err.set_total_gain_loss()
err = err.save().submit()

def make_sales_invoice():
# Submit JV for ERR
jv = frappe.get_doc(err.make_jv_entry())
jv = jv.save()
for x in jv.accounts:
x.cost_center = get_default_cost_center(jv.company)
jv.submit()

filters = {
"company": company,
"report_date": today(),
"range1": 30,
"range2": 60,
"range3": 90,
"range4": 120,
}
report = execute(filters)

expected_data_for_err = [0, -5, 0, 5]
row = [x for x in report[1] if x.voucher_type == jv.doctype and x.voucher_no == jv.name][0]
self.assertEqual(
expected_data_for_err,
[
row.invoiced,
row.paid,
row.credit_note,
row.outstanding,
],
)


def make_sales_invoice(no_payment_schedule=False, do_not_submit=False):
frappe.set_user("Administrator")

si = create_sales_invoice(
Expand All @@ -134,22 +228,26 @@ def make_sales_invoice():
do_not_save=1,
)

si.append(
"payment_schedule",
dict(due_date=getdate(add_days(today(), 30)), invoice_portion=30.00, payment_amount=30),
)
si.append(
"payment_schedule",
dict(due_date=getdate(add_days(today(), 60)), invoice_portion=50.00, payment_amount=50),
)
si.append(
"payment_schedule",
dict(due_date=getdate(add_days(today(), 90)), invoice_portion=20.00, payment_amount=20),
)
if not no_payment_schedule:
si.append(
"payment_schedule",
dict(due_date=getdate(add_days(today(), 30)), invoice_portion=30.00, payment_amount=30),
)
si.append(
"payment_schedule",
dict(due_date=getdate(add_days(today(), 60)), invoice_portion=50.00, payment_amount=50),
)
si.append(
"payment_schedule",
dict(due_date=getdate(add_days(today(), 90)), invoice_portion=20.00, payment_amount=20),
)

si = si.save()

si.submit()
if not do_not_submit:
si = si.submit()

return si.name
return si


def make_payment(docname):
Expand Down

0 comments on commit 123493b

Please sign in to comment.