feat(tickets): update TicketFilterFormService to use getForFilters method and enhance TicketFormService with historical data handling
This commit is contained in:
parent
1ca8fb20af
commit
a71c80248c
|
|
@ -34,7 +34,7 @@ class TicketFilterFormService
|
|||
/** @return list<array<string, mixed>> */
|
||||
private function fiestaFutbolInfantilFields(Tenant $tenant): array
|
||||
{
|
||||
$form = $this->ticketFormService->get($tenant);
|
||||
$form = $this->ticketFormService->getForFilters($tenant);
|
||||
|
||||
return [
|
||||
[
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use App\Domains\Catalog\Models\CatalogItem;
|
|||
use App\Domains\Catalog\Models\Variant;
|
||||
use App\Domains\Tenant\Models\Tenant;
|
||||
use App\Domains\Ticket\Models\Ticket;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
class TicketFormService
|
||||
{
|
||||
|
|
@ -69,15 +70,82 @@ class TicketFormService
|
|||
*/
|
||||
public function get(Tenant $tenant): array
|
||||
{
|
||||
$categories = [];
|
||||
|
||||
$items = CatalogItem::query()
|
||||
->where('tenant_code', $tenant->codigo)
|
||||
->where('has_tickets', true)
|
||||
->whereHas('category')
|
||||
->with($this->relations())
|
||||
->orderBy('group_order')
|
||||
->orderBy('nombre')
|
||||
->get();
|
||||
|
||||
return $this->build($items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return active catalog options plus soft-deleted sources still referenced by
|
||||
* tickets, so historical tickets never become impossible to filter.
|
||||
*
|
||||
* @return array{
|
||||
* statuses: list<array{value: string, label: string}>,
|
||||
* categories: list<array{
|
||||
* value: string,
|
||||
* label: string,
|
||||
* products: list<array{
|
||||
* value: string,
|
||||
* label: string,
|
||||
* types: list<array{value: string, label: string}>
|
||||
* }>
|
||||
* }>
|
||||
* }
|
||||
*/
|
||||
public function getForFilters(Tenant $tenant): array
|
||||
{
|
||||
$historicalVariantIds = Ticket::query()
|
||||
->where('tenant_code', $tenant->codigo)
|
||||
->whereNotNull('source_variant_id')
|
||||
->distinct()
|
||||
->pluck('source_variant_id')
|
||||
->map(fn ($id): int => (int) $id)
|
||||
->all();
|
||||
$historicalCatalogItemIds = Ticket::query()
|
||||
->where('tenant_code', $tenant->codigo)
|
||||
->whereNotNull('source_catalog_item_id')
|
||||
->distinct()
|
||||
->pluck('source_catalog_item_id')
|
||||
->map(fn ($id): int => (int) $id)
|
||||
->merge(
|
||||
Variant::withTrashed()
|
||||
->whereKey($historicalVariantIds)
|
||||
->pluck('catalog_item_id')
|
||||
->map(fn ($id): int => (int) $id),
|
||||
)
|
||||
->unique()
|
||||
->values()
|
||||
->all();
|
||||
|
||||
$items = CatalogItem::withTrashed()
|
||||
->where('tenant_code', $tenant->codigo)
|
||||
->whereHas('category')
|
||||
->where(function ($query) use ($historicalCatalogItemIds): void {
|
||||
$query
|
||||
->where(function ($activeQuery): void {
|
||||
$activeQuery
|
||||
->whereNull('catalog_items.deleted_at')
|
||||
->where('has_tickets', true);
|
||||
})
|
||||
->orWhereIn('catalog_items.id', $historicalCatalogItemIds);
|
||||
})
|
||||
->with([
|
||||
'category',
|
||||
'itemAttributes.attribute.options',
|
||||
'variants' => fn ($query) => $query
|
||||
->withTrashed()
|
||||
->where(function ($variantQuery) use ($historicalVariantIds): void {
|
||||
$variantQuery
|
||||
->whereNull('variantes.deleted_at')
|
||||
->orWhereIn('variantes.id', $historicalVariantIds);
|
||||
}),
|
||||
'variants.definitions.itemAttribute.attribute.options',
|
||||
'variants.eventDates',
|
||||
'variants.eventDate',
|
||||
|
|
@ -86,6 +154,28 @@ class TicketFormService
|
|||
->orderBy('nombre')
|
||||
->get();
|
||||
|
||||
return $this->build($items);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection<int, CatalogItem> $items
|
||||
* @return array{
|
||||
* statuses: list<array{value: string, label: string}>,
|
||||
* categories: list<array{
|
||||
* value: string,
|
||||
* label: string,
|
||||
* products: list<array{
|
||||
* value: string,
|
||||
* label: string,
|
||||
* types: list<array{value: string, label: string}>
|
||||
* }>
|
||||
* }>
|
||||
* }
|
||||
*/
|
||||
private function build(Collection $items): array
|
||||
{
|
||||
$categories = [];
|
||||
|
||||
foreach ($items as $item) {
|
||||
$sourceCategory = trim((string) $item->category?->nombre);
|
||||
$categoryValue = mb_strtolower($sourceCategory);
|
||||
|
|
@ -146,6 +236,18 @@ class TicketFormService
|
|||
];
|
||||
}
|
||||
|
||||
/** @return list<string> */
|
||||
private function relations(): array
|
||||
{
|
||||
return [
|
||||
'category',
|
||||
'itemAttributes.attribute.options',
|
||||
'variants.definitions.itemAttribute.attribute.options',
|
||||
'variants.eventDates',
|
||||
'variants.eventDate',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<array{
|
||||
* value: string,
|
||||
|
|
|
|||
|
|
@ -7,12 +7,15 @@ use App\Domains\Attachable\Models\Attachment;
|
|||
use App\Domains\Auth\Models\User;
|
||||
use App\Domains\Authorization\Enums\RoleCode;
|
||||
use App\Domains\Catalog\Models\CatalogItem;
|
||||
use App\Domains\Catalog\Services\CatalogService;
|
||||
use App\Domains\Menu\Models\Menu;
|
||||
use App\Domains\Tenant\Models\Tenant;
|
||||
use App\Domains\Ticket\Models\Ticket;
|
||||
use Database\Seeders\AttributeSeeder;
|
||||
use Database\Seeders\AuthorizationSeeder;
|
||||
use Database\Seeders\FiestaFutbolInfantilProductSeeder;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Str;
|
||||
use Laravel\Sanctum\Sanctum;
|
||||
use Tests\TestCase;
|
||||
|
||||
|
|
@ -83,7 +86,8 @@ class AdminAppTicketFilterFormControllerTest extends TestCase
|
|||
{
|
||||
$tenant = $this->createFiestaFutbolInfantilTenant();
|
||||
$this->grantTicketsMenu($tenant);
|
||||
Sanctum::actingAs($this->createAdminAppUser($tenant));
|
||||
$admin = $this->createAdminAppUser($tenant);
|
||||
Sanctum::actingAs($admin);
|
||||
|
||||
$response = $this->getJson('/api/v1/adminapp/forms/tickets-filter')
|
||||
->assertOk()
|
||||
|
|
@ -154,6 +158,56 @@ class AdminAppTicketFilterFormControllerTest extends TestCase
|
|||
$this->assertContains('Cena', $schedules);
|
||||
}
|
||||
|
||||
public function test_a_deleted_food_variant_remains_in_the_filter_when_a_ticket_references_it(): void
|
||||
{
|
||||
$tenant = $this->createFiestaFutbolInfantilTenant();
|
||||
$this->grantTicketsMenu($tenant);
|
||||
$admin = $this->createAdminAppUser($tenant);
|
||||
Sanctum::actingAs($admin);
|
||||
|
||||
$food = CatalogItem::query()
|
||||
->where('tenant_code', $tenant->codigo)
|
||||
->where('slug', 'comida')
|
||||
->with([
|
||||
'itemAttributes.attribute.options',
|
||||
'variants.definitions.itemAttribute.attribute.options',
|
||||
'variants.eventDates',
|
||||
'variants.eventDate',
|
||||
])
|
||||
->firstOrFail();
|
||||
$historicalVariant = $food->variants->first(function ($variant): bool {
|
||||
return $variant->selectedEventDates()->first()?->date->format('d/m') === '12/10'
|
||||
&& $variant->selectionValues()->get('horario') === 'Cena';
|
||||
});
|
||||
$this->assertNotNull($historicalVariant);
|
||||
|
||||
Ticket::query()->create([
|
||||
'tenant_code' => $tenant->codigo,
|
||||
'ticket' => (string) Str::uuid(),
|
||||
'user_id' => $admin->id,
|
||||
'source_catalog_item_id' => $food->id,
|
||||
'source_variant_id' => $historicalVariant->id,
|
||||
]);
|
||||
|
||||
$catalogService = app(CatalogService::class);
|
||||
foreach ($food->variants as $variant) {
|
||||
$catalogService->deleteVariant($variant);
|
||||
}
|
||||
|
||||
$this->assertTrue(CatalogItem::withTrashed()->findOrFail($food->id)->trashed());
|
||||
|
||||
$response = $this->getJson('/api/v1/adminapp/forms/tickets-filter')->assertOk();
|
||||
$foodCategory = collect($response->json('data.fields.0.options'))->firstWhere('value', 'comidas');
|
||||
$products = collect($foodCategory['children']['options']);
|
||||
|
||||
$this->assertCount(1, $products);
|
||||
$this->assertSame('12/10', $products->first()['label']);
|
||||
$this->assertSame(
|
||||
['Cena'],
|
||||
collect($products->first()['children']['options'])->pluck('label')->all(),
|
||||
);
|
||||
}
|
||||
|
||||
private function createFiestaFutbolInfantilTenant(): Tenant
|
||||
{
|
||||
$tenant = $this->createTenant('fiesta_futbol_infantil');
|
||||
|
|
|
|||
Loading…
Reference in New Issue