215 lines
7.3 KiB
PHP
215 lines
7.3 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Models\PackSim;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Console\Command;
|
|
|
|
/**
|
|
*
|
|
*/
|
|
class CheckExpiringPackages extends Command
|
|
{
|
|
/**
|
|
* Nombre del comando
|
|
*/
|
|
protected $signature = 'packages:check-expiring
|
|
{--days= : Días de anticipación para notificar}
|
|
{--test : Modo de prueba }
|
|
{--show-all : Mostrar todos los paquetes con sus fechas de vencimiento}';
|
|
|
|
/**
|
|
* La descripción del comando
|
|
*/
|
|
protected $description = 'Verificar paquetes por vencer y enviar notificaciones a los usuarios';
|
|
|
|
/**
|
|
* Ejecutar comando
|
|
*/
|
|
public function handle()
|
|
{
|
|
$this->info('Verificando paquetes por vencer...');
|
|
$this->newLine();
|
|
|
|
// Obtener configuración
|
|
$customDays = $this->option('days');
|
|
$testMode = $this->option('test');
|
|
|
|
if ($testMode) {
|
|
$this->warn('TEST');
|
|
$this->newLine();
|
|
}
|
|
|
|
if ($customDays !== null) {
|
|
$this->info("Usando días personalizados: {$customDays}");
|
|
} else {
|
|
$this->info("Periodo de paquete:");
|
|
$this->line(" • Paquetes de 30 días → Notificar 7 días antes");
|
|
$this->line(" • Paquetes de 15 días → Notificar 3 días antes");
|
|
$this->line(" • Paquetes de 7 días → Notificar 2 días antes");
|
|
}
|
|
$this->newLine();
|
|
|
|
// Obtener paquetes activos con sus relaciones
|
|
$activePackages = PackSim::with(['package', 'simCard.clientSims.client'])
|
|
->where('is_active', true)
|
|
->whereNotNull('activated_at')
|
|
->get();
|
|
|
|
$this->info("paquetes activos: {$activePackages->count()}");
|
|
$this->newLine();
|
|
|
|
$notificationsSent = 0;
|
|
$packagesChecked = 0;
|
|
|
|
if ($this->option('show-all')) {
|
|
$this->showAllPackages($activePackages);
|
|
return Command::SUCCESS;
|
|
}
|
|
|
|
foreach ($activePackages as $packSim) {
|
|
$packagesChecked++;
|
|
|
|
// Calcular fecha de vencimiento
|
|
$activatedAt = Carbon::parse($packSim->activated_at);
|
|
$expirationDate = $activatedAt->copy()->addDays($packSim->package->period);
|
|
|
|
// Días restantes
|
|
$daysRemaining = (int) now()->diffInDays($expirationDate, false);
|
|
|
|
// Determinar si debe notificar según el periodo del paquete
|
|
$shouldNotify = $this->shouldNotifyForPackage(
|
|
$packSim->package->period,
|
|
$daysRemaining,
|
|
$customDays
|
|
);
|
|
|
|
if ($shouldNotify) {
|
|
// Obtener cliente activo
|
|
$clientRelation = $packSim->simCard->activeClient()->first();
|
|
$client = $clientRelation;
|
|
|
|
if (!$client) {
|
|
$this->warn("SIM {$packSim->simCard->iccid} sin cliente activo");
|
|
continue;
|
|
}
|
|
|
|
// Mostrar información
|
|
if ($testMode) {
|
|
$this->displayNotificationDetails($client, $packSim, $daysRemaining);
|
|
} else {
|
|
// notificacion real
|
|
$this->sendWhatsAppNotification($client, $packSim, $daysRemaining);
|
|
}
|
|
|
|
$notificationsSent++;
|
|
}
|
|
}
|
|
|
|
$this->newLine();
|
|
$this->info('Resumen');
|
|
$this->table(
|
|
['Métrica', 'Valor'],
|
|
[
|
|
['Paquetes revisados', $packagesChecked],
|
|
['Notificaciones enviadas', $notificationsSent],
|
|
['Modo', $testMode ? 'TEST' : 'PRODUCCIÓN'],
|
|
]
|
|
);
|
|
|
|
return Command::SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* Determina si se debe notificar según el periodo del paquete y días restantes
|
|
*/
|
|
private function shouldNotifyForPackage($packagePeriod, $daysRemaining, $customDays = null)
|
|
{
|
|
// Si se especificaron días personalizados
|
|
if ($customDays !== null) {
|
|
$notificationDays = array_map('intval', explode(',', $customDays));
|
|
return in_array($daysRemaining, $notificationDays);
|
|
}
|
|
|
|
// Lógica según el periodo del paquete
|
|
switch ($packagePeriod) {
|
|
case 30:
|
|
// Paquetes de 30 días: notificar a los 7 días
|
|
return $daysRemaining === 7;
|
|
|
|
case 15:
|
|
// Paquetes de 15 días: notificar a los 3 días
|
|
return $daysRemaining === 3;
|
|
|
|
case 7:
|
|
// Paquetes de 7 días: notificar a los 2 días
|
|
return $daysRemaining === 2;
|
|
|
|
default:
|
|
// Para otros periodos, no notificar (o puedes ajustar la lógica)
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Envía notificación por WhatsApp (temporal: solo muestra en consola)
|
|
*/
|
|
private function sendWhatsAppNotification($client, $packSim, $daysRemaining)
|
|
{
|
|
$this->warn('PRODUCCIÓN: Aquí se enviaría la notificación real por WhatsApp');
|
|
$this->displayNotificationDetails($client, $packSim, $daysRemaining);
|
|
}
|
|
|
|
private function displayNotificationDetails($client, $packSim, $daysRemaining)
|
|
{
|
|
$activatedAt = Carbon::parse($packSim->activated_at);
|
|
$expirationDate = $activatedAt->copy()->addDays($packSim->package->period);
|
|
|
|
$this->line('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
$this->info(" NOTIFICACIÓN A ENVIAR:");
|
|
$this->line(" Cliente: {$client->full_name}");
|
|
$this->line(" Teléfono: {$client->phone}");
|
|
$this->line(" Email: {$client->email}");
|
|
$this->line(" Paquete: {$packSim->package->name} ({$packSim->package->period} días)");
|
|
$this->line(" SIM (ICCID): {$packSim->simCard->iccid}");
|
|
$this->line(" Activado: " . $activatedAt->format('d/m/Y'));
|
|
$this->line(" Vence el: " . $expirationDate->format('d/m/Y'));
|
|
$this->line(" Días restantes: {$daysRemaining} día(s)");
|
|
$this->line('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
$this->newLine();
|
|
}
|
|
|
|
|
|
private function showAllPackages($packages)
|
|
{
|
|
$this->info('Mostrando todos los paquetes activos con sus fechas de vencimiento:');
|
|
$this->newLine();
|
|
|
|
$data = [];
|
|
|
|
foreach ($packages as $packSim) {
|
|
$activatedAt = Carbon::parse($packSim->activated_at);
|
|
$expirationDate = $activatedAt->copy()->addDays($packSim->package->period);
|
|
$daysRemaining = (int) now()->diffInDays($expirationDate, false);
|
|
|
|
$clientRelation = $packSim->simCard->activeClient()->first();
|
|
$clientName = $clientRelation ? $clientRelation->full_name : 'Sin cliente activo';
|
|
|
|
$data[] = [
|
|
'Cliente' => $clientName,
|
|
'Paquete' => $packSim->package->name,
|
|
'SIM (ICCID)' => $packSim->simCard->iccid,
|
|
'Activado' => $activatedAt->format('d/m/Y'),
|
|
'Vence el' => $expirationDate->format('d/m/Y'),
|
|
'Días restantes' => $daysRemaining,
|
|
];
|
|
}
|
|
|
|
$this->table(
|
|
['Cliente', 'Paquete', 'SIM (ICCID)', 'Activado', 'Vence el', 'Días restantes'],
|
|
$data
|
|
);
|
|
}
|
|
}
|