2026-10-17 23:59:45 +00:00
|
|
|
|
CREATE OR ALTER PROCEDURE [dbo].[Mm_S_MaintenanceInstructionSchedule]
|
|
|
|
|
|
AS
|
|
|
|
|
|
BEGIN
|
|
|
|
|
|
SET NOCOUNT ON;
|
|
|
|
|
|
|
2026-10-18 21:22:40 +00:00
|
|
|
|
-- 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.
|
2026-10-17 23:59:45 +00:00
|
|
|
|
DECLARE @Today date = CAST(GETDATE() AS date);
|
2026-10-18 21:22:40 +00:00
|
|
|
|
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
|
2026-10-17 23:59:45 +00:00
|
|
|
|
|
|
|
|
|
|
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
|
2026-10-18 21:22:40 +00:00
|
|
|
|
WHERE i.IsDeleted = 0 AND i.IsActive = 1 AND i.PeriodValue > 0 AND (@Pass = 2 OR i.NextDueDate IS NULL);
|
|
|
|
|
|
|
|
|
|
|
|
SET @Pass += 1;
|
|
|
|
|
|
END
|
2026-10-17 23:59:45 +00:00
|
|
|
|
|
|
|
|
|
|
UPDATE Mm_T_MaintenanceInstruction SET NextDueDate = NULL
|
|
|
|
|
|
WHERE NextDueDate IS NOT NULL AND (IsDeleted = 1 OR IsActive = 0 OR PeriodValue <= 0);
|
|
|
|
|
|
END
|
2026-10-18 21:22:40 +00:00
|
|
|
|
GO
|