sozsoft-platform/configs/seeds/postgres/object/Prc_P_MaterialRequestPlanLineSave.sql

99 lines
5.5 KiB
MySQL
Raw Normal View History

2026-10-19 14:35:08 +00:00
-- Planla diyaloğunun İç Transfer (Prc.MaterialRequestPlanSource) ve Satınalma (Prc.MaterialRequestPlanVendor) ızgaralarının satır kaydı:
2026-10-14 09:07:11 +00:00
-- 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.
2026-10-14 09:07:11 +00:00
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;
2026-10-14 09:07:11 +00:00
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;
2026-10-14 09:07:11 +00:00
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;
2026-10-14 09:07:11 +00:00
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;
2026-10-14 09:07:11 +00:00
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';
2026-10-14 09:07:11 +00:00
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';
2026-10-14 09:07:11 +00:00
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")
2026-10-14 09:07:11 +00:00
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);
2026-10-14 09:07:11 +00:00
END IF;
END;
$$;