feat: implement product and attribute management services with corresponding controllers and feature tests

This commit is contained in:
2026-06-29 11:37:22 -03:00
parent b5b57a753c
commit 9b7d728117
7 changed files with 365 additions and 137 deletions

View File

@@ -6,6 +6,7 @@ use App\Domains\Catalog\Models\Attribute;
use App\Domains\Catalog\Requests\StoreAttributeRequest;
use App\Domains\Catalog\Requests\UpdateAttributeRequest;
use App\Domains\Catalog\Resources\AttributeResource;
use App\Domains\Catalog\Services\ProductService;
use App\Domains\Shared\Enums\FieldType;
use App\Domains\Tenant\Models\Tenant;
use App\Http\Controllers\Controller;
@@ -28,26 +29,7 @@ class AttributeController extends Controller
public function store(StoreAttributeRequest $request, Tenant $tenant): JsonResponse
{
$attribute = DB::transaction(function () use ($request, $tenant): Attribute {
$validated = $request->validated();
$options = $validated['options'] ?? [];
unset($validated['options']);
$type = FieldType::from((string) $validated['type']);
if (! $type->supportsOptions()) {
$validated['metadata_schema'] = null;
$options = [];
}
/** @var Attribute $attribute */
$attribute = Attribute::query()->create([
...$validated,
'tenant_codigo' => $tenant->codigo,
]);
$attribute->options()->createMany($options);
return $attribute->load('options');
});
$attribute = ProductService::createAttribute($tenant, $request->validated());
return AttributeResource::make($attribute)->response()->setStatusCode(201);
}
@@ -62,24 +44,7 @@ class AttributeController extends Controller
public function update(UpdateAttributeRequest $request, Tenant $tenant, Attribute $attribute): AttributeResource
{
$attribute = $this->resolveScopedAttribute($tenant, $attribute);
$attribute = DB::transaction(function () use ($request, $attribute): Attribute {
$validated = $request->validated();
$options = $validated['options'] ?? [];
unset($validated['options']);
$type = FieldType::from((string) $validated['type']);
if (! $type->supportsOptions()) {
$validated['metadata_schema'] = null;
$options = [];
}
$attribute->update($validated);
$attribute->options()->delete();
$attribute->options()->createMany($options);
return $attribute->load('options');
});
$attribute = ProductService::updateAttribute($attribute, $request->validated());
return AttributeResource::make($attribute);
}
@@ -87,7 +52,7 @@ class AttributeController extends Controller
public function destroy(Tenant $tenant, Attribute $attribute): Response
{
$attribute = $this->resolveScopedAttribute($tenant, $attribute);
$attribute->delete();
ProductService::deleteAttribute($attribute);
return response()->noContent();
}

View File

@@ -24,7 +24,7 @@ class ProductController extends Controller
public function store(StoreProductRequest $request, Tenant $tenant, ProductService $productService): JsonResponse
{
$product = $productService->createProductWithVariants($tenant, $request->validated());
$product = $productService->create($tenant, $request->validated());
return ProductResource::make($product)->response()->setStatusCode(201);
}
@@ -39,15 +39,15 @@ class ProductController extends Controller
public function update(UpdateProductRequest $request, Tenant $tenant, Product $producto, ProductService $productService): ProductResource
{
$producto = $this->resolveScopedProduct($tenant, $producto);
$producto = $productService->updateProductWithVariants($producto, $request->validated());
$producto = $productService->update($producto, $request->validated());
return ProductResource::make($producto);
}
public function destroy(Tenant $tenant, Product $producto): Response
public function destroy(Tenant $tenant, Product $producto, ProductService $productService): Response
{
$producto = $this->resolveScopedProduct($tenant, $producto);
$producto->delete();
$productService->delete($producto);
return response()->noContent();
}

View File

@@ -7,6 +7,7 @@ use App\Domains\Catalog\Models\ProductVariant;
use App\Domains\Catalog\Requests\StoreProductVariantRequest;
use App\Domains\Catalog\Requests\UpdateProductVariantRequest;
use App\Domains\Catalog\Resources\ProductVariantResource;
use App\Domains\Catalog\Services\ProductService;
use App\Domains\Tenant\Models\Tenant;
use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
@@ -26,22 +27,12 @@ class ProductVariantController extends Controller
return ProductVariantResource::collection($query->paginateFromRequest())->response();
}
public function store(StoreProductVariantRequest $request, Tenant $tenant): JsonResponse
public function store(StoreProductVariantRequest $request, Tenant $tenant, ProductService $productService): JsonResponse
{
$validated = $request->validated();
$variant = DB::transaction(function () use ($request, $tenant, $validated): ProductVariant {
$definitions = $validated['definitions'] ?? [];
unset($validated['definitions']);
$product = $this->resolveTenantProduct($tenant, (int) $validated['producto_id']);
$product = $this->resolveTenantProduct($tenant, (int) $validated['producto_id']);
/** @var ProductVariant $variant */
$variant = $product->variants()->create($validated);
$variant->definitions()->createMany($definitions);
return $variant->load(['product', 'definitions.attribute']);
});
$variant = $productService->createVariant($product, $validated);
return ProductVariantResource::make($variant)->response()->setStatusCode(201);
}
@@ -53,31 +44,22 @@ class ProductVariantController extends Controller
return ProductVariantResource::make($productVariant->load(['product', 'definitions.attribute']));
}
public function update(UpdateProductVariantRequest $request, Tenant $tenant, ProductVariant $productVariant): ProductVariantResource
public function update(UpdateProductVariantRequest $request, Tenant $tenant, ProductVariant $productVariant, ProductService $productService): ProductVariantResource
{
$productVariant = $this->resolveScopedVariant($tenant, $productVariant);
$validated = $request->validated();
$productVariant = DB::transaction(function () use ($request, $tenant, $productVariant): ProductVariant {
$validated = $request->validated();
$definitions = $validated['definitions'] ?? [];
unset($validated['definitions']);
$this->resolveTenantProduct($tenant, (int) $validated['producto_id']);
$this->resolveTenantProduct($tenant, (int) $validated['producto_id']);
$productVariant->update($validated);
$productVariant->definitions()->delete();
$productVariant->definitions()->createMany($definitions);
return $productVariant->load(['product', 'definitions.attribute']);
});
$productVariant = $productService->updateVariant($productVariant, $validated);
return ProductVariantResource::make($productVariant);
}
public function destroy(Tenant $tenant, ProductVariant $productVariant): Response
public function destroy(Tenant $tenant, ProductVariant $productVariant, ProductService $productService): Response
{
$productVariant = $this->resolveScopedVariant($tenant, $productVariant);
$productVariant->delete();
$productService->deleteVariant($productVariant);
return response()->noContent();
}