feat: route Terry machine punches to terry_attendance_log
Add TerryAttendanceMachineIps config and persist punches from those IPs directly to terry_attendance_log without worker_type lookup. Add employee worker_type lookup and persist outcomes for unmapped/unsupported workers on non-Terry machines.main
parent
4f84d8834f
commit
8939e9d49c
|
|
@ -83,6 +83,10 @@ internal static class BizFriendlyReasons
|
|||
}
|
||||
}
|
||||
|
||||
public static string FormatTime(DateTime dt) =>
|
||||
dt.ToString("M/d/yyyy h:mm:ss tt", CultureInfo.InvariantCulture);
|
||||
public static string FormatTime(DateTime dt)
|
||||
{
|
||||
if (dt.Kind == DateTimeKind.Utc)
|
||||
dt = dt.ToLocalTime();
|
||||
return dt.ToString("M/d/yyyy h:mm:ss tt", CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,3 +34,9 @@ internal sealed class AttendanceMachineFaceTemplateRow
|
|||
public string SourceMachineId { get; set; } = "";
|
||||
public string SourceMachineIp { get; set; } = "";
|
||||
}
|
||||
|
||||
internal sealed class EmployeeWorkerTypeRow
|
||||
{
|
||||
public int SerialNumberInt { get; set; }
|
||||
public string WorkerType { get; set; } = "";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,22 @@
|
|||
{
|
||||
"MachineScopeMode": "SITE",
|
||||
"ScopedMachineIps": [
|
||||
"192.168.91.80"
|
||||
"192.168.90.184",
|
||||
"192.168.86.7",
|
||||
"192.168.40.225",
|
||||
"192.168.40.226"
|
||||
],
|
||||
|
||||
"TerryAttendanceMachineIps": [
|
||||
"192.168.40.225",
|
||||
"192.168.40.226"
|
||||
],
|
||||
|
||||
"EnableTemplateDeviceToDbSync": false,
|
||||
"EnableTemplateDbToDeviceSync": false,
|
||||
|
||||
"SourceMachineIp": "192.168.91.80",
|
||||
"TargetMachineIps": [
|
||||
"192.168.91.80"
|
||||
],
|
||||
"SourceMachineIp": "",
|
||||
"TargetMachineIps": [],
|
||||
|
||||
"SyncEmployeeIds": [],
|
||||
"SyncDepartmentIds": [],
|
||||
|
|
@ -18,7 +24,7 @@
|
|||
"EnableInitialDepartmentSync": false,
|
||||
"InitialSyncDepartmentIds": [],
|
||||
"InitialSyncEmployeeIds": [],
|
||||
"InitialSyncLocationSiteId": 2,
|
||||
"InitialSyncLocationSiteId":2,
|
||||
"EnableEmployeePhotoSource": true,
|
||||
"EmployeePhotoBaseUrl": "https://portal.utopiaindustries.pk/uind/employee-photo/"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -238,6 +238,13 @@ public sealed class HikvisionAttendanceWindowsService : ServiceBase
|
|||
[DataMember]
|
||||
public List<string> ScopedMachineIps { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Machine IPs whose attendance is always written to hrms.terry_attendance_log
|
||||
/// (no employee/worker_type lookup). Compared to attendance event machine_ip.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public List<string> TerryAttendanceMachineIps { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>DeviceId (from <see cref="DeviceConfig.DeviceId"/>) to treat as the authoritative user source.</summary>
|
||||
[DataMember]
|
||||
public string SourceDeviceId { get; set; } = "";
|
||||
|
|
@ -314,6 +321,7 @@ public sealed class HikvisionAttendanceWindowsService : ServiceBase
|
|||
TemplateFetchIntervalHours = 4,
|
||||
MachineScopeMode = "CENTRAL",
|
||||
ScopedMachineIps = new List<string>(),
|
||||
TerryAttendanceMachineIps = new List<string>(),
|
||||
EnableUserSync = false,
|
||||
SyncIntervalMinutes = 60,
|
||||
SourceDeviceId = "",
|
||||
|
|
@ -402,6 +410,7 @@ public sealed class HikvisionAttendanceWindowsService : ServiceBase
|
|||
TemplateFetchIntervalHours = 4,
|
||||
MachineScopeMode = "CENTRAL",
|
||||
ScopedMachineIps = new List<string>(),
|
||||
TerryAttendanceMachineIps = new List<string>(),
|
||||
EnableUserSync = false,
|
||||
SyncIntervalMinutes = 60,
|
||||
SourceDeviceId = "",
|
||||
|
|
@ -574,6 +583,8 @@ public sealed class HikvisionAttendanceWindowsService : ServiceBase
|
|||
cfg.MachineScopeMode = overlay.MachineScopeMode;
|
||||
if (overlay.ScopedMachineIps != null)
|
||||
cfg.ScopedMachineIps = new List<string>(overlay.ScopedMachineIps);
|
||||
if (overlay.TerryAttendanceMachineIps != null)
|
||||
cfg.TerryAttendanceMachineIps = new List<string>(overlay.TerryAttendanceMachineIps);
|
||||
cfg.EnableTemplateDeviceToDbSync = overlay.EnableTemplateDeviceToDbSync;
|
||||
cfg.EnableTemplateDbToDeviceSync = overlay.EnableTemplateDbToDeviceSync;
|
||||
if (overlay.SourceMachineIp != null)
|
||||
|
|
@ -618,6 +629,9 @@ public sealed class HikvisionAttendanceWindowsService : ServiceBase
|
|||
cfg.ScopedMachineIps ??= new List<string>();
|
||||
for (int i = 0; i < cfg.ScopedMachineIps.Count; i++)
|
||||
cfg.ScopedMachineIps[i] = (cfg.ScopedMachineIps[i] ?? "").Trim();
|
||||
cfg.TerryAttendanceMachineIps ??= new List<string>();
|
||||
for (int i = 0; i < cfg.TerryAttendanceMachineIps.Count; i++)
|
||||
cfg.TerryAttendanceMachineIps[i] = (cfg.TerryAttendanceMachineIps[i] ?? "").Trim();
|
||||
if (cfg.TargetDeviceIds == null)
|
||||
cfg.TargetDeviceIds = new List<string>();
|
||||
else
|
||||
|
|
@ -666,6 +680,12 @@ public sealed class HikvisionAttendanceWindowsService : ServiceBase
|
|||
[DataMember]
|
||||
public List<string> ScopedMachineIps { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// IPs whose punches always go to terry_attendance_log (no worker_type lookup).
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public List<string> TerryAttendanceMachineIps { get; set; } = new List<string>();
|
||||
|
||||
[DataMember]
|
||||
public bool EnableTemplateDeviceToDbSync { get; set; }
|
||||
|
||||
|
|
|
|||
|
|
@ -316,6 +316,8 @@ internal enum AttendancePersistOutcome
|
|||
{
|
||||
Duplicate,
|
||||
SkippedNoEmployee,
|
||||
UnmappedEmployee,
|
||||
UnsupportedWorkerType,
|
||||
DbInserted,
|
||||
DbFailed,
|
||||
PersistedWithoutDb
|
||||
|
|
|
|||
Loading…
Reference in New Issue