fix(scud): исправление маппинга Mode (1=IN, 2=OUT) и привязка FilteredLastOut к финальному событию дня

This commit is contained in:
2026-09-07 17:41:59 +03:00
parent d391a08224
commit 17c960fa34
+14 -8
View File
@@ -85,12 +85,16 @@ WITH DailyLogs AS (
log.TimeVal, log.TimeVal,
log.Event, log.Event,
log.Mode, log.Mode,
-- Приоритет отдается физическому направлению контроллера (Mode):
CASE CASE
WHEN log.Mode = 2 OR log.Event IN (2, 27, 29, 33, 55, 65) THEN 'OUT' WHEN log.Mode = 2 THEN 'OUT'
WHEN log.Mode = 1 OR log.Event IN (1, 21, 26, 28, 32, 54, 64) THEN 'IN' WHEN log.Mode = 1 THEN 'IN'
WHEN log.Event IN (2, 27, 29, 33, 55, 65) THEN 'OUT'
WHEN log.Event IN (1, 21, 26, 54, 64) THEN 'IN'
ELSE 'OTHER' ELSE 'OTHER'
END AS Direction, END AS Direction,
ROW_NUMBER() OVER (PARTITION BY log.HozOrgan ORDER BY log.TimeVal DESC) AS RowNumDesc -- Вычисляем самое последнее событие сотрудника за день:
ROW_NUMBER() OVER (PARTITION BY log.HozOrgan ORDER BY log.TimeVal DESC, log.Event DESC) AS RnLast
FROM pLogData log WITH (NOLOCK) FROM pLogData log WITH (NOLOCK)
WHERE log.TimeVal BETWEEN @StartDate AND @EndDate WHERE log.TimeVal BETWEEN @StartDate AND @EndDate
AND log.HozOrgan IS NOT NULL AND log.HozOrgan IS NOT NULL
@@ -102,20 +106,22 @@ Passages AS (
EmployeeID, EmployeeID,
MIN(TimeVal) AS FirstRawEvent, MIN(TimeVal) AS FirstRawEvent,
MAX(TimeVal) AS LastRawEvent, MAX(TimeVal) AS LastRawEvent,
-- Первый вход за день:
MIN(CASE WHEN Direction = 'IN' THEN TimeVal END) AS FirstIn, MIN(CASE WHEN Direction = 'IN' THEN TimeVal END) AS FirstIn,
-- Реальный выход: должен быть позже входа минимум на 5 минут (отсекает проезд через шлагбаум/парковку) -- Фиксируем выход ТОЛЬКО если самое последнее событие за день было именно выходом (OUT):
MAX(CASE WHEN Direction = 'OUT' THEN TimeVal END) AS RawLastOut MAX(CASE WHEN RnLast = 1 AND Direction = 'OUT' THEN TimeVal END) AS FinalOut
FROM DailyLogs FROM DailyLogs
GROUP BY EmployeeID GROUP BY EmployeeID
), ),
EvaluatedPassages AS ( EvaluatedPassages AS (
SELECT SELECT
p.*, p.*,
-- Время выхода проставляется только при окончательном уходе сотрудника из здания:
CASE CASE
WHEN p.RawLastOut IS NOT NULL WHEN p.FinalOut IS NOT NULL
AND p.FirstIn IS NOT NULL AND p.FirstIn IS NOT NULL
AND p.RawLastOut > DATEADD(MINUTE, 5, p.FirstIn) AND p.FinalOut > DATEADD(MINUTE, 5, p.FirstIn)
THEN p.RawLastOut THEN p.FinalOut
ELSE NULL ELSE NULL
END AS FilteredLastOut END AS FilteredLastOut
FROM Passages p FROM Passages p