CasperSecurity
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Http;
use App\Models\EmployeeRegistration;
use App\Models\EmployeeAttendance;
use Carbon\Carbon;
class ImportBiometricAttendance extends Command
{
protected $signature = 'attendance:import-biometric';
//protected $description = 'Import biometric attendance from API and store in employee_attendances table';
protected $description = 'Import biometric attendance using Bioknox Token API';
public function __construct()
{
parent::__construct();
}
// public function handle()
// {
// $date = Carbon::yesterday()->format('Ymd'); // Previous day
// $apiUrl = "https://api.bioknox.in/api/GetData?license_key=BK2206300011&log_date={$date}&type=J";
//
// $response = Http::get($apiUrl);
//
// if (!$response->successful()) {
// $this->error("API error: " . $response->status());
// return 1;
// }
//
// $data = $response->json();
//
// $grouped = collect($data)->groupBy(function ($item) {
// return $item['device_code'] . '_' . $item['log_date'];
// });
//
// foreach ($grouped as $logs) {
// $sortedLogs = collect($logs)->sortBy('log_time')->values();
// $firstLog = $sortedLogs->first();
// $lastLog = $sortedLogs->last();
//
// $deviceCode = $firstLog['device_code'];
// $logDateFormatted = Carbon::createFromFormat('d-m-Y', $firstLog['log_date'])->format('Y-m-d');
//
// $employee = EmployeeRegistration::where('user_id', $deviceCode)->first();
//
// if ($employee) {
// $exists = EmployeeAttendance::where('employee_id', $employee->id)
// ->where('date', $logDateFormatted)
// ->exists();
//
// if (!$exists) {
// $inTime = $firstLog['log_time'];
// $outTime = (count($sortedLogs) > 1) ? $lastLog['log_time'] : $inTime;
//
// $diff = Carbon::parse($outTime)->diff(Carbon::parse($inTime));
// $workingHours = $diff->h . '.' . str_pad($diff->i, 2, '0', STR_PAD_LEFT);
//
// EmployeeAttendance::create([
// 'employee_id' => $employee->id,
// 'user_id' => $deviceCode,
// 'date' => $logDateFormatted,
// 'attendance_time' => $inTime,
// 'attendance_out_time' => $outTime,
// 'working_hours' => $workingHours,
// 'status' => 1,
// ]);
// }
// }
// }
//
// $this->info('Biometric attendance imported successfully!');
// return 0;
// }
public function handle()
{
try {
// ---------- STEP 1: GENERATE TOKEN ----------
$loginUrl = "https://log.bioknox.in/api/login/login_request";
$loginXml = '<?xml version="1.0" encoding="UTF-8"?>
<login_request>
<username>uiet.tech@gmail.com</username>
<password>Admin@12345</password>
</login_request>';
$loginResponse = Http::withHeaders([
'Content-Type' => 'application/xml',
])->withBody($loginXml, 'application/xml')
->post($loginUrl);
if (!$loginResponse->successful()) {
$this->error("Token API error: " . $loginResponse->status());
return 1;
}
$loginData = $loginResponse->json();
$token = $loginData['token'] ?? null;
if (!$token) {
$this->error("Token not received from Bioknox");
return 1;
}
$this->info("Token generated successfully.");
// ---------- STEP 2: FETCH LOGS ----------
$date = Carbon::yesterday()->format('Y-m-d'); // Fetch logs for yesterday
//$date = '2025-11-20';
$logsUrl = "https://log.bioknox.in/api/logs/get_registered_all";
$logsXml = '<?xml version="1.0" encoding="UTF-8"?>
<request_logs>
<log_date>'.$date.'</log_date>
<out_mode>JSON</out_mode>
</request_logs>';
$logsResponse = Http::withHeaders([
'Authorization' => 'Bearer '.$token,
'Content-Type' => 'application/xml',
])->withBody($logsXml, 'application/xml')
->post($logsUrl);
if (!$logsResponse->successful()) {
$this->error("Logs API error: " . $logsResponse->status());
return 1;
}
$responseData = $logsResponse->json();
// ---------- STEP 3: HANDLE NO DATA ----------
if (isset($responseData['error_code']) && $responseData['error_code'] !== '000') {
$this->info("No biometric data found for date: $date");
return 0;
}
if (!isset($responseData['attendance_logs']) || empty($responseData['attendance_logs'])) {
$this->info("Attendance logs are empty for date: $date");
return 0;
}
$logs = $responseData['attendance_logs'];
// ---------- STEP 4: PROCESS LOGS ----------
$grouped = collect($logs)->groupBy(function ($item) {
return $item['staff_code_in_device'].'_'.$item['log_date'];
});
foreach ($grouped as $logsOfDay) {
$sortedLogs = collect($logsOfDay)
->sortBy('log_time')
->values();
$firstLog = $sortedLogs->first();
$lastLog = $sortedLogs->last();
// Find employee by biometric code
$employee = EmployeeRegistration::where('user_id', $firstLog['staff_code_in_device'])->first();
if (!$employee) continue;
// Check if attendance already exists
$exists = EmployeeAttendance::where('employee_id', $employee->id)
->where('date', Carbon::parse($firstLog['log_date'])->format('Y-m-d'))
->exists();
if ($exists) continue;
$inTime = $firstLog['log_time'];
$outTime = count($sortedLogs) > 1 ? $lastLog['log_time'] : $inTime;
$diff = Carbon::parse($outTime)->diff(Carbon::parse($inTime));
$workingHours = $diff->h . '.' . str_pad($diff->i, 2, '0', STR_PAD_LEFT);
EmployeeAttendance::create([
'employee_id' => $employee->id,
'user_id' => $firstLog['staff_code_in_device'],
'date' => Carbon::parse($firstLog['log_date'])->format('Y-m-d'),
'attendance_time' => $inTime,
'attendance_out_time' => $outTime,
'working_hours' => $workingHours,
'status' => 1,
]);
}
$this->info("Biometric attendance imported successfully for date: $date");
return 0;
} catch (\Exception $e) {
$this->error("Error: " . $e->getMessage());
return 1;
}
}
}