feat: Introduce source type for featured groups; add category association and implement FeaturedGroupService for item sourcing
This commit is contained in:
@@ -2,34 +2,28 @@
|
|||||||
|
|
||||||
namespace App\Domains\Catalog\Controllers;
|
namespace App\Domains\Catalog\Controllers;
|
||||||
|
|
||||||
use App\Domains\Catalog\Enums\GroupLayout;
|
|
||||||
use App\Domains\Catalog\Models\CatalogItem;
|
use App\Domains\Catalog\Models\CatalogItem;
|
||||||
use App\Domains\Catalog\Models\Category;
|
use App\Domains\Catalog\Models\Category;
|
||||||
use App\Domains\Catalog\Models\FeaturedGroup;
|
use App\Domains\Catalog\Models\FeaturedGroup;
|
||||||
use App\Domains\Catalog\Models\FeaturedItem;
|
|
||||||
use App\Domains\Catalog\Requests\CatalogItemDetailRequest;
|
use App\Domains\Catalog\Requests\CatalogItemDetailRequest;
|
||||||
use App\Domains\Catalog\Requests\CategoryPageRequest;
|
use App\Domains\Catalog\Requests\CategoryPageRequest;
|
||||||
use App\Domains\Catalog\Requests\FeaturedGroupPageRequest;
|
use App\Domains\Catalog\Requests\FeaturedGroupPageRequest;
|
||||||
use App\Domains\Catalog\Requests\SearchCatalogItemsRequest;
|
use App\Domains\Catalog\Requests\SearchCatalogItemsRequest;
|
||||||
use App\Domains\Catalog\Requests\StoreCatalogItemRequest;
|
use App\Domains\Catalog\Requests\StoreCatalogItemRequest;
|
||||||
use App\Domains\Catalog\Resources\CatalogFeaturedGroupResource;
|
use App\Domains\Catalog\Resources\CatalogFeaturedGroupResource;
|
||||||
use App\Domains\Catalog\Resources\CatalogFeaturedItemResource;
|
|
||||||
use App\Domains\Catalog\Resources\CatalogItemDetailResource;
|
use App\Domains\Catalog\Resources\CatalogItemDetailResource;
|
||||||
use App\Domains\Catalog\Resources\CatalogItemResource;
|
use App\Domains\Catalog\Resources\CatalogItemResource;
|
||||||
use App\Domains\Catalog\Resources\CatalogSearchItemResource;
|
use App\Domains\Catalog\Resources\CatalogSearchItemResource;
|
||||||
use App\Domains\Catalog\Services\CatalogService;
|
use App\Domains\Catalog\Services\CatalogService;
|
||||||
|
use App\Domains\Catalog\Services\FeaturedGroupService;
|
||||||
use App\Domains\Tenant\Models\Tenant;
|
use App\Domains\Tenant\Models\Tenant;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
|
||||||
|
|
||||||
class CatalogController extends Controller
|
class CatalogController extends Controller
|
||||||
{
|
{
|
||||||
private const ITEMS_PER_PAGE = 12;
|
public function index(Tenant $tenant, FeaturedGroupService $featuredGroupService): JsonResponse
|
||||||
|
|
||||||
public function index(Tenant $tenant): JsonResponse
|
|
||||||
{
|
{
|
||||||
$featuredGroups = FeaturedGroup::query()
|
$featuredGroups = FeaturedGroup::query()
|
||||||
->where('tenant_code', $tenant->codigo)
|
->where('tenant_code', $tenant->codigo)
|
||||||
@@ -39,7 +33,7 @@ class CatalogController extends Controller
|
|||||||
return response()->json($featuredGroups->map(
|
return response()->json($featuredGroups->map(
|
||||||
fn (FeaturedGroup $featuredGroup): array => (new CatalogFeaturedGroupResource(
|
fn (FeaturedGroup $featuredGroup): array => (new CatalogFeaturedGroupResource(
|
||||||
$featuredGroup,
|
$featuredGroup,
|
||||||
$this->featuredItemsResponse($featuredGroup, 1),
|
$featuredGroupService->itemsResponse($featuredGroup, 1),
|
||||||
))->resolve()
|
))->resolve()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -89,12 +83,13 @@ class CatalogController extends Controller
|
|||||||
FeaturedGroupPageRequest $request,
|
FeaturedGroupPageRequest $request,
|
||||||
Tenant $tenant,
|
Tenant $tenant,
|
||||||
FeaturedGroup $featuredGroup,
|
FeaturedGroup $featuredGroup,
|
||||||
|
FeaturedGroupService $featuredGroupService,
|
||||||
): JsonResponse {
|
): JsonResponse {
|
||||||
abort_unless($featuredGroup->tenant_code === $tenant->codigo, 404);
|
abort_unless($featuredGroup->tenant_code === $tenant->codigo, 404);
|
||||||
|
|
||||||
$page = (int) $request->validated('page', 1);
|
$page = (int) $request->validated('page', 1);
|
||||||
|
|
||||||
return response()->json($this->featuredItemsResponse($featuredGroup, $page));
|
return response()->json($featuredGroupService->itemsResponse($featuredGroup, $page));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function show(
|
public function show(
|
||||||
@@ -129,59 +124,4 @@ class CatalogController extends Controller
|
|||||||
->response()
|
->response()
|
||||||
->setStatusCode(201);
|
->setStatusCode(201);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return array<array-key, mixed> */
|
|
||||||
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<FeaturedItem, FeaturedGroup> */
|
|
||||||
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',
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
18
app/Domains/Catalog/Enums/FeaturedGroupSource.php
Normal file
18
app/Domains/Catalog/Enums/FeaturedGroupSource.php
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Domains\Catalog\Enums;
|
||||||
|
|
||||||
|
enum FeaturedGroupSource: string
|
||||||
|
{
|
||||||
|
case Manual = 'manual';
|
||||||
|
case Category = 'category';
|
||||||
|
case All = 'all';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return list<string>
|
||||||
|
*/
|
||||||
|
public static function values(): array
|
||||||
|
{
|
||||||
|
return array_column(self::cases(), 'value');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Domains\Catalog\Models;
|
namespace App\Domains\Catalog\Models;
|
||||||
|
|
||||||
|
use App\Domains\Catalog\Enums\FeaturedGroupSource;
|
||||||
use App\Domains\Catalog\Enums\GroupLayout;
|
use App\Domains\Catalog\Enums\GroupLayout;
|
||||||
use App\Domains\Catalog\Enums\ProductLayout;
|
use App\Domains\Catalog\Enums\ProductLayout;
|
||||||
use App\Domains\Tenant\Models\Tenant;
|
use App\Domains\Tenant\Models\Tenant;
|
||||||
@@ -13,6 +14,8 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
|
|||||||
|
|
||||||
#[Fillable([
|
#[Fillable([
|
||||||
'tenant_code',
|
'tenant_code',
|
||||||
|
'source_type',
|
||||||
|
'category_id',
|
||||||
'product_layout',
|
'product_layout',
|
||||||
'group_layout',
|
'group_layout',
|
||||||
'group_name',
|
'group_name',
|
||||||
@@ -26,9 +29,15 @@ class FeaturedGroup extends Model
|
|||||||
|
|
||||||
protected $table = 'featured_groups';
|
protected $table = 'featured_groups';
|
||||||
|
|
||||||
|
protected $attributes = [
|
||||||
|
'source_type' => FeaturedGroupSource::Manual->value,
|
||||||
|
];
|
||||||
|
|
||||||
protected function casts(): array
|
protected function casts(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
'source_type' => FeaturedGroupSource::class,
|
||||||
|
'category_id' => 'integer',
|
||||||
'product_layout' => ProductLayout::class,
|
'product_layout' => ProductLayout::class,
|
||||||
'group_layout' => GroupLayout::class,
|
'group_layout' => GroupLayout::class,
|
||||||
'group_order' => 'integer',
|
'group_order' => 'integer',
|
||||||
@@ -41,6 +50,12 @@ class FeaturedGroup extends Model
|
|||||||
return $this->belongsTo(Tenant::class, 'tenant_code', 'codigo');
|
return $this->belongsTo(Tenant::class, 'tenant_code', 'codigo');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return BelongsTo<Category, $this> */
|
||||||
|
public function category(): BelongsTo
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Category::class);
|
||||||
|
}
|
||||||
|
|
||||||
/** @return HasMany<FeaturedItem, $this> */
|
/** @return HasMany<FeaturedItem, $this> */
|
||||||
public function featuredItems(): HasMany
|
public function featuredItems(): HasMany
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,20 +5,22 @@ namespace App\Domains\Catalog\Resources;
|
|||||||
use App\Domains\Catalog\Enums\InventoryPolicy;
|
use App\Domains\Catalog\Enums\InventoryPolicy;
|
||||||
use App\Domains\Catalog\Enums\ProductLayout;
|
use App\Domains\Catalog\Enums\ProductLayout;
|
||||||
use App\Domains\Catalog\Models\CatalogItem;
|
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 App\Domains\Catalog\Models\Variant;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
/** @mixin FeaturedItem */
|
/** @mixin CatalogItem */
|
||||||
class CatalogFeaturedItemResource extends JsonResource
|
class CatalogFeaturedItemResource extends JsonResource
|
||||||
{
|
{
|
||||||
/** @return array<string, mixed> */
|
/** @return array<string, mixed> */
|
||||||
public function toArray(Request $request): 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);
|
return $this->columnWithImageData($catalogItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
87
app/Domains/Catalog/Services/FeaturedGroupService.php
Normal file
87
app/Domains/Catalog/Services/FeaturedGroupService.php
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Domains\Catalog\Services;
|
||||||
|
|
||||||
|
use App\Domains\Catalog\Enums\FeaturedGroupSource;
|
||||||
|
use App\Domains\Catalog\Enums\GroupLayout;
|
||||||
|
use App\Domains\Catalog\Models\CatalogItem;
|
||||||
|
use App\Domains\Catalog\Models\FeaturedGroup;
|
||||||
|
use App\Domains\Catalog\Resources\CatalogFeaturedItemResource;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Pagination\LengthAwarePaginator;
|
||||||
|
|
||||||
|
class FeaturedGroupService
|
||||||
|
{
|
||||||
|
private const ITEMS_PER_PAGE = 12;
|
||||||
|
|
||||||
|
/** @return array<array-key, mixed> */
|
||||||
|
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<CatalogItem> */
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Domains\Catalog\Enums\FeaturedGroupSource;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('featured_groups', function (Blueprint $table): void {
|
||||||
|
$table->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');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -4,6 +4,7 @@ namespace Database\Seeders;
|
|||||||
|
|
||||||
use App\Domains\Catalog\Enums\CatalogItemType;
|
use App\Domains\Catalog\Enums\CatalogItemType;
|
||||||
use App\Domains\Catalog\Enums\EventProductType;
|
use App\Domains\Catalog\Enums\EventProductType;
|
||||||
|
use App\Domains\Catalog\Enums\FeaturedGroupSource;
|
||||||
use App\Domains\Catalog\Enums\GroupLayout;
|
use App\Domains\Catalog\Enums\GroupLayout;
|
||||||
use App\Domains\Catalog\Enums\InventoryPolicy;
|
use App\Domains\Catalog\Enums\InventoryPolicy;
|
||||||
use App\Domains\Catalog\Enums\ProductLayout;
|
use App\Domains\Catalog\Enums\ProductLayout;
|
||||||
@@ -61,6 +62,18 @@ class FiestaFutbolInfantilProductSeeder extends Seeder
|
|||||||
'nombre' => 'Gastronomía',
|
'nombre' => 'Gastronomía',
|
||||||
'tenant_code' => $tenant->codigo,
|
'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([
|
$parkingCategory = Category::query()->firstOrCreate([
|
||||||
'nombre' => 'Estacionamiento',
|
'nombre' => 'Estacionamiento',
|
||||||
'tenant_code' => $tenant->codigo,
|
'tenant_code' => $tenant->codigo,
|
||||||
@@ -93,10 +106,10 @@ class FiestaFutbolInfantilProductSeeder extends Seeder
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$items = [
|
$items = [
|
||||||
['slug' => 'hamburguesa-papa-frita', 'nombre' => 'Hamburguesa con papa frita', 'precio' => 8000, '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' => $foodCategory->id],
|
['slug' => 'pancho', 'nombre' => 'Pancho', 'precio' => 4000, 'category_id' => $mealCategory->id],
|
||||||
['slug' => 'coca-cola-500ml', 'nombre' => 'Coca Cola 500ml', 'precio' => 3000, 'category_id' => $foodCategory->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' => $foodCategory->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-auto', 'nombre' => 'Estacionamiento Auto', 'precio' => 5000, 'category_id' => $parkingCategory->id],
|
||||||
['slug' => 'estacionamiento-moto', 'nombre' => 'Estacionamiento Moto', 'precio' => 2000, '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',
|
'nombre' => 'Combo 2 Panchos + 2 Hamburguesas',
|
||||||
'descripcion' => 'Incluye 2 panchos y 2 hamburguesas con papa frita.',
|
'descripcion' => 'Incluye 2 panchos y 2 hamburguesas con papa frita.',
|
||||||
'precio' => 24000,
|
'precio' => 24000,
|
||||||
'category_id' => $foodCategory->id,
|
'category_id' => $mealCategory->id,
|
||||||
'components' => [
|
'components' => [
|
||||||
[
|
[
|
||||||
'catalog_item_id' => $createdItems['pancho']->id,
|
'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
|
private function deleteExistingCatalog(Tenant $tenant): void
|
||||||
@@ -173,7 +191,8 @@ class FiestaFutbolInfantilProductSeeder extends Seeder
|
|||||||
->each(fn (CatalogItem $item) => $this->catalogService->delete($item));
|
->each(fn (CatalogItem $item) => $this->catalogService->delete($item));
|
||||||
}
|
}
|
||||||
|
|
||||||
private function seedFeaturedGroups(Tenant $tenant): void
|
/** @param array<string, Category> $categories */
|
||||||
|
private function seedFeaturedGroups(Tenant $tenant, array $categories): void
|
||||||
{
|
{
|
||||||
FeaturedGroup::query()->where('tenant_code', $tenant->codigo)->delete();
|
FeaturedGroup::query()->where('tenant_code', $tenant->codigo)->delete();
|
||||||
|
|
||||||
@@ -181,62 +200,33 @@ class FiestaFutbolInfantilProductSeeder extends Seeder
|
|||||||
'Entradas' => [
|
'Entradas' => [
|
||||||
'product_layout' => ProductLayout::Row,
|
'product_layout' => ProductLayout::Row,
|
||||||
'group_layout' => GroupLayout::SimpleVertical,
|
'group_layout' => GroupLayout::SimpleVertical,
|
||||||
'slugs' => [
|
|
||||||
'entrada-general',
|
|
||||||
'entrada-general-todos-los-dias',
|
|
||||||
],
|
|
||||||
],
|
],
|
||||||
'Estacionamiento' => [
|
'Estacionamiento' => [
|
||||||
'product_layout' => ProductLayout::ColumnWithCart,
|
'product_layout' => ProductLayout::ColumnWithCart,
|
||||||
'group_layout' => GroupLayout::Simple,
|
'group_layout' => GroupLayout::Simple,
|
||||||
'slugs' => [
|
|
||||||
'estacionamiento-auto',
|
|
||||||
'estacionamiento-moto',
|
|
||||||
],
|
|
||||||
],
|
],
|
||||||
'Comidas' => [
|
'Comidas' => [
|
||||||
'product_layout' => ProductLayout::ColumnWithCart,
|
'product_layout' => ProductLayout::ColumnWithCart,
|
||||||
'group_layout' => GroupLayout::Simple,
|
'group_layout' => GroupLayout::Simple,
|
||||||
'slugs' => [
|
|
||||||
'hamburguesa-papa-frita',
|
|
||||||
'pancho',
|
|
||||||
'combo-2-panchos-2-hamburguesas',
|
|
||||||
],
|
|
||||||
],
|
],
|
||||||
'Bebidas' => [
|
'Bebidas' => [
|
||||||
'product_layout' => ProductLayout::ColumnWithCart,
|
'product_layout' => ProductLayout::ColumnWithCart,
|
||||||
'group_layout' => GroupLayout::Simple,
|
'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;
|
$groupOrder = 0;
|
||||||
foreach ($groups as $groupName => $config) {
|
foreach ($groups as $groupName => $config) {
|
||||||
$featuredGroup = FeaturedGroup::query()->create([
|
FeaturedGroup::query()->create([
|
||||||
'tenant_code' => $tenant->codigo,
|
'tenant_code' => $tenant->codigo,
|
||||||
|
'source_type' => FeaturedGroupSource::Category,
|
||||||
|
'category_id' => $categories[$groupName]->id,
|
||||||
'product_layout' => $config['product_layout'],
|
'product_layout' => $config['product_layout'],
|
||||||
'group_layout' => $config['group_layout'],
|
'group_layout' => $config['group_layout'],
|
||||||
'group_name' => $groupName,
|
'group_name' => $groupName,
|
||||||
'group_order' => $groupOrder++,
|
'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()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace Database\Seeders;
|
namespace Database\Seeders;
|
||||||
|
|
||||||
|
use App\Domains\Catalog\Enums\FeaturedGroupSource;
|
||||||
use App\Domains\Catalog\Enums\GroupLayout;
|
use App\Domains\Catalog\Enums\GroupLayout;
|
||||||
use App\Domains\Catalog\Enums\InventoryPolicy;
|
use App\Domains\Catalog\Enums\InventoryPolicy;
|
||||||
use App\Domains\Catalog\Enums\ProductLayout;
|
use App\Domains\Catalog\Enums\ProductLayout;
|
||||||
@@ -168,30 +169,18 @@ class ProductCatalogFromImagesSeeder extends Seeder
|
|||||||
{
|
{
|
||||||
FeaturedGroup::query()->where('tenant_code', $tenant->codigo)->delete();
|
FeaturedGroup::query()->where('tenant_code', $tenant->codigo)->delete();
|
||||||
|
|
||||||
$paginatedGroup = FeaturedGroup::query()->create([
|
FeaturedGroup::query()->create([
|
||||||
'tenant_code' => $tenant->codigo,
|
'tenant_code' => $tenant->codigo,
|
||||||
|
'source_type' => FeaturedGroupSource::All,
|
||||||
'product_layout' => ProductLayout::ColumnWithImage,
|
'product_layout' => ProductLayout::ColumnWithImage,
|
||||||
'group_layout' => GroupLayout::Paginated,
|
'group_layout' => GroupLayout::Paginated,
|
||||||
'group_name' => 'Productos',
|
'group_name' => 'Productos',
|
||||||
'group_order' => 2,
|
'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([
|
$carouselGroup = FeaturedGroup::query()->create([
|
||||||
'tenant_code' => $tenant->codigo,
|
'tenant_code' => $tenant->codigo,
|
||||||
|
'source_type' => FeaturedGroupSource::Manual,
|
||||||
'product_layout' => ProductLayout::ColumnWithImage,
|
'product_layout' => ProductLayout::ColumnWithImage,
|
||||||
'group_layout' => GroupLayout::Carousel,
|
'group_layout' => GroupLayout::Carousel,
|
||||||
'group_name' => 'Productos destacados',
|
'group_name' => 'Productos destacados',
|
||||||
|
|||||||
@@ -4,9 +4,11 @@ namespace Tests\Feature\Catalog;
|
|||||||
|
|
||||||
use App\Domains\Attachable\Enums\AttachmentType;
|
use App\Domains\Attachable\Enums\AttachmentType;
|
||||||
use App\Domains\Attachable\Models\Attachment;
|
use App\Domains\Attachable\Models\Attachment;
|
||||||
|
use App\Domains\Catalog\Enums\FeaturedGroupSource;
|
||||||
use App\Domains\Catalog\Enums\GroupLayout;
|
use App\Domains\Catalog\Enums\GroupLayout;
|
||||||
use App\Domains\Catalog\Enums\ProductLayout;
|
use App\Domains\Catalog\Enums\ProductLayout;
|
||||||
use App\Domains\Catalog\Models\CatalogItem;
|
use App\Domains\Catalog\Models\CatalogItem;
|
||||||
|
use App\Domains\Catalog\Models\Category;
|
||||||
use App\Domains\Catalog\Models\FeaturedGroup;
|
use App\Domains\Catalog\Models\FeaturedGroup;
|
||||||
use App\Domains\Catalog\Models\Inventory;
|
use App\Domains\Catalog\Models\Inventory;
|
||||||
use App\Domains\Tenant\Models\Tenant;
|
use App\Domains\Tenant\Models\Tenant;
|
||||||
@@ -198,6 +200,46 @@ class CatalogControllerTest extends TestCase
|
|||||||
->assertJsonPath('0.nombre', 'carousel Item 1');
|
->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(
|
private function createGroup(
|
||||||
Tenant $tenant,
|
Tenant $tenant,
|
||||||
ProductLayout $layout,
|
ProductLayout $layout,
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ class CatalogSchemaTest extends TestCase
|
|||||||
$this->assertEqualsCanonicalizing([
|
$this->assertEqualsCanonicalizing([
|
||||||
'id',
|
'id',
|
||||||
'tenant_code',
|
'tenant_code',
|
||||||
|
'source_type',
|
||||||
|
'category_id',
|
||||||
'product_layout',
|
'product_layout',
|
||||||
'group_layout',
|
'group_layout',
|
||||||
'group_name',
|
'group_name',
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use App\Domains\Attachable\Enums\AttachmentType;
|
|||||||
use App\Domains\Attachable\Models\Attachment;
|
use App\Domains\Attachable\Models\Attachment;
|
||||||
use App\Domains\Catalog\Enums\CatalogItemType;
|
use App\Domains\Catalog\Enums\CatalogItemType;
|
||||||
use App\Domains\Catalog\Enums\EventProductType;
|
use App\Domains\Catalog\Enums\EventProductType;
|
||||||
|
use App\Domains\Catalog\Enums\FeaturedGroupSource;
|
||||||
use App\Domains\Catalog\Enums\GroupLayout;
|
use App\Domains\Catalog\Enums\GroupLayout;
|
||||||
use App\Domains\Catalog\Enums\ProductLayout;
|
use App\Domains\Catalog\Enums\ProductLayout;
|
||||||
use App\Domains\Catalog\Models\Attribute;
|
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(9, CatalogItem::query()->where('tenant_code', $tenant->codigo)->count());
|
||||||
$this->assertSame(10, Inventory::query()->count());
|
$this->assertSame(10, Inventory::query()->count());
|
||||||
$this->assertSame(
|
$this->assertSame(
|
||||||
['Entradas', 'Estacionamiento', 'Gastronomía'],
|
['Bebidas', 'Comidas', 'Entradas', 'Estacionamiento', 'Gastronomía'],
|
||||||
Category::query()
|
Category::query()
|
||||||
->where('tenant_code', $tenant->codigo)
|
->where('tenant_code', $tenant->codigo)
|
||||||
->orderBy('nombre')
|
->orderBy('nombre')
|
||||||
@@ -194,7 +195,7 @@ class FiestaFutbolInfantilProductSeederTest extends TestCase
|
|||||||
|
|
||||||
$featuredGroups = FeaturedGroup::query()
|
$featuredGroups = FeaturedGroup::query()
|
||||||
->where('tenant_code', $tenant->codigo)
|
->where('tenant_code', $tenant->codigo)
|
||||||
->with('featuredItems.catalogItem')
|
->with('category.catalogItems')
|
||||||
->orderBy('group_order')
|
->orderBy('group_order')
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
@@ -207,21 +208,23 @@ class FiestaFutbolInfantilProductSeederTest extends TestCase
|
|||||||
],
|
],
|
||||||
$featuredGroups
|
$featuredGroups
|
||||||
->mapWithKeys(fn (FeaturedGroup $group): array => [
|
->mapWithKeys(fn (FeaturedGroup $group): array => [
|
||||||
$group->group_name => $group->featuredItems->pluck('catalogItem.slug')->all(),
|
$group->group_name => $group->category->catalogItems->pluck('slug')->all(),
|
||||||
])
|
])
|
||||||
->all()
|
->all()
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->assertSame(
|
$this->assertSame(
|
||||||
[
|
[
|
||||||
['Entradas', ProductLayout::Row, GroupLayout::SimpleVertical, 0],
|
['Entradas', FeaturedGroupSource::Category, 'Entradas', ProductLayout::Row, GroupLayout::SimpleVertical, 0],
|
||||||
['Estacionamiento', ProductLayout::ColumnWithCart, GroupLayout::Simple, 1],
|
['Estacionamiento', FeaturedGroupSource::Category, 'Estacionamiento', ProductLayout::ColumnWithCart, GroupLayout::Simple, 1],
|
||||||
['Comidas', ProductLayout::ColumnWithCart, GroupLayout::Simple, 2],
|
['Comidas', FeaturedGroupSource::Category, 'Comidas', ProductLayout::ColumnWithCart, GroupLayout::Simple, 2],
|
||||||
['Bebidas', ProductLayout::ColumnWithCart, GroupLayout::Simple, 3],
|
['Bebidas', FeaturedGroupSource::Category, 'Bebidas', ProductLayout::ColumnWithCart, GroupLayout::Simple, 3],
|
||||||
],
|
],
|
||||||
$featuredGroups
|
$featuredGroups
|
||||||
->map(fn (FeaturedGroup $group): array => [
|
->map(fn (FeaturedGroup $group): array => [
|
||||||
$group->group_name,
|
$group->group_name,
|
||||||
|
$group->source_type,
|
||||||
|
$group->category->nombre,
|
||||||
$group->product_layout,
|
$group->product_layout,
|
||||||
$group->group_layout,
|
$group->group_layout,
|
||||||
$group->group_order,
|
$group->group_order,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace Tests\Feature\Seeders;
|
|||||||
|
|
||||||
use App\Domains\Attachable\Enums\AttachmentType;
|
use App\Domains\Attachable\Enums\AttachmentType;
|
||||||
use App\Domains\Attachable\Models\Attachment;
|
use App\Domains\Attachable\Models\Attachment;
|
||||||
|
use App\Domains\Catalog\Enums\FeaturedGroupSource;
|
||||||
use App\Domains\Catalog\Enums\GroupLayout;
|
use App\Domains\Catalog\Enums\GroupLayout;
|
||||||
use App\Domains\Catalog\Enums\ProductLayout;
|
use App\Domains\Catalog\Enums\ProductLayout;
|
||||||
use App\Domains\Catalog\Models\CatalogItem;
|
use App\Domains\Catalog\Models\CatalogItem;
|
||||||
@@ -70,16 +71,14 @@ class ProductCatalogFromImagesSeederTest extends TestCase
|
|||||||
$this->assertNotNull($paginatedGroup);
|
$this->assertNotNull($paginatedGroup);
|
||||||
$this->assertSame(ProductLayout::ColumnWithImage, $paginatedGroup->product_layout);
|
$this->assertSame(ProductLayout::ColumnWithImage, $paginatedGroup->product_layout);
|
||||||
$this->assertSame(GroupLayout::Paginated, $paginatedGroup->group_layout);
|
$this->assertSame(GroupLayout::Paginated, $paginatedGroup->group_layout);
|
||||||
$this->assertSame(0, $paginatedGroup->group_order);
|
$this->assertSame(FeaturedGroupSource::All, $paginatedGroup->source_type);
|
||||||
$this->assertSame(
|
$this->assertSame(2, $paginatedGroup->group_order);
|
||||||
CatalogItem::query()->where('tenant_code', $tenant->codigo)->orderBy('id')->pluck('slug')->all(),
|
$this->assertCount(0, $paginatedGroup->featuredItems);
|
||||||
$paginatedGroup->featuredItems->pluck('catalogItem.slug')->all(),
|
|
||||||
);
|
|
||||||
$this->assertCount(10, $paginatedGroup->featuredItems);
|
|
||||||
|
|
||||||
$this->assertNotNull($carouselGroup);
|
$this->assertNotNull($carouselGroup);
|
||||||
$this->assertSame(ProductLayout::ColumnWithImage, $carouselGroup->product_layout);
|
$this->assertSame(ProductLayout::ColumnWithImage, $carouselGroup->product_layout);
|
||||||
$this->assertSame(GroupLayout::Carousel, $carouselGroup->group_layout);
|
$this->assertSame(GroupLayout::Carousel, $carouselGroup->group_layout);
|
||||||
|
$this->assertSame(FeaturedGroupSource::Manual, $carouselGroup->source_type);
|
||||||
$this->assertSame(1, $carouselGroup->group_order);
|
$this->assertSame(1, $carouselGroup->group_order);
|
||||||
$this->assertCount(5, $carouselGroup->featuredItems);
|
$this->assertCount(5, $carouselGroup->featuredItems);
|
||||||
$this->assertCount(
|
$this->assertCount(
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ namespace Tests\Unit\Catalog;
|
|||||||
use App\Domains\Attachable\Models\Attachment;
|
use App\Domains\Attachable\Models\Attachment;
|
||||||
use App\Domains\Catalog\Enums\CatalogItemType;
|
use App\Domains\Catalog\Enums\CatalogItemType;
|
||||||
use App\Domains\Catalog\Enums\EventProductType;
|
use App\Domains\Catalog\Enums\EventProductType;
|
||||||
|
use App\Domains\Catalog\Enums\FeaturedGroupSource;
|
||||||
use App\Domains\Catalog\Enums\GroupLayout;
|
use App\Domains\Catalog\Enums\GroupLayout;
|
||||||
use App\Domains\Catalog\Enums\InventoryPolicy;
|
use App\Domains\Catalog\Enums\InventoryPolicy;
|
||||||
use App\Domains\Catalog\Enums\ProductLayout;
|
use App\Domains\Catalog\Enums\ProductLayout;
|
||||||
@@ -104,6 +105,8 @@ class CatalogModelsTest extends TestCase
|
|||||||
{
|
{
|
||||||
$group = new FeaturedGroup;
|
$group = new FeaturedGroup;
|
||||||
$group->setRawAttributes([
|
$group->setRawAttributes([
|
||||||
|
'source_type' => FeaturedGroupSource::Category->value,
|
||||||
|
'category_id' => '4',
|
||||||
'product_layout' => ProductLayout::ColumnWithImage->value,
|
'product_layout' => ProductLayout::ColumnWithImage->value,
|
||||||
'group_layout' => GroupLayout::SimpleVertical->value,
|
'group_layout' => GroupLayout::SimpleVertical->value,
|
||||||
'group_order' => '2',
|
'group_order' => '2',
|
||||||
@@ -118,9 +121,12 @@ class CatalogModelsTest extends TestCase
|
|||||||
$this->assertSame('featured_groups', $group->getTable());
|
$this->assertSame('featured_groups', $group->getTable());
|
||||||
$this->assertFalse($group->usesTimestamps());
|
$this->assertFalse($group->usesTimestamps());
|
||||||
$this->assertSame(ProductLayout::ColumnWithImage, $group->product_layout);
|
$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(GroupLayout::SimpleVertical, $group->group_layout);
|
||||||
$this->assertSame(2, $group->group_order);
|
$this->assertSame(2, $group->group_order);
|
||||||
$this->assertInstanceOf(Tenant::class, $group->tenant()->getRelated());
|
$this->assertInstanceOf(Tenant::class, $group->tenant()->getRelated());
|
||||||
|
$this->assertInstanceOf(Category::class, $group->category()->getRelated());
|
||||||
$this->assertInstanceOf(FeaturedItem::class, $group->featuredItems()->getRelated());
|
$this->assertInstanceOf(FeaturedItem::class, $group->featuredItems()->getRelated());
|
||||||
|
|
||||||
$this->assertSame('featured_items', $featuredItem->getTable());
|
$this->assertSame('featured_items', $featuredItem->getTable());
|
||||||
|
|||||||
Reference in New Issue
Block a user