70 lines
3.7 KiB
PL/PgSQL
70 lines
3.7 KiB
PL/PgSQL
-- 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;
|
||
$$;
|