Я пытаюсь извлечь/сохранить время на срок от биометрии ZKTECO, чтобы обновить существующую запись часов пользователя. Я могу получить/сохранить время пользовательского времени, но для Clack Out он не вставляется в столбец тайм-аута . Существующая запись посещаемости найдена, но возвращает ошибку. < /P>
[2025-01-24 18:00:44] local.INFO: Fetched 2 attendance logs from device: Office
[2025-01-24 18:00:44] local.DEBUG: Processing log: {"uid":41,"id":"1","state":1,"timestamp":"2025-01-24 17:32:59","type":1}
[2025-01-24 18:00:44] local.INFO: Attendance saved for user: Albert (Biometric ID: 1)
[2025-01-24 18:00:44] local.DEBUG: Processing log: {"uid":42,"id":"1","state":1,"timestamp":"2025-01-24 17:33:05","type":2}
[2025-01-24 18:00:44] local.INFO: Attendance record ID before saving: 1280
[2025-01-24 18:00:44] local.ERROR: Error updating attendance record: Attempt to read property "id" on null
[2025-01-24 18:00:44] local.INFO: Attendance saved for user: Albert (Biometric ID: 1)
[2025-01-24 18:00:44] local.INFO: Attendance fetching process completed.
< /code>
Я ожидал, что такта-выход (тип 2) будет вставлен в существующую запись в часах пользователя. < /p>
Вот мой код . < /p>
public function handle()
{
$devices = BiometricDevice::all();
$today = Carbon::today();
foreach ($devices as $device) {
$this->info("Connecting to device: {$device->device_name}");
Log::info("Attempting to connect to device: {$device->device_name} (IP: {$device->ip_address}, Port: {$device->port})");
try {
$zk = new ZKTeco($device->ip_address, $device->port);
if (!$zk->connect()) {
$this->warn("Failed to connect to device: {$device->device_name}");
Log::error("Failed to connect to device: {$device->device_name} (IP: {$device->ip_address})");
continue;
}
Log::info("Successfully connected to device: {$device->device_name}");
$logs = $zk->getAttendance();
if (empty($logs)) {
$this->warn("No logs fetched from device: {$device->device_name}");
Log::warning("No logs fetched from device: {$device->device_name}");
$zk->disconnect();
continue;
}
Log::info("Fetched " . count($logs) . " attendance logs from device: {$device->device_name}");
$zk->disconnect();
foreach ($logs as $log) {
// Validate log structure
if (empty($log['uid']) || empty($log['timestamp']) || !strtotime($log['timestamp'])) {
$this->warn("Invalid log data: " . json_encode($log));
Log::warning("Invalid log data: " . json_encode($log));
continue;
}
$logDate = Carbon::parse($log['timestamp'])->toDateString();
// Process only today's logs
if ($logDate === $today->toDateString()) {
Log::debug("Processing log: " . json_encode($log));
try {
// Match user using empNumber and biometric ID
$user = User::where('empNumber', $log['id'])->first();
if (!$user) {
Log::error("No user found with empNumber: {$log['id']}");
continue;
}
if ($user) {
// shift schedule
$shiftSchedule = ShiftSchedule::where('users_id', $user->id)
->where('date', $logDate)
->first();
if (!$shiftSchedule) {
Log::warning("Shift schedule not found for user: {$user->name} on date: {$logDate}");
continue;
}
$status = 'On Time';
$totalLate = '00:00:00';
$timeEnd = null;
$shiftOver = null;
$timeIn = Carbon::parse($log['timestamp'], 'Asia/Manila');
if (!$shiftSchedule->isFlexibleTime) {
$shiftStart = Carbon::parse($shiftSchedule->shiftStart, 'Asia/Manila');
$lateThreshold = Carbon::parse($shiftSchedule->lateThreshold, 'Asia/Manila');
$shiftEnd = Carbon::parse($shiftSchedule->shiftEnd, 'Asia/Manila');
// late
if ($timeIn->gt($lateThreshold)) {
$status = 'Late';
$totalLateInSeconds = $timeIn->diffInSeconds($lateThreshold);
$hours = floor($totalLateInSeconds / 3600);
$minutes = floor(($totalLateInSeconds % 3600) / 60);
$seconds = $totalLateInSeconds % 60;
$totalLate = sprintf('%02d:%02d:%02d', $hours, $minutes, $seconds);
}
//
$allowedHours = Carbon::parse($shiftSchedule->allowedHours)->secondsSinceMidnight();
$calculatedTimeEnd = $timeIn->copy()->addSeconds($allowedHours)->addHour();
//
if ($calculatedTimeEnd->greaterThan($shiftEnd)) {
$timeEnd = $shiftEnd->format('h:i:s A');
} else {
$timeEnd = $calculatedTimeEnd->format('h:i:s A');
}
$shiftOver = $shiftEnd->format('h:i:s A');
}
if ($log['type'] == 1) { // Clock In
$attendance = EmployeeAttendance::firstOrNew(
[
'users_id' => $user->id,
'date' => $logDate,
]
);
if (is_null($attendance->timeIn) || $timeIn->lt(Carbon::parse($attendance->timeIn))) {
$attendance->timeIn = $timeIn->format('H:i:s');
$attendance->status = $status;
$attendance->totalLate = $totalLate;
$attendance->timeEnd = $timeEnd;
$attendance->shiftOver = $shiftOver;
}
$attendance->biometric_device_id = $device->id;
$attendance->device = 'Biometrics';
$attendance->status_code = 'Active';
$attendance->biometric_user_id = $log['id'];
$attendance->save();
} elseif ($log['type'] == 2) {
$attendanceRecord = EmployeeAttendance::where('biometric_user_id', $log['id'])
->where('date', Carbon::parse($log['timestamp'])->format('Y-m-d'))
->first();
if (!$attendanceRecord) {
Log::error("Attendance record not found for biometric ID: {$log['id']} on " . Carbon::parse($log['timestamp'])->format('Y-m-d'));
continue;
}
$attendanceId = $attendanceRecord->getAttribute('id');
if (!$attendanceId) {
Log::error("Attendance ID is null after retrieval.");
continue;
}
Log::info("Attendance record ID before saving: {$attendanceId}");
try {
EmployeeAttendance::unguard();
$attendanceRecord->timeOut = Carbon::parse($log['timestamp'])->format('H:i:s');
$attendanceRecord->save();
EmployeeAttendance::reguard();
Log::info("Clock-out time saved successfully for biometric ID: {$log['id']} at {$attendanceRecord->timeOut}");
} catch (\Exception $e) {
Log::error("Error updating attendance record: " . $e->getMessage());
}
}
$this->info("Attendance saved for {$user->name}");
Log::info("Attendance saved for user: {$user->name} (Biometric ID: {$log['id']})");
} else {
$this->warn("No matching user for biometric ID {$log['id']}.");
Log::warning("No matching user found for biometric ID: {$log['id']} on device: {$device->device_name}");
Log::debug("Query result: " . json_encode(User::where('empNumber', $log['id'])->get()));
}
} catch (\Exception $logException) {
$this->error("Error processing log for device: {$device->device_name} | Log: " . json_encode($log));
Log::error("Error processing log: " . json_encode($log) . " | Exception: " . $logException->getMessage());
}
}
}
} catch (\Exception $e) {
$this->error("Error occurred while processing device: {$device->device_name}. Exception: {$e->getMessage()}");
Log::error("Exception on device: {$device->device_name} - " . $e->getMessage() . " | Trace: " . $e->getTraceAsString());
}
}
$this->info('Attendance fetching completed!');
Log::info('Attendance fetching process completed.');
}
Подробнее здесь: https://stackoverflow.com/questions/794 ... biometrics
Как сэкономить время на срок от биометрии ZKTECO? ⇐ Php
Кемеровские программисты php общаются здесь
-
Anonymous
1739459050
Anonymous
Я пытаюсь извлечь/сохранить время на срок от биометрии ZKTECO, чтобы обновить существующую запись часов пользователя. Я могу получить/сохранить время пользовательского времени, но для Clack Out он не вставляется в столбец тайм-аута . Существующая запись посещаемости найдена, но возвращает ошибку. < /P>
[2025-01-24 18:00:44] local.INFO: Fetched 2 attendance logs from device: Office
[2025-01-24 18:00:44] local.DEBUG: Processing log: {"uid":41,"id":"1","state":1,"timestamp":"2025-01-24 17:32:59","type":1}
[2025-01-24 18:00:44] local.INFO: Attendance saved for user: Albert (Biometric ID: 1)
[2025-01-24 18:00:44] local.DEBUG: Processing log: {"uid":42,"id":"1","state":1,"timestamp":"2025-01-24 17:33:05","type":2}
[2025-01-24 18:00:44] local.INFO: Attendance record ID before saving: 1280
[2025-01-24 18:00:44] local.ERROR: Error updating attendance record: Attempt to read property "id" on null
[2025-01-24 18:00:44] local.INFO: Attendance saved for user: Albert (Biometric ID: 1)
[2025-01-24 18:00:44] local.INFO: Attendance fetching process completed.
< /code>
Я ожидал, что такта-выход (тип 2) будет вставлен в существующую запись в часах пользователя. < /p>
Вот мой код . < /p>
public function handle()
{
$devices = BiometricDevice::all();
$today = Carbon::today();
foreach ($devices as $device) {
$this->info("Connecting to device: {$device->device_name}");
Log::info("Attempting to connect to device: {$device->device_name} (IP: {$device->ip_address}, Port: {$device->port})");
try {
$zk = new ZKTeco($device->ip_address, $device->port);
if (!$zk->connect()) {
$this->warn("Failed to connect to device: {$device->device_name}");
Log::error("Failed to connect to device: {$device->device_name} (IP: {$device->ip_address})");
continue;
}
Log::info("Successfully connected to device: {$device->device_name}");
$logs = $zk->getAttendance();
if (empty($logs)) {
$this->warn("No logs fetched from device: {$device->device_name}");
Log::warning("No logs fetched from device: {$device->device_name}");
$zk->disconnect();
continue;
}
Log::info("Fetched " . count($logs) . " attendance logs from device: {$device->device_name}");
$zk->disconnect();
foreach ($logs as $log) {
// Validate log structure
if (empty($log['uid']) || empty($log['timestamp']) || !strtotime($log['timestamp'])) {
$this->warn("Invalid log data: " . json_encode($log));
Log::warning("Invalid log data: " . json_encode($log));
continue;
}
$logDate = Carbon::parse($log['timestamp'])->toDateString();
// Process only today's logs
if ($logDate === $today->toDateString()) {
Log::debug("Processing log: " . json_encode($log));
try {
// Match user using empNumber and biometric ID
$user = User::where('empNumber', $log['id'])->first();
if (!$user) {
Log::error("No user found with empNumber: {$log['id']}");
continue;
}
if ($user) {
// shift schedule
$shiftSchedule = ShiftSchedule::where('users_id', $user->id)
->where('date', $logDate)
->first();
if (!$shiftSchedule) {
Log::warning("Shift schedule not found for user: {$user->name} on date: {$logDate}");
continue;
}
$status = 'On Time';
$totalLate = '00:00:00';
$timeEnd = null;
$shiftOver = null;
$timeIn = Carbon::parse($log['timestamp'], 'Asia/Manila');
if (!$shiftSchedule->isFlexibleTime) {
$shiftStart = Carbon::parse($shiftSchedule->shiftStart, 'Asia/Manila');
$lateThreshold = Carbon::parse($shiftSchedule->lateThreshold, 'Asia/Manila');
$shiftEnd = Carbon::parse($shiftSchedule->shiftEnd, 'Asia/Manila');
// late
if ($timeIn->gt($lateThreshold)) {
$status = 'Late';
$totalLateInSeconds = $timeIn->diffInSeconds($lateThreshold);
$hours = floor($totalLateInSeconds / 3600);
$minutes = floor(($totalLateInSeconds % 3600) / 60);
$seconds = $totalLateInSeconds % 60;
$totalLate = sprintf('%02d:%02d:%02d', $hours, $minutes, $seconds);
}
//
$allowedHours = Carbon::parse($shiftSchedule->allowedHours)->secondsSinceMidnight();
$calculatedTimeEnd = $timeIn->copy()->addSeconds($allowedHours)->addHour();
//
if ($calculatedTimeEnd->greaterThan($shiftEnd)) {
$timeEnd = $shiftEnd->format('h:i:s A');
} else {
$timeEnd = $calculatedTimeEnd->format('h:i:s A');
}
$shiftOver = $shiftEnd->format('h:i:s A');
}
if ($log['type'] == 1) { // Clock In
$attendance = EmployeeAttendance::firstOrNew(
[
'users_id' => $user->id,
'date' => $logDate,
]
);
if (is_null($attendance->timeIn) || $timeIn->lt(Carbon::parse($attendance->timeIn))) {
$attendance->timeIn = $timeIn->format('H:i:s');
$attendance->status = $status;
$attendance->totalLate = $totalLate;
$attendance->timeEnd = $timeEnd;
$attendance->shiftOver = $shiftOver;
}
$attendance->biometric_device_id = $device->id;
$attendance->device = 'Biometrics';
$attendance->status_code = 'Active';
$attendance->biometric_user_id = $log['id'];
$attendance->save();
} elseif ($log['type'] == 2) {
$attendanceRecord = EmployeeAttendance::where('biometric_user_id', $log['id'])
->where('date', Carbon::parse($log['timestamp'])->format('Y-m-d'))
->first();
if (!$attendanceRecord) {
Log::error("Attendance record not found for biometric ID: {$log['id']} on " . Carbon::parse($log['timestamp'])->format('Y-m-d'));
continue;
}
$attendanceId = $attendanceRecord->getAttribute('id');
if (!$attendanceId) {
Log::error("Attendance ID is null after retrieval.");
continue;
}
Log::info("Attendance record ID before saving: {$attendanceId}");
try {
EmployeeAttendance::unguard();
$attendanceRecord->timeOut = Carbon::parse($log['timestamp'])->format('H:i:s');
$attendanceRecord->save();
EmployeeAttendance::reguard();
Log::info("Clock-out time saved successfully for biometric ID: {$log['id']} at {$attendanceRecord->timeOut}");
} catch (\Exception $e) {
Log::error("Error updating attendance record: " . $e->getMessage());
}
}
$this->info("Attendance saved for {$user->name}");
Log::info("Attendance saved for user: {$user->name} (Biometric ID: {$log['id']})");
} else {
$this->warn("No matching user for biometric ID {$log['id']}.");
Log::warning("No matching user found for biometric ID: {$log['id']} on device: {$device->device_name}");
Log::debug("Query result: " . json_encode(User::where('empNumber', $log['id'])->get()));
}
} catch (\Exception $logException) {
$this->error("Error processing log for device: {$device->device_name} | Log: " . json_encode($log));
Log::error("Error processing log: " . json_encode($log) . " | Exception: " . $logException->getMessage());
}
}
}
} catch (\Exception $e) {
$this->error("Error occurred while processing device: {$device->device_name}. Exception: {$e->getMessage()}");
Log::error("Exception on device: {$device->device_name} - " . $e->getMessage() . " | Trace: " . $e->getTraceAsString());
}
}
$this->info('Attendance fetching completed!');
Log::info('Attendance fetching process completed.');
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79436701/how-to-save-my-clock-out-time-from-zkteco-biometrics[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия