sozsoft-platform/configs/seeds/postgres/object/Hr_S_TimesheetNightly.sql

71 lines
3.7 KiB
MySQL
Raw Permalink Normal View History

2026-10-06 11:24:30 +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."Hr_S_TimesheetNightly"()
RETURNS void
LANGUAGE plpgsql
AS $$
DECLARE
v_Today date := LOCALTIMESTAMP::date;
v_Yesterday date := LOCALTIMESTAMP::date - 1;
v_MonthStart date;
v_PrevStart date;
v_TenantId uuid;
v_PeriodId uuid;
v_From date;
BEGIN
-- Zamanlanmış iş (Timesheet Nightly, her gece 02:00). Hareketi olmayan günleri (devamsız, hafta
-- tatili, resmî tatil, izinli, raporlu) kurar ve geriye dönük onaylanan izin/rapor, takvim ya da
-- vardiya değişikliğini yansıtır: dünün ayı ve kapanmamışsa bir önceki ay, işlenmemiş ve kartı sonradan
-- tanımlanan hareketler.
-- İş host ve her kiracı için çağrılır, prosedür parametre almaz; bu yüzden veritabanındaki bütün
-- kiracıları işler ve aynı gün işlenmiş kiracıyı (dönemin NightlyAt değeri) atlar.
v_MonthStart := make_date(EXTRACT(YEAR FROM v_Yesterday)::integer, EXTRACT(MONTH FROM v_Yesterday)::integer, 1);
v_PrevStart := (v_MonthStart - INTERVAL '1 month')::date;
-- Kart numarası kullanıcı kartına sonradan girilen okutmalar yeniden işlenir.
UPDATE public."Hr_T_AttendanceLog" l
SET "IsProcessed" = FALSE, "ProcessError" = NULL
WHERE l."IsDeleted" = FALSE AND l."ProcessError" = 'UnknownCard'
AND EXISTS (SELECT 1 FROM public."AbpUsers" u
WHERE (lower(u."PdksCardNo") = lower(l."CardNo") OR lower(u."RegistrationNo") = lower(l."CardNo")) AND u."IsDeleted" = FALSE
AND (u."TenantId" = l."TenantId" OR (u."TenantId" IS NULL AND l."TenantId" IS NULL)));
CALL public."Hr_S_AttendanceProcess"(FALSE);
FOR v_TenantId IN
SELECT DISTINCT "TenantId" FROM public."AbpUsers" WHERE "IsDeleted" = FALSE AND "HireDate" IS NOT NULL
LOOP
v_PeriodId := (SELECT "Id" FROM public."Hr_T_TimesheetPeriod"
WHERE "IsDeleted" = FALSE
AND "PeriodYear" = EXTRACT(YEAR FROM v_Yesterday)::integer
AND "PeriodMonth" = EXTRACT(MONTH FROM v_Yesterday)::integer
AND ("TenantId" = v_TenantId OR ("TenantId" IS NULL AND v_TenantId IS NULL))
LIMIT 1);
-- Ay dönemi gece işinde kendiliğinden açılır.
IF v_PeriodId IS NULL THEN
v_PeriodId := gen_random_uuid();
INSERT INTO public."Hr_T_TimesheetPeriod" ("Id", "TenantId", "PeriodYear", "PeriodMonth", "Status", "CreationTime", "IsDeleted")
VALUES (v_PeriodId, v_TenantId, EXTRACT(YEAR FROM v_Yesterday)::integer, EXTRACT(MONTH FROM v_Yesterday)::integer,
'Open', (NOW() AT TIME ZONE 'UTC'), FALSE);
END IF;
IF NOT EXISTS (SELECT 1 FROM public."Hr_T_TimesheetPeriod" WHERE "Id" = v_PeriodId AND "NightlyAt" >= v_Today::timestamp) THEN
v_From := CASE WHEN EXISTS (
SELECT 1 FROM public."Hr_T_TimesheetPeriod"
WHERE "IsDeleted" = FALSE AND "Status" = 'Closed'
AND "PeriodYear" = EXTRACT(YEAR FROM v_PrevStart)::integer
AND "PeriodMonth" = EXTRACT(MONTH FROM v_PrevStart)::integer
AND ("TenantId" = v_TenantId OR ("TenantId" IS NULL AND v_TenantId IS NULL)))
THEN v_MonthStart ELSE v_PrevStart END;
CALL public."Hr_S_TimesheetCalculate"(v_TenantId, NULL, v_From, v_Yesterday, NULL);
UPDATE public."Hr_T_TimesheetPeriod"
SET "NightlyAt" = LOCALTIMESTAMP, "CalculatedAt" = (NOW() AT TIME ZONE 'UTC')
WHERE "Id" = v_PeriodId;
END IF;
END LOOP;
END;
$$;