-- Planla diyaloğunun İç Transfer (Prc.MaterialRequestPlanSource) ve Satınalma (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. @Id ızgara -- satırının anahtarıdır: kalem + ':' + hedef (Transfer'de kaynak konum + ':' + lot — takipsiz üründe lot boş —, Purchase'da tedarikçi). -- Kaynak talebin teslim konumuysa karar Stock'tur (Stoktan: kaynağı ve hedefi aynı iç transfer açılır). Belge açılmaz; onay -- Prc_P_MaterialRequestPlanConfirm'dedir. Taslak toplamı planlanacak kalanı, satır kullanılabilir stoğu (Prc_V_MaterialRequestPlanSource -- .AvailableQuantity: lotun ve konumun 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, Öner): kalanın diğer taslak satırlardan arta kalanı, kullanılabilir stokla sınırlı; -- alınacak bir şey yoksa satır değişmez. CREATE OR ALTER PROCEDURE [dbo].[Prc_P_MaterialRequestPlanLineSave] @Id nvarchar(160), @PlanMethod nvarchar(16), @PlanQuantity decimal(18, 4), @TenantId uniqueidentifier, @LastModifierId uniqueidentifier AS BEGIN SET NOCOUNT ON; SET XACT_ABORT ON; DECLARE @ItemId uniqueidentifier = TRY_CAST(LEFT(@Id, 36) AS uniqueidentifier), @Target uniqueidentifier = TRY_CAST(SUBSTRING(@Id, 38, 36) AS uniqueidentifier), @Lot nvarchar(64) = CASE WHEN @PlanMethod = 'Purchase' THEN '' ELSE ISNULL(SUBSTRING(@Id, 75, 64), '') END, @UomId nvarchar(64), @Location uniqueidentifier, @Remaining decimal(18, 4), @Other decimal(18, 4), @Free decimal(18, 4), @Line uniqueidentifier, @Qty decimal(18, 4) = ISNULL(@PlanQuantity, 0), @Msg nvarchar(400); BEGIN TRANSACTION; SELECT @UomId = i.UomId, @Location = r.LocationId FROM Prc_T_MaterialRequestItem i WITH (UPDLOCK, HOLDLOCK) INNER JOIN Prc_T_MaterialRequest r ON r.Id = i.MaterialRequestId WHERE i.Id = @ItemId AND i.IsDeleted = 0 AND i.LineStatus = 'Waiting' AND r.IsDeleted = 0 AND (i.TenantId = @TenantId OR (i.TenantId IS NULL AND @TenantId IS NULL)) AND r.ApprovalStatus IN (N'Onaylandı', N'Teklif Talebi', N'Teklif Talebi Gönderildi', N'Satınalma Siparişi'); IF @UomId IS NULL THROW 50191, N'Kalem planlanamaz: talep onaylı değil ya da kalem kapalı.', 1; IF @PlanMethod = 'Transfer' AND @Target = @Location SET @PlanMethod = 'Stock'; SELECT @Line = Id FROM Prc_T_MaterialRequestPlanLine WHERE MaterialRequestItemId = @ItemId AND PlanMethod = @PlanMethod AND IsDeleted = 0 AND @Target = CASE WHEN @PlanMethod = 'Purchase' THEN SupplierId ELSE SourceLocationId END AND LotNo = @Lot; IF @Qty = 0 BEGIN DELETE FROM Prc_T_MaterialRequestPlanLine WHERE Id = @Line; COMMIT TRANSACTION; RETURN; END SELECT @Remaining = RemainingQuantity FROM Prc_V_MaterialRequestItemPlan WHERE Id = @ItemId; SELECT @Other = ISNULL(SUM(Quantity), 0) FROM Prc_T_MaterialRequestPlanLine WHERE MaterialRequestItemId = @ItemId AND IsDeleted = 0 AND (@Line IS NULL OR Id <> @Line); IF @Qty < 0 BEGIN SET @Qty = @Remaining - @Other; IF @PlanMethod IN ('Transfer', 'Stock') BEGIN SELECT @Free = AvailableQuantity FROM Prc_V_MaterialRequestPlanSource WHERE BaseId = @ItemId AND LocationId = @Target AND ISNULL(LotNo, '') = @Lot; IF @Free < @Qty SET @Qty = @Free; END IF ISNULL(@Qty, 0) <= 0 BEGIN COMMIT TRANSACTION; RETURN; END END IF @Other + @Qty > @Remaining BEGIN SET @Msg = CONCAT(N'Taslak plan toplamı planlanacak kalanı aşamaz (kalan: ', FORMAT(@Remaining - @Other, '0.####'), N' ', @UomId, N').'); THROW 50200, @Msg, 1; END IF @PlanMethod IN ('Transfer', 'Stock') BEGIN SELECT @Free = AvailableQuantity FROM Prc_V_MaterialRequestPlanSource WHERE BaseId = @ItemId AND LocationId = @Target AND ISNULL(LotNo, '') = @Lot; IF @Free IS NULL THROW 50197, N'Kaynak konum (lot/seri takipli üründe lot) ürünün stoğu olan bir iç konum olmalıdır.', 1; IF @Qty > @Free BEGIN SET @Msg = CONCAT(N'Kaynak konumda (lotta) yeterli serbest stok yok (kullanılabilir: ', FORMAT(CASE WHEN @Free > 0 THEN @Free ELSE 0 END, '0.####'), N' ', @UomId, N').'); THROW 50198, @Msg, 1; END END ELSE IF @PlanMethod = 'Purchase' BEGIN IF NOT EXISTS (SELECT 1 FROM Prc_V_MaterialRequestPlanVendor WHERE BaseId = @ItemId AND ContactId = @Target) THROW 50194, N'Satınalma kararında aktif bir tedarikçi seçilmelidir.', 1; END ELSE THROW 50192, N'Karar Satınalma ya da İç Transfer olmalıdır.', 1; IF @Line IS NOT NULL UPDATE Prc_T_MaterialRequestPlanLine SET Quantity = @Qty, LastModificationTime = GETUTCDATE(), LastModifierId = @LastModifierId WHERE Id = @Line; ELSE INSERT INTO Prc_T_MaterialRequestPlanLine (Id, TenantId, MaterialRequestItemId, PlanMethod, SupplierId, SourceLocationId, LotNo, Quantity, CreationTime, CreatorId, IsDeleted) VALUES (NEWID(), @TenantId, @ItemId, @PlanMethod, CASE WHEN @PlanMethod = 'Purchase' THEN @Target END, CASE WHEN @PlanMethod <> 'Purchase' THEN @Target END, @Lot, @Qty, GETUTCDATE(), @LastModifierId, 0); COMMIT TRANSACTION; END GO