feat(scanner): return scan attempt result context

This commit is contained in:
2026-09-08 08:51:10 -03:00
parent 34058e6a81
commit 67bcb420e4
5 changed files with 55 additions and 11 deletions

View File

@@ -3,10 +3,13 @@
namespace App\Domains\Ticket\Controllers\Scanner; namespace App\Domains\Ticket\Controllers\Scanner;
use App\Domains\Auth\Models\User; use App\Domains\Auth\Models\User;
use App\Domains\Ticket\Resources\Scanner\ScannerScanResultResource;
use App\Domains\Ticket\Resources\TicketResource; use App\Domains\Ticket\Resources\TicketResource;
use App\Domains\Ticket\Services\ScannerTicketService; use App\Domains\Ticket\Services\ScannerTicketService;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class TicketController extends Controller class TicketController extends Controller
{ {
@@ -22,13 +25,13 @@ class TicketController extends Controller
); );
} }
public function scan(Request $request): TicketResource public function scan(Request $request): JsonResponse
{ {
/** @var User $scanner */ /** @var User $scanner */
$scanner = $request->user(); $scanner = $request->user();
return TicketResource::make( return ScannerScanResultResource::make(
$this->ticketService->scan($scanner, $request->input('data')) $this->ticketService->scan($scanner, $request->input('data'))
); )->response()->setStatusCode(Response::HTTP_OK);
} }
} }

View File

@@ -16,8 +16,10 @@ class ScanAttemptResource extends JsonResource
return [ return [
'id' => $this->id, 'id' => $this->id,
'data' => $this->data, 'data' => $this->data,
'ticket_id' => $this->ticket_id,
'ticket' => $this->ticket?->ticket, 'ticket' => $this->ticket?->ticket,
'attempted_at' => $this->created_at, 'attempted_at' => $this->created_at,
'resolved_at' => $this->resolved_at,
'result' => $this->result->value, 'result' => $this->result->value,
'can_view_ticket' => $this->ticket !== null 'can_view_ticket' => $this->ticket !== null
&& $this->result !== ScanAttemptResult::CategoryForbidden, && $this->result !== ScanAttemptResult::CategoryForbidden,

View File

@@ -0,0 +1,28 @@
<?php
namespace App\Domains\Ticket\Resources\Scanner;
use App\Domains\Ticket\Models\ScanAttempt;
use App\Domains\Ticket\Resources\TicketResource;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
/** @mixin ScanAttempt */
class ScannerScanResultResource extends JsonResource
{
/** @return array<string, mixed> */
public function toArray(Request $request): array
{
$ticket = $this->ticket;
$client = $ticket?->user;
return [
'scan_attempt' => ScanAttemptResource::make($this->resource),
'ticket' => $ticket === null ? null : TicketResource::make($ticket),
'client' => $client === null ? null : [
'id' => $client->id,
'nombre_apellido' => $client->nombre_apellido,
],
];
}
}

View File

@@ -98,7 +98,7 @@ class ScannerTicketService
return $query->firstOrFail(); return $query->firstOrFail();
} }
public function scan(User $scanner, mixed $scannedData): Ticket public function scan(User $scanner, mixed $scannedData): ScanAttempt
{ {
$scanAttempt = ScanAttempt::query()->create([ $scanAttempt = ScanAttempt::query()->create([
'tenant_code' => $scanner->tenant_codigo, 'tenant_code' => $scanner->tenant_codigo,
@@ -125,7 +125,7 @@ class ScannerTicketService
$scanAttempt, $scanAttempt,
&$ticketId, &$ticketId,
&$failureResult, &$failureResult,
): Ticket { ): ScanAttempt {
$ticket = $this->baseQuery() $ticket = $this->baseQuery()
->where('tenant_code', $scanner->tenant_codigo) ->where('tenant_code', $scanner->tenant_codigo)
->where('ticket', $scannedData) ->where('ticket', $scannedData)
@@ -172,7 +172,9 @@ class ScannerTicketService
$ticketId, $ticketId,
); );
return $ticket->refresh()->load($this->relations()); $ticket = $ticket->refresh()->load($this->relations());
return $scanAttempt->refresh()->setRelation('ticket', $ticket);
}); });
} catch (Throwable $exception) { } catch (Throwable $exception) {
$result = $exception instanceof ModelNotFoundException $result = $exception instanceof ModelNotFoundException

View File

@@ -87,7 +87,9 @@ class ScannerTicketControllerTest extends TestCase
->assertJsonCount(2, 'data') ->assertJsonCount(2, 'data')
->assertJsonPath('data.0.id', $newer->id) ->assertJsonPath('data.0.id', $newer->id)
->assertJsonPath('data.0.data', $newer->data) ->assertJsonPath('data.0.data', $newer->data)
->assertJsonPath('data.0.ticket_id', $newerTicket->id)
->assertJsonPath('data.0.ticket', $newerTicket->ticket) ->assertJsonPath('data.0.ticket', $newerTicket->ticket)
->assertJsonPath('data.0.resolved_at', $newer->resolved_at->toJSON())
->assertJsonPath('data.0.result', ScanAttemptResult::Accepted->value) ->assertJsonPath('data.0.result', ScanAttemptResult::Accepted->value)
->assertJsonPath('data.0.can_view_ticket', true) ->assertJsonPath('data.0.can_view_ticket', true)
->assertJsonPath('data.1.id', $older->id) ->assertJsonPath('data.1.id', $older->id)
@@ -194,10 +196,17 @@ class ScannerTicketControllerTest extends TestCase
$this->postJson('/api/v1/scanner/tickets/scan', ['data' => $ticket->ticket]) $this->postJson('/api/v1/scanner/tickets/scan', ['data' => $ticket->ticket])
->assertOk() ->assertOk()
->assertJsonPath('data.ticket', $ticket->ticket) ->assertJsonPath('data.scan_attempt.data', $ticket->ticket)
->assertJsonPath('data.scanner_user_id', $this->scanner->id) ->assertJsonPath('data.scan_attempt.ticket_id', $ticket->id)
->assertJsonPath('data.is_valid', false) ->assertJsonPath('data.scan_attempt.ticket', $ticket->ticket)
->assertJsonPath('data.is_used', true); ->assertJsonPath('data.scan_attempt.result', ScanAttemptResult::Accepted->value)
->assertJsonPath('data.ticket.ticket', $ticket->ticket)
->assertJsonPath('data.ticket.scanner_user_id', $this->scanner->id)
->assertJsonPath('data.ticket.is_valid', false)
->assertJsonPath('data.ticket.is_used', true)
->assertJsonPath('data.ticket.client', $this->ticketOwner->nombre_apellido)
->assertJsonPath('data.client.id', $this->ticketOwner->id)
->assertJsonPath('data.client.nombre_apellido', $this->ticketOwner->nombre_apellido);
$this->assertDatabaseHas('tickets', [ $this->assertDatabaseHas('tickets', [
'id' => $ticket->id, 'id' => $ticket->id,
@@ -308,7 +317,7 @@ class ScannerTicketControllerTest extends TestCase
$this->postJson('/api/v1/scanner/tickets/scan', ['data' => $ticket->ticket]) $this->postJson('/api/v1/scanner/tickets/scan', ['data' => $ticket->ticket])
->assertOk() ->assertOk()
->assertJsonPath('data.scanner_user_id', $this->scanner->id); ->assertJsonPath('data.ticket.scanner_user_id', $this->scanner->id);
} }
public function test_disabled_category_validation_does_not_allow_scanning_another_tenant(): void public function test_disabled_category_validation_does_not_allow_scanning_another_tenant(): void