mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-10 05:01:47 +00:00
fix: do not fetch a random inventory account when multiple inventory accounts exist (backport #57626) (#57631)
* fix: do not fetch a random inventory account when multiple inventory accounts exist (#57626)
(cherry picked from commit 386a4ac1f0)
# Conflicts:
# erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
* chore: fix conflicts
Removed redundant test for valuation taxes in purchase receipt.
* fix: build warehouse account map only when perpetual inventory needs it
For asset purchase receipts or provisional accounting with perpetual
inventory disabled, GL entries do not use warehouse accounts. Building
the full warehouse account map in that case now throws when a company
has multiple inventory accounts and no default, breaking asset receipt
submission. Mirrors the gating on develop.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* test: set default inventory account in valuation taxes LCV test
The conflict resolution kept the pre-backport copy of
test_valuation_taxes_lcv_repost_after_billing, which enables perpetual
inventory on _Test Company without configuring a default inventory
account. The test then failed on submit and leaked the perpetual
inventory flag, breaking every stock test that ran after it in the same
process. Restore the cherry-picked version from #57626.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -2802,12 +2802,15 @@ class TestSalesInvoice(FrappeTestCase):
|
||||
|
||||
old_perpetual_inventory = erpnext.is_perpetual_inventory_enabled("_Test Company 1")
|
||||
frappe.local.enable_perpetual_inventory["_Test Company 1"] = 1
|
||||
old_inventory_account = frappe.db.get_value("Company", "_Test Company 1", "default_inventory_account")
|
||||
|
||||
frappe.db.set_value(
|
||||
"Company",
|
||||
"_Test Company 1",
|
||||
"stock_received_but_not_billed",
|
||||
"Stock Received But Not Billed - _TC1",
|
||||
{
|
||||
"stock_received_but_not_billed": "Stock Received But Not Billed - _TC1",
|
||||
"default_inventory_account": "Stock In Hand - _TC1",
|
||||
},
|
||||
)
|
||||
frappe.db.set_value(
|
||||
"Company",
|
||||
@@ -2852,6 +2855,7 @@ class TestSalesInvoice(FrappeTestCase):
|
||||
|
||||
# tear down
|
||||
frappe.local.enable_perpetual_inventory["_Test Company 1"] = old_perpetual_inventory
|
||||
frappe.db.set_value("Company", "_Test Company 1", "default_inventory_account", old_inventory_account)
|
||||
frappe.db.set_single_value("Stock Settings", "allow_negative_stock", old_negative_stock)
|
||||
|
||||
def test_sle_for_target_warehouse(self):
|
||||
|
||||
@@ -177,13 +177,18 @@ class StockController(AccountsController):
|
||||
)
|
||||
|
||||
is_asset_pr = any(d.get("is_fixed_asset") for d in self.get("items"))
|
||||
need_inventory_map = (self.get_stock_items() or self.get("packed_items")) and cint(
|
||||
erpnext.is_perpetual_inventory_enabled(self.company)
|
||||
)
|
||||
|
||||
if (
|
||||
cint(erpnext.is_perpetual_inventory_enabled(self.company))
|
||||
or provisional_accounting_for_non_stock_items
|
||||
or is_asset_pr
|
||||
):
|
||||
warehouse_account = get_warehouse_account_map(self.company)
|
||||
warehouse_account = frappe._dict()
|
||||
if need_inventory_map:
|
||||
warehouse_account = get_warehouse_account_map(self.company)
|
||||
|
||||
if self.docstatus == 1:
|
||||
if not gl_entries:
|
||||
|
||||
@@ -79,10 +79,13 @@ def get_warehouse_account(warehouse, warehouse_account=None):
|
||||
account = get_company_default_inventory_account(warehouse.company)
|
||||
|
||||
if not account and warehouse.company:
|
||||
account = frappe.db.get_value(
|
||||
"Account", {"account_type": "Stock", "is_group": 0, "company": warehouse.company}, "name"
|
||||
inventory_accounts = frappe.get_all(
|
||||
"Account", {"account_type": "Stock", "is_group": 0, "company": warehouse.company}, pluck="name"
|
||||
)
|
||||
|
||||
if len(inventory_accounts) == 1:
|
||||
account = inventory_accounts[0]
|
||||
|
||||
if not account and warehouse.company and not warehouse.is_group:
|
||||
frappe.throw(
|
||||
_("Please set Account in Warehouse {0} or Default Inventory Account in Company {1}").format(
|
||||
|
||||
@@ -194,8 +194,10 @@ class TestLandedCostVoucher(FrappeTestCase):
|
||||
|
||||
epi = is_perpetual_inventory_enabled(company_a)
|
||||
company_doc = frappe.get_doc("Company", company_a)
|
||||
old_inventory_account = company_doc.default_inventory_account
|
||||
company_doc.enable_perpetual_inventory = 1
|
||||
company_doc.stock_received_but_not_billed = srbnb
|
||||
company_doc.default_inventory_account = "Stock In Hand - _TC"
|
||||
company_doc.save()
|
||||
|
||||
pr = make_purchase_receipt(
|
||||
@@ -223,7 +225,11 @@ class TestLandedCostVoucher(FrappeTestCase):
|
||||
distribute_landed_cost_on_items(lcv)
|
||||
lcv.submit()
|
||||
|
||||
frappe.db.set_value("Company", company_a, "enable_perpetual_inventory", epi)
|
||||
frappe.db.set_value(
|
||||
"Company",
|
||||
company_a,
|
||||
{"enable_perpetual_inventory": epi, "default_inventory_account": old_inventory_account},
|
||||
)
|
||||
frappe.local.enable_perpetual_inventory = {}
|
||||
|
||||
def test_landed_cost_voucher_for_zero_purchase_rate(self):
|
||||
|
||||
@@ -3263,11 +3263,14 @@ class TestPurchaseReceipt(FrappeTestCase):
|
||||
|
||||
old_perpetual_inventory = erpnext.is_perpetual_inventory_enabled("_Test Company")
|
||||
frappe.local.enable_perpetual_inventory["_Test Company"] = 1
|
||||
old_inventory_account = frappe.db.get_value("Company", "_Test Company", "default_inventory_account")
|
||||
frappe.db.set_value(
|
||||
"Company",
|
||||
"_Test Company",
|
||||
"stock_received_but_not_billed",
|
||||
"Stock Received But Not Billed - _TC",
|
||||
{
|
||||
"stock_received_but_not_billed": "Stock Received But Not Billed - _TC",
|
||||
"default_inventory_account": "Stock In Hand - _TC",
|
||||
},
|
||||
)
|
||||
|
||||
pr = make_purchase_receipt(qty=10, rate=1000, do_not_submit=1)
|
||||
@@ -3296,13 +3299,14 @@ class TestPurchaseReceipt(FrappeTestCase):
|
||||
gl_entries = get_gl_entries("Purchase Receipt", pr.name, skip_cancelled=True, as_dict=False)
|
||||
warehouse_account = get_warehouse_account_map("_Test Company")
|
||||
expected_gle = (
|
||||
("Stock Received But Not Billed - _TC", 0, 10000, "Main - _TC"),
|
||||
("Freight and Forwarding Charges - _TC", 0, 2000, "Main - _TC"),
|
||||
("Expenses Included In Valuation - _TC", 0, 2000, "Main - _TC"),
|
||||
(warehouse_account[pr.items[0].warehouse]["account"], 14000, 0, "Main - _TC"),
|
||||
("Stock Received But Not Billed - _TC", 0.0, 10000.0, "Main - _TC"),
|
||||
("Freight and Forwarding Charges - _TC", 0.0, 2000.0, "Main - _TC"),
|
||||
("Expenses Included In Valuation - _TC", 0.0, 2000.0, "Main - _TC"),
|
||||
(warehouse_account[pr.items[0].warehouse]["account"], 14000.0, 0.0, "Main - _TC"),
|
||||
)
|
||||
self.assertSequenceEqual(expected_gle, gl_entries)
|
||||
self.assertCountEqual(expected_gle, gl_entries)
|
||||
frappe.local.enable_perpetual_inventory["_Test Company"] = old_perpetual_inventory
|
||||
frappe.db.set_value("Company", "_Test Company", "default_inventory_account", old_inventory_account)
|
||||
|
||||
def test_manufacturing_and_expiry_date_for_batch(self):
|
||||
item = make_item(
|
||||
|
||||
@@ -103,6 +103,44 @@ class TestWarehouse(FrappeTestCase):
|
||||
children = get_children("Warehouse", parent=company, company=company, is_root=True)
|
||||
self.assertTrue(any(wh["value"] == "_Test Warehouse - _TC" for wh in children))
|
||||
|
||||
def test_inventory_account_fallback_with_multiple_stock_accounts(self):
|
||||
from erpnext.stock import get_warehouse_account
|
||||
|
||||
company = create_inventory_fallback_company()
|
||||
frappe.db.set_value("Company", company, "default_inventory_account", None)
|
||||
if frappe.db.exists("Account", "Extra Inventory Account - _TCIF"):
|
||||
frappe.delete_doc("Account", "Extra Inventory Account - _TCIF")
|
||||
|
||||
warehouse = frappe.get_doc("Warehouse", {"company": company, "is_group": 0})
|
||||
single_account = frappe.db.get_value(
|
||||
"Account", {"account_type": "Stock", "is_group": 0, "company": company}, "name"
|
||||
)
|
||||
self.assertEqual(get_warehouse_account(warehouse), single_account)
|
||||
|
||||
create_account(
|
||||
account_name="Extra Inventory Account",
|
||||
parent_account=frappe.db.get_value("Account", single_account, "parent_account"),
|
||||
account_type="Stock",
|
||||
company=company,
|
||||
)
|
||||
self.assertRaises(frappe.ValidationError, get_warehouse_account, warehouse)
|
||||
|
||||
|
||||
def create_inventory_fallback_company():
|
||||
company = "_Test Company Inventory Fallback"
|
||||
if not frappe.db.exists("Company", company):
|
||||
frappe.get_doc(
|
||||
{
|
||||
"doctype": "Company",
|
||||
"company_name": company,
|
||||
"abbr": "_TCIF",
|
||||
"default_currency": "INR",
|
||||
"enable_perpetual_inventory": 0,
|
||||
"country": "India",
|
||||
}
|
||||
).insert(ignore_permissions=True)
|
||||
return company
|
||||
|
||||
|
||||
def create_warehouse(warehouse_name, properties=None, company=None):
|
||||
if not company:
|
||||
|
||||
Reference in New Issue
Block a user