2026-10-17 23:59:45 +00:00
|
|
|
|
-- Zamanlanmış işin BeforeSp'si PostgreSQL'de "SELECT * FROM public.<ad>()" ile çağrıldığı için
|
|
|
|
|
|
-- prosedür değil, void dönen fonksiyondur.
|
|
|
|
|
|
CREATE OR REPLACE FUNCTION public."Mm_S_MaintenanceInstructionSchedule"()
|
|
|
|
|
|
RETURNS void
|
|
|
|
|
|
LANGUAGE plpgsql
|
|
|
|
|
|
AS $$
|
|
|
|
|
|
DECLARE
|
|
|
|
|
|
v_Today date := LOCALTIMESTAMP::date;
|
2026-10-18 21:22:40 +00:00
|
|
|
|
v_due record;
|
|
|
|
|
|
v_wo uuid;
|
|
|
|
|
|
v_no varchar(128);
|
|
|
|
|
|
v_pass integer;
|
2026-10-17 23:59:45 +00:00
|
|
|
|
BEGIN
|
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, fonksiyon parametre almaz; bütün kiracıların satırlarını işler ve aynı gün tekrar
|
|
|
|
|
|
-- çalışması sonucu değiştirmez.
|
|
|
|
|
|
FOR v_pass IN 1..2 LOOP
|
|
|
|
|
|
IF v_pass = 2 THEN
|
|
|
|
|
|
FOR v_due IN
|
|
|
|
|
|
SELECT i."Id", i."TenantId", i."NextDueDate"
|
|
|
|
|
|
FROM "Mm_T_MaintenanceInstruction" i
|
|
|
|
|
|
WHERE i."IsDeleted" = false AND i."IsActive" = true AND i."ApprovalStatus" = 'Onaylandı'
|
|
|
|
|
|
AND i."NextDueDate" IS NOT NULL AND i."NextDueDate" <= v_Today
|
|
|
|
|
|
AND NOT EXISTS (SELECT 1 FROM "Mm_T_WorkOrder" w
|
|
|
|
|
|
WHERE w."MaintenanceInstructionId" = i."Id" AND w."Source" = 'Automatic' AND w."IsDeleted" = false
|
|
|
|
|
|
AND w."PlannedStart"::date = i."NextDueDate")
|
|
|
|
|
|
LOOP
|
|
|
|
|
|
v_wo := gen_random_uuid();
|
|
|
|
|
|
v_no := NULL;
|
|
|
|
|
|
CALL public."Adm_P_SequenceNext"('Mm.WorkOrder', v_due."TenantId", v_no);
|
|
|
|
|
|
|
|
|
|
|
|
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 v_wo, i."TenantId", i."BranchId", left(v_no, 32), left(i."Name" || ' - ' || p."Name", 256), i."EquipmentId", v_Today,
|
|
|
|
|
|
'Preventive', 'Internal', i."MaintenanceTypeId",
|
|
|
|
|
|
CASE WHEN split_part(COALESCE(i."TeamIds", ''), '|', 1) ~* '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$'
|
|
|
|
|
|
THEN split_part(i."TeamIds", '|', 1)::uuid END,
|
|
|
|
|
|
'Automatic', i."Id", v_due."NextDueDate" + interval '8 hours', 0, 'Draft', true, NOW() AT TIME ZONE 'UTC', false
|
|
|
|
|
|
FROM "Mm_T_MaintenanceInstruction" i
|
|
|
|
|
|
INNER JOIN "Inv_T_Product" p ON p."Id" = i."EquipmentId"
|
|
|
|
|
|
WHERE i."Id" = v_due."Id";
|
|
|
|
|
|
|
|
|
|
|
|
INSERT INTO "Mm_T_WorkOrderMaterial" ("Id", "TenantId", "WorkOrderId", "ProductId", "Quantity", "UomId", "LocationId", "Description",
|
|
|
|
|
|
"CreationTime", "IsDeleted")
|
|
|
|
|
|
SELECT gen_random_uuid(), m."TenantId", v_wo, m."ProductId", m."Quantity", m."UomId",
|
|
|
|
|
|
(SELECT 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" = v_due."Id" AND l."IsDeleted" = false AND l."IsActive" = true AND l."LocationType" = 'Internal'
|
|
|
|
|
|
ORDER BY l."Code", l."Name"
|
|
|
|
|
|
LIMIT 1),
|
|
|
|
|
|
m."Description", NOW() AT TIME ZONE 'UTC', false
|
|
|
|
|
|
FROM "Mm_T_MaintenanceInstructionMaterial" m
|
|
|
|
|
|
WHERE m."MaintenanceInstructionId" = v_due."Id" AND m."IsDeleted" = false AND m."IsActive" = true;
|
|
|
|
|
|
|
|
|
|
|
|
CALL public."Mm_P_WorkOrderAfterSave"(v_wo, NULL);
|
|
|
|
|
|
END LOOP;
|
|
|
|
|
|
END IF;
|
|
|
|
|
|
|
2026-10-17 23:59:45 +00:00
|
|
|
|
UPDATE "Mm_T_MaintenanceInstruction" i SET
|
|
|
|
|
|
"NextDueDate" = CASE WHEN n."NextDate" > i."EndDate" THEN NULL ELSE n."NextDate" END
|
|
|
|
|
|
FROM (
|
|
|
|
|
|
SELECT c."Id",
|
|
|
|
|
|
CASE
|
|
|
|
|
|
WHEN c."StartDate" >= v_Today THEN c."StartDate"
|
|
|
|
|
|
WHEN c."Candidate" >= v_Today THEN c."Candidate"
|
|
|
|
|
|
WHEN c."IsMonth" THEN (c."StartDate" + make_interval(months => (c."K" + 1) * c."Step"))::date
|
|
|
|
|
|
ELSE c."StartDate" + (c."K" + 1) * c."Step"
|
|
|
|
|
|
END AS "NextDate"
|
|
|
|
|
|
FROM (
|
|
|
|
|
|
SELECT k.*,
|
|
|
|
|
|
CASE WHEN k."IsMonth" THEN (k."StartDate" + make_interval(months => k."K" * k."Step"))::date
|
|
|
|
|
|
ELSE k."StartDate" + k."K" * k."Step" END AS "Candidate"
|
|
|
|
|
|
FROM (
|
|
|
|
|
|
SELECT s.*,
|
|
|
|
|
|
(CASE WHEN s."IsMonth"
|
|
|
|
|
|
THEN ((EXTRACT(YEAR FROM v_Today) - EXTRACT(YEAR FROM s."StartDate")) * 12
|
|
|
|
|
|
+ EXTRACT(MONTH FROM v_Today) - EXTRACT(MONTH FROM s."StartDate"))::integer
|
|
|
|
|
|
ELSE v_Today - s."StartDate" END) / s."Step" AS "K"
|
|
|
|
|
|
FROM (
|
|
|
|
|
|
SELECT x."Id", x."StartDate",
|
|
|
|
|
|
x."PeriodUnit" IN ('Month', 'Year') AS "IsMonth",
|
|
|
|
|
|
CASE x."PeriodUnit" WHEN 'Week' THEN 7 * x."PeriodValue" WHEN 'Year' THEN 12 * x."PeriodValue" ELSE x."PeriodValue" END AS "Step"
|
|
|
|
|
|
FROM "Mm_T_MaintenanceInstruction" x
|
|
|
|
|
|
WHERE x."IsDeleted" = FALSE AND x."IsActive" = TRUE AND x."PeriodValue" > 0
|
2026-10-18 21:22:40 +00:00
|
|
|
|
AND (v_pass = 2 OR x."NextDueDate" IS NULL)
|
2026-10-17 23:59:45 +00:00
|
|
|
|
) s
|
|
|
|
|
|
) k
|
|
|
|
|
|
) c
|
|
|
|
|
|
) n
|
|
|
|
|
|
WHERE n."Id" = i."Id";
|
2026-10-18 21:22:40 +00:00
|
|
|
|
END LOOP;
|
2026-10-17 23:59:45 +00:00
|
|
|
|
|
|
|
|
|
|
UPDATE "Mm_T_MaintenanceInstruction" SET "NextDueDate" = NULL
|
|
|
|
|
|
WHERE "NextDueDate" IS NOT NULL AND ("IsDeleted" = TRUE OR "IsActive" = FALSE OR "PeriodValue" <= 0);
|
|
|
|
|
|
END;
|
|
|
|
|
|
$$;
|