feat: implement product and variant management controllers with request validation and feature tests

This commit is contained in:
2026-06-29 11:10:04 -03:00
parent 18504594eb
commit b5b57a753c
6 changed files with 152 additions and 196 deletions

View File

@@ -29,7 +29,7 @@ class ProductVariantController extends Controller
public function store(StoreProductVariantRequest $request, Tenant $tenant): JsonResponse
{
$validated = $request->validated();
$variant = DB::transaction(function () use ($request, $tenant): ProductVariant {
$variant = DB::transaction(function () use ($request, $tenant, $validated): ProductVariant {
$definitions = $validated['definitions'] ?? [];
unset($validated['definitions']);

View File

@@ -31,30 +31,6 @@ class StoreProductRequest extends FormRequest
fn ($query) => $query->where('tenant_codigo', $this->route('tenant')?->codigo)
),
],
'variants' => ['sometimes', 'array'],
'variants.*.slug' => ['nullable', 'string', 'max:255'],
'variants.*.nombre' => ['nullable', 'string', 'max:255'],
'variants.*.stock' => ['sometimes', 'integer', 'min:0'],
'variants.*.descripcion' => ['nullable', 'string'],
'variants.*.precio' => ['required', 'numeric', 'min:0'],
'variants.*.definitions' => [
'sometimes',
'array',
function ($attribute, $value, $fail) {
$attributeIds = array_column($value, 'attribute_id');
if (count($attributeIds) !== count(array_unique($attributeIds))) {
$fail('The definitions must have distinct attribute ids.');
}
}
],
'variants.*.definitions.*.attribute_id' => [
'required',
'integer',
Rule::exists('attribute', 'id')->where(
fn ($query) => $query->where('tenant_codigo', $this->route('tenant')?->codigo)
),
],
'variants.*.definitions.*.value' => ['nullable', 'string'],
];
}
}

View File

@@ -45,6 +45,18 @@ class StoreProductVariantRequest extends FormRequest
Rule::exists('attribute', 'id')->where(
fn ($query) => $query->where('tenant_codigo', $this->route('tenant')?->codigo)
),
function ($attribute, $value, $fail) {
$productId = $this->input('producto_id');
if ($productId) {
$exists = \Illuminate\Support\Facades\DB::table('products_attributes')
->where('product_id', $productId)
->where('attribute_id', $value)
->exists();
if (!$exists) {
$fail('The selected attribute is not associated with the product.');
}
}
},
],
'definitions.*.value' => ['nullable', 'string'],
];

View File

@@ -40,37 +40,6 @@ class UpdateProductRequest extends FormRequest
fn ($query) => $query->where('tenant_codigo', $this->route('tenant')?->codigo)
),
],
'variants' => ['sometimes', 'array'],
'variants.*.id' => [
'sometimes',
'integer',
Rule::exists('productos_variantes', 'id')->where(
fn ($query) => $query->where('producto_id', $product?->id)
),
],
'variants.*.slug' => ['nullable', 'string', 'max:255'],
'variants.*.nombre' => ['nullable', 'string', 'max:255'],
'variants.*.stock' => ['sometimes', 'integer', 'min:0'],
'variants.*.descripcion' => ['nullable', 'string'],
'variants.*.precio' => ['required', 'numeric', 'min:0'],
'variants.*.definitions' => [
'sometimes',
'array',
function ($attribute, $value, $fail) {
$attributeIds = array_column($value, 'attribute_id');
if (count($attributeIds) !== count(array_unique($attributeIds))) {
$fail('The definitions must have distinct attribute ids.');
}
}
],
'variants.*.definitions.*.attribute_id' => [
'required',
'integer',
Rule::exists('attribute', 'id')->where(
fn ($query) => $query->where('tenant_codigo', $this->route('tenant')?->codigo)
),
],
'variants.*.definitions.*.value' => ['nullable', 'string'],
];
}
}

View File

@@ -49,6 +49,18 @@ class UpdateProductVariantRequest extends FormRequest
Rule::exists('attribute', 'id')->where(
fn ($query) => $query->where('tenant_codigo', $this->route('tenant')?->codigo)
),
function ($attribute, $value, $fail) {
$productId = $this->input('producto_id');
if ($productId) {
$exists = \Illuminate\Support\Facades\DB::table('products_attributes')
->where('product_id', $productId)
->where('attribute_id', $value)
->exists();
if (!$exists) {
$fail('The selected attribute is not associated with the product.');
}
}
},
],
'definitions.*.value' => ['nullable', 'string'],
];