diff --git a/assets/css/style.css b/assets/css/style.css index 61bb57a9..2acd9193 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -512,6 +512,18 @@ h1, .h1 { background: linear-gradient(135deg, rgba(108, 117, 125, .12), rgba(108, 117, 125, .04)); } +.cc-kpi-pill-total { + background: linear-gradient(135deg, rgba(20, 184, 166, .18), rgba(13, 110, 253, .06)); + border-color: rgba(20, 184, 166, .18); +} + +.cc-kpi-meta { + font-size: .73rem; + line-height: 1.15; + color: #64748b; + font-weight: 600; +} + .cc-kpi-chart-card { border-radius: 1.2rem; overflow: hidden; diff --git a/call_center_pro.php b/call_center_pro.php index 3df45489..adc43d26 100644 --- a/call_center_pro.php +++ b/call_center_pro.php @@ -251,6 +251,7 @@ $allowedViews = [ 'pendientes_hoy' => 'Bandeja principal', 'nuevos_hoy' => 'Pedidos asignados hoy', 'confirmados' => 'Confirmados', + 'recuperados' => 'Recuperados', 'seguimiento' => 'Seguimiento', 'promo_final' => 'Promo Final', 'observados' => 'Observados', @@ -290,6 +291,7 @@ $stats = [ 'pendientes_hoy' => 0, 'nuevos_hoy' => 0, 'confirmados' => 0, + 'recuperados' => 0, 'seguimiento' => 0, 'promo_final' => 0, 'observados' => 0, @@ -462,6 +464,9 @@ try { if (in_array($order['estado'], cc_test_confirmed_states(), true)) { $stats['confirmados']++; } + if (cc_test_is_recovered_today($order, $todayStart)) { + $stats['recuperados']++; + } if ($order['estado'] === 'SE ENVIO NUMERO DE CUENTA' && !$order['es_promo_final']) { $stats['seguimiento']++; } @@ -474,26 +479,33 @@ try { } unset($order); - $performanceDashboard = cc_test_build_performance_dashboard($orders, $assessors, 7); + $performanceOrders = $orders; + if ($selectedAssessorFilter !== '') { + $performanceOrders = array_values(array_filter($orders, static function (array $order) use ($selectedAssessorFilter): bool { + return ($order['matches_assessor_filter'] ?? false) === true; + })); + } + + $performanceDashboard = cc_test_build_performance_dashboard($performanceOrders, $assessors, 7); $performanceTitle = $isAdmin ? ($selectedAssessorFilterLabel !== '' ? 'KPI diario · ' . $selectedAssessorFilterLabel : 'KPI diario por asesora') : 'Mi KPI diario'; $performanceSubtitle = $isAdmin - ? 'Confirmación = pedidos asignados hoy confirmados hoy. Recuperación = pedidos asignados antes de hoy confirmados hoy.' - : 'Tus KPIs de hoy se calculan sobre tus pedidos asignados hoy. Confirmación = asignados hoy confirmados hoy. Recuperación = asignados antes de hoy confirmados hoy.'; + ? 'Confirmación = pedidos asignados hoy confirmados hoy. Recuperación = pedidos asignados antes de hoy confirmados hoy. Rendimiento del día = confirmados totales (nuevos + recuperados) sobre asignados hoy.' + : 'Tus KPIs de hoy se calculan sobre tus pedidos asignados hoy. Confirmación = asignados hoy confirmados hoy. Recuperación = asignados antes de hoy confirmados hoy. Rendimiento del día = confirmados totales (nuevos + recuperados) sobre asignados hoy.'; $performanceDashboardHtml = cc_test_render_performance_dashboard($performanceDashboard, [ 'title' => $performanceTitle, 'subtitle' => $performanceSubtitle, 'chart1_title' => $isAdmin ? 'Distribución de estados' : 'Mi distribución de estados', - 'chart1_note' => 'Verde = confirmados de pedidos asignados hoy, amarillo = confirmados de pedidos asignados antes de hoy, azul = seguimiento abierto, gris = repetidos, rojo = cancelados. La lista lateral muestra el % de cada estado.', + 'chart1_note' => 'La dona separa los pedidos de hoy por estado: confirmados nuevos, recuperados, POR LLAMAR, DEVOLVER LLAMADA, OBSERVADO, SE ENVIO NUMERO DE CUENTA, repetidos y cancelados.', 'chart2_title' => $isAdmin ? 'Evolución de los últimos 7 días' : 'Tu evolución de los últimos 7 días', 'chart2_note' => 'La línea de confirmados separa pedidos asignados hoy y pedidos asignados antes de hoy.', - 'footnote' => 'Seguimiento abierto = pedidos en SE ENVIO NUMERO DE CUENTA que todavía no pasan a Promo Final.', + 'footnote' => 'Seguimiento abierto = pedidos asignados hoy en POR LLAMAR, DEVOLVER LLAMADA, OBSERVADO y SE ENVIO NUMERO DE CUENTA que todavía no pasan a Promo Final.', ]); $panelSignature = cc_test_panel_orders_signature($orders); - $visibleOrders = array_values(array_filter($orders, static function (array $order) use ($view, $selectedAssessorFilter): bool { + $visibleOrders = array_values(array_filter($orders, static function (array $order) use ($view, $selectedAssessorFilter, $todayStart): bool { if ($selectedAssessorFilter !== '' && !($order['matches_assessor_filter'] ?? false)) { return false; } @@ -502,6 +514,7 @@ try { 'pendientes_hoy' => (bool) ($order['es_pendiente_hoy'] ?? false), 'nuevos_hoy' => (bool) ($order['es_nuevo_hoy'] ?? false), 'confirmados' => in_array(($order['estado'] ?? ''), cc_test_confirmed_states(), true), + 'recuperados' => cc_test_is_recovered_today($order, $todayStart), 'seguimiento' => ($order['estado'] ?? '') === 'SE ENVIO NUMERO DE CUENTA' && !($order['es_promo_final'] ?? false), 'promo_final' => (bool) ($order['es_promo_final'] ?? false), 'observados' => ($order['estado'] ?? '') === 'OBSERVADO' && !($order['es_promo_final'] ?? false), @@ -528,6 +541,20 @@ try { } } + if ($view === 'recuperados') { + $aRecovered = cc_test_dashboard_action_datetime($a); + $bRecovered = cc_test_dashboard_action_datetime($b); + if ($aRecovered && $bRecovered && $aRecovered != $bRecovered) { + return $bRecovered <=> $aRecovered; + } + if ($aRecovered && !$bRecovered) { + return -1; + } + if (!$aRecovered && $bRecovered) { + return 1; + } + } + if ($view === 'promo_final') { $aDays = (int) ($a['dias_seguimiento'] ?? 0); $bDays = (int) ($b['dias_seguimiento'] ?? 0); @@ -841,6 +868,16 @@ require_once 'layout_header.php'; +
+ @@ -1141,7 +1205,7 @@ function cc_test_render_performance_dashboard(array $dashboard, array $options =