Initial Ladill Frontdesk release with deploy pipeline.
Visitor management app with SSO, kiosk, badges, reports, and Gitea CI deploy to frontdesk.ladill.com. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Frontdesk;
|
||||
|
||||
use App\Models\AuditLog;
|
||||
use App\Models\Organization;
|
||||
use App\Models\Visit;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class VisitScheduleService
|
||||
{
|
||||
public function __construct(
|
||||
protected VisitCheckInService $checkIns,
|
||||
protected WatchlistService $watchlist,
|
||||
protected NotificationDispatcher $notifications,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Pre-register or schedule a future visit without checking in.
|
||||
*
|
||||
* @param array<string, mixed> $data
|
||||
*/
|
||||
public function schedule(string $ownerRef, Organization $organization, array $data, ?string $actorRef = null): Visit
|
||||
{
|
||||
return DB::transaction(function () use ($ownerRef, $organization, $data, $actorRef) {
|
||||
$visitor = $this->checkIns->resolveVisitorForSchedule($ownerRef, $organization, $data);
|
||||
|
||||
$this->watchlist->assertCanCheckIn($visitor);
|
||||
|
||||
$scheduledAt = isset($data['scheduled_at'])
|
||||
? Carbon::parse($data['scheduled_at'])
|
||||
: now();
|
||||
|
||||
$status = $scheduledAt->startOfDay()->isAfter(now()->startOfDay())
|
||||
? Visit::STATUS_SCHEDULED
|
||||
: Visit::STATUS_EXPECTED;
|
||||
|
||||
$visit = Visit::create([
|
||||
'owner_ref' => $ownerRef,
|
||||
'organization_id' => $organization->id,
|
||||
'branch_id' => $data['branch_id'] ?? null,
|
||||
'visitor_id' => $visitor->id,
|
||||
'host_id' => $data['host_id'] ?? null,
|
||||
'visitor_type' => $data['visitor_type'] ?? 'visitor',
|
||||
'status' => $status,
|
||||
'purpose' => $data['purpose'] ?? null,
|
||||
'expected_duration_minutes' => (int) ($data['expected_duration_minutes']
|
||||
?? config('frontdesk.kiosk.default_visit_duration_minutes', 60)),
|
||||
'scheduled_at' => $scheduledAt,
|
||||
'notes' => $data['notes'] ?? null,
|
||||
'external_ref' => $data['external_ref'] ?? null,
|
||||
'source' => $data['source'] ?? null,
|
||||
'integration_metadata' => $data['integration_metadata'] ?? null,
|
||||
]);
|
||||
|
||||
AuditLog::record(
|
||||
$ownerRef,
|
||||
'visit.scheduled',
|
||||
$organization->id,
|
||||
$actorRef,
|
||||
Visit::class,
|
||||
$visit->id,
|
||||
['visitor' => $visitor->full_name, 'scheduled_at' => $scheduledAt->toIso8601String()],
|
||||
);
|
||||
|
||||
if ($status === Visit::STATUS_EXPECTED) {
|
||||
$this->notifications->visitorExpected($visit);
|
||||
}
|
||||
|
||||
return $visit->load(['visitor', 'host']);
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user