pdv.backend/app/Models/Bundle.php

116 lines
2.8 KiB
PHP

<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Bundle extends Model
{
use SoftDeletes;
protected $fillable = [
'name',
'sku',
'barcode',
];
protected $appends = ['available_stock', 'total_cost'];
/**
* Componentes del kit (items individuales)
*/
public function items()
{
return $this->hasMany(BundleItem::class);
}
/**
* Productos que componen el kit (relación many-to-many)
*/
public function inventories()
{
return $this->belongsToMany(Inventory::class, 'bundle_items')
->withPivot('quantity')
->withTimestamps();
}
/**
* Precio del kit
*/
public function price()
{
return $this->hasOne(BundlePrice::class);
}
/**
* Stock disponible del kit = mínimo(stock_componente / cantidad_requerida)
*/
public function getAvailableStockAttribute(): int
{
if ($this->items->isEmpty()) {
return 0;
}
$minStock = PHP_INT_MAX;
foreach ($this->items as $item) {
$inventory = $item->inventory;
$availableStock = $inventory->stock;
// Cuántos kits puedo hacer con este componente
$possibleKits = $availableStock > 0 ? floor($availableStock / $item->quantity) : 0;
$minStock = min($minStock, $possibleKits);
}
return $minStock === PHP_INT_MAX ? 0 : (int) $minStock;
}
/**
* Stock disponible en un almacén específico
*/
public function stockInWarehouse(int $warehouseId): int
{
if ($this->items->isEmpty()) {
return 0;
}
$minStock = PHP_INT_MAX;
foreach ($this->items as $item) {
$inventory = $item->inventory;
$warehouseStock = $inventory->stockInWarehouse($warehouseId);
$possibleKits = $warehouseStock > 0 ? floor($warehouseStock / $item->quantity) : 0;
$minStock = min($minStock, $possibleKits);
}
return $minStock === PHP_INT_MAX ? 0 : (int) $minStock;
}
/**
* Costo total del kit (suma de costos de componentes)
*/
public function getTotalCostAttribute(): float
{
$total = 0;
foreach ($this->items as $item) {
$componentCost = $item->inventory->price->cost ?? 0;
$total += $componentCost * $item->quantity;
}
return round($total, 2);
}
/**
* Validar si el kit tiene stock disponible
*/
public function hasStock(int $quantity = 1, ?int $warehouseId = null): bool
{
if ($warehouseId) {
return $this->stockInWarehouse($warehouseId) >= $quantity;
}
return $this->available_stock >= $quantity;
}
}