94 lines
5.1 KiB
PL/PgSQL
94 lines
5.1 KiB
PL/PgSQL
-- 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, Purchase'da tedarikçi). Kaynak talebin teslim konumuysa karar
|
||
-- Stock'tur (transfer açılmaz, stoktan karşılanır). Belge açılmaz; onay
|
||
-- Prc_P_MaterialRequestPlanConfirm'dedir. Taslak toplamı planlanacak kalanı, konumun satırı 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): kalanın diğer taslak satırlardan
|
||
-- arta kalanı, konumda serbest 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_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;
|
||
|
||
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 "FreeQuantity" INTO v_free FROM public."Prc_V_MaterialRequestPlanSource" WHERE "BaseId" = v_item AND "LocationId" = v_target;
|
||
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 "FreeQuantity" INTO v_free FROM public."Prc_V_MaterialRequestPlanSource" WHERE "BaseId" = v_item AND "LocationId" = v_target;
|
||
IF v_free IS NULL THEN
|
||
RAISE EXCEPTION 'Kaynak konum ü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 yeterli serbest stok yok (serbest: % %).', 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",
|
||
"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_qty, NOW() AT TIME ZONE 'UTC', p_last_modifier_id, false);
|
||
END IF;
|
||
END;
|
||
$$;
|