183 lines
11 KiB
MySQL
183 lines
11 KiB
MySQL
|
|
-- Planlama kararı: talep kaleminin planlanacak kalanından @PlanQuantity kadarını satınalmaya ya da iç transfere ayırır; kalanın geri kalanı
|
|||
|
|
-- listede kalır. Planla diyaloğunun onayı (Prc_P_MaterialRequestPlanConfirm) her taslak plan satırı için çağırır.
|
|||
|
|
-- Purchase: tedarikçinin talebin şubesi ve deposu için taslak teklif talebi varsa kalem ona eklenir (kalem zaten oradaysa miktarı artar), yoksa
|
|||
|
|
-- talebin deposunun alım operasyon türüyle yeni taslak teklif talebi açılır (para birimi ve koşullar kontak kartından; alıcı — satınalma sorumlusu —
|
|||
|
|
-- planlayan). Fiyat tedarikçinin fiyat listesinden gelir; teklif → sipariş → alım akışı oradan sürer.
|
|||
|
|
-- Transfer: kaynak konumun serbest stoğu (Prc_V_MaterialRequestPlanSource) yetmelidir; aynı kaynak → talebin konumu için onaya
|
|||
|
|
-- girmemiş taslak iç transfer varsa satır ona, yoksa kaynak deponun iç transfer operasyon türüyle yeni taslak açılır. Kalanın tamamı transferle
|
|||
|
|
-- planlanan, satınalma payı olmayan kalem transfer belgesinin yeniden hesabında kapanır (Prc_P_MaterialRequestItemSync).
|
|||
|
|
-- Stock: stok talebin teslim konumundadır; belge açılmaz, serbest stok yetmelidir. Miktar kalemin stoktan karşılanan ve teslim edilen
|
|||
|
|
-- miktarına eklenir; satınalma payı olmayan ve kalanı biten kalem kapanır.
|
|||
|
|
CREATE OR ALTER PROCEDURE [dbo].[Prc_P_MaterialRequestPlan]
|
|||
|
|
@Id uniqueidentifier,
|
|||
|
|
@PlanMethod nvarchar(16),
|
|||
|
|
@PlanQuantity decimal(18, 4),
|
|||
|
|
@PlanSupplierId uniqueidentifier,
|
|||
|
|
@PlanSourceLocationId uniqueidentifier,
|
|||
|
|
@TenantId uniqueidentifier,
|
|||
|
|
@LastModifierId uniqueidentifier
|
|||
|
|
AS
|
|||
|
|
BEGIN
|
|||
|
|
SET NOCOUNT ON;
|
|||
|
|
SET XACT_ABORT ON;
|
|||
|
|
DECLARE @ProductId uniqueidentifier, @UomId nvarchar(64), @DueDate datetime, @Reason nvarchar(256), @Branch uniqueidentifier,
|
|||
|
|
@Warehouse uniqueidentifier, @Location uniqueidentifier, @RequestNo nvarchar(32), @Remaining decimal(18, 4),
|
|||
|
|
@Doc uniqueidentifier, @Line uniqueidentifier, @OpType uniqueidentifier, @SrcWarehouse uniqueidentifier,
|
|||
|
|
@Free decimal(18, 4), @No nvarchar(128), @Msg nvarchar(400);
|
|||
|
|
|
|||
|
|
BEGIN TRANSACTION;
|
|||
|
|
|
|||
|
|
-- Kalem kilitlenir: aynı kalemin eşzamanlı iki planı kalanı iki kez dağıtamaz.
|
|||
|
|
SELECT @ProductId = i.ProductId, @UomId = i.UomId, @DueDate = i.DueDate, @Reason = i.RequestReason, @Branch = r.BranchId,
|
|||
|
|
@Warehouse = r.WarehouseId, @Location = r.LocationId, @RequestNo = r.RequestNo
|
|||
|
|
FROM Prc_T_MaterialRequestItem i WITH (UPDLOCK, HOLDLOCK)
|
|||
|
|
INNER JOIN Prc_T_MaterialRequest r ON r.Id = i.MaterialRequestId
|
|||
|
|
WHERE i.Id = @Id 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 @ProductId IS NULL
|
|||
|
|
THROW 50191, N'Kalem planlanamaz: talep onaylı değil ya da kalem kapalı.', 1;
|
|||
|
|
|
|||
|
|
SELECT @Remaining = RemainingQuantity FROM Prc_V_MaterialRequestItemPlan WHERE Id = @Id;
|
|||
|
|
IF ISNULL(@PlanQuantity, 0) <= 0
|
|||
|
|
THROW 50192, N'Plan miktarı sıfırdan büyük olmalıdır.', 1;
|
|||
|
|
IF @PlanQuantity > @Remaining
|
|||
|
|
BEGIN
|
|||
|
|
SET @Msg = CONCAT(N'Plan miktarı planlanacak kalanı aşamaz (kalan: ', FORMAT(@Remaining, '0.####'), N' ', @UomId, N').');
|
|||
|
|
THROW 50193, @Msg, 1;
|
|||
|
|
END
|
|||
|
|
|
|||
|
|
IF @PlanMethod = 'Purchase'
|
|||
|
|
BEGIN
|
|||
|
|
IF @PlanSupplierId IS NULL
|
|||
|
|
THROW 50194, N'Satınalma kararında tedarikçi seçilmelidir.', 1;
|
|||
|
|
|
|||
|
|
SELECT TOP 1 @Doc = Id
|
|||
|
|
FROM Prc_T_PurchaseRfq
|
|||
|
|
WHERE IsDeleted = 0 AND Status = 'Draft' AND SupplierId = @PlanSupplierId AND BranchId = @Branch AND WarehouseId = @Warehouse
|
|||
|
|
AND (TenantId = @TenantId OR (TenantId IS NULL AND @TenantId IS NULL))
|
|||
|
|
ORDER BY CreationTime DESC;
|
|||
|
|
|
|||
|
|
IF @Doc IS NULL
|
|||
|
|
BEGIN
|
|||
|
|
SELECT TOP 1 @OpType = Id
|
|||
|
|
FROM Inv_T_OperationType
|
|||
|
|
WHERE IsDeleted = 0 AND IsActive = 1 AND OperationKind = 'Receipt' AND WarehouseId = @Warehouse
|
|||
|
|
ORDER BY Name;
|
|||
|
|
IF @OpType IS NULL
|
|||
|
|
THROW 50195, N'Talebin deposu için aktif bir alım operasyon türü tanımlı değil.', 1;
|
|||
|
|
|
|||
|
|
SET @Doc = NEWID();
|
|||
|
|
EXEC Adm_P_SequenceNext N'Prc.PurchaseRfq', @TenantId, @No OUTPUT;
|
|||
|
|
INSERT INTO Prc_T_PurchaseRfq (Id, TenantId, RfqNo, TenderGroupId, SupplierId, BranchId, OperationTypeId, WarehouseId, CurrencyId,
|
|||
|
|
BuyerUserId, IncotermId, IncotermLocation, PaymentTermId, CreationTime, CreatorId, IsDeleted)
|
|||
|
|
SELECT @Doc, @TenantId, LEFT(@No, 32), @Doc, c.Id, @Branch, @OpType, @Warehouse, COALESCE(c.SupplierCurrency, 'TRY'),
|
|||
|
|
@LastModifierId, c.PurchaseIncotermId, c.PurchaseIncotermLocation, c.PurchasePaymentTermId,
|
|||
|
|
GETUTCDATE(), @LastModifierId, 0
|
|||
|
|
FROM Adm_T_Contact c
|
|||
|
|
WHERE c.Id = @PlanSupplierId AND c.IsDeleted = 0;
|
|||
|
|
IF @@ROWCOUNT = 0
|
|||
|
|
THROW 50194, N'Satınalma kararında tedarikçi seçilmelidir.', 1;
|
|||
|
|
END
|
|||
|
|
|
|||
|
|
SELECT @Line = Id FROM Prc_T_PurchaseRfqLine WHERE PurchaseRfqId = @Doc AND MaterialRequestItemId = @Id AND IsDeleted = 0;
|
|||
|
|
IF @Line IS NOT NULL
|
|||
|
|
UPDATE Prc_T_PurchaseRfqLine
|
|||
|
|
SET Quantity = Quantity + dbo.Inv_F_UomConvert(@PlanQuantity, @UomId, UomId), LastModificationTime = GETUTCDATE(), LastModifierId = @LastModifierId
|
|||
|
|
WHERE Id = @Line;
|
|||
|
|
ELSE
|
|||
|
|
INSERT INTO Prc_T_PurchaseRfqLine (Id, TenantId, PurchaseRfqId, ProductId, Description, Quantity, UomId, UnitPrice, TaxRate, Amount,
|
|||
|
|
DeliveryDate, MaterialRequestItemId, CreationTime, CreatorId, IsDeleted)
|
|||
|
|
SELECT NEWID(), @TenantId, @Doc, @ProductId, @Reason, @PlanQuantity, @UomId,
|
|||
|
|
ISNULL((SELECT TOP 1 ps.Price FROM Inv_T_ProductSupplier ps
|
|||
|
|
WHERE ps.ProductId = @ProductId AND ps.ContactId = @PlanSupplierId AND ps.IsDeleted = 0
|
|||
|
|
ORDER BY ps.MinQuantity), 0),
|
|||
|
|
ISNULL(p.PurchaseTaxRate, 0), 0, @DueDate, @Id, GETUTCDATE(), @LastModifierId, 0
|
|||
|
|
FROM Inv_T_Product p
|
|||
|
|
WHERE p.Id = @ProductId;
|
|||
|
|
|
|||
|
|
EXEC Prc_P_PurchaseRfqRecalc @Doc;
|
|||
|
|
END
|
|||
|
|
ELSE IF @PlanMethod = 'Transfer'
|
|||
|
|
BEGIN
|
|||
|
|
IF @PlanSourceLocationId IS NULL
|
|||
|
|
THROW 50196, N'İç transfer kararında kaynak konum seçilmelidir.', 1;
|
|||
|
|
-- Konum ve serbest stok kuralı diyaloğun İç Transfer ızgarasıyla aynıdır.
|
|||
|
|
SELECT @SrcWarehouse = WarehouseId, @Free = FreeQuantity
|
|||
|
|
FROM Prc_V_MaterialRequestPlanSource
|
|||
|
|
WHERE BaseId = @Id AND LocationId = @PlanSourceLocationId;
|
|||
|
|
IF @SrcWarehouse IS NULL OR @PlanSourceLocationId = @Location
|
|||
|
|
THROW 50197, N'Kaynak konum, talebin teslim konumundan farklı ve ürünün stoğu olan bir iç konum olmalıdır.', 1;
|
|||
|
|
IF @PlanQuantity > @Free
|
|||
|
|
BEGIN
|
|||
|
|
SET @Msg = CONCAT(N'Kaynak konumda yeterli serbest stok yok (serbest: ', FORMAT(CASE WHEN @Free > 0 THEN @Free ELSE 0 END, '0.####'), N' ', @UomId, N').');
|
|||
|
|
THROW 50198, @Msg, 1;
|
|||
|
|
END
|
|||
|
|
|
|||
|
|
SELECT TOP 1 @Doc = Id
|
|||
|
|
FROM Inv_T_Transfer
|
|||
|
|
WHERE IsDeleted = 0 AND OperationKind = 'InternalTransfer' AND Status = 'Draft' AND ReturnOfId IS NULL AND BackorderOfId IS NULL
|
|||
|
|
AND SourceLocationId = @PlanSourceLocationId AND DestinationLocationId = @Location
|
|||
|
|
AND ISNULL(ApprovalStatus, N'Onay Gerekmez') = N'Onay Gerekmez'
|
|||
|
|
AND (TenantId = @TenantId OR (TenantId IS NULL AND @TenantId IS NULL))
|
|||
|
|
ORDER BY CreationTime DESC;
|
|||
|
|
|
|||
|
|
IF @Doc IS NULL
|
|||
|
|
BEGIN
|
|||
|
|
SELECT TOP 1 @OpType = Id
|
|||
|
|
FROM Inv_T_OperationType
|
|||
|
|
WHERE IsDeleted = 0 AND IsActive = 1 AND OperationKind = 'InternalTransfer' AND WarehouseId = @SrcWarehouse
|
|||
|
|
ORDER BY Name;
|
|||
|
|
IF @OpType IS NULL
|
|||
|
|
THROW 50199, N'Kaynak depo için aktif bir iç transfer operasyon türü tanımlı değil.', 1;
|
|||
|
|
|
|||
|
|
SET @Doc = NEWID();
|
|||
|
|
INSERT INTO Inv_T_Transfer (Id, TenantId, BranchId, WarehouseId, OperationTypeId, OperationKind, SourceLocationId, DestinationLocationId,
|
|||
|
|
SourceDocument, ResponsibleUserId, Status, CreationTime, CreatorId, IsDeleted)
|
|||
|
|
SELECT @Doc, @TenantId, ot.BranchId, ot.WarehouseId, ot.Id, 'InternalTransfer', @PlanSourceLocationId, @Location,
|
|||
|
|
@RequestNo, @LastModifierId, 'Draft', GETUTCDATE(), @LastModifierId, 0
|
|||
|
|
FROM Inv_T_OperationType ot
|
|||
|
|
WHERE ot.Id = @OpType;
|
|||
|
|
END
|
|||
|
|
ELSE
|
|||
|
|
UPDATE Inv_T_Transfer
|
|||
|
|
SET SourceDocument = LEFT(CONCAT(SourceDocument, CASE WHEN ISNULL(SourceDocument, '') = '' THEN '' ELSE N', ' END, @RequestNo), 128)
|
|||
|
|
WHERE Id = @Doc AND CHARINDEX(@RequestNo, ISNULL(SourceDocument, '')) = 0;
|
|||
|
|
|
|||
|
|
SELECT @Line = Id FROM Inv_T_TransferLine WHERE TransferId = @Doc AND MaterialRequestItemId = @Id AND IsDeleted = 0;
|
|||
|
|
IF @Line IS NOT NULL
|
|||
|
|
UPDATE Inv_T_TransferLine
|
|||
|
|
SET DemandQuantity = DemandQuantity + dbo.Inv_F_UomConvert(@PlanQuantity, @UomId, UomId), LastModificationTime = GETUTCDATE(), LastModifierId = @LastModifierId
|
|||
|
|
WHERE Id = @Line;
|
|||
|
|
ELSE
|
|||
|
|
INSERT INTO Inv_T_TransferLine (Id, TenantId, TransferId, ProductId, Description, DemandQuantity, Quantity, UomId, MaterialRequestItemId,
|
|||
|
|
CreationTime, CreatorId, IsDeleted)
|
|||
|
|
VALUES (NEWID(), @TenantId, @Doc, @ProductId, @Reason, @PlanQuantity, 0, @UomId, @Id, GETUTCDATE(), @LastModifierId, 0);
|
|||
|
|
|
|||
|
|
-- Numara, kaynak depo onaycısı ve yeniden hesap (kalemin kapanması dahil) belge kaydı sonrasıyla aynıdır.
|
|||
|
|
EXEC Inv_P_TransferAfterSave @Doc, @LastModifierId;
|
|||
|
|
END
|
|||
|
|
ELSE IF @PlanMethod = 'Stock'
|
|||
|
|
BEGIN
|
|||
|
|
SELECT @Free = FreeQuantity FROM Prc_V_MaterialRequestPlanSource WHERE BaseId = @Id AND LocationId = @Location;
|
|||
|
|
IF @PlanQuantity > ISNULL(@Free, 0)
|
|||
|
|
BEGIN
|
|||
|
|
SET @Msg = CONCAT(N'Teslim konumunda yeterli serbest stok yok (serbest: ', FORMAT(CASE WHEN @Free > 0 THEN @Free ELSE 0 END, '0.####'), N' ', @UomId, N').');
|
|||
|
|
THROW 50198, @Msg, 1;
|
|||
|
|
END
|
|||
|
|
|
|||
|
|
UPDATE Prc_T_MaterialRequestItem
|
|||
|
|
SET FromStockQuantity = FromStockQuantity + @PlanQuantity, DeliveredQuantity = DeliveredQuantity + @PlanQuantity,
|
|||
|
|
LastModificationTime = GETUTCDATE(), LastModifierId = @LastModifierId
|
|||
|
|
WHERE Id = @Id;
|
|||
|
|
UPDATE i SET LineStatus = 'Done'
|
|||
|
|
FROM Prc_T_MaterialRequestItem i
|
|||
|
|
INNER JOIN Prc_V_MaterialRequestItemPlan p ON p.Id = i.Id
|
|||
|
|
WHERE i.Id = @Id AND p.PurchaseQuantity = 0 AND p.RemainingQuantity <= 0;
|
|||
|
|
END
|
|||
|
|
ELSE
|
|||
|
|
THROW 50192, N'Karar Satınalma, İç Transfer ya da Stoktan olmalıdır.', 1;
|
|||
|
|
|
|||
|
|
COMMIT TRANSACTION;
|
|||
|
|
END
|