98 lines
4.5 KiB
MySQL
98 lines
4.5 KiB
MySQL
|
|
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;
|
|||
|
|
$$;
|