sozsoft-platform/configs/seeds/postgres/object/Prc_V_MaterialRequestPlanSource.sql
2026-10-19 17:35:08 +03:00

80 lines
6.8 KiB
SQL
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 ızgarası (Prc.MaterialRequestPlanSource) ve iç transfer / stoktan karşılama kararlarının stok kuralı:
-- talep kaleminin ürününün stoğu olan iç konumlar. Ürün lot/seri ile takip ediliyorsa satır konum × lottur (seride her seri ayrı satır), yoksa
-- konum başına tek satırdır (LotNo boş). Talebin teslim konumu da listelenir (IsDestination): oraya yazılan plan Stoktan kararıdır (PlanMethod =
-- Stock; kaynağı ve hedefi teslim konumu olan iç transfer açar). Miktarlar kalemin biriminde; ayrılan = açık (Taslak/Bekleyen/Hazır) transferlerde o konumdan istenen
-- (lot satırında o lota atanmış), serbest = eldeki − ayrılan, lot satırında konumun serbest stoğuyla sınırlı (lotu henüz atanmamış istek de
-- konumdan düşer). Plan Miktarı kalemin bu satır için taslak planıdır. BaseId diyaloğun süzdüğü kalem, Id kalem + ':' + konum + ':' + lottur
-- (Prc_P_MaterialRequestPlanLineSave ayırır); taslak kaydı ve onay serbest stoğu buradan okur.
-- AvailableQuantity satırın taslak planda kullanabileceği stoktur (aynı konumun diğer lotlarına yazılmış taslak konumdan düşer);
-- MaxQuantity bununla planlanacak kalandan kalemin diğer taslak satırları düşüldükten sonra kalanın küçüğüdür (ızgaranın doğrulaması; kayıt
-- yordamı aynı kuralı yeniden denetler). RemovalRank Öner'in ve Seçilenleri Planla'nın sırasıdır: teslim konumu önce, sonra ürün
-- kategorisinin çıkış stratejisi (FIFO: en eski giriş, LIFO: en yeni giriş; aynı anda girenlerde lot/seri no — LIFO'da büyükten; kategorisiz ürün FIFO).
DROP VIEW IF EXISTS public."Prc_V_MaterialRequestPlanSource";
CREATE VIEW public."Prc_V_MaterialRequestPlanSource" AS
WITH it AS (
SELECT i."Id", i."TenantId", i."ProductId", i."UomId", i."IsDeleted", r."LocationId" AS "DestinationId",
p."TrackInventory" AND p."TrackingMethod" IN ('Lot', 'Serial') AS "IsTracked",
COALESCE(pc."RemovalStrategy", 'FIFO') AS "RemovalStrategy"
FROM "Prc_T_MaterialRequestItem" i
INNER JOIN "Prc_T_MaterialRequest" r ON r."Id" = i."MaterialRequestId"
INNER JOIN "Stk_T_Product" p ON p."Id" = i."ProductId"
LEFT JOIN "Stk_T_ProductCategory" pc ON pc."Id" = p."CategoryId"
WHERE i."IsDeleted" = false),
st AS (
SELECT it."Id" AS "ItemId", s."LocationId", CASE WHEN it."IsTracked" THEN s."LotNo" ELSE '' END AS "LotNo",
SUM(public."Stk_F_UomConvert"(s."Quantity", s."UomId", it."UomId")) AS "OnHand", MIN(s."InDate") AS "FirstIn",
MAX(s."InDate") AS "LastIn"
FROM it
INNER JOIN "Stk_T_Stock" s ON s."ProductId" = it."ProductId" AND s."IsDeleted" = false
GROUP BY it."Id", s."LocationId", CASE WHEN it."IsTracked" THEN s."LotNo" ELSE '' END
HAVING SUM(s."Quantity") > 0),
rs AS (
SELECT it."Id" AS "ItemId", t."SourceLocationId" AS "LocationId",
SUM(public."Stk_F_UomConvert"(tl."DemandQuantity", tl."UomId", it."UomId")) AS "Quantity"
FROM it
INNER JOIN "Stk_T_TransferLine" tl ON tl."ProductId" = it."ProductId" AND tl."IsDeleted" = false
INNER JOIN "Stk_T_Transfer" t ON t."Id" = tl."TransferId" AND t."IsDeleted" = false AND t."Status" IN ('Draft', 'Waiting', 'Ready')
GROUP BY it."Id", t."SourceLocationId"),
lr AS (
SELECT it."Id" AS "ItemId", t."SourceLocationId" AS "LocationId", tll."LotNo",
SUM(public."Stk_F_UomConvert"(tll."Quantity", tl."UomId", it."UomId")) AS "Quantity"
FROM it
INNER JOIN "Stk_T_TransferLine" tl ON tl."ProductId" = it."ProductId" AND tl."IsDeleted" = false
INNER JOIN "Stk_T_Transfer" t ON t."Id" = tl."TransferId" AND t."IsDeleted" = false AND t."Status" IN ('Draft', 'Waiting', 'Ready')
INNER JOIN "Stk_T_TransferLineLot" tll ON tll."TransferLineId" = tl."Id" AND tll."IsDeleted" = false
WHERE it."IsTracked"
GROUP BY it."Id", t."SourceLocationId", tll."LotNo"),
b AS (
SELECT st."ItemId", st."LocationId", st."LotNo", st."OnHand", st."FirstIn", st."LastIn",
CASE WHEN it."IsTracked" THEN COALESCE(lr."Quantity", 0) ELSE COALESCE(rs."Quantity", 0) END AS "Reserved",
SUM(st."OnHand") OVER (PARTITION BY st."ItemId", st."LocationId") - COALESCE(rs."Quantity", 0) AS "LocationFree"
FROM st
INNER JOIN it ON it."Id" = st."ItemId"
LEFT JOIN rs ON rs."ItemId" = st."ItemId" AND rs."LocationId" = st."LocationId"
LEFT JOIN lr ON lr."ItemId" = st."ItemId" AND lr."LocationId" = st."LocationId" AND lr."LotNo" = st."LotNo")
SELECT CAST(it."Id" AS varchar(36)) || ':' || CAST(b."LocationId" AS varchar(36)) || ':' || b."LotNo" AS "Id", it."TenantId", it."Id" AS "BaseId",
l."BranchId", l."WarehouseId", b."LocationId", NULLIF(b."LotNo", '') AS "LotNo", b."OnHand", b."Reserved" AS "ReservedQuantity",
fr."Quantity" AS "FreeQuantity", it."UomId", pl."Quantity" AS "PlanQuantity", it."IsDeleted",
b."LocationId" = it."DestinationId" AS "IsDestination",
GREATEST(0, LEAST(av."Quantity", ip."RemainingQuantity" - COALESCE(od."Total", 0))) AS "MaxQuantity",
av."Quantity" AS "AvailableQuantity",
ROW_NUMBER() OVER (PARTITION BY it."Id"
ORDER BY CASE WHEN b."LocationId" = it."DestinationId" THEN 0 ELSE 1 END,
CASE WHEN it."RemovalStrategy" = 'LIFO' THEN NULL ELSE COALESCE(b."FirstIn", '9999-12-31') END,
CASE WHEN it."RemovalStrategy" = 'LIFO' THEN COALESCE(b."LastIn", '1900-01-01') END DESC NULLS LAST,
fr."Quantity" DESC,
CASE WHEN it."RemovalStrategy" = 'LIFO' THEN NULL ELSE b."LotNo" END,
CASE WHEN it."RemovalStrategy" = 'LIFO' THEN b."LotNo" END DESC NULLS LAST) AS "RemovalRank"
FROM b
INNER JOIN it ON it."Id" = b."ItemId"
INNER JOIN "Stk_T_Location" l ON l."Id" = b."LocationId" AND l."LocationType" = 'Internal' AND l."IsDeleted" = false
INNER JOIN public."Prc_V_MaterialRequestItemPlan" ip ON ip."Id" = it."Id"
LEFT JOIN "Prc_T_MaterialRequestPlanLine" pl
ON pl."MaterialRequestItemId" = it."Id" AND pl."PlanMethod" IN ('Transfer', 'Stock') AND pl."SourceLocationId" = b."LocationId"
AND pl."LotNo" = b."LotNo" AND pl."IsDeleted" = false
LEFT JOIN LATERAL (SELECT SUM(x."Quantity") AS "Total",
SUM(CASE WHEN x."SourceLocationId" = b."LocationId" THEN x."Quantity" ELSE 0 END) AS "SameLocation"
FROM "Prc_T_MaterialRequestPlanLine" x
WHERE x."MaterialRequestItemId" = it."Id" AND x."IsDeleted" = false AND x."Id" IS DISTINCT FROM pl."Id") od ON TRUE
CROSS JOIN LATERAL (SELECT LEAST(b."OnHand" - b."Reserved", b."LocationFree") AS "Quantity") fr
CROSS JOIN LATERAL (SELECT LEAST(fr."Quantity", b."LocationFree" - COALESCE(od."SameLocation", 0)) AS "Quantity") av;