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) =>
|
public static string FormatTime(DateTime dt)
|
||||||
dt.ToString("M/d/yyyy h:mm:ss tt", CultureInfo.InvariantCulture);
|
{
|
||||||
|
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 SourceMachineId { get; set; } = "";
|
||||||
public string SourceMachineIp { 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",
|
"MachineScopeMode": "SITE",
|
||||||
"ScopedMachineIps": [
|
"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,
|
"EnableTemplateDeviceToDbSync": false,
|
||||||
"EnableTemplateDbToDeviceSync": false,
|
"EnableTemplateDbToDeviceSync": false,
|
||||||
|
|
||||||
"SourceMachineIp": "192.168.91.80",
|
"SourceMachineIp": "",
|
||||||
"TargetMachineIps": [
|
"TargetMachineIps": [],
|
||||||
"192.168.91.80"
|
|
||||||
],
|
|
||||||
|
|
||||||
"SyncEmployeeIds": [],
|
"SyncEmployeeIds": [],
|
||||||
"SyncDepartmentIds": [],
|
"SyncDepartmentIds": [],
|
||||||
|
|
|
||||||
|
|
@ -238,6 +238,13 @@ public sealed class HikvisionAttendanceWindowsService : ServiceBase
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public List<string> ScopedMachineIps { get; set; } = new List<string>();
|
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>
|
/// <summary>DeviceId (from <see cref="DeviceConfig.DeviceId"/>) to treat as the authoritative user source.</summary>
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public string SourceDeviceId { get; set; } = "";
|
public string SourceDeviceId { get; set; } = "";
|
||||||
|
|
@ -314,6 +321,7 @@ public sealed class HikvisionAttendanceWindowsService : ServiceBase
|
||||||
TemplateFetchIntervalHours = 4,
|
TemplateFetchIntervalHours = 4,
|
||||||
MachineScopeMode = "CENTRAL",
|
MachineScopeMode = "CENTRAL",
|
||||||
ScopedMachineIps = new List<string>(),
|
ScopedMachineIps = new List<string>(),
|
||||||
|
TerryAttendanceMachineIps = new List<string>(),
|
||||||
EnableUserSync = false,
|
EnableUserSync = false,
|
||||||
SyncIntervalMinutes = 60,
|
SyncIntervalMinutes = 60,
|
||||||
SourceDeviceId = "",
|
SourceDeviceId = "",
|
||||||
|
|
@ -402,6 +410,7 @@ public sealed class HikvisionAttendanceWindowsService : ServiceBase
|
||||||
TemplateFetchIntervalHours = 4,
|
TemplateFetchIntervalHours = 4,
|
||||||
MachineScopeMode = "CENTRAL",
|
MachineScopeMode = "CENTRAL",
|
||||||
ScopedMachineIps = new List<string>(),
|
ScopedMachineIps = new List<string>(),
|
||||||
|
TerryAttendanceMachineIps = new List<string>(),
|
||||||
EnableUserSync = false,
|
EnableUserSync = false,
|
||||||
SyncIntervalMinutes = 60,
|
SyncIntervalMinutes = 60,
|
||||||
SourceDeviceId = "",
|
SourceDeviceId = "",
|
||||||
|
|
@ -574,6 +583,8 @@ public sealed class HikvisionAttendanceWindowsService : ServiceBase
|
||||||
cfg.MachineScopeMode = overlay.MachineScopeMode;
|
cfg.MachineScopeMode = overlay.MachineScopeMode;
|
||||||
if (overlay.ScopedMachineIps != null)
|
if (overlay.ScopedMachineIps != null)
|
||||||
cfg.ScopedMachineIps = new List<string>(overlay.ScopedMachineIps);
|
cfg.ScopedMachineIps = new List<string>(overlay.ScopedMachineIps);
|
||||||
|
if (overlay.TerryAttendanceMachineIps != null)
|
||||||
|
cfg.TerryAttendanceMachineIps = new List<string>(overlay.TerryAttendanceMachineIps);
|
||||||
cfg.EnableTemplateDeviceToDbSync = overlay.EnableTemplateDeviceToDbSync;
|
cfg.EnableTemplateDeviceToDbSync = overlay.EnableTemplateDeviceToDbSync;
|
||||||
cfg.EnableTemplateDbToDeviceSync = overlay.EnableTemplateDbToDeviceSync;
|
cfg.EnableTemplateDbToDeviceSync = overlay.EnableTemplateDbToDeviceSync;
|
||||||
if (overlay.SourceMachineIp != null)
|
if (overlay.SourceMachineIp != null)
|
||||||
|
|
@ -618,6 +629,9 @@ public sealed class HikvisionAttendanceWindowsService : ServiceBase
|
||||||
cfg.ScopedMachineIps ??= new List<string>();
|
cfg.ScopedMachineIps ??= new List<string>();
|
||||||
for (int i = 0; i < cfg.ScopedMachineIps.Count; i++)
|
for (int i = 0; i < cfg.ScopedMachineIps.Count; i++)
|
||||||
cfg.ScopedMachineIps[i] = (cfg.ScopedMachineIps[i] ?? "").Trim();
|
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)
|
if (cfg.TargetDeviceIds == null)
|
||||||
cfg.TargetDeviceIds = new List<string>();
|
cfg.TargetDeviceIds = new List<string>();
|
||||||
else
|
else
|
||||||
|
|
@ -666,6 +680,12 @@ public sealed class HikvisionAttendanceWindowsService : ServiceBase
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public List<string> ScopedMachineIps { get; set; } = new List<string>();
|
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]
|
[DataMember]
|
||||||
public bool EnableTemplateDeviceToDbSync { get; set; }
|
public bool EnableTemplateDeviceToDbSync { get; set; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -316,6 +316,8 @@ internal enum AttendancePersistOutcome
|
||||||
{
|
{
|
||||||
Duplicate,
|
Duplicate,
|
||||||
SkippedNoEmployee,
|
SkippedNoEmployee,
|
||||||
|
UnmappedEmployee,
|
||||||
|
UnsupportedWorkerType,
|
||||||
DbInserted,
|
DbInserted,
|
||||||
DbFailed,
|
DbFailed,
|
||||||
PersistedWithoutDb
|
PersistedWithoutDb
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue