where('codigo', 'onticket')->first(); if ($tenant === null) { throw new RuntimeException("Tenant 'onticket' no encontrado."); } Attribute::query()->firstOrCreate( ['tenant_codigo' => $tenant->codigo, 'codigo' => 'event_date'], ['nombre' => 'Fecha', 'type' => FieldType::EventDate, 'is_required' => true], ); $event = Event::query()->firstOrCreate( ['tenant_code' => $tenant->codigo, 'title' => self::TITLE], ['published_at' => now()], ); $event->update([ 'subtitle' => 'Una noche para celebrar nuestras raíces y mantener viva la tradición gaucha.', 'description' => 'La 26.º Fiesta de la Tradición y 4.º Encuentro de Agrupaciones Gauchas reunirá a agrupaciones, artesanos, pilcheros y público en general para compartir una jornada dedicada a nuestras costumbres y cultura.' ."\n\n".'Un encuentro para disfrutar de la tradición, la identidad gaucha y el espíritu de camaradería, en el Predio de Doma del Club Unión Deportiva Arrufó.' ."\n\n".'Organiza: Biblioteca Popular Miguel Ángel Sosa.', 'location' => 'Predio de Doma del Club Unión Deportiva Arrufó', ]); $eventImage = $event->attachment; if ($eventImage === null || ! Storage::disk('s3')->exists($eventImage->path)) { $event->update(['attachment_id' => $this->attachments->store($this->image(), 'events')->id]); } // La hora de cierre es provisoria hasta que la organización la confirme. $date = $event->dates()->firstOrCreate( ['date' => '2026-11-14'], ['tenant_code' => $tenant->codigo, 'time_start' => '19:00', 'time_end' => '23:59'], ); $this->createItem($tenant, $event, $date->id, [ 'slug' => 'fiesta-tradicion-arrufo-2026-entrada-anticipada', 'nombre' => 'Entrada anticipada', 'descripcion' => 'Entrada para personas de 12 años en adelante. Venta anticipada hasta el 13/11/2026 a las 22:00 h.', 'precio' => 12000, 'sales_end_at' => Carbon::parse('2026-11-13 22:00:00', 'America/Argentina/Buenos_Aires')->utc(), 'group_order' => 1, ]); $this->createItem($tenant, $event, $date->id, [ 'slug' => 'fiesta-tradicion-arrufo-2026-puesto-feria', 'nombre' => 'Espacio para puesto en la feria', 'descripcion' => 'Para artesanos, pilcheros y otros puestos de venta. Incluye una entrada para la persona que atiende el puesto. No se permiten puestos de venta de comidas ni bebidas.', 'precio' => 50000, 'group_order' => 2, ]); } /** @param array $data */ private function createItem(Tenant $tenant, Event $event, int $dateId, array $data): void { $existing = CatalogItem::query()->where('tenant_code', $tenant->codigo)->where('slug', $data['slug'])->first(); if ($existing !== null) { $existing->update(['sales_end_at' => $data['sales_end_at'] ?? null]); return; } $item = $this->catalog->create([ 'tenant_code' => $tenant->codigo, 'inventory_policy' => InventoryPolicy::Unlimited->value, 'has_tickets' => true, 'attribute_codes' => ['event_date'], 'hidden_attribute_codes' => ['event_date'], 'variants' => [['event_date_id' => $dateId]], 'images' => [$this->image()], ...$data, ]); $item->forceFill(['event_id' => $event->id])->save(); } private function image(): UploadedFile { $path = public_path(self::IMAGE); if (! is_file($path)) { throw new RuntimeException("Image not found at path: {$path}"); } return new UploadedFile($path, basename($path), 'image/avif', null, true); } }