-- Audit orphan stock_allocations (ACTIVE + CONSUME) -- Usage: -- psql -U app_lti_user -d db_lti_erp -f scripts/sql/orphan_allocations_audit.sql \pset pager off WITH active_alloc AS ( SELECT id, usable_type, usable_id, stockable_type, stockable_id, product_warehouse_id, qty FROM stock_allocations WHERE status = 'ACTIVE' AND allocation_purpose = 'CONSUME' AND deleted_at IS NULL ), orphan AS ( SELECT a.* FROM active_alloc a WHERE (a.usable_type = 'ADJUSTMENT_OUT' AND NOT EXISTS (SELECT 1 FROM adjustment_stocks ad WHERE ad.id = a.usable_id)) OR (a.usable_type = 'MARKETING_DELIVERY' AND NOT EXISTS (SELECT 1 FROM marketing_delivery_products mdp WHERE mdp.id = a.usable_id)) OR (a.usable_type = 'RECORDING_STOCK' AND NOT EXISTS ( SELECT 1 FROM recording_stocks rs JOIN recordings r ON r.id = rs.recording_id WHERE rs.id = a.usable_id AND r.deleted_at IS NULL )) OR (a.usable_type = 'RECORDING_DEPLETION' AND NOT EXISTS ( SELECT 1 FROM recording_depletions rd JOIN recordings r ON r.id = rd.recording_id WHERE rd.id = a.usable_id AND r.deleted_at IS NULL )) OR (a.usable_type = 'STOCKTRANSFER_OUT' AND NOT EXISTS ( SELECT 1 FROM stock_transfer_details std JOIN stock_transfers st ON st.id = std.stock_transfer_id WHERE std.id = a.usable_id AND std.deleted_at IS NULL AND st.deleted_at IS NULL )) OR (a.usable_type = 'TRANSFERTOLAYING_OUT' AND NOT EXISTS ( SELECT 1 FROM laying_transfers lt WHERE lt.id = a.usable_id AND lt.deleted_at IS NULL )) ) SELECT usable_type, COUNT(*) AS rows, COALESCE(SUM(qty),0) AS total_qty FROM orphan GROUP BY usable_type ORDER BY usable_type; -- Detail rows (limit) WITH active_alloc AS ( SELECT id, usable_type, usable_id, stockable_type, stockable_id, product_warehouse_id, qty FROM stock_allocations WHERE status = 'ACTIVE' AND allocation_purpose = 'CONSUME' AND deleted_at IS NULL ), orphan AS ( SELECT a.* FROM active_alloc a WHERE (a.usable_type = 'ADJUSTMENT_OUT' AND NOT EXISTS (SELECT 1 FROM adjustment_stocks ad WHERE ad.id = a.usable_id)) OR (a.usable_type = 'MARKETING_DELIVERY' AND NOT EXISTS (SELECT 1 FROM marketing_delivery_products mdp WHERE mdp.id = a.usable_id)) OR (a.usable_type = 'RECORDING_STOCK' AND NOT EXISTS ( SELECT 1 FROM recording_stocks rs JOIN recordings r ON r.id = rs.recording_id WHERE rs.id = a.usable_id AND r.deleted_at IS NULL )) OR (a.usable_type = 'RECORDING_DEPLETION' AND NOT EXISTS ( SELECT 1 FROM recording_depletions rd JOIN recordings r ON r.id = rd.recording_id WHERE rd.id = a.usable_id AND r.deleted_at IS NULL )) OR (a.usable_type = 'STOCKTRANSFER_OUT' AND NOT EXISTS ( SELECT 1 FROM stock_transfer_details std JOIN stock_transfers st ON st.id = std.stock_transfer_id WHERE std.id = a.usable_id AND std.deleted_at IS NULL AND st.deleted_at IS NULL )) OR (a.usable_type = 'TRANSFERTOLAYING_OUT' AND NOT EXISTS ( SELECT 1 FROM laying_transfers lt WHERE lt.id = a.usable_id AND lt.deleted_at IS NULL )) ) SELECT * FROM orphan ORDER BY usable_type, usable_id, id LIMIT 200;