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

80 lines
6.8 KiB
Transact-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ı (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).
CREATE OR ALTER VIEW [dbo].[Prc_V_MaterialRequestPlanSource] AS
WITH it AS (
SELECT i.Id, i.TenantId, i.ProductId, i.UomId, i.IsDeleted, r.LocationId AS DestinationId,
CASE WHEN p.TrackInventory = 1 AND p.TrackingMethod IN ('Lot', 'Serial') THEN 1 ELSE 0 END AS IsTracked,
ISNULL(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 = 0),
st AS (
SELECT it.Id AS ItemId, s.LocationId, CASE WHEN it.IsTracked = 1 THEN s.LotNo ELSE '' END AS LotNo,
SUM(dbo.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 = 0
GROUP BY it.Id, s.LocationId, CASE WHEN it.IsTracked = 1 THEN s.LotNo ELSE '' END
HAVING SUM(s.Quantity) > 0),
rs AS (
SELECT it.Id AS ItemId, t.SourceLocationId AS LocationId, SUM(dbo.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 = 0
INNER JOIN Inv_T_Transfer t ON t.Id = tl.TransferId AND t.IsDeleted = 0 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(dbo.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 = 0
INNER JOIN Inv_T_Transfer t ON t.Id = tl.TransferId AND t.IsDeleted = 0 AND t.Status IN ('Draft', 'Waiting', 'Ready')
INNER JOIN Inv_T_TransferLineLot tll ON tll.TransferLineId = tl.Id AND tll.IsDeleted = 0
WHERE it.IsTracked = 1
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 = 1 THEN ISNULL(lr.Quantity, 0) ELSE ISNULL(rs.Quantity, 0) END AS Reserved,
SUM(st.OnHand) OVER (PARTITION BY st.ItemId, st.LocationId) - ISNULL(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 CONCAT(CAST(it.Id AS nvarchar(36)), ':', CAST(b.LocationId AS nvarchar(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,
CAST(CASE WHEN b.LocationId = it.DestinationId THEN 1 ELSE 0 END AS bit) AS IsDestination, mx.Quantity 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 ISNULL(b.FirstIn, '9999-12-31') END,
CASE WHEN it.RemovalStrategy = 'LIFO' THEN ISNULL(b.LastIn, '1900-01-01') END DESC,
fr.Quantity DESC,
CASE WHEN it.RemovalStrategy = 'LIFO' THEN NULL ELSE b.LotNo END,
CASE WHEN it.RemovalStrategy = 'LIFO' THEN b.LotNo END DESC) 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 = 0
INNER JOIN 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 = 0
OUTER APPLY (SELECT SUM(y.Quantity) AS Total, SUM(y.SameLocation) AS SameLocation
FROM (SELECT x.Quantity, 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 = 0 AND (pl.Id IS NULL OR x.Id <> pl.Id)) y) od
CROSS APPLY (SELECT CASE WHEN b.OnHand - b.Reserved < b.LocationFree THEN b.OnHand - b.Reserved ELSE b.LocationFree END AS Quantity) fr
CROSS APPLY (SELECT CASE WHEN fr.Quantity < b.LocationFree - ISNULL(od.SameLocation, 0) THEN fr.Quantity
ELSE b.LocationFree - ISNULL(od.SameLocation, 0) END AS Quantity) av
CROSS APPLY (SELECT CASE WHEN v.Quantity < 0 THEN 0 ELSE v.Quantity END AS Quantity
FROM (SELECT CASE WHEN av.Quantity < ip.RemainingQuantity - ISNULL(od.Total, 0) THEN av.Quantity
ELSE ip.RemainingQuantity - ISNULL(od.Total, 0) END AS Quantity) v) mx;
GO