feat: implement product creation workflow with variants, attribute definitions, and validation logic
This commit is contained in:
103
app/Domains/Catalog/Controllers/AttributeController.php
Normal file
103
app/Domains/Catalog/Controllers/AttributeController.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Catalog\Controllers;
|
||||
|
||||
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\Shared\Enums\FieldType;
|
||||
use App\Domains\Tenant\Models\Tenant;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
class AttributeController extends Controller
|
||||
{
|
||||
public function index(Tenant $tenant): JsonResponse
|
||||
{
|
||||
$query = Attribute::query()
|
||||
->where('tenant_codigo', $tenant->codigo)
|
||||
->with('options')
|
||||
->latest();
|
||||
|
||||
return AttributeResource::collection($query->paginateFromRequest())->response();
|
||||
}
|
||||
|
||||
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');
|
||||
});
|
||||
|
||||
return AttributeResource::make($attribute)->response()->setStatusCode(201);
|
||||
}
|
||||
|
||||
public function show(Tenant $tenant, Attribute $attribute): AttributeResource
|
||||
{
|
||||
$attribute = $this->resolveScopedAttribute($tenant, $attribute);
|
||||
|
||||
return AttributeResource::make($attribute->load('options'));
|
||||
}
|
||||
|
||||
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');
|
||||
});
|
||||
|
||||
return AttributeResource::make($attribute);
|
||||
}
|
||||
|
||||
public function destroy(Tenant $tenant, Attribute $attribute): Response
|
||||
{
|
||||
$attribute = $this->resolveScopedAttribute($tenant, $attribute);
|
||||
$attribute->delete();
|
||||
|
||||
return response()->noContent();
|
||||
}
|
||||
|
||||
protected function resolveScopedAttribute(Tenant $tenant, Attribute $attribute): Attribute
|
||||
{
|
||||
if ($attribute->tenant_codigo !== $tenant->codigo) {
|
||||
throw new NotFoundHttpException('Attribute not found for tenant.');
|
||||
}
|
||||
|
||||
return $attribute;
|
||||
}
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domains\Catalog\Controllers;
|
||||
|
||||
use App\Domains\Catalog\Models\ProductAttribute;
|
||||
use App\Domains\Catalog\Requests\StoreProductAttributeRequest;
|
||||
use App\Domains\Catalog\Requests\UpdateProductAttributeRequest;
|
||||
use App\Domains\Catalog\Resources\ProductAttributeResource;
|
||||
use App\Domains\Shared\Enums\FieldType;
|
||||
use App\Domains\Tenant\Models\Tenant;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
class ProductAttributeController extends Controller
|
||||
{
|
||||
public function index(Tenant $tenant): JsonResponse
|
||||
{
|
||||
$query = ProductAttribute::query()
|
||||
->where('tenant_codigo', $tenant->codigo)
|
||||
->with('options')
|
||||
->latest();
|
||||
|
||||
return ProductAttributeResource::collection($query->paginateFromRequest())->response();
|
||||
}
|
||||
|
||||
public function store(StoreProductAttributeRequest $request, Tenant $tenant): JsonResponse
|
||||
{
|
||||
$attribute = DB::transaction(function () use ($request, $tenant): ProductAttribute {
|
||||
$validated = $request->validated();
|
||||
$options = $validated['options'] ?? [];
|
||||
unset($validated['options']);
|
||||
|
||||
$type = FieldType::from((string) $validated['type']);
|
||||
if (! $type->supportsOptions()) {
|
||||
$validated['metadata_schema'] = null;
|
||||
$options = [];
|
||||
}
|
||||
|
||||
/** @var ProductAttribute $attribute */
|
||||
$attribute = ProductAttribute::query()->create([
|
||||
...$validated,
|
||||
'tenant_codigo' => $tenant->codigo,
|
||||
]);
|
||||
$attribute->options()->createMany($options);
|
||||
|
||||
return $attribute->load('options');
|
||||
});
|
||||
|
||||
return ProductAttributeResource::make($attribute)->response()->setStatusCode(201);
|
||||
}
|
||||
|
||||
public function show(Tenant $tenant, ProductAttribute $productAttribute): ProductAttributeResource
|
||||
{
|
||||
$productAttribute = $this->resolveScopedAttribute($tenant, $productAttribute);
|
||||
|
||||
return ProductAttributeResource::make($productAttribute->load('options'));
|
||||
}
|
||||
|
||||
public function update(UpdateProductAttributeRequest $request, Tenant $tenant, ProductAttribute $productAttribute): ProductAttributeResource
|
||||
{
|
||||
$productAttribute = $this->resolveScopedAttribute($tenant, $productAttribute);
|
||||
|
||||
$productAttribute = DB::transaction(function () use ($request, $productAttribute): ProductAttribute {
|
||||
$validated = $request->validated();
|
||||
$options = $validated['options'] ?? [];
|
||||
unset($validated['options']);
|
||||
|
||||
$type = FieldType::from((string) $validated['type']);
|
||||
if (! $type->supportsOptions()) {
|
||||
$validated['metadata_schema'] = null;
|
||||
$options = [];
|
||||
}
|
||||
|
||||
$productAttribute->update($validated);
|
||||
$productAttribute->options()->delete();
|
||||
$productAttribute->options()->createMany($options);
|
||||
|
||||
return $productAttribute->load('options');
|
||||
});
|
||||
|
||||
return ProductAttributeResource::make($productAttribute);
|
||||
}
|
||||
|
||||
public function destroy(Tenant $tenant, ProductAttribute $productAttribute): Response
|
||||
{
|
||||
$productAttribute = $this->resolveScopedAttribute($tenant, $productAttribute);
|
||||
$productAttribute->delete();
|
||||
|
||||
return response()->noContent();
|
||||
}
|
||||
|
||||
protected function resolveScopedAttribute(Tenant $tenant, ProductAttribute $attribute): ProductAttribute
|
||||
{
|
||||
if ($attribute->tenant_codigo !== $tenant->codigo) {
|
||||
throw new NotFoundHttpException('Product attribute not found for tenant.');
|
||||
}
|
||||
|
||||
return $attribute;
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ use App\Domains\Catalog\Models\Product;
|
||||
use App\Domains\Catalog\Requests\StoreProductRequest;
|
||||
use App\Domains\Catalog\Requests\UpdateProductRequest;
|
||||
use App\Domains\Catalog\Resources\ProductResource;
|
||||
use App\Domains\Catalog\Services\ProductService;
|
||||
use App\Domains\Tenant\Models\Tenant;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
@@ -21,12 +22,9 @@ class ProductController extends Controller
|
||||
)->response();
|
||||
}
|
||||
|
||||
public function store(StoreProductRequest $request, Tenant $tenant): JsonResponse
|
||||
public function store(StoreProductRequest $request, Tenant $tenant, ProductService $productService): JsonResponse
|
||||
{
|
||||
$product = Product::query()->create([
|
||||
...$request->validated(),
|
||||
'tenant_codigo' => $tenant->codigo,
|
||||
]);
|
||||
$product = $productService->createProductWithVariants($tenant, $request->validated());
|
||||
|
||||
return ProductResource::make($product)->response()->setStatusCode(201);
|
||||
}
|
||||
@@ -35,13 +33,13 @@ class ProductController extends Controller
|
||||
{
|
||||
$producto = $this->resolveScopedProduct($tenant, $producto);
|
||||
|
||||
return ProductResource::make($producto);
|
||||
return ProductResource::make($producto->load('variants.definitions.attribute'));
|
||||
}
|
||||
|
||||
public function update(UpdateProductRequest $request, Tenant $tenant, Product $producto): ProductResource
|
||||
public function update(UpdateProductRequest $request, Tenant $tenant, Product $producto, ProductService $productService): ProductResource
|
||||
{
|
||||
$producto = $this->resolveScopedProduct($tenant, $producto);
|
||||
$producto->update($request->validated());
|
||||
$producto = $productService->updateProductWithVariants($producto, $request->validated());
|
||||
|
||||
return ProductResource::make($producto);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user