sozsoft-platform/configs/seeds/sql/object/Hr_S_AttendanceProcess.sql
2026-10-05 15:58:59 +03:00

96 lines
4.2 KiB
Transact-SQL
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.

CREATE OR ALTER PROCEDURE [dbo].[Hr_S_AttendanceProcess]
@FailOnClosed bit = 1
AS
BEGIN
SET NOCOUNT ON;
-- İş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
-- (@FailOnClosed = 1); PDKS ve gece işinde satır hatalı işaretlenir.
CREATE TABLE #apLog
(
Id uniqueidentifier PRIMARY KEY, TenantId uniqueidentifier NULL, EmployeeId uniqueidentifier NULL,
CardNo nvarchar(64) NULL, EventTime datetime2, IsDeleted bit, OldWorkDate date NULL,
NewWorkDate date NULL, Error nvarchar(32) NULL
);
INSERT INTO #apLog (Id, TenantId, EmployeeId, CardNo, EventTime, IsDeleted, OldWorkDate)
SELECT Id, TenantId, EmployeeId, CardNo, EventTime, IsDeleted, WorkDate
FROM Hr_T_AttendanceLog
WHERE IsProcessed = 0;
IF NOT EXISTS (SELECT 1 FROM #apLog)
RETURN;
UPDATE a
SET EmployeeId = u.Id
FROM #apLog a
CROSS APPLY (
SELECT TOP 1 x.Id
FROM AbpUsers x
WHERE (x.PdksCardNo = a.CardNo OR x.RegistrationNo = a.CardNo) AND x.IsDeleted = 0
AND (x.TenantId = a.TenantId OR (x.TenantId IS NULL AND a.TenantId IS NULL))
ORDER BY CASE WHEN x.PdksCardNo = a.CardNo THEN 0 ELSE 1 END, x.IsActive DESC
) u
WHERE a.EmployeeId IS NULL AND a.CardNo IS NOT NULL AND a.CardNo <> N'';
UPDATE #apLog SET Error = N'UnknownCard' WHERE EmployeeId IS NULL AND IsDeleted = 0;
UPDATE a
SET NewWorkDate = CAST(DATEADD(minute, -s.DayOffset, a.EventTime) AS date)
FROM #apLog a
INNER JOIN Hr_V_AttendanceShift s ON s.EmployeeId = a.EmployeeId
WHERE a.IsDeleted = 0 AND a.Error IS NULL;
-- Kapalı dönem: hareketin eski ya da yeni günü kapalı aya düşüyorsa.
UPDATE a
SET Error = N'ClosedPeriod'
FROM #apLog a
WHERE EXISTS (
SELECT 1 FROM Hr_T_TimesheetPeriod p
WHERE p.IsDeleted = 0 AND p.Status = N'Closed'
AND (p.TenantId = a.TenantId OR (p.TenantId IS NULL AND a.TenantId IS NULL))
AND ((p.PeriodYear = YEAR(a.OldWorkDate) AND p.PeriodMonth = MONTH(a.OldWorkDate))
OR (p.PeriodYear = YEAR(a.NewWorkDate) AND p.PeriodMonth = MONTH(a.NewWorkDate))));
IF @FailOnClosed = 1 AND EXISTS (SELECT 1 FROM #apLog WHERE Error = N'ClosedPeriod')
THROW 51200, N'Kapalı puantaj dönemine ait hareket eklenemez, değiştirilemez ya da silinemez. Dönemi İnsan Kaynakları açabilir.', 1;
UPDATE l
SET EmployeeId = a.EmployeeId,
WorkDate = CASE WHEN a.Error = N'ClosedPeriod' THEN l.WorkDate ELSE a.NewWorkDate END,
ProcessError = a.Error,
Source = COALESCE(l.Source, N'Import'),
IsProcessed = 1
FROM Hr_T_AttendanceLog l
INNER JOIN #apLog a ON a.Id = l.Id;
-- Etkilenen günler: hareketin eski günü (taşındıysa ya da silindiyse) ve yeni günü.
DECLARE @Keys TABLE (TenantId uniqueidentifier NULL, EmployeeId uniqueidentifier, FromDate date, ToDate date);
INSERT INTO @Keys (TenantId, EmployeeId, FromDate, ToDate)
SELECT TenantId, EmployeeId, MIN(D), MAX(D)
FROM (
SELECT TenantId, EmployeeId, OldWorkDate AS D FROM #apLog
WHERE EmployeeId IS NOT NULL AND OldWorkDate IS NOT NULL AND COALESCE(Error, N'') <> N'ClosedPeriod'
UNION ALL
SELECT TenantId, EmployeeId, NewWorkDate FROM #apLog
WHERE EmployeeId IS NOT NULL AND NewWorkDate IS NOT NULL AND Error IS NULL
) k
GROUP BY TenantId, EmployeeId;
DECLARE @TenantId uniqueidentifier, @EmployeeId uniqueidentifier, @FromDate date, @ToDate date;
DECLARE key_cursor CURSOR LOCAL FAST_FORWARD FOR SELECT TenantId, EmployeeId, FromDate, ToDate FROM @Keys;
OPEN key_cursor;
FETCH NEXT FROM key_cursor INTO @TenantId, @EmployeeId, @FromDate, @ToDate;
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC dbo.Hr_S_TimesheetCalculate @TenantId, @EmployeeId, @FromDate, @ToDate, NULL;
FETCH NEXT FROM key_cursor INTO @TenantId, @EmployeeId, @FromDate, @ToDate;
END
CLOSE key_cursor;
DEALLOCATE key_cursor;
END
GO