feat: enhance Category and Brand resources with tenant handling and serialization improvements
This commit is contained in:
@@ -10,6 +10,7 @@ use App\Domains\Tenant\Models\Tenant;
|
|||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
|
||||||
class CategoryController extends Controller
|
class CategoryController extends Controller
|
||||||
@@ -18,7 +19,11 @@ class CategoryController extends Controller
|
|||||||
{
|
{
|
||||||
return CategoryResource::collection(
|
return CategoryResource::collection(
|
||||||
Category::query()
|
Category::query()
|
||||||
->where('tenant_code', $tenant->codigo)
|
->where(function ($query) use ($tenant): void {
|
||||||
|
$query
|
||||||
|
->where('tenant_code', $tenant->codigo)
|
||||||
|
->orWhereNull('tenant_code');
|
||||||
|
})
|
||||||
->with(['parent', 'subCategories', 'tenant'])
|
->with(['parent', 'subCategories', 'tenant'])
|
||||||
->orderByDesc('id')
|
->orderByDesc('id')
|
||||||
->paginateFromRequest()
|
->paginateFromRequest()
|
||||||
@@ -47,6 +52,7 @@ class CategoryController extends Controller
|
|||||||
public function update(UpdateCategoryRequest $request, Tenant $tenant, Category $categoria): CategoryResource
|
public function update(UpdateCategoryRequest $request, Tenant $tenant, Category $categoria): CategoryResource
|
||||||
{
|
{
|
||||||
$categoria = $this->resolveScopedCategory($tenant, $categoria);
|
$categoria = $this->resolveScopedCategory($tenant, $categoria);
|
||||||
|
$this->ensureCategoryIsMutable($categoria);
|
||||||
$categoria->update($request->validated());
|
$categoria->update($request->validated());
|
||||||
|
|
||||||
return CategoryResource::make($categoria->load(['parent', 'subCategories', 'tenant']));
|
return CategoryResource::make($categoria->load(['parent', 'subCategories', 'tenant']));
|
||||||
@@ -55,6 +61,7 @@ class CategoryController extends Controller
|
|||||||
public function destroy(Tenant $tenant, Category $categoria): Response
|
public function destroy(Tenant $tenant, Category $categoria): Response
|
||||||
{
|
{
|
||||||
$categoria = $this->resolveScopedCategory($tenant, $categoria);
|
$categoria = $this->resolveScopedCategory($tenant, $categoria);
|
||||||
|
$this->ensureCategoryIsMutable($categoria);
|
||||||
$categoria->delete();
|
$categoria->delete();
|
||||||
|
|
||||||
return response()->noContent();
|
return response()->noContent();
|
||||||
@@ -62,10 +69,17 @@ class CategoryController extends Controller
|
|||||||
|
|
||||||
protected function resolveScopedCategory(Tenant $tenant, Category $category): Category
|
protected function resolveScopedCategory(Tenant $tenant, Category $category): Category
|
||||||
{
|
{
|
||||||
if ($category->tenant_code !== $tenant->codigo) {
|
if ($category->tenant_code !== null && $category->tenant_code !== $tenant->codigo) {
|
||||||
throw new NotFoundHttpException('Category not found for tenant.');
|
throw new NotFoundHttpException('Category not found for tenant.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $category;
|
return $category;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function ensureCategoryIsMutable(Category $category): void
|
||||||
|
{
|
||||||
|
if ($category->isGlobal()) {
|
||||||
|
throw new AccessDeniedHttpException('Global categories are read-only.');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ class BrandResource extends JsonResource
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id' => $this->id,
|
'id' => $this->id,
|
||||||
'tenant_codigo' => $this->tenant_codigo,
|
|
||||||
'nombre' => $this->nombre,
|
'nombre' => $this->nombre,
|
||||||
'descripcion' => $this->descripcion,
|
'descripcion' => $this->descripcion,
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace App\Domains\Catalog\Resources;
|
namespace App\Domains\Catalog\Resources;
|
||||||
|
|
||||||
use App\Domains\Tenant\Resources\TenantResource;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
@@ -18,15 +17,28 @@ class CategoryResource extends JsonResource
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id' => $this->id,
|
'id' => $this->id,
|
||||||
'tenant_code' => $this->tenant_code,
|
|
||||||
'is_global' => $this->resource->isGlobal(),
|
'is_global' => $this->resource->isGlobal(),
|
||||||
'tenant' => $this->resource->isGlobal()
|
|
||||||
? null
|
|
||||||
: TenantResource::make($this->whenLoaded('tenant')),
|
|
||||||
'categoria_id' => $this->categoria_id,
|
|
||||||
'nombre' => $this->nombre,
|
'nombre' => $this->nombre,
|
||||||
'parent' => self::make($this->whenLoaded('parent')),
|
'parent' => $this->whenLoaded('parent', fn () => $this->serializeRelatedCategory($this->parent)),
|
||||||
'sub_categories' => self::collection($this->whenLoaded('subCategories')),
|
'sub_categories' => $this->whenLoaded('subCategories', fn () =>
|
||||||
|
$this->subCategories->map(fn ($category) => $this->serializeRelatedCategory($category))->values()
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, mixed>|null
|
||||||
|
*/
|
||||||
|
protected function serializeRelatedCategory(?\App\Domains\Catalog\Models\Category $category): ?array
|
||||||
|
{
|
||||||
|
if ($category === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'id' => $category->id,
|
||||||
|
'is_global' => $category->isGlobal(),
|
||||||
|
'nombre' => $category->nombre,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user