diff --git a/call_center_pro.php b/call_center_pro.php index 6826a05b..297a72fb 100644 --- a/call_center_pro.php +++ b/call_center_pro.php @@ -350,6 +350,12 @@ $viewCards = $isTuaniRecuperablesStore ? [ 'stat_key' => 'pendientes_hoy', 'active_class' => 'bg-dark text-white', ], + 'nuevos_hoy' => [ + 'label' => 'Nuevos hoy', + 'heading' => 'Nuevos hoy', + 'stat_key' => 'nuevos_hoy', + 'active_class' => 'bg-primary-subtle border border-primary', + ], 'confirmados' => [ 'label' => 'Confirmados', 'heading' => 'Confirmados', @@ -458,7 +464,7 @@ $_SESSION[cc_test_callcenter_store_session_key()] = cc_test_normalize_context_ke $_SESSION[cc_test_callcenter_view_session_key()] = cc_test_normalize_context_key($view); $viewStatesNote = $isTuaniRecuperablesStore - ? 'Estados disponibles: Carritos recuperables, Seguimiento, Observados, Confirmados, Recuperados y Todos. Esta bandeja compartida está disponible para cualquier asesora y, cuando una asesora gestiona un carrito recuperable, el sistema lo asigna automáticamente a quien lo trabaja. Si el teléfono ya existe en TUANI principal, se marca en gris como Pedido repetido en tienda solo en esta bandeja. Las vistas Carritos recuperables y Todos arrancan en la fila 2000, solo toman pedidos desde esa fila y se ordenan por el número #D más alto, lo que mantiene arriba el código más reciente, al más antiguo, en bloques de 200 pedidos.' + ? 'Estados disponibles: Carritos recuperables, Nuevos hoy, Seguimiento, Observados, Confirmados, Recuperados y Todos. La vista Nuevos hoy agrupa los pedidos más recientes agregados desde Drive. Esta bandeja compartida está disponible para cualquier asesora y, cuando una asesora gestiona un carrito recuperable, el sistema lo asigna automáticamente a quien lo trabaja. Si el teléfono ya existe en TUANI principal, se marca en gris como Pedido repetido en tienda solo en esta bandeja. Las vistas Carritos recuperables y Todos arrancan en la fila 2000, solo toman pedidos desde esa fila y se ordenan por el número #D más alto, lo que mantiene arriba el código más reciente, al más antiguo, en bloques de 200 pedidos.' : 'Estados disponibles: Por llamar, Devolver llamada, Observado, Se envió número de cuenta, Confirmado contraentrega, Confirmado envío, Cancelado y Repetido. Promo Final se habilita para mover el pedido desde el Día 4; la imagen de sustento se puede cargar desde el Día 3 para dejarlo listo antes del pase. Además, esta bandeja principal incluye reparto intercalado diario: en modo automático reparte pedidos sin asignar entre asesoras activas; en modo manual el supervisor los mueve pedido por pedido. También puedes usar la vista Últimos 4 días hábiles para concentrar el seguimiento reciente.'; $errorMessage = null; @@ -714,7 +720,9 @@ try { $currentUserId = (int) ($_SESSION['user_id'] ?? 0); $isAdmin = in_array($role, ['Administrador', 'admin'], true); if ($isAdmin) { - $selectedAssessorFilter = cc_test_resolve_callcenter_assessor_filter($assessors, $_GET['assessor'] ?? null, !$isTuaniRecuperablesStore, true); + $selectedAssessorFilter = $isTuaniRecuperablesStore + ? '' + : cc_test_resolve_callcenter_assessor_filter($assessors, $_GET['assessor'] ?? null, !$isTuaniRecuperablesStore, true); } else { unset($_SESSION[cc_test_callcenter_assessor_filter_session_key()]); $selectedAssessorFilter = ''; @@ -734,6 +742,21 @@ try { $openStates = cc_test_open_states(); $closedStates = cc_test_closed_states(); + $recoverablesRecentSourceRowThreshold = null; + if ($isTuaniRecuperablesStore) { + $recoverablesMaxSourceRow = 0; + foreach ($orders as $recoverablesThresholdOrder) { + $recoverablesSourceRow = (int) ($recoverablesThresholdOrder['source_row'] ?? 0); + if ($recoverablesSourceRow > $recoverablesMaxSourceRow) { + $recoverablesMaxSourceRow = $recoverablesSourceRow; + } + } + + if ($recoverablesMaxSourceRow > 0) { + $recoverablesRecentSourceRowThreshold = max(0, $recoverablesMaxSourceRow - 4); + } + } + foreach ($orders as &$order) { $order['estado'] = cc_test_normalize_state((string) ($order['estado'] ?? '')); $order['total_llamadas'] = (int) ($callCounts[$order['source_key']] ?? 0); @@ -752,7 +775,12 @@ try { $order['pendiente_logistica_destino'] = cc_test_is_tuani_store_key($storeKey) ? cc_test_pending_logistica_destination($order) : null; $order['pendiente_logistica'] = $order['pendiente_logistica_destino'] !== null; - $order['es_nuevo_hoy'] = $assignedDate ? $assignedDate->format('Y-m-d') === $todayStart->format('Y-m-d') : false; + if ($isTuaniRecuperablesStore) { + $order['es_nuevo_hoy'] = $recoverablesRecentSourceRowThreshold !== null + && (int) ($order['source_row'] ?? 0) >= $recoverablesRecentSourceRowThreshold; + } else { + $order['es_nuevo_hoy'] = $assignedDate ? $assignedDate->format('Y-m-d') === $todayStart->format('Y-m-d') : false; + } $order['es_ultimos_3_dias'] = cc_test_is_within_last_days_window($order, $todayStart, 4); $order['es_pendiente_hoy'] = !$order['es_promo_final'] && (in_array($order['estado'], $openStates, true) || $order['pendiente_logistica']); $order['es_cerrado'] = in_array($order['estado'], $closedStates, true); @@ -1371,7 +1399,7 @@ require_once 'layout_header.php'; Solo pedidos válidos: IDs #D... - Abrir Carritos recuperables (#D...) + Abrir Carritos recuperables (#D...)
@@ -1384,7 +1412,7 @@ require_once 'layout_header.php'; $group): ?> @@ -1394,9 +1422,9 @@ require_once 'layout_header.php';
Dentro de
- Pedidos + Pedidos $childConfig): ?> - + @@ -3571,7 +3599,12 @@ syncServerAssessorSelects(); ccCallCenterPanelBindDirtyTracking(); ccCallCenterPanelRestoreScroll(); window.addEventListener('beforeunload', ccCallCenterPanelSaveScroll); -window.addEventListener('pageshow', function () { +window.addEventListener('pageshow', function (event) { + if (event && event.persisted) { + window.location.reload(); + return; + } + syncServerAssessorSelects(); ccCallCenterPanelRestoreScroll(); ccCallCenterPanelCheckForUpdates(); diff --git a/gestiones_callcenter.php b/gestiones_callcenter.php index 618365cf..8cb6d296 100644 --- a/gestiones_callcenter.php +++ b/gestiones_callcenter.php @@ -247,6 +247,12 @@ $viewCards = $isTuaniRecuperablesStore ? [ 'stat_key' => 'pendientes_hoy', 'active_class' => 'bg-dark text-white', ], + 'nuevos_hoy' => [ + 'label' => 'Nuevos hoy', + 'heading' => 'Nuevos hoy', + 'stat_key' => 'nuevos_hoy', + 'active_class' => 'bg-primary-subtle border border-primary', + ], 'confirmados' => [ 'label' => 'Confirmados', 'heading' => 'Confirmados', @@ -349,7 +355,7 @@ $_SESSION[cc_test_callcenter_store_session_key()] = cc_test_normalize_context_ke $_SESSION[cc_test_callcenter_view_session_key()] = cc_test_normalize_context_key($view); $viewStatesNote = $isTuaniRecuperablesStore - ? 'Estados disponibles: Carritos recuperables, Seguimiento, Observados, Confirmados, Recuperados y Todos. Esta bandeja compartida está disponible para cualquier asesora y, cuando una asesora gestiona un carrito recuperable, el sistema lo asigna automáticamente a quien lo trabaja. Si el teléfono ya existe en TUANI principal, se marca en gris como Pedido repetido en tienda solo en esta bandeja. Las vistas Carritos recuperables y Todos arrancan en la fila 2000, solo toman pedidos desde esa fila y se ordenan por el número #D más alto, lo que mantiene arriba el código más reciente, al más antiguo, en bloques de 200 pedidos.' + ? 'Estados disponibles: Carritos recuperables, Nuevos hoy, Seguimiento, Observados, Confirmados, Recuperados y Todos. La vista Nuevos hoy agrupa los pedidos más recientes agregados desde Drive. Esta bandeja compartida está disponible para cualquier asesora y, cuando una asesora gestiona un carrito recuperable, el sistema lo asigna automáticamente a quien lo trabaja. Si el teléfono ya existe en TUANI principal, se marca en gris como Pedido repetido en tienda solo en esta bandeja. Las vistas Carritos recuperables y Todos arrancan en la fila 2000, solo toman pedidos desde esa fila y se ordenan por el número #D más alto, lo que mantiene arriba el código más reciente, al más antiguo, en bloques de 200 pedidos.' : 'Estados disponibles: Por llamar, Devolver llamada, Observado, Se envió número de cuenta, Confirmado contraentrega, Confirmado envío, Cancelado y Repetido. Promo Final se habilita para mover el pedido desde el Día 4; la imagen de sustento se puede cargar desde el Día 3 para dejarlo listo. En las vistas Todos y Últimos 4 días hábiles, la llamada y la gestión siguen disponibles desde el panel.'; $errorMessage = null; @@ -420,7 +426,9 @@ try { cc_test_ensure_tracking_table($pdo); cc_test_ensure_historial_llamadas_table($pdo); $assessors = cc_test_fetch_assessors($pdo); - $selectedAssessorFilter = cc_test_resolve_callcenter_assessor_filter($assessors, $_GET['assessor'] ?? null, false, false); + $selectedAssessorFilter = $isTuaniRecuperablesStore + ? '' + : cc_test_resolve_callcenter_assessor_filter($assessors, $_GET['assessor'] ?? null, false, false); $selectedAssessorFilterLabel = $selectedAssessorFilter !== '' ? (string) ($assessors[$selectedAssessorFilter]['label'] ?? $selectedAssessorFilter) : ''; @@ -902,6 +910,21 @@ try { $openStates = cc_test_open_states(); $closedStates = cc_test_closed_states(); + $recoverablesRecentSourceRowThreshold = null; + if ($isTuaniRecuperablesStore) { + $recoverablesMaxSourceRow = 0; + foreach ($orders as $recoverablesThresholdOrder) { + $recoverablesSourceRow = (int) ($recoverablesThresholdOrder['source_row'] ?? 0); + if ($recoverablesSourceRow > $recoverablesMaxSourceRow) { + $recoverablesMaxSourceRow = $recoverablesSourceRow; + } + } + + if ($recoverablesMaxSourceRow > 0) { + $recoverablesRecentSourceRowThreshold = max(0, $recoverablesMaxSourceRow - 4); + } + } + $advisorOpenCounts = []; $advisorTotalCounts = []; foreach ($assessors as $assessor) { @@ -930,7 +953,12 @@ try { $order['pendiente_logistica_destino'] = cc_test_is_tuani_store_key($storeKey) ? cc_test_pending_logistica_destination($order) : null; $order['pendiente_logistica'] = $order['pendiente_logistica_destino'] !== null; - $order['es_nuevo_hoy'] = $firstSeenDate ? $firstSeenDate->format('Y-m-d') === $todayStart->format('Y-m-d') : false; + if ($isTuaniRecuperablesStore) { + $order['es_nuevo_hoy'] = $recoverablesRecentSourceRowThreshold !== null + && (int) ($order['source_row'] ?? 0) >= $recoverablesRecentSourceRowThreshold; + } else { + $order['es_nuevo_hoy'] = $firstSeenDate ? $firstSeenDate->format('Y-m-d') === $todayStart->format('Y-m-d') : false; + } $order['es_pendiente_hoy'] = !$order['es_promo_final'] && (in_array($order['estado'], $openStates, true) || $order['pendiente_logistica']); $order['es_cerrado'] = in_array($order['estado'], $closedStates, true); $order['assessor_key'] = cc_test_dashboard_bucket_key($order, $assessors, false); @@ -1627,7 +1655,7 @@ require_once 'layout_header.php'; Solo pedidos válidos: IDs #D... - Abrir Carritos recuperables (#D...) + Abrir Carritos recuperables (#D...)
@@ -1638,7 +1666,7 @@ require_once 'layout_header.php'; $group): ?> @@ -1648,9 +1676,9 @@ require_once 'layout_header.php';
Dentro de
- Pedidos + Pedidos $childConfig): ?> - + @@ -4093,7 +4121,12 @@ document.querySelectorAll('.cc-callcenter-assign-form').forEach(function (form) } }); -window.addEventListener('pageshow', function () { +window.addEventListener('pageshow', function (event) { + if (event && event.persisted) { + window.location.reload(); + return; + } + syncAllAssessorFormsFromServer(); }); window.addEventListener('load', function () { diff --git a/includes/callcenter_test_helpers.php b/includes/callcenter_test_helpers.php index 03768002..402701af 100644 --- a/includes/callcenter_test_helpers.php +++ b/includes/callcenter_test_helpers.php @@ -275,7 +275,7 @@ function cc_test_callcenter_pro_default_view_key(string $storeKey): string } if (cc_test_is_tuani_recoverables_store_key($storeKey)) { - return 'todos'; + return 'nuevos_hoy'; } return 'pendientes_hoy';