feat(scanner): update scan handling to return results for invalid QR data and other scan conditions

This commit is contained in:
2026-09-09 12:49:27 -03:00
parent 64e965aff7
commit cac4fcf2b2
2 changed files with 39 additions and 40 deletions

View File

@@ -11,13 +11,10 @@ use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
use Throwable;
class ScannerTicketService
{
private const INVALID_QR_MESSAGE = 'El QR proporcionado es inválido.';
/**
* @param array{q?: string|null, page?: int, per_page?: int} $filters
* @return LengthAwarePaginator<ScanAttempt>
@@ -188,13 +185,10 @@ class ScannerTicketService
if (! is_string($scannedData) || ! Str::isUuid($scannedData)) {
$this->resolveScanAttempt($scanAttempt, ScanAttemptResult::InvalidQr);
throw ValidationException::withMessages([
'data' => self::INVALID_QR_MESSAGE,
]);
return $scanAttempt->refresh();
}
$ticketId = null;
$failureResult = null;
try {
return DB::transaction(function () use (
@@ -202,7 +196,6 @@ class ScannerTicketService
$scannedData,
$scanAttempt,
&$ticketId,
&$failureResult,
): ScanAttempt {
$ticket = $this->baseQuery()
->where('tenant_code', $scanner->tenant_codigo)
@@ -212,31 +205,32 @@ class ScannerTicketService
$ticketId = (int) $ticket->getKey();
if (! $this->scannerCanScan($scanner, $ticket)) {
$failureResult = ScanAttemptResult::CategoryForbidden;
$this->resolveScanAttempt(
$scanAttempt,
ScanAttemptResult::CategoryForbidden,
$ticketId,
);
throw ValidationException::withMessages([
'ticket' => __('api.ticket.scanner_category_forbidden'),
]);
return $scanAttempt->refresh()->setRelation('ticket', $ticket);
}
if ($ticket->is_used) {
$failureResult = ScanAttemptResult::AlreadyScanned;
$this->resolveScanAttempt(
$scanAttempt,
ScanAttemptResult::AlreadyScanned,
$ticketId,
);
throw ValidationException::withMessages([
'ticket' => __('api.ticket.already_scanned'),
]);
return $scanAttempt->refresh()->setRelation('ticket', $ticket);
}
if (! $ticket->is_valid) {
$failureResult = $ticket->is_expired
$result = $ticket->is_expired
? ScanAttemptResult::Expired
: ScanAttemptResult::NotValid;
$this->resolveScanAttempt($scanAttempt, $result, $ticketId);
throw ValidationException::withMessages([
'ticket' => $ticket->is_expired
? __('api.ticket.expired_for_scan')
: __('api.ticket.not_valid_for_scan'),
]);
return $scanAttempt->refresh()->setRelation('ticket', $ticket);
}
$ticket->forceFill([
@@ -254,14 +248,15 @@ class ScannerTicketService
return $scanAttempt->refresh()->setRelation('ticket', $ticket);
});
} catch (ModelNotFoundException) {
$this->resolveScanAttempt($scanAttempt, ScanAttemptResult::TicketNotFound);
return $scanAttempt->refresh();
} catch (Throwable $exception) {
$result = $exception instanceof ModelNotFoundException
? ScanAttemptResult::TicketNotFound
: ($failureResult ?? ScanAttemptResult::UnexpectedError);
report($exception);
$this->resolveScanAttempt($scanAttempt, ScanAttemptResult::UnexpectedError, $ticketId);
$this->resolveScanAttempt($scanAttempt, $result, $ticketId);
throw $exception;
return $scanAttempt->refresh();
}
}