sozsoft-platform/configs/seeds/postgres/object/Prc_P_MaterialRequestPlanLineSave.sql
2026-10-14 22:26:03 +03:00

98 lines
5.5 KiB
PL/PgSQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- Planla diyaloğunun İç Transfer (App.Prc.MaterialRequestPlanSource) ve Satınalma (App.Prc.MaterialRequestPlanVendor) ızgaralarının satır kaydı:
-- girilen Plan Miktarı kalemin taslak planına (Prc_T_MaterialRequestPlanLine) yazılır, 0 ya da boş satırı plandan çıkarır. p_id ızgara
-- satırının anahtarıdır: kalem + ':' + hedef (Transfer'de kaynak konum + ':' + lot — takipsiz üründe lot boş —, Purchase'da tedarikçi).
-- Kaynak talebin teslim konumuysa karar Stock'tur (Stoktan: kaynağı ve hedefi aynı iç transfer açılır). Belge açılmaz; onay
-- Prc_P_MaterialRequestPlanConfirm'dedir. Taslak toplamı planlanacak kalanı, satır kullanılabilir stoğu (Prc_V_MaterialRequestPlanSource
-- .AvailableQuantity: lotun ve konumun serbest stoğu) aşamaz. Batch kaydı satırları eşzamanlı gönderdiği için kalem kilitlenir. Eksi miktar
-- "alabileceği en fazla"dır (Seçilenleri Planla, Öner): kalanın diğer taslak satırlardan arta kalanı, kullanılabilir stokla sınırlı;
-- alınacak bir şey yoksa satır değişmez.
CREATE OR REPLACE PROCEDURE public."Prc_P_MaterialRequestPlanLineSave"(
p_id varchar,
p_plan_method varchar,
p_plan_quantity numeric(18, 4),
p_tenant_id uuid,
p_last_modifier_id uuid
)
LANGUAGE plpgsql AS $$
DECLARE v_item uuid := left(p_id, 36)::uuid;
v_target uuid := substring(p_id from 38 for 36)::uuid;
v_qty numeric(18, 4) := COALESCE(p_plan_quantity, 0);
v_lot varchar(64) := CASE WHEN p_plan_method = 'Purchase' THEN '' ELSE COALESCE(substring(p_id from 75 for 64), '') END;
v_method varchar(16) := p_plan_method; v_location uuid;
v_uom varchar(64); v_remaining numeric(18, 4); v_other numeric(18, 4); v_free numeric(18, 4); v_line uuid;
BEGIN
SELECT i."UomId", r."LocationId" INTO v_uom, v_location
FROM "Prc_T_MaterialRequestItem" i
INNER JOIN "Prc_T_MaterialRequest" r ON r."Id" = i."MaterialRequestId"
WHERE i."Id" = v_item AND i."IsDeleted" = false AND i."LineStatus" = 'Waiting' AND r."IsDeleted" = false
AND i."TenantId" IS NOT DISTINCT FROM p_tenant_id
AND r."ApprovalStatus" IN ('Onaylandı', 'Teklif Talebi', 'Teklif Talebi Gönderildi', 'Satınalma Siparişi')
FOR UPDATE OF i;
IF v_uom IS NULL THEN
RAISE EXCEPTION 'Kalem planlanamaz: talep onaylı değil ya da kalem kapalı.' USING ERRCODE = 'P0001', DETAIL = '50191';
END IF;
IF v_method = 'Transfer' AND v_target = v_location THEN
v_method := 'Stock';
END IF;
SELECT "Id" INTO v_line
FROM "Prc_T_MaterialRequestPlanLine"
WHERE "MaterialRequestItemId" = v_item AND "PlanMethod" = v_method AND "IsDeleted" = false
AND v_target = CASE WHEN v_method = 'Purchase' THEN "SupplierId" ELSE "SourceLocationId" END AND "LotNo" = v_lot;
IF v_qty = 0 THEN
DELETE FROM "Prc_T_MaterialRequestPlanLine" WHERE "Id" = v_line;
RETURN;
END IF;
SELECT "RemainingQuantity" INTO v_remaining FROM public."Prc_V_MaterialRequestItemPlan" WHERE "Id" = v_item;
SELECT COALESCE(SUM("Quantity"), 0) INTO v_other
FROM "Prc_T_MaterialRequestPlanLine"
WHERE "MaterialRequestItemId" = v_item AND "IsDeleted" = false AND "Id" IS DISTINCT FROM v_line;
IF v_qty < 0 THEN
v_qty := v_remaining - v_other;
IF v_method IN ('Transfer', 'Stock') THEN
SELECT "AvailableQuantity" INTO v_free FROM public."Prc_V_MaterialRequestPlanSource"
WHERE "BaseId" = v_item AND "LocationId" = v_target AND COALESCE("LotNo", '') = v_lot;
IF v_free < v_qty THEN
v_qty := v_free;
END IF;
END IF;
IF COALESCE(v_qty, 0) <= 0 THEN
RETURN;
END IF;
END IF;
IF v_other + v_qty > v_remaining THEN
RAISE EXCEPTION 'Taslak plan toplamı planlanacak kalanı aşamaz (kalan: % %).', trim_scale(v_remaining - v_other), v_uom
USING ERRCODE = 'P0001', DETAIL = '50200';
END IF;
IF v_method IN ('Transfer', 'Stock') THEN
SELECT "AvailableQuantity" INTO v_free FROM public."Prc_V_MaterialRequestPlanSource"
WHERE "BaseId" = v_item AND "LocationId" = v_target AND COALESCE("LotNo", '') = v_lot;
IF v_free IS NULL THEN
RAISE EXCEPTION 'Kaynak konum (lot/seri takipli üründe lot) ürünün stoğu olan bir iç konum olmalıdır.' USING ERRCODE = 'P0001', DETAIL = '50197';
END IF;
IF v_qty > v_free THEN
RAISE EXCEPTION 'Kaynak konumda (lotta) yeterli serbest stok yok (kullanılabilir: % %).', trim_scale(GREATEST(v_free, 0)), v_uom USING ERRCODE = 'P0001', DETAIL = '50198';
END IF;
ELSIF v_method = 'Purchase' THEN
IF NOT EXISTS (SELECT 1 FROM public."Prc_V_MaterialRequestPlanVendor" WHERE "BaseId" = v_item AND "ContactId" = v_target) THEN
RAISE EXCEPTION 'Satınalma kararında aktif bir tedarikçi seçilmelidir.' USING ERRCODE = 'P0001', DETAIL = '50194';
END IF;
ELSE
RAISE EXCEPTION 'Karar Satınalma ya da İç Transfer olmalıdır.' USING ERRCODE = 'P0001', DETAIL = '50192';
END IF;
IF v_line IS NOT NULL THEN
UPDATE "Prc_T_MaterialRequestPlanLine"
SET "Quantity" = v_qty, "LastModificationTime" = NOW() AT TIME ZONE 'UTC', "LastModifierId" = p_last_modifier_id
WHERE "Id" = v_line;
ELSE
INSERT INTO "Prc_T_MaterialRequestPlanLine" ("Id", "TenantId", "MaterialRequestItemId", "PlanMethod", "SupplierId", "SourceLocationId",
"LotNo", "Quantity", "CreationTime", "CreatorId", "IsDeleted")
VALUES (gen_random_uuid(), p_tenant_id, v_item, v_method, CASE WHEN v_method = 'Purchase' THEN v_target END,
CASE WHEN v_method <> 'Purchase' THEN v_target END, v_lot, v_qty, NOW() AT TIME ZONE 'UTC', p_last_modifier_id, false);
END IF;
END;
$$;