feat: Implement inventory policy for product variants

- Introduced InventoryPolicy enum to manage tracked and unlimited inventory types.
- Updated ProductVariant model to include inventory_policy and cantidad_vendida attributes.
- Modified addItem and updateItem methods in Cart to check available quantity based on inventory policy.
- Added migration to include inventory_policy and cantidad_vendida in productos_variantes table.
- Enhanced tests to validate inventory behavior for both tracked and unlimited policies.
- Updated various request and resource classes to handle new inventory fields.
This commit is contained in:
2026-07-16 08:36:59 -03:00
parent 716d8e447c
commit 10157d7c63
16 changed files with 547 additions and 73 deletions

View File

@@ -2,6 +2,7 @@
namespace App\Domains\Catalog\Requests;
use App\Domains\Catalog\Enums\InventoryPolicy;
use App\Domains\Shared\Rules\ImageOrBase64Rule;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
@@ -32,6 +33,8 @@ class StoreProductRequest extends FormRequest
'descripcion' => ['nullable', 'string'],
'precio' => ['required', 'numeric', 'min:0'],
'stock' => ['sometimes', 'integer', 'min:0'],
'inventory_policy' => ['sometimes', Rule::enum(InventoryPolicy::class)],
'cantidad_vendida' => ['prohibited'],
'attribute_ids' => ['sometimes', 'array'],
'attribute_ids.*' => [
'required',
@@ -41,7 +44,7 @@ class StoreProductRequest extends FormRequest
),
],
'images' => ['sometimes', 'nullable', 'array'],
'images.*' => ['required', new ImageOrBase64Rule()],
'images.*' => ['required', new ImageOrBase64Rule],
];
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Domains\Catalog\Requests;
use App\Domains\Catalog\Enums\InventoryPolicy;
use App\Domains\Shared\Rules\ImageOrBase64Rule;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
@@ -20,6 +21,8 @@ class StoreProductVariantRequest extends FormRequest
{
return [
'stock' => ['sometimes', 'integer', 'min:0'],
'inventory_policy' => ['sometimes', Rule::enum(InventoryPolicy::class)],
'cantidad_vendida' => ['prohibited'],
'definitions' => ['sometimes', 'array'],
'definitions.*.products_attribute_id' => [
'required',
@@ -31,7 +34,7 @@ class StoreProductVariantRequest extends FormRequest
],
'definitions.*.value' => ['nullable', 'string'],
'images' => ['sometimes', 'nullable', 'array'],
'images.*' => ['required', new ImageOrBase64Rule()],
'images.*' => ['required', new ImageOrBase64Rule],
'has_tickets' => ['boolean'],
'minimum_use_date' => ['nullable', 'date'],
'maximum_use_date' => ['nullable', 'date', 'after_or_equal:minimum_use_date'],

View File

@@ -20,6 +20,8 @@ class UpdateProductVariantRequest extends FormRequest
{
return [
'stock' => ['sometimes', 'integer', 'min:0'],
'inventory_policy' => ['prohibited'],
'cantidad_vendida' => ['prohibited'],
'definitions' => ['sometimes', 'array'],
'definitions.*.products_attribute_id' => [
'required',
@@ -31,7 +33,7 @@ class UpdateProductVariantRequest extends FormRequest
],
'definitions.*.value' => ['nullable', 'string'],
'images' => ['sometimes', 'nullable', 'array'],
'images.*' => ['required', new ImageOrBase64Rule()],
'images.*' => ['required', new ImageOrBase64Rule],
'has_tickets' => ['boolean'],
'minimum_use_date' => ['nullable', 'date'],
'maximum_use_date' => ['nullable', 'date', 'after_or_equal:minimum_use_date'],