feat(ticketing): add entry reservations management for admin app
- Introduced new routes for entry reservations in admin app, including form, index, store, and download functionalities. - Created a migration to add the "Reserva de Tickets" menu item to the admin app. - Updated MenuSeeder to include the new menu item for ticket reservations. - Developed a PDF view for entry reservations. - Implemented tests for the EntryReservationController and EntryReservationService to ensure proper functionality and access control. - Refactored test setup to use a dedicated schema creation trait for better isolation and maintainability.
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Ticketing\Ticket\Services;
|
||||
|
||||
use App\Domains\Commerce\Catalog\Enums\InventoryPolicy;
|
||||
use App\Domains\Commerce\Catalog\Models\CatalogItem;
|
||||
use App\Domains\Commerce\Catalog\Models\Variant;
|
||||
use App\Domains\Core\Tenant\Models\Tenant;
|
||||
use App\Domains\Ticketing\Ticket\Enums\EntryReservationPaymentType;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class EntryReservationFormService
|
||||
{
|
||||
public function get(Tenant $tenant, ?int $eventId = null): array
|
||||
{
|
||||
$items = CatalogItem::query()->where('tenant_code', $tenant->codigo)->where('has_tickets', true)
|
||||
->when($eventId !== null, fn (Builder $query) => $query->where('event_id', $eventId))
|
||||
->with([
|
||||
'inventory', 'itemAttributes.attribute.options',
|
||||
'variants' => fn ($query) => $query->orderBy('id'),
|
||||
'variants.inventory', 'variants.definitions.itemAttribute.attribute.options',
|
||||
'variants.eventDates', 'variants.eventDate',
|
||||
])->orderBy('nombre')->orderBy('id')->get();
|
||||
|
||||
$filterItems = $items->map(fn (CatalogItem $item): array => [
|
||||
'id' => $item->id, 'name' => $item->nombre,
|
||||
'variants' => $item->variants->map(function (Variant $variant) use ($item): array {
|
||||
$variant->setRelation('catalogItem', $item);
|
||||
|
||||
return ['id' => $variant->id, 'label' => $variant->getSelectionLabel()];
|
||||
})->values()->all(),
|
||||
])->values()->all();
|
||||
|
||||
$reservationEventId = $eventId ?? $tenant->active_event_id;
|
||||
$available = $items->filter(fn (CatalogItem $item): bool => ! $item->isBundle()
|
||||
&& $item->isSaleOpen()
|
||||
&& ($reservationEventId === null || $item->event_id === $reservationEventId))
|
||||
->map(function (CatalogItem $item): ?array {
|
||||
$tracked = $item->inventory_policy !== InventoryPolicy::Unlimited;
|
||||
$requiresVariant = $item->variants->isNotEmpty();
|
||||
$variants = $item->variants->filter(function (Variant $variant) use ($item, $tracked): bool {
|
||||
$variant->setRelation('catalogItem', $item);
|
||||
|
||||
return $variant->isSellable()
|
||||
&& (! $tracked || ($variant->inventory?->availableStock() ?? 0) > 0);
|
||||
})->map(fn (Variant $variant): array => [
|
||||
'id' => $variant->id, 'label' => $variant->getSelectionLabel(),
|
||||
'price' => $variant->getPrice(),
|
||||
'available_stock' => $tracked ? $variant->inventory->availableStock() : null,
|
||||
])->values()->all();
|
||||
if (($requiresVariant && $variants === [])
|
||||
|| (! $requiresVariant && $tracked && ($item->inventory?->availableStock() ?? 0) <= 0)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => $item->id, 'name' => $item->nombre, 'price' => $item->getPrice(),
|
||||
'requires_variant' => $requiresVariant, 'variants' => $variants,
|
||||
'available_stock' => $tracked ? $item->inventory?->availableStock() : null,
|
||||
];
|
||||
})->filter()->values()->all();
|
||||
|
||||
return ['payment_types' => EntryReservationPaymentType::options(), 'items' => $available, 'filter_items' => $filterItems];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user