From 92170b72f2ff70aeef226f0300c3ea34f0bf560a Mon Sep 17 00:00:00 2001 From: ncoronel Date: Thu, 24 Sep 2026 12:56:23 -0300 Subject: [PATCH] feat(migration): enhance Mutual SMEP catalog seeding with featured groups and highlighted products --- ..._09_24_030000_seed_mutual_smep_catalog.php | 123 ++++++++++++++++-- .../Migrations/SeedMutualSmepCatalogTest.php | 65 ++++++++- 2 files changed, 171 insertions(+), 17 deletions(-) diff --git a/database/migrations/2026_09_24_030000_seed_mutual_smep_catalog.php b/database/migrations/2026_09_24_030000_seed_mutual_smep_catalog.php index 192d5b6..691bf8b 100644 --- a/database/migrations/2026_09_24_030000_seed_mutual_smep_catalog.php +++ b/database/migrations/2026_09_24_030000_seed_mutual_smep_catalog.php @@ -15,7 +15,34 @@ return new class extends Migration private const BRAND_MARKER = 'Provisioned by Mutual SMEP catalog migration v1.'; - private const FEATURED_GROUP_CODE = 'productos-smep'; + /** @var list */ + private const FEATURED_GROUPS = [ + ['code' => 'smep-dormitorio-y-blanco', 'category' => 'Dormitorio y Blanco'], + ['code' => 'smep-electrodomesticos', 'category' => 'Electrodomésticos'], + ['code' => 'smep-climatizacion', 'category' => 'Climatización'], + ['code' => 'smep-tecnologia', 'category' => 'Tecnología'], + ['code' => 'smep-bicicletas-y-aire-libre', 'category' => 'Bicicletas y Aire Libre'], + ['code' => 'smep-bazar', 'category' => 'Bazar'], + ]; + + private const HIGHLIGHTED_GROUP_CODE = 'productos-destacados-smep'; + + /** @var list */ + private const HIGHLIGHTED_PRODUCT_SLUGS = [ + 'acolchado-kavanagh-simil-plumon-reversible', + 'acolchado-sense-duo-bitono-corderito', + 'colchon-inducol-constanza', + 'edredon-lisboa-jean-cartier', + 'frazada-kavanagh-premium-soft', + 'kit-edredon-alaska-corderito', + 'motorola-g15', + 'smart-tv-noblex-50-dr50-x8500-google-tv', + 'heladera-gafa-hgf-368afp-330-lt-color-plata', + 'cafetera-express-atma-ceat-5418p-1-litro', + 'split-3300-w-tcl-taca-3300fcsa-frio-calor', + 'bicicleta-venzo-loki-r29-fd-21-v-shimano', + 'termo-stanley-1-l-adventure-go-to-con-tapon', + ]; /** @var list */ private array $storedPaths = []; @@ -121,16 +148,7 @@ return new class extends Migration } } - DB::table('featured_groups')->insert([ - 'tenant_code' => self::TENANT_CODE, - 'code' => self::FEATURED_GROUP_CODE, - 'source_type' => 'all', - 'category_id' => null, - 'product_layout' => 'column_with_image', - 'group_layout' => 'paginated', - 'group_name' => 'Productos', - 'group_order' => 1, - ]); + $this->createFeaturedGroups(); }); } catch (Throwable $throwable) { Storage::disk('s3')->delete($this->storedPaths); @@ -172,7 +190,10 @@ return new class extends Migration ): void { DB::table('featured_groups') ->where('tenant_code', self::TENANT_CODE) - ->where('code', self::FEATURED_GROUP_CODE) + ->whereIn('code', [ + self::HIGHLIGHTED_GROUP_CODE, + ...array_column(self::FEATURED_GROUPS, 'code'), + ]) ->delete(); DB::table('catalog_items')->whereIn('id', $catalogItemIds)->delete(); DB::table('inventories') @@ -306,6 +327,84 @@ return new class extends Migration ]); } + private function createFeaturedGroups(): void + { + $this->createHighlightedGroup(); + + foreach (self::FEATURED_GROUPS as $order => $group) { + $categoryId = DB::table('categorias') + ->where('tenant_code', self::TENANT_CODE) + ->whereNull('categoria_id') + ->where('nombre', $group['category']) + ->value('id'); + + if ($categoryId === null) { + throw new RuntimeException("Parent category '{$group['category']}' not found for Mutual SMEP."); + } + + $featuredGroupId = DB::table('featured_groups')->insertGetId([ + 'tenant_code' => self::TENANT_CODE, + 'code' => $group['code'], + 'source_type' => 'manual', + 'category_id' => $categoryId, + 'product_layout' => 'column_with_image', + 'group_layout' => 'carousel', + 'group_name' => $group['category'], + 'group_order' => $order + 2, + ]); + + $catalogItemIds = DB::table('catalog_items') + ->join('categorias', 'categorias.id', '=', 'catalog_items.category_id') + ->where('catalog_items.tenant_code', self::TENANT_CODE) + ->where('categorias.tenant_code', self::TENANT_CODE) + ->where('categorias.categoria_id', $categoryId) + ->orderBy('catalog_items.group_order') + ->orderBy('catalog_items.id') + ->pluck('catalog_items.id'); + + foreach ($catalogItemIds as $itemOrder => $catalogItemId) { + DB::table('featured_items')->insert([ + 'featured_group_id' => $featuredGroupId, + 'catalog_item_id' => $catalogItemId, + 'order' => $itemOrder + 1, + ]); + } + } + } + + private function createHighlightedGroup(): void + { + $featuredGroupId = DB::table('featured_groups')->insertGetId([ + 'tenant_code' => self::TENANT_CODE, + 'code' => self::HIGHLIGHTED_GROUP_CODE, + 'source_type' => 'manual', + 'category_id' => null, + 'product_layout' => 'column_with_image', + 'group_layout' => 'carousel', + 'group_name' => 'Productos destacados', + 'group_order' => 1, + ]); + + $catalogItemIds = DB::table('catalog_items') + ->where('tenant_code', self::TENANT_CODE) + ->whereIn('slug', self::HIGHLIGHTED_PRODUCT_SLUGS) + ->pluck('id', 'slug'); + + foreach (self::HIGHLIGHTED_PRODUCT_SLUGS as $order => $slug) { + $catalogItemId = $catalogItemIds->get($slug); + + if ($catalogItemId === null) { + throw new RuntimeException("Highlighted product '{$slug}' not found for Mutual SMEP."); + } + + DB::table('featured_items')->insert([ + 'featured_group_id' => $featuredGroupId, + 'catalog_item_id' => $catalogItemId, + 'order' => $order + 1, + ]); + } + } + /** @param list $images */ private function attachImages(int $catalogItemId, ?int $variantId, array $images): void { diff --git a/tests/Feature/Migrations/SeedMutualSmepCatalogTest.php b/tests/Feature/Migrations/SeedMutualSmepCatalogTest.php index 3abd63a..dd9e5e9 100644 --- a/tests/Feature/Migrations/SeedMutualSmepCatalogTest.php +++ b/tests/Feature/Migrations/SeedMutualSmepCatalogTest.php @@ -23,6 +23,7 @@ class SeedMutualSmepCatalogTest extends TestCase protected function tearDown(): void { foreach ([ + 'featured_items', 'featured_groups', 'catalog_items_attachments', 'attachments', @@ -61,11 +62,58 @@ class SeedMutualSmepCatalogTest extends TestCase 511, count(Storage::disk('s3')->allFiles('tenants/mutual_smep/catalog-v1')), ); - $this->assertDatabaseHas('featured_groups', [ - 'tenant_code' => 'mutual_smep', - 'code' => 'productos-smep', - 'source_type' => 'all', - ]); + $this->assertDatabaseCount('featured_groups', 7); + $this->assertSame([ + 'Productos destacados', + 'Dormitorio y Blanco', + 'Electrodomésticos', + 'Climatización', + 'Tecnología', + 'Bicicletas y Aire Libre', + 'Bazar', + ], DB::table('featured_groups')->orderBy('group_order')->pluck('group_name')->all()); + + DB::table('featured_groups')->orderBy('group_order')->each(function (object $group): void { + $this->assertSame('manual', $group->source_type); + $this->assertSame('carousel', $group->group_layout); + $this->assertSame('column_with_image', $group->product_layout); + if ($group->code === 'productos-destacados-smep') { + $this->assertNull($group->category_id); + } else { + $this->assertNotNull($group->category_id); + $this->assertDatabaseHas('categorias', [ + 'id' => $group->category_id, + 'tenant_code' => 'mutual_smep', + 'categoria_id' => null, + 'nombre' => $group->group_name, + ]); + } + $this->assertGreaterThan( + 0, + DB::table('featured_items')->where('featured_group_id', $group->id)->count(), + ); + }); + + $highlightedGroupId = DB::table('featured_groups') + ->where('code', 'productos-destacados-smep') + ->value('id'); + $highlightedSlugs = DB::table('featured_items') + ->join('catalog_items', 'catalog_items.id', '=', 'featured_items.catalog_item_id') + ->where('featured_items.featured_group_id', $highlightedGroupId) + ->orderBy('featured_items.order') + ->pluck('catalog_items.slug') + ->all(); + $variantProductSlugs = DB::table('catalog_items') + ->whereExists(fn ($query) => $query + ->selectRaw('1') + ->from('variantes') + ->whereColumn('variantes.catalog_item_id', 'catalog_items.id')) + ->pluck('slug') + ->all(); + + $this->assertCount(13, $highlightedSlugs); + $this->assertSame([], array_values(array_diff($variantProductSlugs, $highlightedSlugs))); + $this->assertSame(155, DB::table('featured_items')->count()); $this->assertDatabaseHas('catalog_items', [ 'tenant_code' => 'mutual_smep', 'slug' => 'motorola-g15', @@ -77,6 +125,7 @@ class SeedMutualSmepCatalogTest extends TestCase $migration->down(); foreach ([ + 'featured_items', 'featured_groups', 'catalog_items_attachments', 'attachments', @@ -226,5 +275,11 @@ class SeedMutualSmepCatalogTest extends TestCase $table->string('group_name'); $table->unsignedInteger('group_order')->default(0); }); + Schema::create('featured_items', function (Blueprint $table): void { + $table->id(); + $table->foreignId('featured_group_id')->constrained('featured_groups')->cascadeOnDelete(); + $table->foreignId('catalog_item_id')->constrained('catalog_items')->cascadeOnDelete(); + $table->unsignedInteger('order')->default(0); + }); } }