From e6785eb5af7cbc0934cb145e54952ca0c7755a11 Mon Sep 17 00:00:00 2001 From: ncoronel Date: Tue, 18 Aug 2026 15:44:20 -0300 Subject: [PATCH] feat(seeder): add Desfile Pura Tendencia seeder and corresponding test --- database/seeders/DatabaseSeeder.php | 1 + .../seeders/DesfilePuraTendenciaSeeder.php | 251 ++++++++++++++++++ .../DesfilePuraTendenciaSeederTest.php} | 31 +-- 3 files changed, 256 insertions(+), 27 deletions(-) create mode 100644 database/seeders/DesfilePuraTendenciaSeeder.php rename tests/Feature/{Migrations/CreateDesfilePuraTendenciaTenantTest.php => Seeders/DesfilePuraTendenciaSeederTest.php} (91%) diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index a13d0ec..5ac3e1a 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -27,6 +27,7 @@ class DatabaseSeeder extends Seeder AuthorizationSeeder::class, SocialMediaSeeder::class, TenantSeeder::class, + DesfilePuraTendenciaSeeder::class, AttributeSeeder::class, CategorySeeder::class, BrandSeeder::class, diff --git a/database/seeders/DesfilePuraTendenciaSeeder.php b/database/seeders/DesfilePuraTendenciaSeeder.php new file mode 100644 index 0000000..1c684ef --- /dev/null +++ b/database/seeders/DesfilePuraTendenciaSeeder.php @@ -0,0 +1,251 @@ +where('codigo', self::TENANT_CODE)->exists()) { + return; + } + + DB::transaction(function (): void { + $this->createTenant(); + $this->createEventDate(); + $this->createEntryCatalog(); + }); + } + + private function createTenant(): void + { + $this->tenantService->create([ + 'codigo' => self::TENANT_CODE, + 'nombre' => 'Desfile Pura Tendencia', + 'dominio' => 'desfile-pura-tendencia.localhost', + 'site_title' => 'Desfile Pura Tendencia', + 'event_title' => 'Desfile Pura Tendencia', + 'event_location' => 'Salón Centro Recreativo Luz y Fuerza', + 'event_date_text' => '16 de Octubre 2026', + 'primary_color' => '#BA69A9', + 'secondary_color' => '#A0A0A0', + 'danger_color' => '#FF8888', + 'success_color' => '#198754', + 'header_bg_color' => '#ffffff', + 'footer_bg_color' => '#D4441C', + 'display_categories' => false, + 'display_seach_bar' => false, + 'display_cart' => true, + 'scanner_category_validation_enabled' => false, + 'website_type_code' => 'onticket', + 'header_logo' => $this->uploadedImage( + 'images/tennants/desfile_pura_tendencia/desfile_pura_tendencia_header.png', + 'desfile_pura_tendencia_header.png', + ), + 'footer_logo' => $this->uploadedImage( + 'images/tennants/desfile_pura_tendencia/desfile_pura_tendencia_footer.png', + 'desfile_pura_tendencia_footer.png', + ), + 'favicon' => $this->uploadedImage( + 'images/tennants/desfile_pura_tendencia/pura_tendencia_favicon.png', + 'pura_tendencia_favicon.png', + ), + 'footer_bg_image' => $this->uploadedImage( + 'images/tennants/desfile_pura_tendencia/desfile_pura_tendencia_footer_background.png', + 'desfile_pura_tendencia_footer_background.png', + ), + 'extras' => [ + 'heroConfig' => [ + 'title_html' => '

LA NOCHE DE LA MODA

', + 'description_html' => 'Viví una experiencia de Alta Costura con conducción exclusiva de Pampita y las colecciones de Pucheta-Paz.', + 'background_image_id' => $this->uploadedImage( + 'images/tennants/desfile_pura_tendencia/desfile_pura_tendencia_hero.png', + 'desfile_pura_tendencia_hero.png', + ), + ], + ], + ]); + } + + private function createEventDate(): void + { + $now = now(); + $validityTimeId = DB::table('validity_times')->insertGetId([ + 'type' => 'fixed_window', + 'start_time' => null, + 'end_time' => null, + 'fixed_starts_at' => '2026-10-16 20:30:00', + 'fixed_expires_at' => '2026-10-16 23:59:00', + 'created_at' => $now, + 'updated_at' => $now, + ]); + + DB::table('event_dates')->insert([ + 'tenant_code' => self::TENANT_CODE, + 'validity_time_id' => $validityTimeId, + 'date' => '2026-10-16', + 'time_start' => '20:30:00', + 'time_end' => '23:59:00', + ]); + } + + private function createEntryCatalog(): void + { + $attributes = [ + 'tipo' => ['name' => 'Tipo', 'options' => ['VIP + LUNCH', 'NORMAL']], + 'sector' => ['name' => 'Sector', 'options' => ['A', 'B', 'C', 'D']], + 'fila' => ['name' => 'Fila', 'options' => array_map('strval', range(1, 5))], + 'asiento' => ['name' => 'Asiento', 'options' => array_map('strval', range(1, 100))], + ]; + + foreach ($attributes as $code => $definition) { + $attribute = Attribute::query()->create([ + 'tenant_codigo' => self::TENANT_CODE, + 'codigo' => $code, + 'nombre' => $definition['name'], + 'is_required' => true, + 'metadata_schema' => null, + 'type' => 'select', + ]); + + $attribute->options()->createMany(array_map( + fn (string $option, int $index): array => [ + 'value' => $option, + 'label' => $option, + 'sort_order' => $index + 1, + 'metadata' => null, + ], + $definition['options'], + array_keys($definition['options']), + )); + } + + $catalogItem = $this->catalogService->create([ + 'tenant_code' => self::TENANT_CODE, + 'category_id' => null, + 'brand_id' => null, + 'slug' => 'entrada', + 'nombre' => 'Entrada', + 'descripcion' => 'Entrada para Desfile Pura Tendencia', + 'precio' => 40000, + 'inventory_policy' => InventoryPolicy::Tracked->value, + 'inventory_subject' => InventorySubject::Seat->value, + 'has_tickets' => true, + 'attribute_codes' => array_keys($attributes), + 'variants' => $this->entryVariants(), + 'images' => [ + $this->uploadedImage( + 'images/tennants/desfile_pura_tendencia/catalog/entrada_pasarela.png', + 'entrada_pasarela.png', + ), + ], + ]); + + $this->setAttributeOrder($catalogItem); + + FeaturedGroup::query()->create([ + 'tenant_code' => self::TENANT_CODE, + 'source_type' => FeaturedGroupSource::All, + 'category_id' => null, + 'product_layout' => ProductLayout::TicketSelector, + 'group_layout' => GroupLayout::Single, + 'group_name' => 'Entradas', + 'group_order' => 0, + ]); + } + + /** @return list> */ + private function entryVariants(): array + { + $variants = []; + + foreach (['A', 'B', 'C', 'D'] as $sector) { + $lastSeat = in_array($sector, ['B', 'D'], true) ? 16 : 17; + + foreach (range(1, 5) as $row) { + foreach (range(1, $lastSeat) as $seat) { + [$type, $price] = $this->entryTypeAndPrice($sector, $row); + $variants[] = [ + 'real_stock' => 1, + 'descripcion' => "Sector {$sector} - Fila {$row} - Asiento {$seat} - {$type}", + 'precio' => $price, + 'values' => [ + 'tipo' => $type, + 'sector' => $sector, + 'fila' => (string) $row, + 'asiento' => (string) $seat, + ], + ]; + } + } + } + + return $variants; + } + + private function setAttributeOrder(CatalogItem $catalogItem): void + { + $sortOrders = ['tipo' => 1, 'sector' => 2, 'fila' => 3, 'asiento' => 4]; + + $catalogItem->itemAttributes() + ->with('attribute:id,codigo') + ->get() + ->each(function ($itemAttribute) use ($sortOrders): void { + $itemAttribute->update([ + 'sort_order' => $sortOrders[$itemAttribute->attribute->codigo], + ]); + }); + } + + /** @return array{string, int} */ + private function entryTypeAndPrice(string $sector, int $row): array + { + $prices = in_array($sector, ['A', 'C'], true) + ? [1 => 250000, 2 => 200000, 3 => 100000, 4 => 75000, 5 => 50000] + : [1 => 240000, 2 => 190000, 3 => 90000, 4 => 65000, 5 => 40000]; + + return [$row <= 2 ? 'VIP + LUNCH' : 'NORMAL', $prices[$row]]; + } + + private function uploadedImage(string $relativePath, string $filename): UploadedFile + { + $path = public_path($relativePath); + + if (! is_file($path)) { + throw new RuntimeException("Image not found at path: {$path}"); + } + + $mimeType = mime_content_type($path); + + return new UploadedFile( + $path, + $filename, + is_string($mimeType) ? $mimeType : null, + null, + true, + ); + } +} diff --git a/tests/Feature/Migrations/CreateDesfilePuraTendenciaTenantTest.php b/tests/Feature/Seeders/DesfilePuraTendenciaSeederTest.php similarity index 91% rename from tests/Feature/Migrations/CreateDesfilePuraTendenciaTenantTest.php rename to tests/Feature/Seeders/DesfilePuraTendenciaSeederTest.php index 85db67b..64e02b4 100644 --- a/tests/Feature/Migrations/CreateDesfilePuraTendenciaTenantTest.php +++ b/tests/Feature/Seeders/DesfilePuraTendenciaSeederTest.php @@ -1,7 +1,8 @@ up(); - - $rowAndSeatMigration = require database_path( - 'migrations/2026_08_14_030000_swap_desfile_row_and_seat_semantics.php' - ); - $rowAndSeatMigration->up(); - - $seatOptionsMigration = require database_path( - 'migrations/2026_08_14_040000_expand_desfile_seat_options.php' - ); - $seatOptionsMigration->up(); - - $footerBackgroundMigration = require database_path( - 'migrations/2026_08_12_060000_set_desfile_footer_background_image.php' - ); - $footerBackgroundMigration->up(); - - $browserBrandingMigration = require database_path( - 'migrations/2026_08_14_010000_set_seeded_tenant_browser_branding.php' - ); - $browserBrandingMigration->up(); - $this->assertDatabaseHas('tenants', [ 'codigo' => 'desfile_pura_tendencia', 'nombre' => 'Desfile Pura Tendencia',