refactor(catalog): Complete catalog refactor to simplify its data model and its querying.

source commits: refactor/catalog
This commit is contained in:
2026-07-21 09:23:19 -03:00
parent d3182fbd13
commit 29a2ca19a3
116 changed files with 5141 additions and 5217 deletions

View File

@@ -2,31 +2,122 @@
namespace App\Domains\Catalog\Controllers;
use App\Domains\Bundle\Models\Bundle;
use App\Domains\Catalog\Models\CatalogItem;
use App\Domains\Catalog\Models\FeaturedGroup;
use App\Domains\Catalog\Models\ProductVariant;
use App\Domains\Catalog\Requests\CatalogItemDetailRequest;
use App\Domains\Catalog\Requests\FeaturedGroupPageRequest;
use App\Domains\Catalog\Requests\StoreCatalogItemRequest;
use App\Domains\Catalog\Resources\CatalogFeaturedGroupResource;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use App\Domains\Catalog\Resources\CatalogFeaturedItemResource;
use App\Domains\Catalog\Resources\CatalogItemDetailResource;
use App\Domains\Catalog\Resources\CatalogItemResource;
use App\Domains\Catalog\Services\CatalogService;
use App\Domains\Tenant\Models\Tenant;
use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Routing\Controller;
use Illuminate\Pagination\LengthAwarePaginator;
class CatalogController extends Controller
{
public function index(string $tenant): JsonResponse
private const ITEMS_PER_PAGE = 12;
public function index(Tenant $tenant): JsonResponse
{
$featuredGroups = FeaturedGroup::where('tenant_codigo', $tenant)
->with([
'groupItems' => fn ($query) => $query->orderBy('order'),
'groupItems.groupable' => function (MorphTo $morphTo): void {
$morphTo->morphWith([
ProductVariant::class => ['product', 'attachments', 'product.attachments'],
Bundle::class => ['items.variant.product', 'items.variant.attachments', 'items.variant.product.attachments'],
]);
},
])
$featuredGroups = FeaturedGroup::query()
->where('tenant_code', $tenant->codigo)
->orderBy('group_order')
->get();
return response()->json(CatalogFeaturedGroupResource::collection($featuredGroups)->resolve());
return response()->json($featuredGroups->map(
fn (FeaturedGroup $featuredGroup): array => (new CatalogFeaturedGroupResource(
$featuredGroup,
$this->featuredItemsResponse($featuredGroup, 1),
))->resolve()
));
}
public function featuredGroupItems(
FeaturedGroupPageRequest $request,
Tenant $tenant,
FeaturedGroup $featuredGroup,
): JsonResponse {
abort_unless($featuredGroup->tenant_code === $tenant->codigo, 404);
$page = (int) $request->validated('page', 1);
return response()->json($this->featuredItemsResponse($featuredGroup, $page));
}
public function show(
CatalogItemDetailRequest $request,
Tenant $tenant,
CatalogItem $catalogItem,
CatalogService $catalogService,
): CatalogItemDetailResource {
abort_unless($catalogItem->tenant_code === $tenant->codigo, 404);
$variantId = $request->validated('variant_id');
return CatalogItemDetailResource::make(
$catalogService->getDetail(
$catalogItem,
$variantId === null ? null : (int) $variantId,
)
);
}
public function store(
StoreCatalogItemRequest $request,
Tenant $tenant,
CatalogService $catalogService,
): JsonResponse {
$catalogItem = $catalogService->create([
...$request->validated(),
'tenant_code' => $tenant->codigo,
]);
return CatalogItemResource::make($catalogItem)
->response()
->setStatusCode(201);
}
/** @return array<string, mixed> */
private function featuredItemsResponse(FeaturedGroup $featuredGroup, int $page): array
{
$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 = $featuredGroup->featuredItems()
->with([
'catalogItem.inventory',
'catalogItem.attachments',
'catalogItem.variants.inventory',
'catalogItem.variants.attachments',
'catalogItem.variants.definitions.itemAttribute.attribute',
'catalogItem.bundleComponents.catalogItem',
'catalogItem.bundleComponents.variant.catalogItem',
])
->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,
]));
}
}