From 84e45bb964ba2cc5494310a5c1e020362f5485df Mon Sep 17 00:00:00 2001 From: ncoronel Date: Tue, 4 Aug 2026 13:17:00 -0300 Subject: [PATCH] feat: Introduce source type for featured groups; add category association and implement FeaturedGroupService for item sourcing --- .../Catalog/Controllers/CatalogController.php | 70 ++------------- .../Catalog/Enums/FeaturedGroupSource.php | 18 ++++ app/Domains/Catalog/Models/FeaturedGroup.php | 15 ++++ .../Resources/CatalogFeaturedItemResource.php | 10 ++- .../Catalog/Services/FeaturedGroupService.php | 87 +++++++++++++++++++ ...00_add_source_to_featured_groups_table.php | 31 +++++++ .../FiestaFutbolInfantilProductSeeder.php | 68 +++++++-------- .../ProductCatalogFromImagesSeeder.php | 19 +--- .../Feature/Catalog/CatalogControllerTest.php | 42 +++++++++ tests/Feature/Catalog/CatalogSchemaTest.php | 2 + .../FiestaFutbolInfantilProductSeederTest.php | 17 ++-- .../ProductCatalogFromImagesSeederTest.php | 11 ++- tests/Unit/Catalog/CatalogModelsTest.php | 6 ++ 13 files changed, 260 insertions(+), 136 deletions(-) create mode 100644 app/Domains/Catalog/Enums/FeaturedGroupSource.php create mode 100644 app/Domains/Catalog/Services/FeaturedGroupService.php create mode 100644 database/migrations/2026_08_04_000200_add_source_to_featured_groups_table.php diff --git a/app/Domains/Catalog/Controllers/CatalogController.php b/app/Domains/Catalog/Controllers/CatalogController.php index 07dbd06..476ec33 100644 --- a/app/Domains/Catalog/Controllers/CatalogController.php +++ b/app/Domains/Catalog/Controllers/CatalogController.php @@ -2,34 +2,28 @@ namespace App\Domains\Catalog\Controllers; -use App\Domains\Catalog\Enums\GroupLayout; use App\Domains\Catalog\Models\CatalogItem; use App\Domains\Catalog\Models\Category; use App\Domains\Catalog\Models\FeaturedGroup; -use App\Domains\Catalog\Models\FeaturedItem; use App\Domains\Catalog\Requests\CatalogItemDetailRequest; use App\Domains\Catalog\Requests\CategoryPageRequest; use App\Domains\Catalog\Requests\FeaturedGroupPageRequest; use App\Domains\Catalog\Requests\SearchCatalogItemsRequest; use App\Domains\Catalog\Requests\StoreCatalogItemRequest; use App\Domains\Catalog\Resources\CatalogFeaturedGroupResource; -use App\Domains\Catalog\Resources\CatalogFeaturedItemResource; use App\Domains\Catalog\Resources\CatalogItemDetailResource; use App\Domains\Catalog\Resources\CatalogItemResource; use App\Domains\Catalog\Resources\CatalogSearchItemResource; use App\Domains\Catalog\Services\CatalogService; +use App\Domains\Catalog\Services\FeaturedGroupService; use App\Domains\Tenant\Models\Tenant; use App\Http\Controllers\Controller; -use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Http\JsonResponse; use Illuminate\Http\Resources\Json\AnonymousResourceCollection; -use Illuminate\Pagination\LengthAwarePaginator; class CatalogController extends Controller { - private const ITEMS_PER_PAGE = 12; - - public function index(Tenant $tenant): JsonResponse + public function index(Tenant $tenant, FeaturedGroupService $featuredGroupService): JsonResponse { $featuredGroups = FeaturedGroup::query() ->where('tenant_code', $tenant->codigo) @@ -39,7 +33,7 @@ class CatalogController extends Controller return response()->json($featuredGroups->map( fn (FeaturedGroup $featuredGroup): array => (new CatalogFeaturedGroupResource( $featuredGroup, - $this->featuredItemsResponse($featuredGroup, 1), + $featuredGroupService->itemsResponse($featuredGroup, 1), ))->resolve() )); } @@ -89,12 +83,13 @@ class CatalogController extends Controller FeaturedGroupPageRequest $request, Tenant $tenant, FeaturedGroup $featuredGroup, + FeaturedGroupService $featuredGroupService, ): JsonResponse { abort_unless($featuredGroup->tenant_code === $tenant->codigo, 404); $page = (int) $request->validated('page', 1); - return response()->json($this->featuredItemsResponse($featuredGroup, $page)); + return response()->json($featuredGroupService->itemsResponse($featuredGroup, $page)); } public function show( @@ -129,59 +124,4 @@ class CatalogController extends Controller ->response() ->setStatusCode(201); } - - /** @return array */ - private function featuredItemsResponse(FeaturedGroup $featuredGroup, int $page): array - { - if ($featuredGroup->group_layout !== GroupLayout::Paginated) { - $featuredItems = $this->featuredItemsQuery($featuredGroup)->get(); - - $featuredItems->each( - fn ($featuredItem) => $featuredItem->setRelation('featuredGroup', $featuredGroup) - ); - - return CatalogFeaturedItemResource::collection($featuredItems)->resolve(); - } - - $paginator = $this->paginateFeaturedItems($featuredGroup, $page); - - $paginator->getCollection()->each( - fn ($featuredItem) => $featuredItem->setRelation('featuredGroup', $featuredGroup) - ); - - return CatalogFeaturedItemResource::collection($paginator) - ->response() - ->getData(true); - } - - private function paginateFeaturedItems( - FeaturedGroup $featuredGroup, - int $page, - ): LengthAwarePaginator { - $paginator = $this->featuredItemsQuery($featuredGroup)->paginate( - perPage: self::ITEMS_PER_PAGE, - pageName: 'page', - page: $page, - ); - - return $paginator->withPath(route('catalog.featured-groups.items.index', [ - 'tenant' => $featuredGroup->tenant_code, - 'featuredGroup' => $featuredGroup->id, - ])); - } - - /** @return HasMany */ - private function featuredItemsQuery(FeaturedGroup $featuredGroup): HasMany - { - return $featuredGroup->featuredItems()->with([ - 'catalogItem.inventory', - 'catalogItem.attachments', - 'catalogItem.variants.inventory', - 'catalogItem.variants.attachments', - 'catalogItem.variants.eventDate', - 'catalogItem.variants.definitions.itemAttribute.attribute', - 'catalogItem.bundleComponents.catalogItem', - 'catalogItem.bundleComponents.variant.catalogItem', - ]); - } } diff --git a/app/Domains/Catalog/Enums/FeaturedGroupSource.php b/app/Domains/Catalog/Enums/FeaturedGroupSource.php new file mode 100644 index 0000000..efc7946 --- /dev/null +++ b/app/Domains/Catalog/Enums/FeaturedGroupSource.php @@ -0,0 +1,18 @@ + + */ + public static function values(): array + { + return array_column(self::cases(), 'value'); + } +} diff --git a/app/Domains/Catalog/Models/FeaturedGroup.php b/app/Domains/Catalog/Models/FeaturedGroup.php index f68a944..78af04d 100644 --- a/app/Domains/Catalog/Models/FeaturedGroup.php +++ b/app/Domains/Catalog/Models/FeaturedGroup.php @@ -2,6 +2,7 @@ namespace App\Domains\Catalog\Models; +use App\Domains\Catalog\Enums\FeaturedGroupSource; use App\Domains\Catalog\Enums\GroupLayout; use App\Domains\Catalog\Enums\ProductLayout; use App\Domains\Tenant\Models\Tenant; @@ -13,6 +14,8 @@ use Illuminate\Database\Eloquent\Relations\HasMany; #[Fillable([ 'tenant_code', + 'source_type', + 'category_id', 'product_layout', 'group_layout', 'group_name', @@ -26,9 +29,15 @@ class FeaturedGroup extends Model protected $table = 'featured_groups'; + protected $attributes = [ + 'source_type' => FeaturedGroupSource::Manual->value, + ]; + protected function casts(): array { return [ + 'source_type' => FeaturedGroupSource::class, + 'category_id' => 'integer', 'product_layout' => ProductLayout::class, 'group_layout' => GroupLayout::class, 'group_order' => 'integer', @@ -41,6 +50,12 @@ class FeaturedGroup extends Model return $this->belongsTo(Tenant::class, 'tenant_code', 'codigo'); } + /** @return BelongsTo */ + public function category(): BelongsTo + { + return $this->belongsTo(Category::class); + } + /** @return HasMany */ public function featuredItems(): HasMany { diff --git a/app/Domains/Catalog/Resources/CatalogFeaturedItemResource.php b/app/Domains/Catalog/Resources/CatalogFeaturedItemResource.php index b94122a..2c44aaf 100644 --- a/app/Domains/Catalog/Resources/CatalogFeaturedItemResource.php +++ b/app/Domains/Catalog/Resources/CatalogFeaturedItemResource.php @@ -5,20 +5,22 @@ namespace App\Domains\Catalog\Resources; use App\Domains\Catalog\Enums\InventoryPolicy; use App\Domains\Catalog\Enums\ProductLayout; use App\Domains\Catalog\Models\CatalogItem; -use App\Domains\Catalog\Models\FeaturedItem; +use App\Domains\Catalog\Models\FeaturedGroup; use App\Domains\Catalog\Models\Variant; use Illuminate\Http\Request; use Illuminate\Http\Resources\Json\JsonResource; -/** @mixin FeaturedItem */ +/** @mixin CatalogItem */ class CatalogFeaturedItemResource extends JsonResource { /** @return array */ public function toArray(Request $request): array { - $catalogItem = $this->catalogItem; + $catalogItem = $this->resource; + /** @var FeaturedGroup $featuredGroup */ + $featuredGroup = $catalogItem->getRelation('featuredGroup'); - if ($this->featuredGroup->product_layout === ProductLayout::ColumnWithImage) { + if ($featuredGroup->product_layout === ProductLayout::ColumnWithImage) { return $this->columnWithImageData($catalogItem); } diff --git a/app/Domains/Catalog/Services/FeaturedGroupService.php b/app/Domains/Catalog/Services/FeaturedGroupService.php new file mode 100644 index 0000000..3d68dcb --- /dev/null +++ b/app/Domains/Catalog/Services/FeaturedGroupService.php @@ -0,0 +1,87 @@ + */ + public function itemsResponse(FeaturedGroup $featuredGroup, int $page): array + { + if ($featuredGroup->group_layout !== GroupLayout::Paginated) { + $items = $this->itemsQuery($featuredGroup)->get(); + $this->attachGroup($items, $featuredGroup); + + return CatalogFeaturedItemResource::collection($items)->resolve(); + } + + $paginator = $this->paginateItems($featuredGroup, $page); + $this->attachGroup($paginator->getCollection(), $featuredGroup); + + return CatalogFeaturedItemResource::collection($paginator) + ->response() + ->getData(true); + } + + /** @return Builder */ + private function itemsQuery(FeaturedGroup $featuredGroup): Builder + { + $query = CatalogItem::query() + ->where('catalog_items.tenant_code', $featuredGroup->tenant_code) + ->with([ + 'inventory', + 'attachments', + 'variants.inventory', + 'variants.attachments', + 'variants.eventDate', + 'variants.definitions.itemAttribute.attribute', + 'bundleComponents.catalogItem', + 'bundleComponents.variant.catalogItem', + ]); + + return match ($featuredGroup->source_type) { + FeaturedGroupSource::Manual => $query + ->select('catalog_items.*') + ->join('featured_items', 'featured_items.catalog_item_id', '=', 'catalog_items.id') + ->where('featured_items.featured_group_id', $featuredGroup->id) + ->orderBy('featured_items.order') + ->orderBy('featured_items.id'), + FeaturedGroupSource::Category => $query + ->where('catalog_items.category_id', $featuredGroup->category_id) + ->orderBy('catalog_items.id'), + FeaturedGroupSource::All => $query->orderBy('catalog_items.id'), + }; + } + + private function paginateItems( + FeaturedGroup $featuredGroup, + int $page, + ): LengthAwarePaginator { + $paginator = $this->itemsQuery($featuredGroup)->paginate( + perPage: self::ITEMS_PER_PAGE, + pageName: 'page', + page: $page, + ); + + return $paginator->withPath(route('catalog.featured-groups.items.index', [ + 'tenant' => $featuredGroup->tenant_code, + 'featuredGroup' => $featuredGroup->id, + ])); + } + + private function attachGroup(iterable $items, FeaturedGroup $featuredGroup): void + { + foreach ($items as $item) { + $item->setRelation('featuredGroup', $featuredGroup); + } + } +} diff --git a/database/migrations/2026_08_04_000200_add_source_to_featured_groups_table.php b/database/migrations/2026_08_04_000200_add_source_to_featured_groups_table.php new file mode 100644 index 0000000..309877e --- /dev/null +++ b/database/migrations/2026_08_04_000200_add_source_to_featured_groups_table.php @@ -0,0 +1,31 @@ +enum('source_type', FeaturedGroupSource::values()) + ->default(FeaturedGroupSource::Manual->value) + ->after('tenant_code'); + $table->foreignId('category_id') + ->nullable() + ->after('source_type') + ->constrained('categorias') + ->nullOnDelete(); + }); + } + + public function down(): void + { + Schema::table('featured_groups', function (Blueprint $table): void { + $table->dropConstrainedForeignId('category_id'); + $table->dropColumn('source_type'); + }); + } +}; diff --git a/database/seeders/FiestaFutbolInfantilProductSeeder.php b/database/seeders/FiestaFutbolInfantilProductSeeder.php index c8174a2..5797c0b 100644 --- a/database/seeders/FiestaFutbolInfantilProductSeeder.php +++ b/database/seeders/FiestaFutbolInfantilProductSeeder.php @@ -4,6 +4,7 @@ namespace Database\Seeders; use App\Domains\Catalog\Enums\CatalogItemType; use App\Domains\Catalog\Enums\EventProductType; +use App\Domains\Catalog\Enums\FeaturedGroupSource; use App\Domains\Catalog\Enums\GroupLayout; use App\Domains\Catalog\Enums\InventoryPolicy; use App\Domains\Catalog\Enums\ProductLayout; @@ -61,6 +62,18 @@ class FiestaFutbolInfantilProductSeeder extends Seeder 'nombre' => 'Gastronomía', 'tenant_code' => $tenant->codigo, ]); + $mealCategory = Category::query()->updateOrCreate([ + 'nombre' => 'Comidas', + 'tenant_code' => $tenant->codigo, + ], [ + 'categoria_id' => $foodCategory->id, + ]); + $drinkCategory = Category::query()->updateOrCreate([ + 'nombre' => 'Bebidas', + 'tenant_code' => $tenant->codigo, + ], [ + 'categoria_id' => $foodCategory->id, + ]); $parkingCategory = Category::query()->firstOrCreate([ 'nombre' => 'Estacionamiento', 'tenant_code' => $tenant->codigo, @@ -93,10 +106,10 @@ class FiestaFutbolInfantilProductSeeder extends Seeder ]); $items = [ - ['slug' => 'hamburguesa-papa-frita', 'nombre' => 'Hamburguesa con papa frita', 'precio' => 8000, 'category_id' => $foodCategory->id], - ['slug' => 'pancho', 'nombre' => 'Pancho', 'precio' => 4000, 'category_id' => $foodCategory->id], - ['slug' => 'coca-cola-500ml', 'nombre' => 'Coca Cola 500ml', 'precio' => 3000, 'category_id' => $foodCategory->id], - ['slug' => 'agua-mineral-1l', 'nombre' => 'Agua Mineral 1L', 'precio' => 2500, 'category_id' => $foodCategory->id], + ['slug' => 'hamburguesa-papa-frita', 'nombre' => 'Hamburguesa con papa frita', 'precio' => 8000, 'category_id' => $mealCategory->id], + ['slug' => 'pancho', 'nombre' => 'Pancho', 'precio' => 4000, 'category_id' => $mealCategory->id], + ['slug' => 'coca-cola-500ml', 'nombre' => 'Coca Cola 500ml', 'precio' => 3000, 'category_id' => $drinkCategory->id], + ['slug' => 'agua-mineral-1l', 'nombre' => 'Agua Mineral 1L', 'precio' => 2500, 'category_id' => $drinkCategory->id], ['slug' => 'estacionamiento-auto', 'nombre' => 'Estacionamiento Auto', 'precio' => 5000, 'category_id' => $parkingCategory->id], ['slug' => 'estacionamiento-moto', 'nombre' => 'Estacionamiento Moto', 'precio' => 2000, 'category_id' => $parkingCategory->id], ]; @@ -144,7 +157,7 @@ class FiestaFutbolInfantilProductSeeder extends Seeder 'nombre' => 'Combo 2 Panchos + 2 Hamburguesas', 'descripcion' => 'Incluye 2 panchos y 2 hamburguesas con papa frita.', 'precio' => 24000, - 'category_id' => $foodCategory->id, + 'category_id' => $mealCategory->id, 'components' => [ [ 'catalog_item_id' => $createdItems['pancho']->id, @@ -157,7 +170,12 @@ class FiestaFutbolInfantilProductSeeder extends Seeder ], ]); - $this->seedFeaturedGroups($tenant); + $this->seedFeaturedGroups($tenant, [ + 'Entradas' => $ticketCategory, + 'Estacionamiento' => $parkingCategory, + 'Comidas' => $mealCategory, + 'Bebidas' => $drinkCategory, + ]); } private function deleteExistingCatalog(Tenant $tenant): void @@ -173,7 +191,8 @@ class FiestaFutbolInfantilProductSeeder extends Seeder ->each(fn (CatalogItem $item) => $this->catalogService->delete($item)); } - private function seedFeaturedGroups(Tenant $tenant): void + /** @param array $categories */ + private function seedFeaturedGroups(Tenant $tenant, array $categories): void { FeaturedGroup::query()->where('tenant_code', $tenant->codigo)->delete(); @@ -181,62 +200,33 @@ class FiestaFutbolInfantilProductSeeder extends Seeder 'Entradas' => [ 'product_layout' => ProductLayout::Row, 'group_layout' => GroupLayout::SimpleVertical, - 'slugs' => [ - 'entrada-general', - 'entrada-general-todos-los-dias', - ], ], 'Estacionamiento' => [ 'product_layout' => ProductLayout::ColumnWithCart, 'group_layout' => GroupLayout::Simple, - 'slugs' => [ - 'estacionamiento-auto', - 'estacionamiento-moto', - ], ], 'Comidas' => [ 'product_layout' => ProductLayout::ColumnWithCart, 'group_layout' => GroupLayout::Simple, - 'slugs' => [ - 'hamburguesa-papa-frita', - 'pancho', - 'combo-2-panchos-2-hamburguesas', - ], ], 'Bebidas' => [ 'product_layout' => ProductLayout::ColumnWithCart, 'group_layout' => GroupLayout::Simple, - 'slugs' => [ - 'coca-cola-500ml', - 'agua-mineral-1l', - ], ], ]; - $catalogItems = CatalogItem::query() - ->where('tenant_code', $tenant->codigo) - ->whereIn('slug', collect($groups)->pluck('slugs')->flatten()->all()) - ->get() - ->keyBy('slug'); - $groupOrder = 0; foreach ($groups as $groupName => $config) { - $featuredGroup = FeaturedGroup::query()->create([ + FeaturedGroup::query()->create([ 'tenant_code' => $tenant->codigo, + 'source_type' => FeaturedGroupSource::Category, + 'category_id' => $categories[$groupName]->id, 'product_layout' => $config['product_layout'], 'group_layout' => $config['group_layout'], 'group_name' => $groupName, 'group_order' => $groupOrder++, ]); - $featuredGroup->featuredItems()->createMany( - collect($config['slugs'])->values()->map( - fn (string $slug, int $order): array => [ - 'catalog_item_id' => $catalogItems->get($slug)->id, - 'order' => $order, - ] - )->all() - ); } } } diff --git a/database/seeders/ProductCatalogFromImagesSeeder.php b/database/seeders/ProductCatalogFromImagesSeeder.php index 38a5e22..b6c0482 100644 --- a/database/seeders/ProductCatalogFromImagesSeeder.php +++ b/database/seeders/ProductCatalogFromImagesSeeder.php @@ -2,6 +2,7 @@ namespace Database\Seeders; +use App\Domains\Catalog\Enums\FeaturedGroupSource; use App\Domains\Catalog\Enums\GroupLayout; use App\Domains\Catalog\Enums\InventoryPolicy; use App\Domains\Catalog\Enums\ProductLayout; @@ -168,30 +169,18 @@ class ProductCatalogFromImagesSeeder extends Seeder { FeaturedGroup::query()->where('tenant_code', $tenant->codigo)->delete(); - $paginatedGroup = FeaturedGroup::query()->create([ + FeaturedGroup::query()->create([ 'tenant_code' => $tenant->codigo, + 'source_type' => FeaturedGroupSource::All, 'product_layout' => ProductLayout::ColumnWithImage, 'group_layout' => GroupLayout::Paginated, 'group_name' => 'Productos', 'group_order' => 2, ]); - $items = CatalogItem::query() - ->where('tenant_code', $tenant->codigo) - ->orderBy('id') - ->get('id'); - - $paginatedGroup->featuredItems()->createMany( - $items->values()->map( - fn (CatalogItem $item, int $order): array => [ - 'catalog_item_id' => $item->id, - 'order' => $order, - ] - )->all() - ); - $carouselGroup = FeaturedGroup::query()->create([ 'tenant_code' => $tenant->codigo, + 'source_type' => FeaturedGroupSource::Manual, 'product_layout' => ProductLayout::ColumnWithImage, 'group_layout' => GroupLayout::Carousel, 'group_name' => 'Productos destacados', diff --git a/tests/Feature/Catalog/CatalogControllerTest.php b/tests/Feature/Catalog/CatalogControllerTest.php index 8122b0f..c560b54 100644 --- a/tests/Feature/Catalog/CatalogControllerTest.php +++ b/tests/Feature/Catalog/CatalogControllerTest.php @@ -4,9 +4,11 @@ namespace Tests\Feature\Catalog; use App\Domains\Attachable\Enums\AttachmentType; use App\Domains\Attachable\Models\Attachment; +use App\Domains\Catalog\Enums\FeaturedGroupSource; use App\Domains\Catalog\Enums\GroupLayout; use App\Domains\Catalog\Enums\ProductLayout; use App\Domains\Catalog\Models\CatalogItem; +use App\Domains\Catalog\Models\Category; use App\Domains\Catalog\Models\FeaturedGroup; use App\Domains\Catalog\Models\Inventory; use App\Domains\Tenant\Models\Tenant; @@ -198,6 +200,46 @@ class CatalogControllerTest extends TestCase ->assertJsonPath('0.nombre', 'carousel Item 1'); } + public function test_groups_can_source_items_from_a_category_or_the_entire_catalog(): void + { + $tenant = $this->createTenant('catalog-sources'); + $category = Category::query()->create([ + 'tenant_code' => $tenant->codigo, + 'nombre' => 'Food', + ]); + + FeaturedGroup::query()->create([ + 'tenant_code' => $tenant->codigo, + 'source_type' => FeaturedGroupSource::Category, + 'category_id' => $category->id, + 'product_layout' => ProductLayout::Row, + 'group_layout' => GroupLayout::Simple, + 'group_name' => 'Food', + 'group_order' => 0, + ]); + FeaturedGroup::query()->create([ + 'tenant_code' => $tenant->codigo, + 'source_type' => FeaturedGroupSource::All, + 'product_layout' => ProductLayout::Row, + 'group_layout' => GroupLayout::Paginated, + 'group_name' => 'All products', + 'group_order' => 1, + ]); + + $food = $this->createItem($tenant, 'Hamburger'); + $food->category()->associate($category)->save(); + $this->createItem($tenant, 'Parking'); + + $this->getJson("/api/tenants/{$tenant->codigo}/catalog") + ->assertOk() + ->assertJsonPath('0.title', 'Food') + ->assertJsonCount(1, '0.items') + ->assertJsonPath('0.items.0.nombre', 'Hamburger') + ->assertJsonPath('1.title', 'All products') + ->assertJsonCount(2, '1.items.data') + ->assertJsonPath('1.items.meta.total', 2); + } + private function createGroup( Tenant $tenant, ProductLayout $layout, diff --git a/tests/Feature/Catalog/CatalogSchemaTest.php b/tests/Feature/Catalog/CatalogSchemaTest.php index 0c1a252..f561360 100644 --- a/tests/Feature/Catalog/CatalogSchemaTest.php +++ b/tests/Feature/Catalog/CatalogSchemaTest.php @@ -79,6 +79,8 @@ class CatalogSchemaTest extends TestCase $this->assertEqualsCanonicalizing([ 'id', 'tenant_code', + 'source_type', + 'category_id', 'product_layout', 'group_layout', 'group_name', diff --git a/tests/Feature/Seeders/FiestaFutbolInfantilProductSeederTest.php b/tests/Feature/Seeders/FiestaFutbolInfantilProductSeederTest.php index 6f9ce42..edf87ce 100644 --- a/tests/Feature/Seeders/FiestaFutbolInfantilProductSeederTest.php +++ b/tests/Feature/Seeders/FiestaFutbolInfantilProductSeederTest.php @@ -6,6 +6,7 @@ use App\Domains\Attachable\Enums\AttachmentType; use App\Domains\Attachable\Models\Attachment; use App\Domains\Catalog\Enums\CatalogItemType; use App\Domains\Catalog\Enums\EventProductType; +use App\Domains\Catalog\Enums\FeaturedGroupSource; use App\Domains\Catalog\Enums\GroupLayout; use App\Domains\Catalog\Enums\ProductLayout; use App\Domains\Catalog\Models\Attribute; @@ -174,7 +175,7 @@ class FiestaFutbolInfantilProductSeederTest extends TestCase $this->assertSame(9, CatalogItem::query()->where('tenant_code', $tenant->codigo)->count()); $this->assertSame(10, Inventory::query()->count()); $this->assertSame( - ['Entradas', 'Estacionamiento', 'Gastronomía'], + ['Bebidas', 'Comidas', 'Entradas', 'Estacionamiento', 'Gastronomía'], Category::query() ->where('tenant_code', $tenant->codigo) ->orderBy('nombre') @@ -194,7 +195,7 @@ class FiestaFutbolInfantilProductSeederTest extends TestCase $featuredGroups = FeaturedGroup::query() ->where('tenant_code', $tenant->codigo) - ->with('featuredItems.catalogItem') + ->with('category.catalogItems') ->orderBy('group_order') ->get(); @@ -207,21 +208,23 @@ class FiestaFutbolInfantilProductSeederTest extends TestCase ], $featuredGroups ->mapWithKeys(fn (FeaturedGroup $group): array => [ - $group->group_name => $group->featuredItems->pluck('catalogItem.slug')->all(), + $group->group_name => $group->category->catalogItems->pluck('slug')->all(), ]) ->all() ); $this->assertSame( [ - ['Entradas', ProductLayout::Row, GroupLayout::SimpleVertical, 0], - ['Estacionamiento', ProductLayout::ColumnWithCart, GroupLayout::Simple, 1], - ['Comidas', ProductLayout::ColumnWithCart, GroupLayout::Simple, 2], - ['Bebidas', ProductLayout::ColumnWithCart, GroupLayout::Simple, 3], + ['Entradas', FeaturedGroupSource::Category, 'Entradas', ProductLayout::Row, GroupLayout::SimpleVertical, 0], + ['Estacionamiento', FeaturedGroupSource::Category, 'Estacionamiento', ProductLayout::ColumnWithCart, GroupLayout::Simple, 1], + ['Comidas', FeaturedGroupSource::Category, 'Comidas', ProductLayout::ColumnWithCart, GroupLayout::Simple, 2], + ['Bebidas', FeaturedGroupSource::Category, 'Bebidas', ProductLayout::ColumnWithCart, GroupLayout::Simple, 3], ], $featuredGroups ->map(fn (FeaturedGroup $group): array => [ $group->group_name, + $group->source_type, + $group->category->nombre, $group->product_layout, $group->group_layout, $group->group_order, diff --git a/tests/Feature/Seeders/ProductCatalogFromImagesSeederTest.php b/tests/Feature/Seeders/ProductCatalogFromImagesSeederTest.php index f04915b..98f5104 100644 --- a/tests/Feature/Seeders/ProductCatalogFromImagesSeederTest.php +++ b/tests/Feature/Seeders/ProductCatalogFromImagesSeederTest.php @@ -4,6 +4,7 @@ namespace Tests\Feature\Seeders; use App\Domains\Attachable\Enums\AttachmentType; use App\Domains\Attachable\Models\Attachment; +use App\Domains\Catalog\Enums\FeaturedGroupSource; use App\Domains\Catalog\Enums\GroupLayout; use App\Domains\Catalog\Enums\ProductLayout; use App\Domains\Catalog\Models\CatalogItem; @@ -70,16 +71,14 @@ class ProductCatalogFromImagesSeederTest extends TestCase $this->assertNotNull($paginatedGroup); $this->assertSame(ProductLayout::ColumnWithImage, $paginatedGroup->product_layout); $this->assertSame(GroupLayout::Paginated, $paginatedGroup->group_layout); - $this->assertSame(0, $paginatedGroup->group_order); - $this->assertSame( - CatalogItem::query()->where('tenant_code', $tenant->codigo)->orderBy('id')->pluck('slug')->all(), - $paginatedGroup->featuredItems->pluck('catalogItem.slug')->all(), - ); - $this->assertCount(10, $paginatedGroup->featuredItems); + $this->assertSame(FeaturedGroupSource::All, $paginatedGroup->source_type); + $this->assertSame(2, $paginatedGroup->group_order); + $this->assertCount(0, $paginatedGroup->featuredItems); $this->assertNotNull($carouselGroup); $this->assertSame(ProductLayout::ColumnWithImage, $carouselGroup->product_layout); $this->assertSame(GroupLayout::Carousel, $carouselGroup->group_layout); + $this->assertSame(FeaturedGroupSource::Manual, $carouselGroup->source_type); $this->assertSame(1, $carouselGroup->group_order); $this->assertCount(5, $carouselGroup->featuredItems); $this->assertCount( diff --git a/tests/Unit/Catalog/CatalogModelsTest.php b/tests/Unit/Catalog/CatalogModelsTest.php index 10f5719..1f4abd3 100644 --- a/tests/Unit/Catalog/CatalogModelsTest.php +++ b/tests/Unit/Catalog/CatalogModelsTest.php @@ -5,6 +5,7 @@ namespace Tests\Unit\Catalog; use App\Domains\Attachable\Models\Attachment; use App\Domains\Catalog\Enums\CatalogItemType; use App\Domains\Catalog\Enums\EventProductType; +use App\Domains\Catalog\Enums\FeaturedGroupSource; use App\Domains\Catalog\Enums\GroupLayout; use App\Domains\Catalog\Enums\InventoryPolicy; use App\Domains\Catalog\Enums\ProductLayout; @@ -104,6 +105,8 @@ class CatalogModelsTest extends TestCase { $group = new FeaturedGroup; $group->setRawAttributes([ + 'source_type' => FeaturedGroupSource::Category->value, + 'category_id' => '4', 'product_layout' => ProductLayout::ColumnWithImage->value, 'group_layout' => GroupLayout::SimpleVertical->value, 'group_order' => '2', @@ -118,9 +121,12 @@ class CatalogModelsTest extends TestCase $this->assertSame('featured_groups', $group->getTable()); $this->assertFalse($group->usesTimestamps()); $this->assertSame(ProductLayout::ColumnWithImage, $group->product_layout); + $this->assertSame(FeaturedGroupSource::Category, $group->source_type); + $this->assertSame(4, $group->category_id); $this->assertSame(GroupLayout::SimpleVertical, $group->group_layout); $this->assertSame(2, $group->group_order); $this->assertInstanceOf(Tenant::class, $group->tenant()->getRelated()); + $this->assertInstanceOf(Category::class, $group->category()->getRelated()); $this->assertInstanceOf(FeaturedItem::class, $group->featuredItems()->getRelated()); $this->assertSame('featured_items', $featuredItem->getTable());