-- 1. Stock summary per jenis-grade-gudang SELECT it.name AS item_type, ig.name AS item_grade, w.name AS warehouse, SUM(il.available_qty) AS qty_total, SUM(il.available_qty * il.unit_cost) AS inventory_value, COUNT(*) FILTER (WHERE il.status = 'ACTIVE') AS active_lot_count FROM inventory_lots il JOIN item_types it ON it.id = il.item_type_id JOIN item_grades ig ON ig.id = il.item_grade_id JOIN warehouses w ON w.id = il.warehouse_id WHERE il.status = 'ACTIVE' GROUP BY it.name, ig.name, w.name ORDER BY it.name, ig.name, w.name; -- 2. Stock aging report SELECT il.lot_code, s.name AS supplier, it.name AS item_type, ig.name AS item_grade, il.available_qty, il.unit_cost, il.received_at, DATE_PART('day', NOW() - il.received_at) AS aging_days, il.status FROM inventory_lots il LEFT JOIN suppliers s ON s.id = il.supplier_id JOIN item_types it ON it.id = il.item_type_id JOIN item_grades ig ON ig.id = il.item_grade_id WHERE il.available_qty > 0 ORDER BY aging_days DESC; -- 3. Purchase history per supplier SELECT p.purchase_no, p.purchase_date, s.name AS supplier, COUNT(pl.id) AS total_lines, SUM(pl.subtotal) AS grand_total FROM purchases p JOIN suppliers s ON s.id = p.supplier_id JOIN purchase_lines pl ON pl.purchase_id = p.id GROUP BY p.id, p.purchase_no, p.purchase_date, s.name ORDER BY p.purchase_date DESC; -- 4. Sales margin report SELECT sa.sales_no, sa.sales_date, c.name AS customer, SUM(sl.subtotal) AS sales_total, SUM(sl.costing_total) AS costing_total, SUM(sl.gross_margin) AS gross_margin FROM sales sa JOIN customers c ON c.id = sa.customer_id JOIN sales_lines sl ON sl.sales_id = sa.id GROUP BY sa.id, sa.sales_no, sa.sales_date, c.name ORDER BY sa.sales_date DESC; -- 5. Supplier quality report berdasarkan hasil sortasi SELECT sup.name AS supplier, parent.lot_code AS source_lot, ss.input_qty, ss.output_qty, ss.shrinkage_qty, ROUND((ss.output_qty / NULLIF(ss.input_qty, 0)) * 100, 2) AS yield_percent FROM sorting_sessions ss JOIN inventory_lots parent ON parent.id = ss.source_lot_id LEFT JOIN suppliers sup ON sup.id = parent.supplier_id ORDER BY ss.sorting_date DESC; -- 6. Shrinkage report SELECT sa.adjustment_no, il.lot_code, sup.name AS supplier, it.name AS item_type, ig.name AS item_grade, ar.name AS reason, sa.qty_before, sa.qty_change, sa.qty_after, sa.cost_impact, sa.adjustment_date FROM stock_adjustments sa JOIN inventory_lots il ON il.id = sa.inventory_lot_id LEFT JOIN suppliers sup ON sup.id = il.supplier_id JOIN item_types it ON it.id = il.item_type_id JOIN item_grades ig ON ig.id = il.item_grade_id JOIN adjustment_reasons ar ON ar.id = sa.reason_id ORDER BY sa.adjustment_date DESC; -- 7. Traceability by sales SELECT s.sales_no, c.name AS customer, sl.id AS sales_line_id, it.name AS item_type, ig.name AS item_grade, sl.qty_sold, il.lot_code, sup.name AS supplier, sa.qty_allocated, sa.unit_cost, sa.total_cost, p.purchase_no FROM sales s JOIN customers c ON c.id = s.customer_id JOIN sales_lines sl ON sl.sales_id = s.id JOIN item_types it ON it.id = sl.item_type_id JOIN item_grades ig ON ig.id = sl.item_grade_id JOIN sales_allocations sa ON sa.sales_line_id = sl.id JOIN inventory_lots il ON il.id = sa.inventory_lot_id LEFT JOIN suppliers sup ON sup.id = il.supplier_id LEFT JOIN purchases p ON p.id = il.purchase_id ORDER BY s.sales_no, sl.id, il.lot_code; -- 8. Forward trace by lot SELECT il.lot_code, sup.name AS supplier, s.sales_no, c.name AS customer, sa.qty_allocated, sa.total_cost, s.sales_date FROM inventory_lots il JOIN sales_allocations sa ON sa.inventory_lot_id = il.id JOIN sales_lines sl ON sl.id = sa.sales_line_id JOIN sales s ON s.id = sl.sales_id JOIN customers c ON c.id = s.customer_id LEFT JOIN suppliers sup ON sup.id = il.supplier_id ORDER BY il.lot_code, s.sales_date; -- 9. Movement ledger per lot SELECT il.lot_code, im.movement_no, im.movement_type, im.qty_in, im.qty_out, im.balance_after, im.unit_cost, im.reference_type, im.reference_id, im.movement_date, u.name AS created_by FROM inventory_movements im JOIN inventory_lots il ON il.id = im.inventory_lot_id JOIN users u ON u.id = im.created_by ORDER BY il.lot_code, im.movement_date; -- 10. Top customer by sales value SELECT c.name AS customer, SUM(sl.subtotal) AS total_sales, SUM(sl.gross_margin) AS total_margin FROM sales s JOIN customers c ON c.id = s.customer_id JOIN sales_lines sl ON sl.sales_id = s.id GROUP BY c.name ORDER BY total_sales DESC;