97 lines
4.5 KiB
PL/PgSQL
97 lines
4.5 KiB
PL/PgSQL
CREATE OR REPLACE PROCEDURE public."Hr_S_AttendanceProcess"(
|
||
p_FailOnClosed boolean DEFAULT TRUE
|
||
)
|
||
LANGUAGE plpgsql
|
||
AS $$
|
||
DECLARE
|
||
v_Key record;
|
||
BEGIN
|
||
-- İşlenmemiş hareketleri (ekran, Excel import, PDKS ucu; silinenler dahil) işler: çalışanı kullanıcı
|
||
-- kartındaki PDKS Kart No'dan (yoksa Sicil No'dan) bulur, hareketin iş gününü vardiyaya göre belirler ve etkilenen günlerin puantajını
|
||
-- yeniden hesaplar. Ekrandan gelen değişiklik kapalı döneme düşerse kayıt geri alınır
|
||
-- (p_FailOnClosed = TRUE); PDKS ve gece işinde satır hatalı işaretlenir.
|
||
-- Kart/sicil eşleşmesi SQL Server harmanlaması gibi büyük/küçük harf duyarsızdır.
|
||
DROP TABLE IF EXISTS ap_log;
|
||
CREATE TEMP TABLE ap_log
|
||
(
|
||
Id uuid PRIMARY KEY, TenantId uuid NULL, EmployeeId uuid NULL,
|
||
CardNo varchar(64) NULL, EventTime timestamp, IsDeleted boolean, OldWorkDate date NULL,
|
||
NewWorkDate date NULL, Error varchar(32) NULL
|
||
) ON COMMIT DROP;
|
||
|
||
INSERT INTO ap_log (Id, TenantId, EmployeeId, CardNo, EventTime, IsDeleted, OldWorkDate)
|
||
SELECT "Id", "TenantId", "EmployeeId", "CardNo", "EventTime", "IsDeleted", "WorkDate"
|
||
FROM public."Hr_T_AttendanceLog"
|
||
WHERE "IsProcessed" = FALSE;
|
||
|
||
IF NOT EXISTS (SELECT 1 FROM ap_log) THEN
|
||
RETURN;
|
||
END IF;
|
||
|
||
UPDATE ap_log a
|
||
SET EmployeeId = u.Id
|
||
FROM (
|
||
SELECT a2.Id AS LogId, (
|
||
SELECT x."Id"
|
||
FROM public."AbpUsers" x
|
||
WHERE (lower(x."PdksCardNo") = lower(a2.CardNo) OR lower(x."RegistrationNo") = lower(a2.CardNo)) AND x."IsDeleted" = FALSE
|
||
AND (x."TenantId" = a2.TenantId OR (x."TenantId" IS NULL AND a2.TenantId IS NULL))
|
||
ORDER BY CASE WHEN lower(x."PdksCardNo") = lower(a2.CardNo) THEN 0 ELSE 1 END, x."IsActive" DESC NULLS LAST
|
||
LIMIT 1) AS Id
|
||
FROM ap_log a2
|
||
WHERE a2.EmployeeId IS NULL AND a2.CardNo IS NOT NULL AND a2.CardNo <> ''
|
||
) u
|
||
WHERE u.LogId = a.Id AND u.Id IS NOT NULL;
|
||
|
||
UPDATE ap_log SET Error = 'UnknownCard' WHERE EmployeeId IS NULL AND IsDeleted = FALSE;
|
||
|
||
UPDATE ap_log a
|
||
SET NewWorkDate = (a.EventTime - s."DayOffset" * INTERVAL '1 minute')::date
|
||
FROM public."Hr_V_AttendanceShift" s
|
||
WHERE s."EmployeeId" = a.EmployeeId
|
||
AND a.IsDeleted = FALSE AND a.Error IS NULL;
|
||
|
||
-- Kapalı dönem: hareketin eski ya da yeni günü kapalı aya düşüyorsa.
|
||
UPDATE ap_log a
|
||
SET Error = 'ClosedPeriod'
|
||
WHERE EXISTS (
|
||
SELECT 1 FROM public."Hr_T_TimesheetPeriod" p
|
||
WHERE p."IsDeleted" = FALSE AND p."Status" = 'Closed'
|
||
AND (p."TenantId" = a.TenantId OR (p."TenantId" IS NULL AND a.TenantId IS NULL))
|
||
AND ((p."PeriodYear" = EXTRACT(YEAR FROM a.OldWorkDate)::integer AND p."PeriodMonth" = EXTRACT(MONTH FROM a.OldWorkDate)::integer)
|
||
OR (p."PeriodYear" = EXTRACT(YEAR FROM a.NewWorkDate)::integer AND p."PeriodMonth" = EXTRACT(MONTH FROM a.NewWorkDate)::integer)));
|
||
|
||
IF p_FailOnClosed = TRUE AND EXISTS (SELECT 1 FROM ap_log WHERE Error = 'ClosedPeriod') THEN
|
||
RAISE EXCEPTION 'Kapalı puantaj dönemine ait hareket eklenemez, değiştirilemez ya da silinemez. Dönemi İnsan Kaynakları açabilir.'
|
||
USING ERRCODE = 'P0001', DETAIL = '51200';
|
||
END IF;
|
||
|
||
UPDATE public."Hr_T_AttendanceLog" l
|
||
SET "EmployeeId" = a.EmployeeId,
|
||
"WorkDate" = CASE WHEN a.Error = 'ClosedPeriod' THEN l."WorkDate" ELSE a.NewWorkDate END,
|
||
"ProcessError" = a.Error,
|
||
"Source" = COALESCE(l."Source", 'Import'),
|
||
"IsProcessed" = TRUE
|
||
FROM ap_log a
|
||
WHERE a.Id = l."Id";
|
||
|
||
-- Etkilenen günler: hareketin eski günü (taşındıysa ya da silindiyse) ve yeni günü.
|
||
DROP TABLE IF EXISTS ap_keys;
|
||
CREATE TEMP TABLE ap_keys (TenantId uuid NULL, EmployeeId uuid, FromDate date, ToDate date) ON COMMIT DROP;
|
||
|
||
INSERT INTO ap_keys (TenantId, EmployeeId, FromDate, ToDate)
|
||
SELECT k.TenantId, k.EmployeeId, MIN(k.D), MAX(k.D)
|
||
FROM (
|
||
SELECT TenantId, EmployeeId, OldWorkDate AS D FROM ap_log
|
||
WHERE EmployeeId IS NOT NULL AND OldWorkDate IS NOT NULL AND COALESCE(Error, '') <> 'ClosedPeriod'
|
||
UNION ALL
|
||
SELECT TenantId, EmployeeId, NewWorkDate FROM ap_log
|
||
WHERE EmployeeId IS NOT NULL AND NewWorkDate IS NOT NULL AND Error IS NULL
|
||
) k
|
||
GROUP BY k.TenantId, k.EmployeeId;
|
||
|
||
FOR v_Key IN SELECT TenantId, EmployeeId, FromDate, ToDate FROM ap_keys LOOP
|
||
CALL public."Hr_S_TimesheetCalculate"(v_Key.TenantId, v_Key.EmployeeId, v_Key.FromDate, v_Key.ToDate, NULL);
|
||
END LOOP;
|
||
END;
|
||
$$;
|