mirror of
https://github.com/frappe/erpnext.git
synced 2026-09-16 18:24:10 +00:00
perf(stock): look up stock accounts once per company in the warehouse account map (#59056)
This commit is contained in:
@@ -30,14 +30,25 @@ def get_warehouse_account_map(company=None):
|
||||
filters["company"] = company
|
||||
frappe.flags.setdefault("warehouse_account_map", {}).setdefault(company, {})
|
||||
|
||||
for d in frappe.get_all(
|
||||
warehouses = frappe.get_all(
|
||||
"Warehouse",
|
||||
fields=["name", "account", "parent_warehouse", "company", "is_group"],
|
||||
filters=filters,
|
||||
order_by="lft, rgt",
|
||||
):
|
||||
)
|
||||
stock_accounts = {
|
||||
company_name: get_company_stock_accounts(company_name)
|
||||
for company_name in {d.company for d in warehouses if d.company and not d.account}
|
||||
}
|
||||
|
||||
for d in warehouses:
|
||||
if not d.account:
|
||||
d.account = get_warehouse_account(d, warehouse_account, raise_error=False)
|
||||
d.account = get_warehouse_account(
|
||||
d,
|
||||
warehouse_account,
|
||||
raise_error=False,
|
||||
stock_accounts=stock_accounts.get(d.company, []),
|
||||
)
|
||||
|
||||
if d.account:
|
||||
d.account_currency = frappe.db.get_value("Account", d.account, "account_currency", cache=True)
|
||||
@@ -53,7 +64,7 @@ def get_warehouse_account_map(company=None):
|
||||
return frappe.flags.warehouse_account_map
|
||||
|
||||
|
||||
def get_warehouse_account(warehouse, warehouse_account=None, *, raise_error=True):
|
||||
def get_warehouse_account(warehouse, warehouse_account=None, *, raise_error=True, stock_accounts=None):
|
||||
account = warehouse.account
|
||||
if not account and warehouse.parent_warehouse:
|
||||
if warehouse_account:
|
||||
@@ -79,12 +90,11 @@ def get_warehouse_account(warehouse, warehouse_account=None, *, raise_error=True
|
||||
account = get_company_default_inventory_account(warehouse.company)
|
||||
|
||||
if not account and warehouse.company:
|
||||
inventory_accounts = frappe.get_all(
|
||||
"Account", {"account_type": "Stock", "is_group": 0, "company": warehouse.company}, pluck="name"
|
||||
)
|
||||
if stock_accounts is None:
|
||||
stock_accounts = get_company_stock_accounts(warehouse.company)
|
||||
|
||||
if len(inventory_accounts) == 1:
|
||||
account = inventory_accounts[0]
|
||||
if len(stock_accounts) == 1:
|
||||
account = stock_accounts[0]
|
||||
|
||||
if raise_error and not account and warehouse.company and not warehouse.is_group:
|
||||
frappe.throw(
|
||||
@@ -97,3 +107,9 @@ def get_warehouse_account(warehouse, warehouse_account=None, *, raise_error=True
|
||||
|
||||
def get_company_default_inventory_account(company):
|
||||
return frappe.get_cached_value("Company", company, "default_inventory_account")
|
||||
|
||||
|
||||
def get_company_stock_accounts(company):
|
||||
return frappe.get_all(
|
||||
"Account", {"account_type": "Stock", "is_group": 0, "company": company}, pluck="name"
|
||||
)
|
||||
|
||||
@@ -227,6 +227,27 @@ class TestWarehouse(ERPNextTestSuite):
|
||||
|
||||
self.assertNotIn("account", warehouse.get_onload())
|
||||
|
||||
def test_stock_accounts_are_fetched_once_per_company(self):
|
||||
from unittest.mock import patch
|
||||
|
||||
from erpnext.stock import get_company_stock_accounts, get_warehouse_account_map
|
||||
|
||||
company, warehouse = create_ambiguous_inventory_account_warehouse()
|
||||
other_warehouse = frappe.get_all(
|
||||
"Warehouse",
|
||||
filters={"company": company, "is_group": 0, "name": ["!=", warehouse.name]},
|
||||
pluck="name",
|
||||
limit=1,
|
||||
)[0]
|
||||
frappe.db.set_value("Warehouse", other_warehouse, "account", None)
|
||||
|
||||
with patch(
|
||||
"erpnext.stock.get_company_stock_accounts", wraps=get_company_stock_accounts
|
||||
) as fetch_stock_accounts:
|
||||
get_warehouse_account_map(company)
|
||||
|
||||
fetch_stock_accounts.assert_called_once_with(company)
|
||||
|
||||
|
||||
def create_inventory_fallback_company():
|
||||
company = "_Test Company Inventory Fallback"
|
||||
|
||||
Reference in New Issue
Block a user