up
This commit is contained in:
@@ -112,6 +112,11 @@ class MenuController extends Controller
|
||||
return view('menu/log_historial');
|
||||
}
|
||||
|
||||
public function showDiagnostico()
|
||||
{
|
||||
return view('menu/diagnostico');
|
||||
}
|
||||
|
||||
public function showroles()
|
||||
{
|
||||
return view('menu/roles');
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Models\Cuentas;
|
||||
use App\Models\Historial_cuenta;
|
||||
use App\Models\Historiale;
|
||||
use App\Models\Log_general;
|
||||
use Livewire\Component;
|
||||
|
||||
class ShowDiagnostico extends Component
|
||||
{
|
||||
public $buscar_cuenta = '';
|
||||
public $cuenta = null;
|
||||
public $historial_perfiles = [];
|
||||
public $logs_relacionados = [];
|
||||
public $resumen = [];
|
||||
|
||||
public function buscar()
|
||||
{
|
||||
$this->cuenta = null;
|
||||
$this->historial_perfiles = [];
|
||||
$this->logs_relacionados = [];
|
||||
$this->resumen = [];
|
||||
|
||||
if (empty(trim($this->buscar_cuenta))) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->cuenta = Cuentas::with('servicio')
|
||||
->where('correo', 'ILIKE', '%' . trim($this->buscar_cuenta) . '%')
|
||||
->first();
|
||||
|
||||
if (!$this->cuenta) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Todos los historial_cuenta de esta cuenta, con su historial padre
|
||||
$this->historial_perfiles = Historial_cuenta::with(['historial.vendedor', 'historial.cliente'])
|
||||
->where('cuenta_id', $this->cuenta->id)
|
||||
->orderBy('perfil')
|
||||
->orderBy('created_at', 'desc')
|
||||
->get()
|
||||
->map(function ($hc) {
|
||||
return [
|
||||
'id' => $hc->id,
|
||||
'perfil' => $hc->perfil,
|
||||
'historial_id' => $hc->historial_id,
|
||||
'estado_historial' => $hc->historial->estado ?? 'N/A',
|
||||
'vendedor' => $hc->historial->vendedor->name ?? 'N/A',
|
||||
'cliente' => $hc->historial->nombre_cliente ?? ($hc->historial->cliente->name ?? 'N/A'),
|
||||
'fecha_inicio' => $hc->historial->fecha_inicio ?? 'N/A',
|
||||
'fecha_final' => $hc->historial->fecha_final ?? 'N/A',
|
||||
'created_at' => $hc->created_at,
|
||||
];
|
||||
})
|
||||
->toArray();
|
||||
|
||||
// Logs relacionados con todos los historiales de esta cuenta
|
||||
$historial_ids = Historial_cuenta::where('cuenta_id', $this->cuenta->id)
|
||||
->whereNotNull('historial_id')
|
||||
->pluck('historial_id')
|
||||
->unique();
|
||||
|
||||
$this->logs_relacionados = Log_general::with('user')
|
||||
->whereIn('historial_id', $historial_ids)
|
||||
->orderBy('created_at', 'desc')
|
||||
->take(50)
|
||||
->get()
|
||||
->map(function ($log) {
|
||||
return [
|
||||
'id' => $log->id,
|
||||
'tipo' => $log->tipo,
|
||||
'usuario' => $log->user->name ?? 'N/A',
|
||||
'detalle' => $log->detalle,
|
||||
'historial_id' => $log->historial_id,
|
||||
'created_at' => $log->created_at,
|
||||
];
|
||||
})
|
||||
->toArray();
|
||||
|
||||
// Resumen por perfil
|
||||
$perfiles_activos = collect($this->historial_perfiles)->where('estado_historial', 'activo');
|
||||
$perfiles_cancelados = collect($this->historial_perfiles)->where('estado_historial', 'cancelado');
|
||||
|
||||
$this->resumen = [
|
||||
'total_registros' => count($this->historial_perfiles),
|
||||
'activos' => $perfiles_activos->count(),
|
||||
'cancelados' => $perfiles_cancelados->count(),
|
||||
'max_perfil_activo' => $perfiles_activos->max('perfil') ?? 0,
|
||||
'perfiles_unicos_activos' => $perfiles_activos->pluck('perfil')->unique()->sort()->values()->toArray(),
|
||||
'perfil_6_activos' => $perfiles_activos->where('perfil', 6)->count(),
|
||||
'perfil_6_cancelados' => $perfiles_cancelados->where('perfil', 6)->count(),
|
||||
];
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.show-diagnostico');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
<div class="h-full w-full md:my-2">
|
||||
<div class="bg-[#f5f5f5] md:w-full m-auto p-2 md:p-5 rounded-2xl relative mb-4">
|
||||
|
||||
{{-- Título --}}
|
||||
<div class="flex items-center gap-2 mb-4 text-sm text-gray-500">
|
||||
<x-icon-arrow-right />
|
||||
<span class="font-semibold text-gray-700">Diagnóstico de cuenta</span>
|
||||
</div>
|
||||
|
||||
{{-- Buscador --}}
|
||||
<div class="flex gap-2 mb-6">
|
||||
<input
|
||||
type="text"
|
||||
wire:model="buscar_cuenta"
|
||||
wire:keydown.enter="buscar"
|
||||
placeholder="Correo de la cuenta (ej: JeffreyWilliams2379@outlook.com)"
|
||||
class="flex-1 shadow-sm border-2 border-neutral-200 rounded-lg px-4 py-2 text-sm focus:ring-0 focus:border-neutral-300 focus:outline-none"
|
||||
/>
|
||||
<button
|
||||
wire:click="buscar"
|
||||
class="inline-flex items-center gap-1.5 px-4 py-2 rounded-lg text-sm font-medium text-white bg-[#B221FD] hover:bg-[#7a02b8] transition-colors"
|
||||
>Buscar</button>
|
||||
</div>
|
||||
|
||||
@if (!empty($buscar_cuenta) && is_null($cuenta))
|
||||
<div class="text-center py-8 text-gray-400 text-sm">No se encontró ninguna cuenta con ese correo.</div>
|
||||
@endif
|
||||
|
||||
@if ($cuenta)
|
||||
|
||||
{{-- Info de la cuenta --}}
|
||||
<div class="bg-white rounded-xl shadow p-4 mb-4 text-sm">
|
||||
<p class="font-bold text-gray-700 text-base mb-2">{{ $cuenta->correo }}</p>
|
||||
<div class="grid grid-cols-2 sm:grid-cols-4 gap-3 text-gray-500">
|
||||
<div><span class="block text-xs text-gray-400">Servicio</span>{{ $cuenta->servicio->nombre ?? 'N/A' }}</div>
|
||||
<div><span class="block text-xs text-gray-400">Estado cuenta</span>
|
||||
<span class="px-2 py-0.5 rounded-full text-xs font-medium {{ $cuenta->estado === 'activo' ? 'bg-green-100 text-green-700' : ($cuenta->estado === 'pendiente' ? 'bg-yellow-100 text-yellow-700' : 'bg-red-100 text-red-600') }}">{{ $cuenta->estado }}</span>
|
||||
</div>
|
||||
<div><span class="block text-xs text-gray-400">Vencimiento</span>{{ $cuenta->vencimiento }}</div>
|
||||
<div><span class="block text-xs text-gray-400">Pantallas servicio</span>{{ $cuenta->servicio->pantallas ?? 'N/A' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Resumen --}}
|
||||
@if (!empty($resumen))
|
||||
<div class="grid grid-cols-2 sm:grid-cols-4 gap-3 mb-4">
|
||||
<div class="bg-white rounded-xl shadow p-3 text-center">
|
||||
<p class="text-2xl font-bold text-gray-700">{{ $resumen['total_registros'] }}</p>
|
||||
<p class="text-xs text-gray-400">Total perfiles asignados</p>
|
||||
</div>
|
||||
<div class="bg-green-50 rounded-xl shadow p-3 text-center">
|
||||
<p class="text-2xl font-bold text-green-600">{{ $resumen['activos'] }}</p>
|
||||
<p class="text-xs text-gray-400">Activos actualmente</p>
|
||||
</div>
|
||||
<div class="bg-red-50 rounded-xl shadow p-3 text-center">
|
||||
<p class="text-2xl font-bold text-red-500">{{ $resumen['cancelados'] }}</p>
|
||||
<p class="text-xs text-gray-400">Cancelados / liberados</p>
|
||||
</div>
|
||||
<div class="bg-purple-50 rounded-xl shadow p-3 text-center">
|
||||
<p class="text-lg font-bold text-purple-600">{{ implode(', ', $resumen['perfiles_unicos_activos']) ?: 'ninguno' }}</p>
|
||||
<p class="text-xs text-gray-400">Perfiles activos</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if ($resumen['perfil_6_cancelados'] > 0)
|
||||
<div class="bg-yellow-50 border border-yellow-300 rounded-xl p-3 mb-4 text-sm text-yellow-800">
|
||||
⚠️ El <strong>perfil 6</strong> ha sido asignado y cancelado <strong>{{ $resumen['perfil_6_cancelados'] }}</strong> vez/veces.
|
||||
Esto confirma que se está re-entregando el mismo perfil porque las compras anteriores fueron canceladas y liberaron el slot.
|
||||
</div>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
{{-- Tabla historial de perfiles --}}
|
||||
<div class="bg-white rounded-xl shadow mb-4 overflow-x-auto">
|
||||
<p class="text-sm font-semibold text-gray-600 px-4 pt-4 pb-2">Historial de perfiles asignados a esta cuenta</p>
|
||||
<table class="w-full text-xs text-left">
|
||||
<thead class="bg-gray-50 text-gray-500 border-b border-gray-200">
|
||||
<tr>
|
||||
<th class="px-4 py-2">Perfil #</th>
|
||||
<th class="px-4 py-2">Estado historial</th>
|
||||
<th class="px-4 py-2">Vendedor</th>
|
||||
<th class="px-4 py-2">Cliente</th>
|
||||
<th class="px-4 py-2">Fecha inicio</th>
|
||||
<th class="px-4 py-2">Fecha final</th>
|
||||
<th class="px-4 py-2">Historial ID</th>
|
||||
<th class="px-4 py-2">Asignado el</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
@forelse ($historial_perfiles as $hc)
|
||||
<tr class="{{ $hc['estado_historial'] === 'cancelado' ? 'bg-red-50' : ($hc['estado_historial'] === 'activo' ? 'bg-green-50' : '') }}">
|
||||
<td class="px-4 py-2 font-bold text-gray-700">{{ $hc['perfil'] }}</td>
|
||||
<td class="px-4 py-2">
|
||||
<span class="px-2 py-0.5 rounded-full text-xs font-medium
|
||||
{{ $hc['estado_historial'] === 'activo' ? 'bg-green-100 text-green-700' : '' }}
|
||||
{{ $hc['estado_historial'] === 'cancelado' ? 'bg-red-100 text-red-600' : '' }}
|
||||
{{ $hc['estado_historial'] === 'pendiente' ? 'bg-yellow-100 text-yellow-700' : '' }}
|
||||
">{{ $hc['estado_historial'] }}</span>
|
||||
</td>
|
||||
<td class="px-4 py-2">{{ $hc['vendedor'] }}</td>
|
||||
<td class="px-4 py-2">{{ $hc['cliente'] }}</td>
|
||||
<td class="px-4 py-2">{{ $hc['fecha_inicio'] }}</td>
|
||||
<td class="px-4 py-2">{{ $hc['fecha_final'] }}</td>
|
||||
<td class="px-4 py-2 text-gray-400">{{ $hc['historial_id'] }}</td>
|
||||
<td class="px-4 py-2 text-gray-400">{{ $hc['created_at'] }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="8" class="px-4 py-6 text-center text-gray-400">Sin registros</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{{-- Tabla logs relacionados --}}
|
||||
<div class="bg-white rounded-xl shadow overflow-x-auto">
|
||||
<p class="text-sm font-semibold text-gray-600 px-4 pt-4 pb-2">Logs relacionados (últimos 50)</p>
|
||||
<table class="w-full text-xs text-left">
|
||||
<thead class="bg-gray-50 text-gray-500 border-b border-gray-200">
|
||||
<tr>
|
||||
<th class="px-4 py-2">Tipo</th>
|
||||
<th class="px-4 py-2">Usuario</th>
|
||||
<th class="px-4 py-2">Historial ID</th>
|
||||
<th class="px-4 py-2">Detalle</th>
|
||||
<th class="px-4 py-2">Fecha</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-100">
|
||||
@forelse ($logs_relacionados as $log)
|
||||
<tr>
|
||||
<td class="px-4 py-2">
|
||||
<span class="px-2 py-0.5 rounded-full text-xs font-medium
|
||||
{{ $log['tipo'] === 'compra' ? 'bg-green-100 text-green-700' : '' }}
|
||||
{{ $log['tipo'] === 'compra_error' ? 'bg-red-100 text-red-600' : '' }}
|
||||
{{ $log['tipo'] === 'corregido' ? 'bg-blue-100 text-blue-700' : '' }}
|
||||
{{ $log['tipo'] === 'revertida' ? 'bg-orange-100 text-orange-700' : '' }}
|
||||
">{{ $log['tipo'] }}</span>
|
||||
</td>
|
||||
<td class="px-4 py-2">{{ $log['usuario'] }}</td>
|
||||
<td class="px-4 py-2 text-gray-400">{{ $log['historial_id'] }}</td>
|
||||
<td class="px-4 py-2 text-gray-500 max-w-xs truncate" title="{{ $log['detalle'] }}">{{ $log['detalle'] }}</td>
|
||||
<td class="px-4 py-2 text-gray-400 whitespace-nowrap">{{ $log['created_at'] }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="5" class="px-4 py-6 text-center text-gray-400">Sin logs</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,7 @@
|
||||
<x-app-layout>
|
||||
<div class="pb-4">
|
||||
<livewire:show-diagnostico />
|
||||
</div>
|
||||
|
||||
@include('layouts.footer')
|
||||
</x-app-layout>
|
||||
+1
-2
@@ -68,8 +68,7 @@ Route::middleware(["auth", "solo_usuario_administrador"])->group(function () {
|
||||
Route::any('/logs', [MenuController::class, 'showlogs'])->name('logs');
|
||||
Route::any('/logs-recargas', [MenuController::class, 'showLogRecargas'])->name('logsRecargas');
|
||||
Route::any('/log-general', [MenuController::class, 'showLogGeneral'])->name('logGeneral');
|
||||
Route::any('/log-historial', [MenuController::class, 'showLogHistorial'])->name('logHistorial');
|
||||
Route::get('/utilidades', [MenuController::class, 'showutilidad'])->name('utilidades');
|
||||
Route::any('/log-historial', [MenuController::class, 'showLogHistorial'])->name('logHistorial'); Route::get('/diagnostico', [MenuController::class, 'showDiagnostico'])->name('diagnostico'); Route::get('/utilidades', [MenuController::class, 'showutilidad'])->name('utilidades');
|
||||
Route::get('/mantenimiento', [MenuController::class, 'mantenimiento'])->name('mantenimiento');
|
||||
Route::get('/rank-management', [MenuController::class, 'showgestionrangos'])->name('gestion-rangos');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user