From bfb16ef60ea873ce001473647d8a62aca100c605 Mon Sep 17 00:00:00 2001 From: ncoronel Date: Mon, 31 Aug 2026 12:31:13 -0300 Subject: [PATCH] feat(tickets): define tenant-specific table columns --- .../Resources/TicketFilterFormResource.php | 1 + .../Services/TicketFilterFormService.php | 7 +- .../Services/AdminAppTicketColumnService.php | 85 +++++++++++++++++++ ...AdminAppTicketFilterFormControllerTest.php | 22 ++++- 4 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 app/Domains/Ticket/Services/AdminAppTicketColumnService.php diff --git a/app/Domains/Forms/Resources/TicketFilterFormResource.php b/app/Domains/Forms/Resources/TicketFilterFormResource.php index f1f4aa7..f82513c 100644 --- a/app/Domains/Forms/Resources/TicketFilterFormResource.php +++ b/app/Domains/Forms/Resources/TicketFilterFormResource.php @@ -15,6 +15,7 @@ class TicketFilterFormResource extends JsonResource 'action' => $this->resource['action'], 'method' => $this->resource['method'], 'fields' => $this->resource['fields'], + 'columns' => $this->resource['columns'], ]; } } diff --git a/app/Domains/Forms/Services/TicketFilterFormService.php b/app/Domains/Forms/Services/TicketFilterFormService.php index 856fe9c..f9f22bc 100644 --- a/app/Domains/Forms/Services/TicketFilterFormService.php +++ b/app/Domains/Forms/Services/TicketFilterFormService.php @@ -4,12 +4,16 @@ namespace App\Domains\Forms\Services; use App\Domains\Tenant\Models\Tenant; use App\Domains\Ticket\Models\Ticket; +use App\Domains\Ticket\Services\AdminAppTicketColumnService; class TicketFilterFormService { private const FIESTA_FUTBOL_INFANTIL = 'fiesta_futbol_infantil'; - public function __construct(private readonly TicketFormService $ticketFormService) {} + public function __construct( + private readonly TicketFormService $ticketFormService, + private readonly AdminAppTicketColumnService $columnService, + ) {} /** @return array */ public function get(Tenant $tenant): array @@ -28,6 +32,7 @@ class TicketFilterFormService 'action' => '/api/v1/adminapp/tenant/tickets', 'method' => 'GET', 'fields' => $fields, + 'columns' => $this->columnService->publicColumns($tenant), ]; } diff --git a/app/Domains/Ticket/Services/AdminAppTicketColumnService.php b/app/Domains/Ticket/Services/AdminAppTicketColumnService.php new file mode 100644 index 0000000..a935e90 --- /dev/null +++ b/app/Domains/Ticket/Services/AdminAppTicketColumnService.php @@ -0,0 +1,85 @@ + */ + public function columns(Tenant $tenant): array + { + $keys = $tenant->codigo === self::FIESTA_FUTBOL_INFANTIL + ? ['order_number', 'category', 'product', 'type', 'amount', 'client', 'ticket', 'date', 'status', 'scanned_by'] + : ['order_number', 'product', 'amount', 'client', 'ticket', 'date', 'status', 'scanned_by']; + + $columns = array_map(fn (string $key): array => $this->definitions()[$key], $keys); + + if ($tenant->codigo !== self::FIESTA_FUTBOL_INFANTIL) { + $widths = [ + 'order_number' => '11%', + 'product' => '15%', + 'amount' => '10%', + 'client' => '15%', + 'ticket' => '19%', + 'date' => '11%', + 'status' => '8%', + 'scanned_by' => '11%', + ]; + $columns = array_map(function (array $column) use ($widths): array { + $column['width'] = $widths[$column['key']]; + + return $column; + }, $columns); + } + + return $columns; + } + + /** @return list */ + public function publicColumns(Tenant $tenant): array + { + return array_map(function (array $column): array { + unset($column['excel_width']); + + return $column; + }, $this->columns($tenant)); + } + + /** @return array */ + private function definitions(): array + { + return [ + 'order_number' => $this->column('order_number', 'N° de orden', 'order_number', '10.5%', 14), + 'category' => $this->column('category', 'Categoría', 'text', '11%', 18), + 'product' => $this->column('product', 'Producto', 'text', '11%', 22), + 'type' => $this->column('type', 'Tipo', 'text', '8%', 18), + 'amount' => $this->column('amount', 'Importe', 'currency', '9%', 15), + 'client' => $this->column('client', 'Cliente', 'text', '13%', 30), + 'ticket' => $this->column('ticket', 'ID', 'text', '14.5%', 39), + 'date' => $this->column('date', 'Fecha', 'date', '9.5%', 20), + 'status' => $this->column('status', 'Estado', 'status', '7%', 13), + 'scanned_by' => $this->column('scanned_by', 'Escaneado por', 'text', '9%', 28), + ]; + } + + /** @return array{key: string, label: string, type: string, sortable: bool, width: string, excel_width: int} */ + private function column( + string $key, + string $label, + string $type, + string $width, + int $excelWidth, + ): array { + return [ + 'key' => $key, + 'label' => $label, + 'type' => $type, + 'sortable' => true, + 'width' => $width, + 'excel_width' => $excelWidth, + ]; + } +} diff --git a/tests/Feature/Forms/AdminAppTicketFilterFormControllerTest.php b/tests/Feature/Forms/AdminAppTicketFilterFormControllerTest.php index 6a74c3b..296187b 100644 --- a/tests/Feature/Forms/AdminAppTicketFilterFormControllerTest.php +++ b/tests/Feature/Forms/AdminAppTicketFilterFormControllerTest.php @@ -56,6 +56,7 @@ class AdminAppTicketFilterFormControllerTest extends TestCase 'code' => 'tickets_filter', 'action' => '/api/v1/adminapp/tenant/tickets', 'method' => 'GET', + 'columns' => $this->commonColumns(), 'fields' => [ [ 'name' => 'date', @@ -104,7 +105,11 @@ class AdminAppTicketFilterFormControllerTest extends TestCase ->assertJsonPath('data.fields.3.name', 'date') ->assertJsonPath('data.fields.3.query_param', 'date') ->assertJsonPath('data.fields.4.name', 'status') - ->assertJsonPath('data.fields.4.query_param', 'status'); + ->assertJsonPath('data.fields.4.query_param', 'status') + ->assertJsonPath('data.columns.0.key', 'order_number') + ->assertJsonPath('data.columns.1.key', 'category') + ->assertJsonPath('data.columns.2.key', 'product') + ->assertJsonPath('data.columns.3.key', 'type'); $categories = collect($response->json('data.fields.0.options')); $this->assertSame( @@ -232,6 +237,21 @@ class AdminAppTicketFilterFormControllerTest extends TestCase return $tenant->refresh(); } + /** @return list> */ + private function commonColumns(): array + { + return [ + ['key' => 'order_number', 'label' => 'N° de orden', 'type' => 'order_number', 'sortable' => true, 'width' => '11%'], + ['key' => 'product', 'label' => 'Producto', 'type' => 'text', 'sortable' => true, 'width' => '15%'], + ['key' => 'amount', 'label' => 'Importe', 'type' => 'currency', 'sortable' => true, 'width' => '10%'], + ['key' => 'client', 'label' => 'Cliente', 'type' => 'text', 'sortable' => true, 'width' => '15%'], + ['key' => 'ticket', 'label' => 'ID', 'type' => 'text', 'sortable' => true, 'width' => '19%'], + ['key' => 'date', 'label' => 'Fecha', 'type' => 'date', 'sortable' => true, 'width' => '11%'], + ['key' => 'status', 'label' => 'Estado', 'type' => 'status', 'sortable' => true, 'width' => '8%'], + ['key' => 'scanned_by', 'label' => 'Escaneado por', 'type' => 'text', 'sortable' => true, 'width' => '11%'], + ]; + } + private function createTenant(string $code): Tenant { $headerLogo = $this->createAttachment("{$code}-header.png");