feat(scanner): scope login tickets scanning and history by event

This commit is contained in:
2026-09-30 15:31:56 -03:00
parent 86ca57a3ad
commit bebf6a7ed5
10 changed files with 549 additions and 3 deletions

View File

@@ -11,6 +11,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
#[Fillable([
'tenant_code',
'event_id',
'scanner_user_id',
'ticket_id',
'data',
@@ -43,6 +44,7 @@ class ScanAttempt extends Model
{
return [
'scanner_user_id' => 'integer',
'event_id' => 'integer',
'ticket_id' => 'integer',
'result' => ScanAttemptResult::class,
'created_at' => 'datetime',

View File

@@ -32,7 +32,7 @@ class ScanAttemptResource extends JsonResource
ScanAttemptResult::Processing => 'Error',
ScanAttemptResult::Accepted => 'Verificado',
ScanAttemptResult::InvalidQr => 'QR no pertenece al evento',
ScanAttemptResult::TicketNotFound => 'Error',
ScanAttemptResult::TicketNotFound => 'QR no pertenece al evento',
ScanAttemptResult::CategoryForbidden => 'Error',
ScanAttemptResult::AlreadyScanned => 'Usado',
ScanAttemptResult::Expired => 'Vencido',

View File

@@ -3,6 +3,7 @@
namespace App\Domains\Ticketing\Ticket\Services;
use App\Domains\Core\Auth\Models\User;
use App\Domains\Core\Auth\Services\EventScopeService;
use App\Domains\Ticketing\Ticket\Enums\ScanAttemptResult;
use App\Domains\Ticketing\Ticket\Models\ScanAttempt;
use App\Domains\Ticketing\Ticket\Models\Ticket;
@@ -27,6 +28,7 @@ class ScannerTicketService
->with('ticket.sourceCatalogItem.category')
->where('tenant_code', $scanner->tenant_codigo)
->where('scanner_user_id', $scanner->getKey())
->when($this->eventId($scanner) !== null, fn (Builder $query) => $query->where('event_id', $this->eventId($scanner)))
->when($search !== '', function (Builder $query) use ($search): void {
$attemptedAtDate = $this->parseSearchDate($search);
@@ -60,6 +62,7 @@ class ScannerTicketService
->with('ticket.sourceCatalogItem.category')
->where('tenant_code', $scanner->tenant_codigo)
->where('scanner_user_id', $scanner->getKey())
->when($this->eventId($scanner) !== null, fn (Builder $query) => $query->where('event_id', $this->eventId($scanner)))
->when($search !== '', function (Builder $query) use ($search): void {
$attemptedAtDate = $this->parseSearchDate($search);
$attemptedAtDayMonth = $this->parseSearchDayMonth($search);
@@ -106,6 +109,7 @@ class ScannerTicketService
->with('ticket')
->where('tenant_code', $scanner->tenant_codigo)
->where('scanner_user_id', $scanner->getKey())
->when($this->eventId($scanner) !== null, fn (Builder $query) => $query->where('event_id', $this->eventId($scanner)))
->findOrFail($scanAttemptId);
$scanAttempt->ticket?->loadMissing($this->relations());
@@ -113,6 +117,11 @@ class ScannerTicketService
return $scanAttempt;
}
private function eventId(User $scanner): ?int
{
return app(EventScopeService::class)->eventId($scanner);
}
private function parseSearchDate(string $search): ?string
{
if (preg_match('/^(\d{4})-(\d{2})-(\d{2})$/', $search, $matches) === 1) {
@@ -154,7 +163,8 @@ class ScannerTicketService
{
$query = $this->baseQuery()
->where('tenant_code', $scanner->tenant_codigo)
->where('ticket', $ticketUuid);
->where('ticket', $ticketUuid)
->when($this->eventId($scanner) !== null, fn (Builder $query) => $query->where('event_id', $this->eventId($scanner)));
if ($this->requiresCategoryValidation($scanner)) {
$categoryIds = $this->scannerCategoryIds($scanner);
@@ -178,6 +188,7 @@ class ScannerTicketService
$scanAttempt = ScanAttempt::query()->create([
'tenant_code' => $scanner->tenant_codigo,
'scanner_user_id' => $scanner->getKey(),
'event_id' => $this->eventId($scanner),
'data' => $this->serializeScannedData($scannedData),
'result' => ScanAttemptResult::Processing,
]);
@@ -200,6 +211,7 @@ class ScannerTicketService
$ticket = $this->baseQuery()
->where('tenant_code', $scanner->tenant_codigo)
->where('ticket', $scannedData)
->when($this->eventId($scanner) !== null, fn (Builder $query) => $query->where('event_id', $this->eventId($scanner)))
->lockForUpdate()
->firstOrFail();
$ticketId = (int) $ticket->getKey();