mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-16 07:58:38 +00:00
fix: adjust outstanding amount calculation in purchase and sales registers
(cherry picked from commit 6115af720b)
# Conflicts:
# erpnext/accounts/report/purchase_register/purchase_register.py
This commit is contained in:
committed by
ruthra kumar
parent
1cc2890f3e
commit
1a2a9b6cfc
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe import _, msgprint
|
from frappe import _, msgprint
|
||||||
|
from frappe.model.meta import get_field_precision
|
||||||
from frappe.query_builder.custom import ConstantColumn
|
from frappe.query_builder.custom import ConstantColumn
|
||||||
from frappe.utils import flt, getdate
|
from frappe.utils import flt, getdate
|
||||||
from pypika.terms import Bracket, LiteralValue, Order
|
from pypika.terms import Bracket, LiteralValue, Order
|
||||||
@@ -125,17 +126,32 @@ def _execute(filters=None, additional_table_columns=None):
|
|||||||
row.update({frappe.scrub(tax_acc): tax_amount})
|
row.update({frappe.scrub(tax_acc): tax_amount})
|
||||||
|
|
||||||
# total tax, grand total, rounded total & outstanding amount
|
# total tax, grand total, rounded total & outstanding amount
|
||||||
|
|
||||||
|
outstanding_precision = (
|
||||||
|
get_field_precision(
|
||||||
|
frappe.get_meta("Purchase Invoice").get_field("outstanding_amount"),
|
||||||
|
currency=company_currency,
|
||||||
|
)
|
||||||
|
or 2
|
||||||
|
)
|
||||||
row.update(
|
row.update(
|
||||||
{
|
{
|
||||||
"total_tax": total_tax,
|
"total_tax": total_tax,
|
||||||
"grand_total": inv.base_grand_total,
|
"grand_total": inv.base_grand_total,
|
||||||
"rounded_total": inv.base_rounded_total,
|
"rounded_total": inv.base_rounded_total,
|
||||||
"outstanding_amount": inv.outstanding_amount,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
if inv.doctype == "Purchase Invoice":
|
if inv.doctype == "Purchase Invoice":
|
||||||
row.update({"debit": inv.base_grand_total, "credit": 0.0})
|
row.update(
|
||||||
|
{
|
||||||
|
"debit": inv.base_grand_total,
|
||||||
|
"credit": 0.0,
|
||||||
|
"outstanding_amount": flt(
|
||||||
|
(inv.outstanding_amount * (inv.conversion_rate or 1)), outstanding_precision
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
row.update({"debit": 0.0, "credit": inv.base_grand_total})
|
row.update({"debit": 0.0, "credit": inv.base_grand_total})
|
||||||
data.append(row)
|
data.append(row)
|
||||||
@@ -395,6 +411,7 @@ def get_invoices(filters, additional_query_columns):
|
|||||||
pi.base_rounded_total,
|
pi.base_rounded_total,
|
||||||
pi.outstanding_amount,
|
pi.outstanding_amount,
|
||||||
pi.mode_of_payment,
|
pi.mode_of_payment,
|
||||||
|
pi.conversion_rate,
|
||||||
)
|
)
|
||||||
.where(pi.docstatus == 1)
|
.where(pi.docstatus == 1)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# MIT License. See license.txt
|
# MIT License. See license.txt
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
from frappe.utils import add_months, today
|
from frappe.utils import add_months, flt, today
|
||||||
|
|
||||||
from erpnext.accounts.report.purchase_register.purchase_register import execute
|
from erpnext.accounts.report.purchase_register.purchase_register import execute
|
||||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
|
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
|
||||||
@@ -67,6 +67,35 @@ class TestPurchaseRegister(ERPNextTestSuite):
|
|||||||
self.assertEqual(first_row.total_tax, 100)
|
self.assertEqual(first_row.total_tax, 100)
|
||||||
self.assertEqual(first_row.grand_total, 1100)
|
self.assertEqual(first_row.grand_total, 1100)
|
||||||
|
|
||||||
|
def test_purchase_currency_conversion(self):
|
||||||
|
usd_creditors = frappe.get_doc(
|
||||||
|
{
|
||||||
|
"doctype": "Account",
|
||||||
|
"account_name": "USD Creditors",
|
||||||
|
"parent_account": "Accounts Payable - _TC",
|
||||||
|
"company": "_Test Company",
|
||||||
|
"account_type": "Payable",
|
||||||
|
"root_type": "Liability",
|
||||||
|
"report_type": "Balance Sheet",
|
||||||
|
"account_currency": "USD",
|
||||||
|
}
|
||||||
|
).insert()
|
||||||
|
foreign_invoice = make_purchase_invoice()
|
||||||
|
foreign_invoice.db_set("currency", "USD")
|
||||||
|
foreign_invoice.db_set("conversion_rate", 80)
|
||||||
|
foreign_invoice.db_set("credit_to", usd_creditors.name)
|
||||||
|
foreign_invoice.db_set("outstanding_amount", 100.236)
|
||||||
|
local_invoice = make_purchase_invoice()
|
||||||
|
local_invoice.db_set("currency", "INR")
|
||||||
|
local_invoice.db_set("conversion_rate", 1)
|
||||||
|
local_invoice.db_set("outstanding_amount", 200.456)
|
||||||
|
columns, data, *_ = execute(frappe._dict({"company": foreign_invoice.company}))
|
||||||
|
outstanding_precision = 2
|
||||||
|
|
||||||
|
data_by_name = {x.get("voucher_no"): x.get("outstanding_amount") for x in data}
|
||||||
|
self.assertEqual(data_by_name.get(foreign_invoice.name), flt((100.236 * 80), outstanding_precision))
|
||||||
|
self.assertEqual(data_by_name.get(local_invoice.name), flt(200.456, outstanding_precision))
|
||||||
|
|
||||||
def test_purchase_register_ledger_view(self):
|
def test_purchase_register_ledger_view(self):
|
||||||
filters = frappe._dict(
|
filters = frappe._dict(
|
||||||
company="_Test Company 6",
|
company="_Test Company 6",
|
||||||
|
|||||||
@@ -141,17 +141,31 @@ def _execute(filters, additional_table_columns=None):
|
|||||||
|
|
||||||
# total tax, grand total, outstanding amount & rounded total
|
# total tax, grand total, outstanding amount & rounded total
|
||||||
|
|
||||||
|
outstanding_precision = (
|
||||||
|
get_field_precision(
|
||||||
|
frappe.get_meta("Sales Invoice").get_field("outstanding_amount"),
|
||||||
|
currency=company_currency,
|
||||||
|
)
|
||||||
|
or 2
|
||||||
|
)
|
||||||
row.update(
|
row.update(
|
||||||
{
|
{
|
||||||
"tax_total": total_tax,
|
"tax_total": total_tax,
|
||||||
"grand_total": inv.base_grand_total,
|
"grand_total": inv.base_grand_total,
|
||||||
"rounded_total": inv.base_rounded_total,
|
"rounded_total": inv.base_rounded_total,
|
||||||
"outstanding_amount": inv.outstanding_amount,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
if inv.doctype == "Sales Invoice":
|
if inv.doctype == "Sales Invoice":
|
||||||
row.update({"debit": inv.base_grand_total, "credit": 0.0})
|
row.update(
|
||||||
|
{
|
||||||
|
"debit": inv.base_grand_total,
|
||||||
|
"credit": 0.0,
|
||||||
|
"outstanding_amount": flt(
|
||||||
|
(inv.outstanding_amount * (inv.conversion_rate or 1)), outstanding_precision
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
row.update({"debit": 0.0, "credit": inv.base_grand_total})
|
row.update({"debit": 0.0, "credit": inv.base_grand_total})
|
||||||
data.append(row)
|
data.append(row)
|
||||||
@@ -437,6 +451,7 @@ def get_invoices(filters, additional_query_columns):
|
|||||||
si.is_internal_customer,
|
si.is_internal_customer,
|
||||||
si.represents_company,
|
si.represents_company,
|
||||||
si.company,
|
si.company,
|
||||||
|
si.conversion_rate,
|
||||||
)
|
)
|
||||||
.where(si.docstatus == 1)
|
.where(si.docstatus == 1)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe.utils import getdate, today
|
from frappe.utils import add_days, flt, getdate, today
|
||||||
|
|
||||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||||
from erpnext.accounts.report.sales_register.sales_register import execute
|
from erpnext.accounts.report.sales_register.sales_register import execute
|
||||||
from erpnext.accounts.test.accounts_mixin import AccountsTestMixin
|
from erpnext.accounts.test.accounts_mixin import AccountsTestMixin
|
||||||
|
from erpnext.selling.doctype.customer.test_customer import make_customer
|
||||||
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
||||||
from erpnext.tests.utils import ERPNextTestSuite
|
from erpnext.tests.utils import ERPNextTestSuite
|
||||||
|
|
||||||
@@ -216,3 +217,25 @@ class TestItemWiseSalesRegister(ERPNextTestSuite, AccountsTestMixin):
|
|||||||
}
|
}
|
||||||
result_output = {k: v for k, v in filtered_output[0].items() if k in expected_result}
|
result_output = {k: v for k, v in filtered_output[0].items() if k in expected_result}
|
||||||
self.assertDictEqual(result_output, expected_result)
|
self.assertDictEqual(result_output, expected_result)
|
||||||
|
|
||||||
|
def test_outstanding_currency_conversion(self):
|
||||||
|
foreign_invoice = create_sales_invoice(
|
||||||
|
customer="_Test Customer",
|
||||||
|
posting_date=add_days(today(), -1),
|
||||||
|
qty=1,
|
||||||
|
rate=100,
|
||||||
|
)
|
||||||
|
foreign_invoice.db_set("currency", "USD")
|
||||||
|
foreign_invoice.db_set("conversion_rate", 80)
|
||||||
|
foreign_invoice.db_set("outstanding_amount", 100.236)
|
||||||
|
make_customer("_Test Customer2")
|
||||||
|
local_invoice = create_sales_invoice(
|
||||||
|
customer="_Test Customer2", currency="INR", conversion_rate=1, qty=1, rate=200
|
||||||
|
)
|
||||||
|
local_invoice.db_set("outstanding_amount", 200.456)
|
||||||
|
columns, data, *_ = execute(frappe._dict({"company": foreign_invoice.company}))
|
||||||
|
outstanding_precision = 2
|
||||||
|
|
||||||
|
data_by_name = {x.get("voucher_no"): x.get("outstanding_amount") for x in data}
|
||||||
|
self.assertEqual(data_by_name.get(foreign_invoice.name), flt((100.236 * 80), outstanding_precision))
|
||||||
|
self.assertEqual(data_by_name.get(local_invoice.name), flt(200.456, outstanding_precision))
|
||||||
|
|||||||
Reference in New Issue
Block a user