ADD: mostrar paquetes por expirar
This commit is contained in:
parent
8e7873f2dc
commit
1523cd408d
@ -15,7 +15,7 @@ class CheckExpiringPackages extends Command
|
||||
* Nombre del comando
|
||||
*/
|
||||
protected $signature = 'packages:check-expiring
|
||||
{--days=7,3,1 : Días de anticipación para notificar}
|
||||
{--days= : Días de anticipación para notificar}
|
||||
{--test : Modo de prueba }
|
||||
{--show-all : Mostrar todos los paquetes con sus fechas de vencimiento}';
|
||||
|
||||
@ -33,7 +33,7 @@ public function handle()
|
||||
$this->newLine();
|
||||
|
||||
// Obtener configuración
|
||||
$notificationDays = array_map('intval', explode(',', $this->option('days')));
|
||||
$customDays = $this->option('days');
|
||||
$testMode = $this->option('test');
|
||||
|
||||
if ($testMode) {
|
||||
@ -41,6 +41,16 @@ public function handle()
|
||||
$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)
|
||||
@ -65,11 +75,17 @@ public function handle()
|
||||
$activatedAt = Carbon::parse($packSim->activated_at);
|
||||
$expirationDate = $activatedAt->copy()->addDays($packSim->package->period);
|
||||
|
||||
// Días restante
|
||||
// Días restantes
|
||||
$daysRemaining = (int) now()->diffInDays($expirationDate, false);
|
||||
|
||||
// Verificar si debe notificar
|
||||
if (in_array($daysRemaining, $notificationDays)) {
|
||||
// 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;
|
||||
@ -105,17 +121,61 @@ public function handle()
|
||||
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}");
|
||||
$this->line(" Paquete: {$packSim->package->name} ({$packSim->package->period} días)");
|
||||
$this->line(" SIM (ICCID): {$packSim->simCard->iccid}");
|
||||
$this->line(" Activado: " . Carbon::parse($packSim->activated_at)->format('d/m/Y'));
|
||||
$this->line(" Vence en: {$daysRemaining} día(s)");
|
||||
$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();
|
||||
}
|
||||
|
||||
@ -7,6 +7,9 @@
|
||||
use App\Http\Requests\Netbien\PackagesStoreRequest;
|
||||
use App\Http\Requests\Netbien\PackagesUpdateRequest;
|
||||
use App\Models\Packages;
|
||||
use App\Models\PackSim;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
use Notsoweb\ApiResponse\Enums\ApiResponse;
|
||||
|
||||
/**
|
||||
@ -56,4 +59,119 @@ public function destroy(Packages $package)
|
||||
|
||||
return ApiResponse::NO_CONTENT->response();
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene los paquetes que están por vencer
|
||||
*
|
||||
*/
|
||||
public function expiring(Request $request)
|
||||
{
|
||||
// Parámetros de consulta
|
||||
$customDays = $request->query('days');
|
||||
$period = $request->query('period');
|
||||
$withClientOnly = $request->boolean('with_client', false);
|
||||
|
||||
// Obtener paquetes activos con sus relaciones
|
||||
$query = PackSim::with(['package', 'simCard.activeClient'])
|
||||
->where('is_active', true)
|
||||
->whereNotNull('activated_at');
|
||||
|
||||
// Filtrar por periodo si se especifica
|
||||
if ($period !== null) {
|
||||
$query->whereHas('package', function ($q) use ($period) {
|
||||
$q->where('period', $period);
|
||||
});
|
||||
}
|
||||
|
||||
$activePackages = $query->get();
|
||||
|
||||
// Filtrar y calcular días restantes
|
||||
$expiringPackages = $activePackages
|
||||
->map(function ($packSim) use ($customDays, $withClientOnly) {
|
||||
// Calcular fecha de vencimiento
|
||||
$activatedAt = Carbon::parse($packSim->activated_at);
|
||||
$expirationDate = $activatedAt->copy()->addDays($packSim->package->period);
|
||||
$daysRemaining = (int) now()->diffInDays($expirationDate, false);
|
||||
|
||||
// Determinar si debe incluirse
|
||||
$shouldInclude = $this->shouldIncludePackage(
|
||||
$packSim->package->period,
|
||||
$daysRemaining,
|
||||
$customDays
|
||||
);
|
||||
|
||||
if (!$shouldInclude) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Obtener cliente
|
||||
$client = $packSim->simCard->activeClient()->first();
|
||||
|
||||
// Filtrar por cliente si se requiere
|
||||
if ($withClientOnly && !$client) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Formatear respuesta
|
||||
return [
|
||||
'id' => $packSim->id,
|
||||
'sim_card' => [
|
||||
'id' => $packSim->simCard->id,
|
||||
'iccid' => $packSim->simCard->iccid,
|
||||
'msisdn' => $packSim->simCard->msisdn,
|
||||
],
|
||||
'package' => [
|
||||
'id' => $packSim->package->id,
|
||||
'name' => $packSim->package->name,
|
||||
'period' => $packSim->package->period,
|
||||
],
|
||||
'client' => $client ? [
|
||||
'id' => $client->id,
|
||||
'full_name' => $client->full_name,
|
||||
'phone' => $client->phone,
|
||||
'email' => $client->email,
|
||||
] : null,
|
||||
'activated_at' => $activatedAt->format('Y-m-d'),
|
||||
'expires_at' => $expirationDate->format('Y-m-d'),
|
||||
'days_remaining' => $daysRemaining,
|
||||
];
|
||||
})
|
||||
->filter()
|
||||
->values();
|
||||
|
||||
return ApiResponse::OK->response([
|
||||
'packages' => $expiringPackages,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determina si un paquete debe incluirse según el periodo y días restantes
|
||||
*/
|
||||
private function shouldIncludePackage(int $packagePeriod, int $daysRemaining, ?string $customDays = null): bool
|
||||
{
|
||||
// Si se especificaron días personalizados, usarlos
|
||||
if ($customDays !== null) {
|
||||
$notificationDays = array_map('intval', explode(',', $customDays));
|
||||
return in_array($daysRemaining, $notificationDays);
|
||||
}
|
||||
|
||||
// Lógica automática según el periodo del paquete
|
||||
switch ($packagePeriod) {
|
||||
case 30:
|
||||
// Paquetes de 30 días: incluir si quedan 7 días o menos
|
||||
return $daysRemaining <= 7 && $daysRemaining >= 0;
|
||||
|
||||
case 15:
|
||||
// Paquetes de 15 días: incluir si quedan 3 días o menos
|
||||
return $daysRemaining <= 3 && $daysRemaining >= 0;
|
||||
|
||||
case 7:
|
||||
// Paquetes de 7 días: incluir si quedan 2 días o menos
|
||||
return $daysRemaining <= 2 && $daysRemaining >= 0;
|
||||
|
||||
default:
|
||||
// Para otros periodos, incluir si quedan 7 días o menos
|
||||
return $daysRemaining <= 7 && $daysRemaining >= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
Route::post('import', [SimCardController::class, 'import']);
|
||||
Route::resource('sim-cards', SimCardController::class);
|
||||
|
||||
Route::get('packages/expiring', [PackagesController::class, 'expiring']);
|
||||
Route::resource('packages', PackagesController::class);
|
||||
|
||||
Route::get('clients/search', [ClientController::class, 'search']);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user