diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index a739956c837..61b0aabbe69 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -1053,7 +1053,7 @@ class StockController(AccountsController): for row in self.get("items"): qi_required = False - if inspection_required_fieldname and frappe.db.get_value( + if inspection_required_fieldname and frappe.get_cached_value( "Item", row.item_code, inspection_required_fieldname ): qi_required = True @@ -1769,7 +1769,7 @@ def get_conditions_to_validate_future_sle(sl_entries): for warehouse, items in warehouse_items_map.items(): or_conditions.append( f"""warehouse = {frappe.db.escape(warehouse)} - and item_code in ({', '.join(frappe.db.escape(item) for item in items)})""" + and item_code in ({", ".join(frappe.db.escape(item) for item in items)})""" ) return or_conditions diff --git a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py index 663e9cad955..e7aa5988f06 100644 --- a/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py +++ b/erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.py @@ -45,6 +45,7 @@ class TestStockReconciliation(IntegrationTestCase, StockTestMixin): def test_reco_for_moving_average(self): self._test_reco_sle_gle("Moving Average") + @IntegrationTestCase.change_settings("Stock Settings", {"allow_negative_stock": 1}) def _test_reco_sle_gle(self, valuation_method): item_code = self.make_item(properties={"valuation_method": valuation_method}).name diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index 60c7a9d7cd6..e8119f0c6bc 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -3,6 +3,7 @@ import json +import typing from functools import WRAPPER_ASSIGNMENTS, wraps import frappe @@ -366,7 +367,7 @@ def get_basic_details(ctx: ItemDetailsCtx, item, overwrite_warehouse=True) -> It """ if not item: - item = frappe.get_doc("Item", ctx.item_code) + item = frappe.get_cached_doc("Item", ctx.item_code) if item.variant_of and not item.taxes and frappe.db.exists("Item Tax", {"parent": item.variant_of}): item.update_template_tables() @@ -532,8 +533,8 @@ def get_basic_details(ctx: ItemDetailsCtx, item, overwrite_warehouse=True) -> It out.manufacturer_part_no = None out.manufacturer = None else: - data = frappe.get_value( - "Item", item.name, ["default_item_manufacturer", "default_manufacturer_part_no"], as_dict=1 + data = frappe.get_cached_value( + "Item", item.name, ["default_item_manufacturer", "default_manufacturer_part_no"], as_dict=True ) if data: @@ -1178,9 +1179,8 @@ def check_packing_list(price_list_rate_name, desired_qty, item_code): """ flag = True - item_price = frappe.get_doc("Item Price", price_list_rate_name) - if item_price.packing_unit: - packing_increment = desired_qty % item_price.packing_unit + if packing_unit := frappe.db.get_value("Item Price", price_list_rate_name, "packing_unit", cache=True): + packing_increment = desired_qty % packing_unit if packing_increment != 0: flag = False @@ -1317,15 +1317,20 @@ def get_pos_profile(company, pos_profile=None, user=None): @frappe.whitelist() def get_conversion_factor(item_code, uom): - variant_of = frappe.db.get_value("Item", item_code, "variant_of", cache=True) + item = frappe.get_cached_value("Item", item_code, ["variant_of", "stock_uom"], as_dict=True) + if not item_code or not item: + return {"conversion_factor": 1.0} + + if uom == item.stock_uom: + return {"conversion_factor": 1.0} + filters = {"parent": item_code, "uom": uom} - if variant_of: - filters["parent"] = ("in", (item_code, variant_of)) + if item.variant_of: + filters["parent"] = ("in", (item_code, item.variant_of)) conversion_factor = frappe.db.get_value("UOM Conversion Detail", filters, "conversion_factor") if not conversion_factor: - stock_uom = frappe.db.get_value("Item", item_code, "stock_uom") - conversion_factor = get_uom_conv_factor(uom, stock_uom) + conversion_factor = get_uom_conv_factor(uom, item.stock_uom) return {"conversion_factor": conversion_factor or 1.0} @@ -1447,7 +1452,7 @@ def apply_price_list(ctx: ItemDetailsCtx, as_doc=False, doc=None): def apply_price_list_on_item(ctx, doc=None): - item_doc = frappe.db.get_value("Item", ctx.item_code, ["name", "variant_of"], as_dict=1) + item_doc = frappe.get_cached_doc("Item", ctx.item_code) item_details = get_price_list_rate(ctx, item_doc) item_details.update(get_pricing_rule_for_item(ctx, doc=doc)) @@ -1515,7 +1520,6 @@ def get_valuation_rate(item_code, company, warehouse=None): item = get_item_defaults(item_code, company) item_group = get_item_group_defaults(item_code, company) brand = get_brand_defaults(item_code, company) - # item = frappe.get_doc("Item", item_code) if item.get("is_stock_item"): if not warehouse: warehouse = ( diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index 8a2541a8587..8d3c92c8736 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -2189,9 +2189,9 @@ def validate_reserved_batch_nos(item_code, warehouse, batch_nos): def is_negative_stock_allowed(*, item_code: str | None = None) -> bool: - if cint(frappe.db.get_single_value("Stock Settings", "allow_negative_stock", cache=True)): + if frappe.get_cached_doc("Stock Settings").allow_negative_stock: return True - if item_code and cint(frappe.db.get_value("Item", item_code, "allow_negative_stock", cache=True)): + if item_code and cint(frappe.get_cached_value("Item", item_code, "allow_negative_stock")): return True return False diff --git a/erpnext/stock/utils.py b/erpnext/stock/utils.py index 435acbe02c6..ab8f7a7d2dd 100644 --- a/erpnext/stock/utils.py +++ b/erpnext/stock/utils.py @@ -374,9 +374,9 @@ def get_avg_purchase_rate(serial_nos): def get_valuation_method(item_code): """get valuation method from item or default""" - val_method = frappe.db.get_value("Item", item_code, "valuation_method", cache=True) + val_method = frappe.get_cached_value("Item", item_code, "valuation_method") if not val_method: - val_method = frappe.db.get_single_value("Stock Settings", "valuation_method", cache=True) or "FIFO" + val_method = frappe.get_cached_doc("Stock Settings").valuation_method or "FIFO" return val_method