feat(tickets): define tenant-specific table columns

This commit is contained in:
2026-08-31 12:31:13 -03:00
parent 5250d1a818
commit adce4ab59e
4 changed files with 113 additions and 2 deletions

View File

@@ -15,6 +15,7 @@ class TicketFilterFormResource extends JsonResource
'action' => $this->resource['action'],
'method' => $this->resource['method'],
'fields' => $this->resource['fields'],
'columns' => $this->resource['columns'],
];
}
}

View File

@@ -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<string, mixed> */
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),
];
}

View File

@@ -0,0 +1,85 @@
<?php
namespace App\Domains\Ticket\Services;
use App\Domains\Tenant\Models\Tenant;
class AdminAppTicketColumnService
{
private const FIESTA_FUTBOL_INFANTIL = 'fiesta_futbol_infantil';
/** @return list<array{key: string, label: string, type: string, sortable: bool, width: string, excel_width: int}> */
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<array{key: string, label: string, type: string, sortable: bool, width: string}> */
public function publicColumns(Tenant $tenant): array
{
return array_map(function (array $column): array {
unset($column['excel_width']);
return $column;
}, $this->columns($tenant));
}
/** @return array<string, array{key: string, label: string, type: string, sortable: bool, width: string, excel_width: int}> */
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,
];
}
}

View File

@@ -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<array<string, mixed>> */
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");