fix: purchase invoice return GLe

voucher_wise_stock_value contains tuples and the condition was looking
for string, so it's never triggered.

Caused by https://github.com/frappe/erpnext/pull/24200
This commit is contained in:
Ankush Menat 2022-06-01 14:17:06 +05:30
parent 293eb8d722
commit 7726271e2a
4 changed files with 95 additions and 3 deletions

View File

@ -1127,7 +1127,7 @@ class PurchaseInvoice(BuyingController):
# Stock ledger value is not matching with the warehouse amount # Stock ledger value is not matching with the warehouse amount
if ( if (
self.update_stock self.update_stock
and voucher_wise_stock_value.get(item.name) and voucher_wise_stock_value.get((item.name, item.warehouse))
and warehouse_debit_amount and warehouse_debit_amount
!= flt(voucher_wise_stock_value.get((item.name, item.warehouse)), net_amt_precision) != flt(voucher_wise_stock_value.get((item.name, item.warehouse)), net_amt_precision)
): ):

View File

@ -27,12 +27,13 @@ from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import (
make_purchase_receipt, make_purchase_receipt,
) )
from erpnext.stock.doctype.stock_entry.test_stock_entry import get_qty_after_transaction from erpnext.stock.doctype.stock_entry.test_stock_entry import get_qty_after_transaction
from erpnext.stock.tests.test_utils import StockTestMixin
test_dependencies = ["Item", "Cost Center", "Payment Term", "Payment Terms Template"] test_dependencies = ["Item", "Cost Center", "Payment Term", "Payment Terms Template"]
test_ignore = ["Serial No"] test_ignore = ["Serial No"]
class TestPurchaseInvoice(unittest.TestCase): class TestPurchaseInvoice(unittest.TestCase, StockTestMixin):
@classmethod @classmethod
def setUpClass(self): def setUpClass(self):
unlink_payment_on_cancel_of_invoice() unlink_payment_on_cancel_of_invoice()
@ -693,6 +694,80 @@ class TestPurchaseInvoice(unittest.TestCase):
self.assertEqual(expected_values[gle.account][0], gle.debit) self.assertEqual(expected_values[gle.account][0], gle.debit)
self.assertEqual(expected_values[gle.account][1], gle.credit) self.assertEqual(expected_values[gle.account][1], gle.credit)
def test_standalone_return_using_pi(self):
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
item = self.make_item().name
company = "_Test Company with perpetual inventory"
warehouse = "Stores - TCP1"
make_stock_entry(item_code=item, target=warehouse, qty=50, rate=120)
return_pi = make_purchase_invoice(
is_return=1,
item=item,
qty=-10,
update_stock=1,
rate=100,
company=company,
warehouse=warehouse,
cost_center="Main - TCP1",
)
# assert that stock consumption is with actual rate
self.assertGLEs(
return_pi,
[{"credit": 1200, "debit": 0}],
gle_filters={"account": "Stock In Hand - TCP1"},
)
# assert loss booked in COGS
self.assertGLEs(
return_pi,
[{"credit": 0, "debit": 200}],
gle_filters={"account": "Cost of Goods Sold - TCP1"},
)
def test_return_with_lcv(self):
from erpnext.controllers.sales_and_purchase_return import make_return_doc
from erpnext.stock.doctype.landed_cost_voucher.test_landed_cost_voucher import (
create_landed_cost_voucher,
)
item = self.make_item().name
company = "_Test Company with perpetual inventory"
warehouse = "Stores - TCP1"
cost_center = "Main - TCP1"
pi = make_purchase_invoice(
item=item,
company=company,
warehouse=warehouse,
cost_center=cost_center,
update_stock=1,
qty=10,
rate=100,
)
# Create landed cost voucher - will increase valuation of received item by 10
create_landed_cost_voucher("Purchase Invoice", pi.name, pi.company, charges=100)
return_pi = make_return_doc(pi.doctype, pi.name)
return_pi.save().submit()
# assert that stock consumption is with actual in rate
self.assertGLEs(
return_pi,
[{"credit": 1100, "debit": 0}],
gle_filters={"account": "Stock In Hand - TCP1"},
)
# assert loss booked in COGS
self.assertGLEs(
return_pi,
[{"credit": 0, "debit": 100}],
gle_filters={"account": "Cost of Goods Sold - TCP1"},
)
def test_multi_currency_gle(self): def test_multi_currency_gle(self):
pi = make_purchase_invoice( pi = make_purchase_invoice(
supplier="_Test Supplier USD", supplier="_Test Supplier USD",

View File

@ -316,7 +316,7 @@ def get_returned_qty_map_for_row(return_against, party, row_name, doctype):
return data[0] return data[0]
def make_return_doc(doctype, source_name, target_doc=None): def make_return_doc(doctype: str, source_name: str, target_doc=None):
from frappe.model.mapper import get_mapped_doc from frappe.model.mapper import get_mapped_doc
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos

View File

@ -38,6 +38,23 @@ class StockTestMixin:
self.assertEqual(v, act_value, msg=f"{k} doesn't match \n{exp_sle}\n{act_sle}") self.assertEqual(v, act_value, msg=f"{k} doesn't match \n{exp_sle}\n{act_sle}")
def assertGLEs(self, doc, expected_gles, gle_filters=None, order_by=None):
filters = {"voucher_no": doc.name, "voucher_type": doc.doctype, "is_cancelled": 0}
if gle_filters:
filters.update(gle_filters)
actual_gles = frappe.get_all(
"GL Entry",
fields=["*"],
filters=filters,
order_by=order_by or "posting_date, creation",
)
for exp_gle, act_gle in zip(expected_gles, actual_gles):
for k, exp_value in exp_gle.items():
act_value = act_gle[k]
self.assertEqual(exp_value, act_value, msg=f"{k} doesn't match \n{exp_gle}\n{act_gle}")
class TestStockUtilities(FrappeTestCase, StockTestMixin): class TestStockUtilities(FrappeTestCase, StockTestMixin):
def test_barcode_scanning(self): def test_barcode_scanning(self):