refactor(catalog): Complete catalog refactor to simplify its data model and its querying.
source commits: refactor/catalog
This commit is contained in:
@@ -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,
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user