102 lines
5.4 KiB
Transact-SQL
102 lines
5.4 KiB
Transact-SQL
CREATE OR ALTER PROCEDURE [dbo].[Mm_S_MaintenanceInstructionSchedule]
|
||
AS
|
||
BEGIN
|
||
SET NOCOUNT ON;
|
||
|
||
-- Zamanlanmış iş (Maintenance Instruction Schedule, her gece 01:00).
|
||
-- 0. Sonraki bakım tarihi boş olan aktif talimatın tarihi önce hesaplanır; böylece başlangıcı geçmiş ya da yeni
|
||
-- onaylanan talimatın bugünkü vadesi aynı çalıştırmada iş emri alır.
|
||
-- 1. Sonraki bakım tarihi bugün ya da geçmiş olan aktif ve onaylanmış her talimattan o vade için Taslak, Otomatik bakım
|
||
-- iş emri açar: numara Mm.WorkOrder numaratöründen, ekip talimatın ilk ekibi, malzemeler talimattan; kullanım konumu
|
||
-- ekipmanın departmanının ilk iç konumudur. Aynı talimat ve vade için otomatik emir varsa tekrar açılmaz; önceki
|
||
-- emir kapanmamış olsa da her vade yeni emir alır.
|
||
-- 2. Aktif talimatların sonraki bakım tarihini Başlangıç Tarihi + k × periyot dizisinde bugüne eşit ya da bugünden
|
||
-- sonraki ilk tarihe taşır; Bitiş Tarihi geçmişse ya da talimat pasifse tarih boşalır.
|
||
-- İş host ve her kiracı için çağrılır, yordam parametre almaz; bütün kiracıların satırlarını işler ve aynı gün tekrar
|
||
-- çalışması sonucu değiştirmez.
|
||
DECLARE @Today date = CAST(GETDATE() AS date);
|
||
DECLARE @Ins uniqueidentifier, @Tenant uniqueidentifier, @Due date, @Wo uniqueidentifier, @No nvarchar(128), @Pass int = 1;
|
||
|
||
WHILE @Pass <= 2
|
||
BEGIN
|
||
IF @Pass = 2
|
||
BEGIN
|
||
DECLARE due_cursor CURSOR LOCAL FAST_FORWARD FOR
|
||
SELECT i.Id, i.TenantId, i.NextDueDate
|
||
FROM Mm_T_MaintenanceInstruction i
|
||
WHERE i.IsDeleted = 0 AND i.IsActive = 1 AND i.ApprovalStatus = N'Onaylandı'
|
||
AND i.NextDueDate IS NOT NULL AND i.NextDueDate <= @Today
|
||
AND NOT EXISTS (SELECT 1 FROM Mm_T_WorkOrder w
|
||
WHERE w.MaintenanceInstructionId = i.Id AND w.Source = 'Automatic' AND w.IsDeleted = 0
|
||
AND CAST(w.PlannedStart AS date) = i.NextDueDate);
|
||
OPEN due_cursor;
|
||
FETCH NEXT FROM due_cursor INTO @Ins, @Tenant, @Due;
|
||
WHILE @@FETCH_STATUS = 0
|
||
BEGIN
|
||
SET @Wo = NEWID();
|
||
SET @No = NULL;
|
||
EXEC dbo.Adm_P_SequenceNext N'Mm.WorkOrder', @Tenant, @No OUTPUT;
|
||
|
||
INSERT INTO Mm_T_WorkOrder (Id, TenantId, BranchId, WorkOrderNo, Name, EquipmentId, RequestDate, MaintenanceKind,
|
||
ResourceType, MaintenanceTypeId, TeamId, Source, MaintenanceInstructionId, PlannedStart,
|
||
Priority, Status, IsActive, CreationTime, IsDeleted)
|
||
SELECT @Wo, i.TenantId, i.BranchId, LEFT(@No, 32), LEFT(CONCAT(i.Name, N' - ', p.Name), 256), i.EquipmentId, @Today,
|
||
'Preventive', 'Internal', i.MaintenanceTypeId,
|
||
TRY_CAST(LEFT(i.TeamIds, CHARINDEX('|', CONCAT(i.TeamIds, '|')) - 1) AS uniqueidentifier),
|
||
'Automatic', i.Id, DATEADD(hour, 8, CAST(@Due AS datetime)), 0, 'Draft', 1, GETUTCDATE(), 0
|
||
FROM Mm_T_MaintenanceInstruction i
|
||
INNER JOIN Inv_T_Product p ON p.Id = i.EquipmentId
|
||
WHERE i.Id = @Ins;
|
||
|
||
INSERT INTO Mm_T_WorkOrderMaterial (Id, TenantId, WorkOrderId, ProductId, Quantity, UomId, LocationId, Description,
|
||
CreationTime, IsDeleted)
|
||
SELECT NEWID(), m.TenantId, @Wo, m.ProductId, m.Quantity, m.UomId,
|
||
(SELECT TOP 1 l.Id
|
||
FROM Mm_T_MaintenanceInstruction i
|
||
INNER JOIN Inv_T_Product p ON p.Id = i.EquipmentId
|
||
INNER JOIN Inv_T_Location l ON l.DepartmentId = p.EquipmentDepartmentId
|
||
WHERE i.Id = @Ins AND l.IsDeleted = 0 AND l.IsActive = 1 AND l.LocationType = 'Internal'
|
||
ORDER BY l.Code, l.Name),
|
||
m.Description, GETUTCDATE(), 0
|
||
FROM Mm_T_MaintenanceInstructionMaterial m
|
||
WHERE m.MaintenanceInstructionId = @Ins AND m.IsDeleted = 0 AND m.IsActive = 1;
|
||
|
||
EXEC dbo.Mm_P_WorkOrderAfterSave @Wo, NULL;
|
||
|
||
FETCH NEXT FROM due_cursor INTO @Ins, @Tenant, @Due;
|
||
END
|
||
CLOSE due_cursor;
|
||
DEALLOCATE due_cursor;
|
||
END
|
||
|
||
UPDATE i SET
|
||
NextDueDate = CASE WHEN n.NextDate > i.EndDate THEN NULL ELSE n.NextDate END
|
||
FROM Mm_T_MaintenanceInstruction i
|
||
CROSS APPLY (
|
||
SELECT
|
||
CASE WHEN i.PeriodUnit IN ('Month', 'Year') THEN 1 ELSE 0 END AS IsMonth,
|
||
CASE i.PeriodUnit WHEN 'Week' THEN 7 * i.PeriodValue WHEN 'Year' THEN 12 * i.PeriodValue ELSE i.PeriodValue END AS Step
|
||
) s
|
||
CROSS APPLY (
|
||
SELECT CASE WHEN s.IsMonth = 1 THEN DATEDIFF(month, i.StartDate, @Today) ELSE DATEDIFF(day, i.StartDate, @Today) END / s.Step AS K
|
||
) k
|
||
CROSS APPLY (
|
||
SELECT CASE WHEN s.IsMonth = 1 THEN DATEADD(month, k.K * s.Step, i.StartDate) ELSE DATEADD(day, k.K * s.Step, i.StartDate) END AS Candidate
|
||
) c
|
||
CROSS APPLY (
|
||
SELECT CASE
|
||
WHEN i.StartDate >= @Today THEN i.StartDate
|
||
WHEN c.Candidate >= @Today THEN c.Candidate
|
||
WHEN s.IsMonth = 1 THEN DATEADD(month, (k.K + 1) * s.Step, i.StartDate)
|
||
ELSE DATEADD(day, (k.K + 1) * s.Step, i.StartDate)
|
||
END AS NextDate
|
||
) n
|
||
WHERE i.IsDeleted = 0 AND i.IsActive = 1 AND i.PeriodValue > 0 AND (@Pass = 2 OR i.NextDueDate IS NULL);
|
||
|
||
SET @Pass += 1;
|
||
END
|
||
|
||
UPDATE Mm_T_MaintenanceInstruction SET NextDueDate = NULL
|
||
WHERE NextDueDate IS NOT NULL AND (IsDeleted = 1 OR IsActive = 0 OR PeriodValue <= 0);
|
||
END
|
||
GO
|