-- Planla diyaloğunun İç Transfer ızgarası (App.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 "Inv_T_Product" p ON p."Id" = i."ProductId" LEFT JOIN "Inv_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."Inv_F_UomConvert"(s."Quantity", s."UomId", it."UomId")) AS "OnHand", MIN(s."InDate") AS "FirstIn", MAX(s."InDate") AS "LastIn" FROM it INNER JOIN "Inv_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."Inv_F_UomConvert"(tl."DemandQuantity", tl."UomId", it."UomId")) AS "Quantity" FROM it INNER JOIN "Inv_T_TransferLine" tl ON tl."ProductId" = it."ProductId" AND tl."IsDeleted" = false INNER JOIN "Inv_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."Inv_F_UomConvert"(tll."Quantity", tl."UomId", it."UomId")) AS "Quantity" FROM it INNER JOIN "Inv_T_TransferLine" tl ON tl."ProductId" = it."ProductId" AND tl."IsDeleted" = false INNER JOIN "Inv_T_Transfer" t ON t."Id" = tl."TransferId" AND t."IsDeleted" = false AND t."Status" IN ('Draft', 'Waiting', 'Ready') INNER JOIN "Inv_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 "Inv_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;