Co-authored-by: Juan Felipe Zapata Moreno <juan.zapata@golsystems.com.mx> Co-committed-by: Juan Felipe Zapata Moreno <juan.zapata@golsystems.com.mx>
189 lines
6.1 KiB
PHP
189 lines
6.1 KiB
PHP
<?php namespace App\Http\Controllers\Netbien;
|
|
/**
|
|
* @copyright (c) 2025 Notsoweb Software (https://notsoweb.com) - All Rights Reserved
|
|
*/
|
|
|
|
use App\Http\Controllers\Controller;
|
|
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;
|
|
|
|
/**
|
|
*
|
|
*/
|
|
class PackagesController extends Controller
|
|
{
|
|
public function index()
|
|
{
|
|
$packages = Packages::OrderBy('id', 'asc')->paginate(config('app.pagination'));
|
|
|
|
return ApiResponse::OK->response([
|
|
'data' => $packages,
|
|
]);
|
|
}
|
|
|
|
public function show(Packages $package)
|
|
{
|
|
return ApiResponse::OK->response([
|
|
'data' => $package,
|
|
]);
|
|
}
|
|
|
|
public function store(PackagesStoreRequest $request)
|
|
{
|
|
$validated = $request->validated();
|
|
|
|
$package = Packages::create($validated);
|
|
|
|
return ApiResponse::CREATED->response([
|
|
'data' => $package,
|
|
]);
|
|
}
|
|
|
|
public function update(PackagesUpdateRequest $request, Packages $package)
|
|
{
|
|
$package->update($request->validated());
|
|
|
|
return ApiResponse::OK->response([
|
|
'data' => $package,
|
|
]);
|
|
}
|
|
|
|
public function destroy(Packages $package)
|
|
{
|
|
$package->delete();
|
|
|
|
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);
|
|
|
|
$now = Carbon::now()->startOfDay();
|
|
$expirationDateStart = $expirationDate->copy()->startOfDay();
|
|
|
|
if ($expirationDateStart->isFuture()) {
|
|
$daysRemaining = (int) $now->diffInDays($expirationDateStart, false);
|
|
} elseif ($expirationDateStart->isToday()) {
|
|
$daysRemaining = 0;
|
|
} else {
|
|
// Ya expiró, no incluir
|
|
return null;
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
}
|
|
}
|