BEGIN; ALTER TABLE laying_transfers ADD COLUMN IF NOT EXISTS source_project_flock_kandang_id BIGINT, ADD COLUMN IF NOT EXISTS source_product_warehouse_id BIGINT, ADD COLUMN IF NOT EXISTS source_requested_qty NUMERIC(15,3) NOT NULL DEFAULT 0, ADD COLUMN IF NOT EXISTS source_usage_qty NUMERIC(15,3) NOT NULL DEFAULT 0, ADD COLUMN IF NOT EXISTS source_pending_usage_qty NUMERIC(15,3) NOT NULL DEFAULT 0; DO $$ BEGIN IF EXISTS (SELECT 1 FROM pg_tables WHERE tablename = 'project_flock_kandangs') AND NOT EXISTS ( SELECT 1 FROM pg_constraint WHERE conname = 'fk_laying_transfers_source_project_flock_kandang_id' ) THEN ALTER TABLE laying_transfers ADD CONSTRAINT fk_laying_transfers_source_project_flock_kandang_id FOREIGN KEY (source_project_flock_kandang_id) REFERENCES project_flock_kandangs(id) ON DELETE RESTRICT ON UPDATE CASCADE; END IF; IF EXISTS (SELECT 1 FROM pg_tables WHERE tablename = 'product_warehouses') AND NOT EXISTS ( SELECT 1 FROM pg_constraint WHERE conname = 'fk_laying_transfers_source_product_warehouse_id' ) THEN ALTER TABLE laying_transfers ADD CONSTRAINT fk_laying_transfers_source_product_warehouse_id FOREIGN KEY (source_product_warehouse_id) REFERENCES product_warehouses(id) ON DELETE SET NULL ON UPDATE CASCADE; END IF; END $$; CREATE INDEX IF NOT EXISTS idx_laying_transfers_source_project_flock_kandang_id ON laying_transfers(source_project_flock_kandang_id); CREATE INDEX IF NOT EXISTS idx_laying_transfers_source_product_warehouse_id ON laying_transfers(source_product_warehouse_id); WITH single_source AS ( SELECT lts.laying_transfer_id, MIN(lts.source_project_flock_kandang_id) AS source_project_flock_kandang_id, MIN(lts.product_warehouse_id) AS source_product_warehouse_id FROM laying_transfer_sources lts WHERE lts.deleted_at IS NULL GROUP BY lts.laying_transfer_id HAVING COUNT(*) = 1 ) UPDATE laying_transfers lt SET source_project_flock_kandang_id = ss.source_project_flock_kandang_id, source_product_warehouse_id = ss.source_product_warehouse_id FROM single_source ss WHERE lt.id = ss.laying_transfer_id AND (lt.source_project_flock_kandang_id IS NULL OR lt.source_project_flock_kandang_id = 0); WITH source_totals AS ( SELECT laying_transfer_id, COALESCE(SUM(requested_qty), 0) AS requested_qty, COALESCE(SUM(usage_qty), 0) AS usage_qty, COALESCE(SUM(pending_usage_qty), 0) AS pending_qty FROM laying_transfer_sources WHERE deleted_at IS NULL GROUP BY laying_transfer_id ) UPDATE laying_transfers lt SET source_requested_qty = CASE WHEN lt.source_requested_qty = 0 THEN st.requested_qty ELSE lt.source_requested_qty END, source_usage_qty = CASE WHEN lt.source_usage_qty = 0 THEN st.usage_qty ELSE lt.source_usage_qty END, source_pending_usage_qty = CASE WHEN lt.source_pending_usage_qty = 0 THEN st.pending_qty ELSE lt.source_pending_usage_qty END FROM source_totals st WHERE lt.id = st.laying_transfer_id; WITH target_totals AS ( SELECT laying_transfer_id, COALESCE(SUM(total_qty), 0) AS total_qty FROM laying_transfer_targets WHERE deleted_at IS NULL GROUP BY laying_transfer_id ) UPDATE laying_transfers lt SET source_requested_qty = tt.total_qty FROM target_totals tt WHERE lt.id = tt.laying_transfer_id AND (lt.source_requested_qty IS NULL OR lt.source_requested_qty = 0); INSERT INTO fifo_stock_v2_traits( source_table, lane, date_table, date_join_left_col, date_join_right_col, date_column, fallback_date_column, sort_priority, id_column ) VALUES ('laying_transfers', 'USABLE', NULL, NULL, NULL, 'transfer_date', NULL, 25, 'id') ON CONFLICT (source_table, lane) DO UPDATE SET date_table = EXCLUDED.date_table, date_join_left_col = EXCLUDED.date_join_left_col, date_join_right_col = EXCLUDED.date_join_right_col, date_column = EXCLUDED.date_column, fallback_date_column = EXCLUDED.fallback_date_column, sort_priority = EXCLUDED.sort_priority, id_column = EXCLUDED.id_column, is_active = TRUE; UPDATE fifo_stock_v2_traits SET is_active = FALSE WHERE source_table = 'laying_transfer_sources' AND lane = 'USABLE'; INSERT INTO fifo_stock_v2_route_rules( flag_group_code, lane, function_code, source_table, source_id_column, product_warehouse_col, quantity_col, used_quantity_col, pending_quantity_col, scope_sql, legacy_type_key, allow_pending_default, is_active ) VALUES ('AYAM', 'USABLE', 'TRANSFER_TO_LAYING_OUT', 'laying_transfers', 'id', 'source_product_warehouse_id', 'source_usage_qty', NULL, 'source_pending_usage_qty', 'deleted_at IS NULL', 'TRANSFERTOLAYING_OUT', TRUE, TRUE) ON CONFLICT (flag_group_code, lane, function_code, source_table) DO UPDATE SET source_id_column = EXCLUDED.source_id_column, product_warehouse_col = EXCLUDED.product_warehouse_col, quantity_col = EXCLUDED.quantity_col, used_quantity_col = EXCLUDED.used_quantity_col, pending_quantity_col = EXCLUDED.pending_quantity_col, scope_sql = EXCLUDED.scope_sql, legacy_type_key = EXCLUDED.legacy_type_key, allow_pending_default = EXCLUDED.allow_pending_default, is_active = TRUE, updated_at = NOW(); UPDATE fifo_stock_v2_route_rules SET is_active = FALSE, updated_at = NOW() WHERE flag_group_code = 'AYAM' AND lane = 'USABLE' AND function_code = 'TRANSFER_TO_LAYING_OUT' AND source_table = 'laying_transfer_sources'; COMMIT;