info('🔍 Iniciando verificación de niveles de stock...'); // Obtener productos con stock mínimo o inferior $productosStockMinimo = $this->obtenerProductosStockMinimo(); // Obtener productos que exceden el stock máximo $productosStockMaximo = $this->obtenerProductosStockMaximo(); if ($productosStockMinimo->isEmpty() && $productosStockMaximo->isEmpty()) { $this->info('✅ Todos los productos están en niveles normales de stock.'); return Command::SUCCESS; } // Mostrar resumen en consola $this->mostrarResumen($productosStockMinimo, $productosStockMaximo); // Enviar alertas por correo $this->enviarAlertas($productosStockMinimo, $productosStockMaximo); return Command::SUCCESS; } private function obtenerProductosStockMinimo() { return Producto::with(['categoria', 'variants', 'bodegas']) ->where('estado', true) ->get() ->filter(function ($producto) { // Usar el método getStockEfectivo que considera bodegas $stockActual = $producto->getStockEfectivo(); return $stockActual <= $producto->stock_minimo; }); } private function obtenerProductosStockMaximo() { return Producto::with(['categoria', 'variants', 'bodegas']) ->where('estado', true) ->whereNotNull('stock_maximo') ->get() ->filter(function ($producto) { // Usar el método getStockEfectivo que considera bodegas $stockActual = $producto->getStockEfectivo(); return $stockActual > $producto->stock_maximo; }); } private function mostrarResumen($productosStockMinimo, $productosStockMaximo) { if ($productosStockMinimo->isNotEmpty()) { $this->warn("⚠️ {$productosStockMinimo->count()} productos con stock mínimo o inferior:"); $headers = ['Producto', 'Stock Actual', 'Stock Mínimo', 'Estado']; $rows = []; foreach ($productosStockMinimo as $producto) { $stockActual = $producto->getStockEfectivo(); $estado = $stockActual == 0 ? 'Sin Stock' : ($stockActual < $producto->stock_minimo ? 'Por debajo' : 'En mínimo'); $rows[] = [ $producto->nombre, $stockActual, $producto->stock_minimo, $estado ]; } $this->table($headers, $rows); } if ($productosStockMaximo->isNotEmpty()) { $this->info("📈 {$productosStockMaximo->count()} productos que exceden el stock máximo:"); $headers = ['Producto', 'Stock Actual', 'Stock Máximo', 'Exceso']; $rows = []; foreach ($productosStockMaximo as $producto) { $stockActual = $producto->getStockEfectivo(); $exceso = $stockActual - $producto->stock_maximo; $rows[] = [ $producto->nombre, $stockActual, $producto->stock_maximo, "+{$exceso}" ]; } $this->table($headers, $rows); } } private function enviarAlertas($productosStockMinimo, $productosStockMaximo) { // Determinar destinatarios $email = $this->option('email'); if ($email) { $destinatarios = collect([$email]); $this->info("📧 Enviando alerta a email específico: {$email}"); } else { // Obtener administradores $administradores = User::role('Administrador')->get(); if ($administradores->isEmpty()) { $this->warn('⚠️ No se encontraron usuarios con el rol Administrador.'); return; } $destinatarios = $administradores->pluck('email'); $this->info("📧 Enviando alertas a {$administradores->count()} administradores..."); } // Enviar correos foreach ($destinatarios as $emailDestino) { try { Mail::to($emailDestino)->send(new AlertaStockMail( $productosStockMinimo, $productosStockMaximo, $emailDestino )); $this->info("✅ Alerta enviada a: {$emailDestino}"); } catch (\Exception $e) { $this->error("❌ Error al enviar a {$emailDestino}: " . $e->getMessage()); } } $this->info('🎉 Proceso de envío de alertas completado.'); } }