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',