Visitor management app with SSO, kiosk, badges, reports, and Gitea CI deploy to frontdesk.ladill.com. Co-authored-by: Cursor <cursoragent@cursor.com>
66 lines
2.2 KiB
PHP
66 lines
2.2 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Http\Controllers\Api\Concerns\ScopesToOwner;
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Device;
|
|
use App\Models\OfflineCheckIn;
|
|
use App\Models\Organization;
|
|
use App\Services\Frontdesk\DeviceService;
|
|
use App\Services\Frontdesk\VisitCheckInService;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
|
|
class OfflineSyncController extends Controller
|
|
{
|
|
public function store(Request $request, DeviceService $devices, VisitCheckInService $checkIn): JsonResponse
|
|
{
|
|
$token = $request->header('X-Device-Token') ?? $request->input('device_token');
|
|
abort_unless(is_string($token) && $token !== '', 422);
|
|
|
|
$device = $devices->findByToken($token);
|
|
abort_unless($device, 404);
|
|
|
|
$validated = $request->validate([
|
|
'client_id' => ['required', 'uuid'],
|
|
'payload' => ['required', 'array'],
|
|
'payload.full_name' => ['required', 'string', 'max:255'],
|
|
'payload.visitor_type' => ['required', 'string'],
|
|
'payload.policies_accepted' => ['required', 'boolean'],
|
|
]);
|
|
|
|
$existing = OfflineCheckIn::where('client_id', $validated['client_id'])->first();
|
|
if ($existing?->visit_id) {
|
|
return response()->json([
|
|
'visit_id' => $existing->visit_id,
|
|
'status' => 'already_synced',
|
|
]);
|
|
}
|
|
|
|
$organization = Organization::findOrFail($device->organization_id);
|
|
$payload = array_merge($validated['payload'], [
|
|
'branch_id' => $device->branch_id,
|
|
'reception_desk_id' => $device->reception_desk_id,
|
|
]);
|
|
|
|
$visit = $checkIn->checkIn($device->owner_ref, $organization, $payload);
|
|
|
|
OfflineCheckIn::updateOrCreate(
|
|
['client_id' => $validated['client_id']],
|
|
[
|
|
'device_id' => $device->id,
|
|
'payload' => $validated['payload'],
|
|
'synced_at' => now(),
|
|
'visit_id' => $visit->id,
|
|
],
|
|
);
|
|
|
|
return response()->json([
|
|
'visit_id' => $visit->id,
|
|
'public_id' => $visit->public_id,
|
|
'status' => 'synced',
|
|
], 201);
|
|
}
|
|
}
|