* * @version 1.0.0 */ class InventoryWarehouseObserver { /** * Roles que reciben alertas de stock bajo */ protected array $notifiableRoles = ['developer', 'admin']; /** * Umbral por defecto cuando min_stock no está configurado */ protected int $defaultThreshold = 5; /** * Detectar cuando el stock cruza el umbral mínimo hacia abajo */ public function updated(InventoryWarehouse $inventoryWarehouse): void { $previousStock = (float) $inventoryWarehouse->getOriginal('stock'); $currentStock = (float) $inventoryWarehouse->stock; $threshold = (float) ($inventoryWarehouse->min_stock ?? $this->defaultThreshold); // Solo notificar si el stock CRUZÓ el umbral (no en cada update mientras ya esté bajo) if ($previousStock >= $threshold && $currentStock < $threshold) { $this->notifyLowStock($inventoryWarehouse, $currentStock); } } /** * Enviar notificación de stock bajo a usuarios con rol relevante */ protected function notifyLowStock(InventoryWarehouse $inventoryWarehouse, float $currentStock): void { $inventoryWarehouse->load('inventory', 'warehouse'); $productName = $inventoryWarehouse->inventory?->name ?? 'Producto desconocido'; $warehouseName = $inventoryWarehouse->warehouse?->name ?? 'Almacén desconocido'; $users = User::role($this->notifiableRoles)->get(); foreach ($users as $user) { $user->notify(new UserNotification( title: 'Stock bajo: ' . $productName, description: "El producto \"{$productName}\" tiene {$currentStock} unidad(es) disponible(s) en \"{$warehouseName}\".", type: 'warning', timeout: 30, save: true, )); } } }