From ceb1e2b04a3212bb113425b14a65035ebc4723c0 Mon Sep 17 00:00:00 2001 From: ncoronel Date: Tue, 14 Jul 2026 16:11:25 -0300 Subject: [PATCH] feat: implement Stockable interface and methods for Bundle and ProductVariant models --- app/Domains/Bundle/Models/Bundle.php | 33 ++++++++++++++++++- app/Domains/Catalog/Models/ProductVariant.php | 6 +++- app/Domains/Shared/Contracts/Stockable.php | 15 +++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 app/Domains/Shared/Contracts/Stockable.php diff --git a/app/Domains/Bundle/Models/Bundle.php b/app/Domains/Bundle/Models/Bundle.php index e1b664a..5b1b2f6 100644 --- a/app/Domains/Bundle/Models/Bundle.php +++ b/app/Domains/Bundle/Models/Bundle.php @@ -10,13 +10,15 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Casts\Attribute; +use App\Domains\Shared\Contracts\Stockable; + #[Fillable([ 'tenant_codigo', 'nombre', 'descripcion', 'precio', ])] -class Bundle extends Model +class Bundle extends Model implements Stockable { use HasFactory; @@ -47,6 +49,28 @@ class Bundle extends Model return $this->hasMany(BundleItem::class, 'bundle_id'); } + public function incrementRealStock(int $amount): void + { + if ($amount < 0) { + throw new \InvalidArgumentException('El monto a incrementar debe ser positivo.'); + } + + foreach ($this->items as $item) { + $item->variant->incrementRealStock($amount * $item->cantidad); + } + } + + public function decrementRealStock(int $amount): void + { + if ($amount < 0) { + throw new \InvalidArgumentException('El monto a decrementar debe ser positivo.'); + } + + foreach ($this->items as $item) { + $item->variant->decrementRealStock($amount * $item->cantidad); + } + } + public function incrementReservedStock(int $amount): void { if ($amount < 0) { @@ -80,6 +104,13 @@ class Bundle extends Model } } + public function validateStock(): void + { + if ($this->stock_tecnico <= 0) { + throw new \InvalidArgumentException('El bundle no tiene stock técnico disponible.'); + } + } + protected function stockTecnico(): Attribute { return Attribute::get(function () { diff --git a/app/Domains/Catalog/Models/ProductVariant.php b/app/Domains/Catalog/Models/ProductVariant.php index f4a7a49..1f809db 100644 --- a/app/Domains/Catalog/Models/ProductVariant.php +++ b/app/Domains/Catalog/Models/ProductVariant.php @@ -12,6 +12,10 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Database\Eloquent\Casts\Attribute; + +use App\Domains\Shared\Contracts\Stockable; + #[Fillable([ 'producto_id', 'inventory_policy', @@ -23,7 +27,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany; 'minimum_use_date', 'maximum_use_date', ])] -class ProductVariant extends Model +class ProductVariant extends Model implements Stockable { use HasFactory; diff --git a/app/Domains/Shared/Contracts/Stockable.php b/app/Domains/Shared/Contracts/Stockable.php new file mode 100644 index 0000000..78cc3a6 --- /dev/null +++ b/app/Domains/Shared/Contracts/Stockable.php @@ -0,0 +1,15 @@ +