-- Transfer belgesinin durum butonları: Confirm (Hazırla, taslakta), Check (Hazırla, bekleyende), Validate (Tamamla), Cancel (İptal Et), Return (İade Et). CREATE OR REPLACE PROCEDURE public."Stk_P_TransferSetStatus"(p_id uuid, p_action varchar, p_user_id uuid DEFAULT NULL) LANGUAGE plpgsql AS $$ DECLARE v_status varchar(16); v_kind varchar(32); v_src uuid; v_dst uuid; v_new uuid; BEGIN SELECT "Status", "OperationKind", "SourceLocationId", "DestinationLocationId" INTO v_status, v_kind, v_src, v_dst FROM "Stk_T_Transfer" WHERE "Id" = p_id; UPDATE "Stk_T_Transfer" SET "PendingAction" = NULL WHERE "Id" = p_id; -- İç transfer depo içinde taşımadır: iki uç da stok tutan iç konum olmalı (dış konuma giden mal stoktan düşer, hiçbir yere girmez). -- Kaynak ve hedef aynı olabilir: stok zaten teslim konumundaki talebin teslimidir (Planlama'nın Stoktan kararı), Doğrula stoğa dokunmaz. -- İade belgesi muaftır: yanlışlıkla dış konuma yapılmış transfer İade Et ile geri alınabilmeli. IF v_kind = 'InternalTransfer' AND p_action IN ('Confirm', 'Check', 'Validate') AND NOT EXISTS (SELECT 1 FROM "Stk_T_Transfer" WHERE "Id" = p_id AND "ReturnOfId" IS NOT NULL) THEN IF EXISTS (SELECT 1 FROM "Stk_T_Location" WHERE "Id" IN (v_src, v_dst) AND "LocationType" <> 'Internal') THEN RAISE EXCEPTION 'İç transferde kaynak ve hedef konum iç konum olmalıdır.' USING ERRCODE = 'P0001', DETAIL = '50326'; END IF; END IF; IF p_action = 'Confirm' THEN IF v_status <> 'Draft' THEN RAISE EXCEPTION 'Yalnız taslak belge hazırlanabilir.' USING ERRCODE = 'P0001', DETAIL = '50301'; END IF; IF NOT EXISTS (SELECT 1 FROM "Stk_T_TransferLine" WHERE "TransferId" = p_id AND "IsDeleted" = false) THEN RAISE EXCEPTION 'Ürün satırı olmayan belge hazırlanamaz.' USING ERRCODE = 'P0001', DETAIL = '50302'; END IF; IF v_src IS NULL OR v_dst IS NULL THEN RAISE EXCEPTION 'Kaynak ve hedef konum seçilmelidir.' USING ERRCODE = 'P0001', DETAIL = '50303'; END IF; CALL public."Stk_P_TransferCheckAvailability"(p_id); CALL public."Stk_P_TransferRecalc"(p_id); ELSIF p_action = 'Check' THEN IF v_status NOT IN ('Waiting', 'Ready') THEN RAISE EXCEPTION 'Stok kontrolü yalnız bekleyen ya da hazır belgede yapılır.' USING ERRCODE = 'P0001', DETAIL = '50305'; END IF; CALL public."Stk_P_TransferCheckAvailability"(p_id); CALL public."Stk_P_TransferRecalc"(p_id); ELSIF p_action = 'Validate' THEN IF v_status <> 'Ready' THEN RAISE EXCEPTION 'Yalnız hazır belge tamamlanabilir.' USING ERRCODE = 'P0001', DETAIL = '50306'; END IF; CALL public."Stk_P_TransferValidate"(p_id, p_user_id); ELSIF p_action = 'Cancel' THEN IF v_status IN ('Done', 'Cancelled') THEN RAISE EXCEPTION 'Tamamlanmış ya da iptal edilmiş belge iptal edilemez.' USING ERRCODE = 'P0001', DETAIL = '50307'; END IF; UPDATE "Stk_T_Transfer" SET "Status" = 'Cancelled' WHERE "Id" = p_id; -- İptal edilen transferin payı talep kalemine geri döner. CALL public."Prc_P_MaterialRequestItemSync"(p_id); ELSIF p_action = 'Return' THEN IF v_status <> 'Done' THEN RAISE EXCEPTION 'Yalnız tamamlanmış belge iade edilebilir.' USING ERRCODE = 'P0001', DETAIL = '50308'; END IF; IF EXISTS (SELECT 1 FROM "Stk_T_Transfer" WHERE "Id" = p_id AND "ReturnOfId" IS NOT NULL) THEN RAISE EXCEPTION 'İade belgesi yeniden iade edilemez; asıl belgeden yeni bir hareket açın.' USING ERRCODE = 'P0001', DETAIL = '50327'; END IF; CALL public."Stk_P_TransferCopy"(p_id, 'Return', p_user_id, v_new); END IF; END; $$;