where('codigo', 'onticket')->firstOrFail(); $events = [ [ 'title' => '[Prueba] Noche de Música en Vivo', 'slug' => 'prueba-noche-de-musica-en-vivo', 'category' => 'Música', 'subtitle' => 'Una noche para cantar y bailar', 'description' => 'Evento de prueba para explorar la cartelera de OnTicket.', 'location' => 'Teatro Broadway, Rosario', 'image' => 'live-music.avif', 'weeks_from_now' => [2], 'time_start' => '21:00:00', 'time_end' => '23:30:00', 'catalog_items' => [ [ 'slug' => 'prueba-noche-musica-entrada-general', 'name' => 'Entrada general', 'description' => 'Acceso general a la noche de música en vivo.', 'price' => 18000, 'stock' => 100, ], [ 'slug' => 'prueba-noche-musica-entrada-vip', 'name' => 'Entrada VIP', 'description' => 'Acceso preferencial y ubicación VIP.', 'price' => 32000, 'stock' => 40, ], ], ], [ 'title' => '[Prueba] Festival de Sabores', 'slug' => 'prueba-festival-de-sabores', 'category' => 'Otros', 'subtitle' => 'Gastronomía y música para toda la familia', 'description' => 'Evento de prueba con dos jornadas disponibles.', 'location' => 'Parque de España, Rosario', 'image' => 'food-festival.avif', 'weeks_from_now' => [3, 3], 'day_offsets' => [0, 1], 'time_start' => '12:00:00', 'time_end' => '20:00:00', 'catalog_items' => [ [ 'slug' => 'prueba-festival-sabores-entrada-general', 'name' => 'Entrada general', 'description' => 'Acceso general para la jornada seleccionada.', 'price' => 12000, 'stock' => 150, ], [ 'slug' => 'prueba-festival-sabores-pase-premium', 'name' => 'Pase premium', 'description' => 'Acceso premium para la jornada seleccionada.', 'price' => 22000, 'stock' => 50, ], ], ], [ 'title' => '[Prueba] Stand Up en el Centro', 'slug' => 'prueba-stand-up-en-el-centro', 'category' => 'Teatro', 'subtitle' => 'Humor para compartir', 'description' => 'Evento de prueba para visualizar distintas propuestas.', 'location' => 'Centro Cultural La Comedia, Rosario', 'image' => 'stand-up.avif', 'weeks_from_now' => [4], 'time_start' => '20:30:00', 'time_end' => '22:00:00', 'catalog_items' => [ [ 'slug' => 'prueba-stand-up-entrada-general', 'name' => 'Entrada general', 'description' => 'Acceso general al show de stand up.', 'price' => 14000, 'stock' => 120, ], [ 'slug' => 'prueba-stand-up-primera-fila', 'name' => 'Primera fila', 'description' => 'Ubicación preferencial en primera fila.', 'price' => 26000, 'stock' => 30, ], ], ], ]; DB::transaction(function () use ($tenant, $events): void { Attribute::query()->firstOrCreate( [ 'tenant_codigo' => $tenant->codigo, 'codigo' => 'event_date', ], [ 'nombre' => 'Fecha', 'type' => FieldType::EventDate->value, 'is_required' => true, ], ); $entryCategory = Category::query()->firstOrCreate([ 'tenant_code' => $tenant->codigo, 'nombre' => 'Entradas', ]); foreach ($events as $definition) { $event = $tenant->events()->firstOrCreate( ['title' => $definition['title']], [ 'slug' => $definition['slug'], 'subtitle' => $definition['subtitle'], 'description' => $definition['description'], 'location' => $definition['location'], 'published_at' => now(), 'event_category_id' => $tenant->eventCategories() ->where('nombre', $definition['category'])->value('id'), ], ); if ($event->slug !== $definition['slug']) { $event->update(['slug' => $definition['slug']]); } if ($event->event_category_id === null) { $event->update(['event_category_id' => $tenant->eventCategories() ->where('nombre', $definition['category'])->value('id')]); } if ($event->attachment_id === null) { $path = public_path(self::IMAGE_DIRECTORY.'/'.$definition['image']); if (! is_file($path)) { throw new RuntimeException("Image not found at path: {$path}"); } $attachment = $this->attachmentService->store( new UploadedFile($path, $definition['image'], 'image/avif', null, true), 'tenants/onticket/events', ); $event->update(['attachment_id' => $attachment->id]); } if (! $event->dates()->exists()) { foreach ($definition['weeks_from_now'] as $index => $weeks) { $date = now()->startOfDay()->addWeeks($weeks) ->addDays($definition['day_offsets'][$index] ?? 0); $event->dates()->create([ 'tenant_code' => $tenant->codigo, 'date' => $date->toDateString(), 'time_start' => $definition['time_start'], 'time_end' => $definition['time_end'], ]); } } $this->seedCatalogItems($tenant, $event, $entryCategory, $definition['catalog_items']); } }); } /** @param array> $definitions */ private function seedCatalogItems( Tenant $tenant, Event $event, Category $category, array $definitions, ): void { $eventDateIds = $event->dates() ->pluck('id') ->map(fn ($id): int => (int) $id) ->values(); foreach ($definitions as $order => $definition) { $catalogItem = CatalogItem::query() ->where('tenant_code', $tenant->codigo) ->where('slug', $definition['slug']) ->first(); if ($catalogItem === null) { $catalogItem = $this->catalogService->create([ 'tenant_code' => $tenant->codigo, 'category_id' => $category->id, 'slug' => $definition['slug'], 'nombre' => $definition['name'], 'descripcion' => $definition['description'], 'precio' => $definition['price'], 'group_order' => $order, 'has_tickets' => true, 'inventory_policy' => InventoryPolicy::Tracked->value, 'attribute_codes' => ['event_date'], 'hidden_attribute_codes' => ['event_date'], 'images' => [$event->attachment->key], 'variants' => $eventDateIds->map(fn (int $eventDateId): array => [ 'real_stock' => $definition['stock'], 'event_date_ids' => [$eventDateId], ])->all(), ]); } $catalogItem->forceFill(['event_id' => $event->id])->save(); } } }