153 lines
5.4 KiB
PHP
153 lines
5.4 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\Mail;
|
|
use App\Mail\AlertaStockMail;
|
|
use App\Models\User;
|
|
use App\Models\Producto;
|
|
|
|
class VerificarAlertasStock extends Command
|
|
{
|
|
protected $signature = 'stock:verificar-alertas {--email= : Email específico para enviar la alerta}';
|
|
|
|
protected $description = 'Verificar niveles de stock y enviar alertas por correo cuando se alcance el mínimo o máximo';
|
|
|
|
public function handle()
|
|
{
|
|
$this->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.');
|
|
}
|
|
} |