sozsoft-platform/configs/seeds/postgres/object/Hr_S_TimesheetNightly.sql
2026-10-06 14:24:30 +03:00

70 lines
3.7 KiB
PL/PgSQL
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 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;
$$;