feat: support template load by serial and department

Batched template queries and department-based employee selection.
main
SYED MUSTUFA AHMED NAQVI 2026-09-04 12:41:02 +05:00
parent 6bb23a93ab
commit b9f2216207
1 changed files with 84 additions and 0 deletions

View File

@ -69,6 +69,7 @@ namespace HanvonF710XAttendanceService
using (var cmd = new MySqlCommand(query, connection))
{
cmd.CommandTimeout = 300;
for (int i = 0; i < chunk.Length; i++)
{
cmd.Parameters.AddWithValue(parameterNames[i], chunk[i]);
@ -178,6 +179,89 @@ namespace HanvonF710XAttendanceService
return result.ToList();
}
/// <summary>
/// Active template serial numbers for employees in the given departments (HRMS employees table).
/// When department lookup is unavailable, returns an empty list and the caller should fall back.
/// </summary>
public List<string> GetActiveSerialNumbersByDepartmentIds(
MySqlConnection connection,
IReadOnlyList<string> departmentIds,
IReadOnlyList<string> allowedMachineIds)
{
var result = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
if (departmentIds == null || departmentIds.Count == 0)
{
return new List<string>();
}
var machineIds = (allowedMachineIds ?? Array.Empty<string>())
.Where(id => !string.IsNullOrWhiteSpace(id))
.Select(id => id.Trim())
.Distinct(StringComparer.OrdinalIgnoreCase)
.ToList();
const int chunkSize = 80;
for (int offset = 0; offset < departmentIds.Count; offset += chunkSize)
{
var deptChunk = departmentIds.Skip(offset).Take(chunkSize).ToArray();
var deptParamNames = new List<string>(deptChunk.Length);
for (int i = 0; i < deptChunk.Length; i++)
{
deptParamNames.Add("@Dept" + i);
}
string deptInClause = string.Join(",", deptParamNames);
string machineJoin = "";
string machineFilter = "";
if (machineIds.Count > 0)
{
var machineParamNames = new List<string>(machineIds.Count);
for (int i = 0; i < machineIds.Count; i++)
{
machineParamNames.Add("@Mid" + i);
}
machineJoin = " INNER JOIN hrms.attendance_machine_user u ON u.serial_number = t.serial_no AND u.is_deleted = 0 ";
machineFilter = " AND u.machine_id IN (" + string.Join(",", machineParamNames) + ") ";
}
string query =
"SELECT DISTINCT t.serial_no " +
"FROM hrms.attendance_machine_face_templates t " +
"INNER JOIN hrms.employee e ON CAST(e.emp_id AS CHAR) = t.serial_no " +
machineJoin +
"WHERE t.is_active = 1 AND e.department_id IN (" + deptInClause + ")" +
machineFilter;
using (var cmd = new MySqlCommand(query, connection))
{
cmd.CommandTimeout = 120;
for (int i = 0; i < deptChunk.Length; i++)
{
cmd.Parameters.AddWithValue(deptParamNames[i], deptChunk[i]);
}
for (int i = 0; i < machineIds.Count; i++)
{
cmd.Parameters.AddWithValue("@Mid" + i, machineIds[i]);
}
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
if (reader.IsDBNull(0)) continue;
var s = reader.GetString(0);
if (!string.IsNullOrWhiteSpace(s))
{
result.Add(s.Trim());
}
}
}
}
}
return result.ToList();
}
/// <summary>
/// Active templates for employees registered on a specific Nedo machine.
/// Registration-based target selection: attendance_machine_user (is_deleted=0) drives which employees are allowed.