187 lines
6.3 KiB
PHP
187 lines
6.3 KiB
PHP
<?php
|
|
|
|
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\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
|
|
{
|
|
$featuredGroups = FeaturedGroup::query()
|
|
->where('tenant_code', $tenant->codigo)
|
|
->orderBy('group_order')
|
|
->get();
|
|
|
|
return response()->json($featuredGroups->map(
|
|
fn (FeaturedGroup $featuredGroup): array => (new CatalogFeaturedGroupResource(
|
|
$featuredGroup,
|
|
$this->featuredItemsResponse($featuredGroup, 1),
|
|
))->resolve()
|
|
));
|
|
}
|
|
|
|
public function search(
|
|
SearchCatalogItemsRequest $request,
|
|
Tenant $tenant,
|
|
CatalogService $catalogService,
|
|
): AnonymousResourceCollection {
|
|
return CatalogSearchItemResource::collection(
|
|
$catalogService->search(
|
|
$tenant,
|
|
$request->validated('q'),
|
|
$tenant->search_items_per_page,
|
|
(int) $request->validated('page', 1),
|
|
)
|
|
);
|
|
}
|
|
|
|
public function category(
|
|
CategoryPageRequest $request,
|
|
Tenant $tenant,
|
|
Category $category,
|
|
CatalogService $catalogService,
|
|
): AnonymousResourceCollection {
|
|
abort_unless($category->tenant_code === $tenant->codigo, 404);
|
|
|
|
return CatalogSearchItemResource::collection(
|
|
$catalogService->categoryItems(
|
|
$tenant,
|
|
$category,
|
|
$tenant->search_items_per_page,
|
|
(int) $request->validated('page', 1),
|
|
)
|
|
)->additional([
|
|
'category' => [
|
|
'id' => $category->id,
|
|
'nombre' => $category->nombre,
|
|
'categoria_id' => $category->categoria_id,
|
|
],
|
|
'layout' => $tenant->search_product_layout->value,
|
|
'group_layout' => $tenant->search_group_layout->value,
|
|
]);
|
|
}
|
|
|
|
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<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.definitions.itemAttribute.attribute',
|
|
'catalogItem.bundleComponents.catalogItem',
|
|
'catalogItem.bundleComponents.variant.catalogItem',
|
|
]);
|
|
}
|
|
}
|