diff --git a/custom_addons/dashboard/models/stock_dashboard.py b/custom_addons/dashboard/models/stock_dashboard.py index 7155af4f9..fae299ecb 100644 --- a/custom_addons/dashboard/models/stock_dashboard.py +++ b/custom_addons/dashboard/models/stock_dashboard.py @@ -16,111 +16,95 @@ class SamashtiDashboard(models.AbstractModel): toDate = "'"+str(to_date)+" 23:59:59'" sql = f""" - SELECT - pp.default_code AS product_code, - pt.name AS product_name, - pc.name AS category, - uom.name AS uom, - - -- Current Cost (from Valuation Layer) - COALESCE(( - SELECT SUM(svl.value) / NULLIF(SUM(svl.quantity), 0) - FROM stock_valuation_layer svl - WHERE svl.product_id = pp.id - ), 0) AS current_cost, - - -- Opening Stock (before start date) - COALESCE(SUM( - CASE - WHEN sml.create_date < {fromDate} - AND sl_dest.usage = 'internal' THEN sml.quantity - WHEN sml.create_date < {fromDate} - AND sl_src.usage = 'internal' THEN -sml.quantity - ELSE 0 - END - ), 0) AS opening_stock, - - -- Receipts (Supplier → Internal) - COALESCE(SUM( - CASE - WHEN sml.create_date BETWEEN {fromDate} AND {toDate} - AND sl_dest.usage = 'internal' - AND sl_src.usage in ('supplier', 'inventory') THEN sml.quantity - ELSE 0 - END - ), 0) AS receipts, - - -- Production (Production → Internal) - COALESCE(SUM( - CASE - WHEN sml.create_date BETWEEN {fromDate} AND {toDate} - AND sl_dest.usage = 'internal' - AND sl_src.usage = 'production' THEN sml.quantity - ELSE 0 - END - ), 0) AS production, - - -- Consumption (Internal → Production) - COALESCE(SUM( - CASE - WHEN sml.create_date BETWEEN {fromDate} AND {toDate} - AND sl_src.usage = 'internal' - AND sl_dest.usage = 'production' THEN sml.quantity - ELSE 0 - END - ), 0) AS consumption, - - -- Dispatch (Internal → Customer) - COALESCE(SUM( - CASE - WHEN sml.create_date BETWEEN {fromDate} AND {toDate} - AND sl_src.usage = 'internal' - AND sl_dest.usage = 'customer' THEN sml.quantity - ELSE 0 - END - ), 0) AS dispatch, - - -- Closing Stock = Opening + Receipts + Production - Consumption - Dispatch - ( - COALESCE(SUM( - CASE - WHEN sml.create_date < {fromDate} AND sl_dest.usage = 'internal' THEN sml.quantity - WHEN sml.create_date < {fromDate} AND sl_src.usage = 'internal' THEN -sml.quantity - WHEN sml.create_date BETWEEN {fromDate} AND {toDate} - AND sl_dest.usage = 'internal' AND sl_src.usage IN ('supplier', 'production') THEN sml.quantity - WHEN sml.create_date BETWEEN {fromDate} AND {toDate} - AND sl_src.usage = 'internal' AND sl_dest.usage IN ('production', 'customer') THEN -sml.quantity + SELECT + pp.default_code AS product_code, + pt.name AS product_name, + pc.name AS category, + uom.name AS uom, + + -- Opening Stock: includes inventory adjustments before fromDate + COALESCE(SUM(CASE + WHEN sm.date < {fromDate} AND sl_dest.usage = 'internal' THEN sm.product_uom_qty * (uom.factor /sm_uom.factor) + WHEN sm.date < {fromDate} AND sl_src.usage = 'internal' THEN -sm.product_uom_qty * (uom.factor /sm_uom.factor) + WHEN sm.date < {fromDate} AND (sl_src.usage = 'inventory' OR sl_dest.usage = 'inventory') THEN sm.product_uom_qty * (uom.factor /sm_uom.factor) ELSE 0 - END - ), 0) - ) AS closing_stock - - FROM - stock_move_line sml - JOIN - product_product pp ON sml.product_id = pp.id - JOIN - product_template pt ON pp.product_tmpl_id = pt.id - JOIN - product_category pc ON pt.categ_id = pc.id - JOIN - uom_uom uom ON pt.uom_id = uom.id - JOIN - stock_location sl_src ON sml.location_id = sl_src.id - JOIN - stock_location sl_dest ON sml.location_dest_id = sl_dest.id - - WHERE - sml.state = 'done' - AND pt.type IN ('product', 'consu') - AND sl_src.usage IN ('internal', 'supplier', 'production', 'customer','inventory') - AND sl_dest.usage IN ('internal', 'supplier', 'production', 'customer', 'inventory') - - GROUP BY - pp.default_code, pt.name, pc.name, uom.name, pp.id - - ORDER BY - pt.name; + END), 0) AS opening_stock, + + -- Receipts: from supplier and inventory adjustments in date range + COALESCE(SUM(CASE + WHEN sm.date BETWEEN {fromDate} AND {toDate} + AND sl_dest.usage = 'internal' + AND sl_src.usage in ('supplier','inventory') THEN sm.product_uom_qty * (uom.factor /sm_uom.factor) + WHEN sm.date BETWEEN {fromDate} AND {toDate} AND (sl_src.usage = 'inventory' OR sl_dest.usage = 'inventory') THEN sm.product_uom_qty * (uom.factor /sm_uom.factor) + ELSE 0 + END), 0) AS receipts, + + -- Production: internal moves from production + COALESCE(SUM(CASE + WHEN sm.date BETWEEN {fromDate} AND {toDate} + AND sl_dest.usage = 'internal' + AND sl_src.usage = 'production' THEN sm.product_uom_qty * (uom.factor /sm_uom.factor) + ELSE 0 + END), 0) AS production, + + -- Consumption: internal moves to production + COALESCE(SUM(CASE + WHEN sm.date BETWEEN {fromDate} AND {toDate} + AND sl_src.usage = 'internal' + AND sl_dest.usage = 'production' THEN sm.product_uom_qty * (uom.factor /sm_uom.factor) + ELSE 0 + END), 0) AS consumption, + + -- Dispatch: internal moves to customer + COALESCE(SUM(CASE + WHEN sm.date BETWEEN {fromDate} AND {toDate} + AND sl_src.usage = 'internal' + AND sl_dest.usage = 'customer' THEN sm.product_uom_qty * (uom.factor /sm_uom.factor) + ELSE 0 + END), 0) AS dispatch, + + -- Closing Stock = Opening + Receipts + Production - Consumption - Dispatch + Inventory adjustments + ( + COALESCE(SUM(CASE + WHEN sm.date < {fromDate} AND sl_dest.usage = 'internal' THEN sm.product_uom_qty * (uom.factor /sm_uom.factor) + WHEN sm.date < {fromDate} AND sl_src.usage = 'internal' THEN -sm.product_uom_qty * (uom.factor /sm_uom.factor) + WHEN sm.date < {fromDate} AND (sl_src.usage = 'inventory' OR sl_dest.usage = 'inventory') THEN sm.product_uom_qty * (uom.factor /sm_uom.factor) + WHEN sm.date BETWEEN {fromDate} AND {toDate} AND sl_dest.usage = 'internal' AND sl_src.usage IN ('supplier', 'production') THEN sm.product_uom_qty * (uom.factor /sm_uom.factor) + WHEN sm.date BETWEEN {fromDate} AND {toDate} AND (sl_src.usage = 'inventory' OR sl_dest.usage = 'inventory') THEN sm.product_uom_qty * (uom.factor /sm_uom.factor) + WHEN sm.date BETWEEN {fromDate} AND {toDate} AND sl_src.usage = 'internal' AND sl_dest.usage = 'production' THEN -sm.product_uom_qty * (uom.factor /sm_uom.factor) + WHEN sm.date BETWEEN {fromDate} AND {toDate} AND sl_src.usage = 'internal' AND sl_dest.usage = 'customer' THEN -sm.product_uom_qty * (uom.factor /sm_uom.factor) + ELSE 0 + END), 0) + ) AS closing_stock + + FROM + stock_move sm + JOIN + product_product pp ON sm.product_id = pp.id + JOIN + product_template pt ON pp.product_tmpl_id = pt.id + JOIN + product_category pc ON pt.categ_id = pc.id + JOIN + uom_uom uom ON pt.uom_id = uom.id -- Product default UOM + JOIN + uom_uom sm_uom ON sm.product_uom = sm_uom.id -- Stock move UOM + JOIN + stock_location sl_src ON sm.location_id = sl_src.id + JOIN + stock_location sl_dest ON sm.location_dest_id = sl_dest.id + + WHERE + sl_src.usage IN ('internal', 'supplier', 'production', 'customer', 'inventory') AND + sl_dest.usage IN ('internal', 'supplier', 'production', 'customer', 'inventory') AND + sm.state = 'done' AND + pt.type = 'consu' + + GROUP BY + pp.default_code, pt.name, pc.name, uom.name + + ORDER BY + pt.name; """ self.env.cr.execute(sql)