refactor: bom stock report

(cherry picked from commit ee4e0c646d)
This commit is contained in:
Mihir Kandoi
2025-06-24 17:40:41 +05:30
committed by Mergify
parent 1ea3daeb17
commit ce7dbf3090

View File

@@ -1,12 +1,10 @@
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors # Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt # For license information, please see license.txt
import frappe import frappe
from frappe import _ from frappe import _
from frappe.query_builder.functions import Floor, Sum from frappe.query_builder.functions import Floor, Sum
from frappe.utils import cint from frappe.utils import cint
from pypika.terms import ExistsCriterion
def execute(filters=None): def execute(filters=None):
@@ -20,8 +18,7 @@ def execute(filters=None):
def get_columns(): def get_columns():
"""return columns""" return [
columns = [
_("Item") + ":Link/Item:150", _("Item") + ":Link/Item:150",
_("Item Name") + "::240", _("Item Name") + "::240",
_("Description") + "::300", _("Description") + "::300",
@@ -32,55 +29,54 @@ def get_columns():
_("Enough Parts to Build") + ":Float:200", _("Enough Parts to Build") + ":Float:200",
] ]
return columns
def get_bom_stock(filters): def get_bom_stock(filters):
qty_to_produce = filters.get("qty_to_produce") qty_to_produce = filters.get("qty_to_produce")
if cint(qty_to_produce) <= 0: if cint(qty_to_produce) <= 0:
frappe.throw(_("Quantity to Produce should be greater than zero.")) frappe.throw(_("Quantity to Produce should be greater than zero."))
if filters.get("show_exploded_view"): bom_item_table = "BOM Explosion Item" if filters.get("show_exploded_view") else "BOM Item"
bom_item_table = "BOM Explosion Item"
else:
bom_item_table = "BOM Item"
warehouse_details = frappe.db.get_value("Warehouse", filters.get("warehouse"), ["lft", "rgt"], as_dict=1) warehouse = filters.get("warehouse")
warehouse_details = frappe.db.get_value("Warehouse", warehouse, ["lft", "rgt"], as_dict=1)
BOM = frappe.qb.DocType("BOM") BOM = frappe.qb.DocType("BOM")
BOM_ITEM = frappe.qb.DocType(bom_item_table) BOM_ITEM = frappe.qb.DocType(bom_item_table)
BIN = frappe.qb.DocType("Bin") BIN = frappe.qb.DocType("Bin")
WH = frappe.qb.DocType("Warehouse") WH = frappe.qb.DocType("Warehouse")
CONDITIONS = ()
if warehouse_details: if warehouse_details:
CONDITIONS = ExistsCriterion( bin_subquery = (
frappe.qb.from_(WH) frappe.qb.from_(BIN)
.select(WH.name) .join(WH)
.where( .on(BIN.warehouse == WH.name)
(WH.lft >= warehouse_details.lft) .select(BIN.item_code, Sum(BIN.actual_qty).as_("actual_qty"))
& (WH.rgt <= warehouse_details.rgt) .where((WH.lft >= warehouse_details.lft) & (WH.rgt <= warehouse_details.rgt))
& (BIN.warehouse == WH.name) .groupby(BIN.item_code)
)
) )
else: else:
CONDITIONS = BIN.warehouse == filters.get("warehouse") bin_subquery = (
frappe.qb.from_(BIN)
.select(BIN.item_code, Sum(BIN.actual_qty).as_("actual_qty"))
.where(BIN.warehouse == warehouse)
.groupby(BIN.item_code)
)
QUERY = ( QUERY = (
frappe.qb.from_(BOM) frappe.qb.from_(BOM)
.inner_join(BOM_ITEM) .join(BOM_ITEM)
.on(BOM.name == BOM_ITEM.parent) .on(BOM.name == BOM_ITEM.parent)
.left_join(BIN) .left_join(bin_subquery)
.on((BOM_ITEM.item_code == BIN.item_code) & (CONDITIONS)) .on(BOM_ITEM.item_code == bin_subquery.item_code)
.select( .select(
BOM_ITEM.item_code, BOM_ITEM.item_code,
BOM_ITEM.item_name, BOM_ITEM.item_name,
BOM_ITEM.description, BOM_ITEM.description,
BOM_ITEM.stock_qty, Sum(BOM_ITEM.stock_qty),
BOM_ITEM.stock_uom, BOM_ITEM.stock_uom,
BOM_ITEM.stock_qty * qty_to_produce / BOM.quantity, (Sum(BOM_ITEM.stock_qty) * qty_to_produce) / BOM.quantity,
BIN.actual_qty.as_("actual_qty"), bin_subquery.actual_qty,
Sum(Floor(BIN.actual_qty / (BOM_ITEM.stock_qty * qty_to_produce / BOM.quantity))), Floor(bin_subquery.actual_qty / ((Sum(BOM_ITEM.stock_qty) * qty_to_produce) / BOM.quantity)),
) )
.where((BOM_ITEM.parent == filters.get("bom")) & (BOM_ITEM.parenttype == "BOM")) .where((BOM_ITEM.parent == filters.get("bom")) & (BOM_ITEM.parenttype == "BOM"))
.groupby(BOM_ITEM.item_code) .groupby(BOM_ITEM.item_code)