collection_logs table. ScanService validates code state (active only; used = duplicate, expired = expired, unassigned/allocated = invalid), geo proximity (≤200m from DOP via ST_Distance_Sphere), then atomically transitions code -> Used and writes a CollectionLog. Scans inside a trip context bump trip_stop.total_scans + emit qr_scanned timeline event. Bulk scan endpoint processes each scan independently for offline sync. Triggers QrBalanceLow when household active count drops below threshold. 155 feature tests passing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
28 lines
776 B
PHP
28 lines
776 B
PHP
<?php
|
|
|
|
namespace App\Services\Scan;
|
|
|
|
use App\Models\CollectionLog;
|
|
use App\Models\QrCode;
|
|
|
|
class ScanResult
|
|
{
|
|
public function __construct(
|
|
public readonly bool $accepted,
|
|
public readonly ?QrCode $code = null,
|
|
public readonly ?CollectionLog $log = null,
|
|
public readonly ?string $rejectReason = null,
|
|
public readonly ?string $verificationStatus = null,
|
|
) {}
|
|
|
|
public static function accepted(QrCode $code, CollectionLog $log): self
|
|
{
|
|
return new self(true, $code, $log, null, CollectionLog::STATUS_VALID);
|
|
}
|
|
|
|
public static function reject(string $reason, ?QrCode $code = null, ?string $verificationStatus = null): self
|
|
{
|
|
return new self(false, $code, null, $reason, $verificationStatus);
|
|
}
|
|
}
|