diff --git a/app/Domains/FiestaFutbolInfantil/Resources/AccommodationResource.php b/app/Domains/FiestaFutbolInfantil/Resources/AccommodationResource.php index ea59d91..e674ff4 100644 --- a/app/Domains/FiestaFutbolInfantil/Resources/AccommodationResource.php +++ b/app/Domains/FiestaFutbolInfantil/Resources/AccommodationResource.php @@ -12,6 +12,14 @@ class AccommodationResource extends JsonResource /** @return array */ public function toArray(Request $request): array { + if ($this->resource === null) { + return [ + 'id' => null, + 'name' => 'Alojamiento', + 'variants' => [], + ]; + } + $typeAttribute = $this->itemAttributes ->first(fn ($itemAttribute) => $itemAttribute->attribute?->codigo === 'tipo_alojamiento'); $options = $typeAttribute?->attribute?->options?->keyBy('value') ?? collect(); diff --git a/app/Domains/FiestaFutbolInfantil/Resources/FoodResource.php b/app/Domains/FiestaFutbolInfantil/Resources/FoodResource.php index fbd61e9..ad1f800 100644 --- a/app/Domains/FiestaFutbolInfantil/Resources/FoodResource.php +++ b/app/Domains/FiestaFutbolInfantil/Resources/FoodResource.php @@ -12,6 +12,14 @@ class FoodResource extends JsonResource /** @return array */ public function toArray(Request $request): array { + if ($this->resource === null) { + return [ + 'id' => null, + 'name' => 'Comida', + 'variants' => [], + ]; + } + return [ 'id' => $this->id, 'name' => $this->nombre, diff --git a/app/Domains/FiestaFutbolInfantil/Services/AccommodationService.php b/app/Domains/FiestaFutbolInfantil/Services/AccommodationService.php index 394312f..6aa6c30 100644 --- a/app/Domains/FiestaFutbolInfantil/Services/AccommodationService.php +++ b/app/Domains/FiestaFutbolInfantil/Services/AccommodationService.php @@ -20,7 +20,7 @@ class AccommodationService { private const ATTRIBUTE_CODE = 'tipo_alojamiento'; - public function current(Tenant $tenant): CatalogItem + public function current(Tenant $tenant): ?CatalogItem { return CatalogItem::query() ->where('tenant_code', $tenant->codigo) @@ -31,7 +31,7 @@ class AccommodationService 'variants.inventory', 'variants.definitions', ]) - ->firstOrFail(); + ->first(); } /** diff --git a/app/Domains/FiestaFutbolInfantil/Services/FoodService.php b/app/Domains/FiestaFutbolInfantil/Services/FoodService.php index 13aef1a..ea76d4d 100644 --- a/app/Domains/FiestaFutbolInfantil/Services/FoodService.php +++ b/app/Domains/FiestaFutbolInfantil/Services/FoodService.php @@ -20,7 +20,7 @@ class FoodService { private const ATTRIBUTE_CODES = ['event_date', 'horario', 'servicio']; - public function current(Tenant $tenant): CatalogItem + public function current(Tenant $tenant): ?CatalogItem { return CatalogItem::query() ->where('tenant_code', $tenant->codigo) @@ -32,7 +32,7 @@ class FoodService 'variants.eventDates', 'variants.definitions.itemAttribute.attribute', ]) - ->firstOrFail(); + ->first(); } /** @@ -282,7 +282,7 @@ class FoodService /** @param Collection $itemAttributes */ private function syncDefinitions(Variant $variant, Collection $itemAttributes, array $data): void { - $definitionAttributes = $itemAttributes->only(['horario', 'servicio']); + $definitionAttributes = $itemAttributes->toBase()->only(['horario', 'servicio']); $variant->definitions()->whereIn('item_attribute_id', $definitionAttributes->pluck('id'))->delete(); $variant->definitions()->createMany([ [ diff --git a/app/Domains/Forms/Controllers/AdminApp/FoodFormController.php b/app/Domains/Forms/Controllers/AdminApp/FoodFormController.php new file mode 100644 index 0000000..cb2380f --- /dev/null +++ b/app/Domains/Forms/Controllers/AdminApp/FoodFormController.php @@ -0,0 +1,22 @@ +foodFormService->get( + $request->user('sanctum')->tenant()->firstOrFail() + ) + ); + } +} diff --git a/app/Domains/Forms/Resources/FoodFormResource.php b/app/Domains/Forms/Resources/FoodFormResource.php new file mode 100644 index 0000000..4aa20eb --- /dev/null +++ b/app/Domains/Forms/Resources/FoodFormResource.php @@ -0,0 +1,39 @@ + */ + public function toArray(Request $request): array + { + return [ + 'event_dates' => $this->resource['event_dates']->map( + fn (EventDate $eventDate): array => [ + 'id' => $eventDate->id, + 'date' => $eventDate->date->format('Y-m-d'), + ] + )->values(), + 'schedules' => $this->options($this->resource['schedules']), + 'services' => $this->options($this->resource['services']), + ]; + } + + /** + * @param Collection $options + * @return Collection + */ + private function options(Collection $options): Collection + { + return $options->map(fn (AttributeOption $option): array => [ + 'value' => $option->value, + 'label' => $option->label, + ])->values(); + } +} diff --git a/app/Domains/Forms/Services/FoodFormService.php b/app/Domains/Forms/Services/FoodFormService.php new file mode 100644 index 0000000..03235f5 --- /dev/null +++ b/app/Domains/Forms/Services/FoodFormService.php @@ -0,0 +1,35 @@ +, + * schedules: Collection, + * services: Collection + * } + */ + public function get(Tenant $tenant): array + { + $attributes = Attribute::query() + ->where('tenant_codigo', $tenant->codigo) + ->whereIn('codigo', ['horario', 'servicio']) + ->with('options') + ->get() + ->keyBy('codigo'); + + return [ + 'event_dates' => $tenant->eventDates()->get(), + 'schedules' => $attributes->get('horario')?->options ?? new Collection, + 'services' => $attributes->get('servicio')?->options ?? new Collection, + ]; + } +} diff --git a/app/Domains/Forms/routes/adminapp.php b/app/Domains/Forms/routes/adminapp.php index 77bd8e8..cb8683f 100644 --- a/app/Domains/Forms/routes/adminapp.php +++ b/app/Domains/Forms/routes/adminapp.php @@ -1,6 +1,7 @@ seed(AuthorizationSeeder::class); + WebsiteType::query()->create(['codigo' => 'onticket', 'nombre' => 'OnTicket']); + } + + public function test_authentication_is_required(): void + { + $this->getJson('/api/v1/adminapp/forms/fiesta-futbol-infantil/food') + ->assertUnauthorized(); + } + + public function test_it_returns_event_dates_schedules_and_services_for_the_tenant(): void + { + $tenant = Tenant::query()->create([ + 'codigo' => 'fiesta', + 'nombre' => 'Fiesta', + 'dominio' => 'fiesta.test', + 'website_type_code' => 'onticket', + ]); + $tenant->eventDates()->create([ + 'date' => '2026-10-09', + 'time_start' => '00:00', + 'time_end' => '23:59', + ]); + $this->createAttribute($tenant, 'horario', [ + ['value' => 'Cena', 'label' => 'Cena', 'sort_order' => 2], + ['value' => 'Almuerzo', 'label' => 'Almuerzo', 'sort_order' => 1], + ]); + $this->createAttribute($tenant, 'servicio', [ + ['value' => 'Comedor', 'label' => 'Comedor', 'sort_order' => 1], + ]); + + Sanctum::actingAs(User::factory()->create([ + 'rol_codigo' => RoleCode::AdminApp->value, + 'tenant_codigo' => $tenant->codigo, + ])); + + $this->getJson('/api/v1/adminapp/forms/fiesta-futbol-infantil/food') + ->assertOk() + ->assertJsonCount(1, 'data.event_dates') + ->assertJsonPath('data.event_dates.0.date', '2026-10-09') + ->assertJsonPath('data.schedules.0.value', 'Almuerzo') + ->assertJsonPath('data.schedules.1.value', 'Cena') + ->assertJsonPath('data.services.0.value', 'Comedor'); + } + + /** @param array $options */ + private function createAttribute(Tenant $tenant, string $code, array $options): void + { + $attribute = Attribute::query()->create([ + 'tenant_codigo' => $tenant->codigo, + 'codigo' => $code, + 'nombre' => ucfirst($code), + 'type' => FieldType::Select, + 'is_required' => true, + ]); + $attribute->options()->createMany($options); + } +}