Files
shopit-back/app/Domains/Ticketing/Ticket/Services/EntryReservationFormService.php
ncoronel 45e92602ed 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.
2026-10-02 12:20:25 -03:00

66 lines
3.3 KiB
PHP

<?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];
}
}