80 lines
6.8 KiB
Transact-SQL
80 lines
6.8 KiB
Transact-SQL
-- 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).
|
||
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 Stk_T_Product p ON p.Id = i.ProductId
|
||
LEFT JOIN Stk_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.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 = 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.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 = 0
|
||
INNER JOIN Stk_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.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 = 0
|
||
INNER JOIN Stk_T_Transfer t ON t.Id = tl.TransferId AND t.IsDeleted = 0 AND t.Status IN ('Draft', 'Waiting', 'Ready')
|
||
INNER JOIN Stk_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 Stk_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
|