Compare commits
3 Commits
24235c5ca9
...
a7372f9d08
| Author | SHA1 | Date | |
|---|---|---|---|
| a7372f9d08 | |||
| b05a574610 | |||
| 59ed592787 |
@@ -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,10 +19,14 @@ 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()
|
->get()
|
||||||
)->response();
|
)->response();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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.');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,11 @@ class ProductController extends Controller
|
|||||||
return ProductResource::collection(
|
return ProductResource::collection(
|
||||||
Product::query()
|
Product::query()
|
||||||
->where('tenant_codigo', $tenant->codigo)
|
->where('tenant_codigo', $tenant->codigo)
|
||||||
->with(['attachments', 'brand', 'category'])
|
->with([
|
||||||
|
'attachments' => fn ($query) => $query->orderBy('attachments.id')->limit(1),
|
||||||
|
'brand',
|
||||||
|
'category',
|
||||||
|
])
|
||||||
->latest()
|
->latest()
|
||||||
->paginateFromRequest()
|
->paginateFromRequest()
|
||||||
)->response();
|
)->response();
|
||||||
@@ -41,7 +45,7 @@ class ProductController extends Controller
|
|||||||
'attachments',
|
'attachments',
|
||||||
'brand',
|
'brand',
|
||||||
'category',
|
'category',
|
||||||
'variants.definitions.attribute',
|
'variants.definitions.attribute.options',
|
||||||
'variants.attachments',
|
'variants.attachments',
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class ProductVariantController extends Controller
|
|||||||
{
|
{
|
||||||
$query = ProductVariant::query()
|
$query = ProductVariant::query()
|
||||||
->whereHas('product', fn ($query) => $query->where('tenant_codigo', $tenant->codigo))
|
->whereHas('product', fn ($query) => $query->where('tenant_codigo', $tenant->codigo))
|
||||||
->with(['product', 'definitions.attribute', 'attachments'])
|
->with(['product', 'definitions.attribute.options', 'attachments'])
|
||||||
->latest();
|
->latest();
|
||||||
|
|
||||||
return ProductVariantResource::collection($query->paginateFromRequest())->response();
|
return ProductVariantResource::collection($query->paginateFromRequest())->response();
|
||||||
@@ -41,7 +41,7 @@ class ProductVariantController extends Controller
|
|||||||
{
|
{
|
||||||
$productVariant = $this->resolveScopedVariant($tenant, $productVariant);
|
$productVariant = $this->resolveScopedVariant($tenant, $productVariant);
|
||||||
|
|
||||||
return ProductVariantResource::make($productVariant->load(['product', 'definitions.attribute', 'attachments']));
|
return ProductVariantResource::make($productVariant->load(['product', 'definitions.attribute.options', 'attachments']));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function update(UpdateProductVariantRequest $request, Tenant $tenant, ProductVariant $productVariant, ProductService $productService): ProductVariantResource
|
public function update(UpdateProductVariantRequest $request, Tenant $tenant, ProductVariant $productVariant, ProductService $productService): ProductVariantResource
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ class AttributeResource extends JsonResource
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id' => $this->id,
|
'id' => $this->id,
|
||||||
'tenant_codigo' => $this->tenant_codigo,
|
|
||||||
'codigo' => $this->codigo,
|
'codigo' => $this->codigo,
|
||||||
'nombre' => $this->nombre,
|
'nombre' => $this->nombre,
|
||||||
'is_required' => $this->is_required,
|
'is_required' => $this->is_required,
|
||||||
|
|||||||
@@ -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,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
namespace App\Domains\Catalog\Resources;
|
namespace App\Domains\Catalog\Resources;
|
||||||
|
|
||||||
use App\Domains\Catalog\Resources\BrandResource;
|
|
||||||
use App\Domains\Catalog\Resources\CategoryResource;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
@@ -20,20 +18,20 @@ class ProductResource extends JsonResource
|
|||||||
return [
|
return [
|
||||||
'id' => $this->id,
|
'id' => $this->id,
|
||||||
'tenant_codigo' => $this->tenant_codigo,
|
'tenant_codigo' => $this->tenant_codigo,
|
||||||
'categoria_id' => $this->categoria_id,
|
'category_id' => $this->categoria_id,
|
||||||
'brand_id' => $this->brand_id,
|
'brand_id' => $this->brand_id,
|
||||||
'slug' => $this->slug,
|
'slug' => $this->slug,
|
||||||
'nombre' => $this->nombre,
|
'nombre' => $this->nombre,
|
||||||
'descripcion' => $this->descripcion,
|
'descripcion' => $this->descripcion,
|
||||||
'precio' => $this->precio,
|
'precio' => $this->precio,
|
||||||
'category' => CategoryResource::make($this->whenLoaded('category')),
|
'category' => $this->whenLoaded('category', fn () => $this->category?->nombre),
|
||||||
'brand' => BrandResource::make($this->whenLoaded('brand')),
|
'brand' => $this->whenLoaded('brand', fn () => $this->brand?->nombre),
|
||||||
'images' => $this->whenLoaded('attachments', fn () =>
|
'images' => $this->whenLoaded('attachments', fn () =>
|
||||||
$this->attachments->map(fn ($attachment) => $attachment->getTemporaryUrl(1440))->values()
|
$this->attachments
|
||||||
|
->map(fn ($attachment) => $attachment->getTemporaryUrl(1440))
|
||||||
|
->values()
|
||||||
),
|
),
|
||||||
'variants' => ProductVariantResource::collection($this->whenLoaded('variants')),
|
'variants' => ProductVariantResource::collection($this->whenLoaded('variants')),
|
||||||
'created_at' => $this->created_at,
|
|
||||||
'updated_at' => $this->updated_at,
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,26 @@ class ProductVariantDefinitionResource extends JsonResource
|
|||||||
'producto_variante_id' => $this->producto_variante_id,
|
'producto_variante_id' => $this->producto_variante_id,
|
||||||
'attribute_id' => $this->attribute_id,
|
'attribute_id' => $this->attribute_id,
|
||||||
'value' => $this->value,
|
'value' => $this->value,
|
||||||
'attribute' => AttributeResource::make($this->whenLoaded('attribute')),
|
'attribute' => $this->whenLoaded('attribute', fn () => $this->attribute?->nombre),
|
||||||
|
'metadata' => $this->resolveMetadata(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, mixed>|null
|
||||||
|
*/
|
||||||
|
protected function resolveMetadata(): ?array
|
||||||
|
{
|
||||||
|
if (! $this->relationLoaded('attribute') || ! $this->attribute?->relationLoaded('options')) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$option = $this->attribute->options->firstWhere('value', $this->value);
|
||||||
|
|
||||||
|
if ($option === null || $option->metadata === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $option->metadata;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,8 +40,6 @@ class ProductVariantResource extends JsonResource
|
|||||||
?->values()
|
?->values()
|
||||||
?? collect();
|
?? collect();
|
||||||
}),
|
}),
|
||||||
'created_at' => $this->created_at,
|
|
||||||
'updated_at' => $this->updated_at,
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ class ProductService
|
|||||||
$this->syncVariantImages($variant, $images);
|
$this->syncVariantImages($variant, $images);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $variant->load(['product', 'definitions.attribute', 'attachments']);
|
return $variant->load(['product', 'definitions.attribute.options', 'attachments']);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ class ProductService
|
|||||||
$this->syncVariantImages($updatedVariant, $images);
|
$this->syncVariantImages($updatedVariant, $images);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $updatedVariant->load(['product', 'definitions.attribute', 'attachments']);
|
return $updatedVariant->load(['product', 'definitions.attribute.options', 'attachments']);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user