diff --git a/call_center_pro.php b/call_center_pro.php index b5880540..9c25089c 100644 --- a/call_center_pro.php +++ b/call_center_pro.php @@ -14,7 +14,7 @@ $provinciasPorDepartamentoContraentrega = contraentregaProvinciasPorDepartamento $distritosPorProvinciaContraentrega = contraentregaDistritosPorProvincia(); $departamentosContraentrega = array_keys($provinciasPorDepartamentoContraentrega); $pageTitle = 'Pedidos Asignados | Bandeja de la asesora'; -$pageDescription = 'Bandeja para que cada asesora gestione sus pedidos asignados con vistas de hoy, últimos 3 días hábiles, estados, historial y acciones.'; +$pageDescription = 'Bandeja para que cada asesora gestione sus pedidos asignados con vistas de hoy, últimos 4 días hábiles, estados, historial y acciones.'; $kpiPeriodConfig = cc_test_resolve_kpi_period((string) ($_GET['kpi_period'] ?? 'today'), (string) ($_GET['kpi_date'] ?? '')); $kpiPeriodKey = (string) ($kpiPeriodConfig['key'] ?? 'today'); @@ -386,8 +386,8 @@ $viewCards = $isTuaniRecuperablesStore ? [ 'active_class' => 'bg-primary-subtle border border-primary', ], 'ultimos_3_dias' => [ - 'label' => 'Últimos 3 días hábiles', - 'heading' => 'Pedidos asignados de los últimos 3 días hábiles', + 'label' => 'Últimos 4 días hábiles', + 'heading' => 'Pedidos asignados de los últimos 4 días hábiles', 'stat_key' => 'ultimos_3_dias', 'active_class' => 'bg-info-subtle border border-info', ], @@ -456,8 +456,8 @@ $_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.' - : '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 desde el Día 3 para todos los pedidos; desde ese momento el número queda visible para llamar y gestionar, y el sustento solo se usa para mover el pedido a Promo Final. 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 3 días hábiles para concentrar el seguimiento reciente.'; + ? '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. La vista Todos arranca en la fila 2000 y se pagina 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; $noticeMessage = null; @@ -705,7 +705,7 @@ 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, true, true); + $selectedAssessorFilter = 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 +734,7 @@ try { $order['seguimiento_dia_info'] = $followupDayInfo; $order['dias_seguimiento'] = $followupDayInfo['day_number'] ?? null; $order['promo_final_habilitado'] = !empty($followupDayInfo['is_promo_final']); + $order['promo_final_evidencia_habilitada'] = !empty($followupDayInfo['can_upload_promo_final_evidence']); $order['promo_final_evidencia_cargada'] = trim((string) ($order['promo_final_evidencia_path'] ?? '')) !== ''; $order['es_promo_final'] = $order['promo_final_habilitado'] && $order['promo_final_evidencia_cargada']; $order['promo_final_pendiente'] = $order['promo_final_habilitado'] && !$order['promo_final_evidencia_cargada']; @@ -743,7 +744,7 @@ try { $order['pendiente_logistica'] = $order['pendiente_logistica_destino'] !== null; $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, 3); + $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); $order['assessor_key'] = cc_test_find_assessor_key_by_user_id(isset($order['user_id']) ? (int) $order['user_id'] : null, $assessors); @@ -789,8 +790,6 @@ try { $pendingPromoFinalCounts = cc_test_followup_pending_promo_final_counts($orders); - $orders = cc_test_mark_recoverables_duplicate_orders($pdo, $orders, $storeKey); - $performanceOrders = $orders; if ($selectedAssessorFilter !== '') { $performanceOrders = array_values(array_filter($orders, static function (array $order) use ($selectedAssessorFilter): bool { @@ -989,7 +988,9 @@ try { $aSourceRow = (int) ($a['source_row'] ?? 0); $bSourceRow = (int) ($b['source_row'] ?? 0); if ($aSourceRow !== $bSourceRow) { - return $bSourceRow <=> $aSourceRow; + return cc_test_is_tuani_recoverables_store_key($storeKey) + ? ($aSourceRow <=> $bSourceRow) + : ($bSourceRow <=> $aSourceRow); } $aId = (int) ($a['id'] ?? 0); @@ -1022,7 +1023,7 @@ try { $assessorInboxLocked = $assessorInboxLockedCount > 0; $assessorInboxLockedView = $assessorInboxLocked && $view === 'nuevos_hoy'; $assessorInboxLockNotice = $assessorInboxLocked - ? 'Tienes ' . $assessorInboxLockedCount . ' pedido' . ($assessorInboxLockedCount === 1 ? '' : 's') . ' pendiente' . ($assessorInboxLockedCount === 1 ? '' : 's') . ' de Promo Final. Mientras existan pendientes, los pedidos de Día 1 mantienen el número oculto; cuando los muevas todos a Promo Final, el celular volverá a mostrarse.' + ? 'Tienes ' . $assessorInboxLockedCount . ' pedido' . ($assessorInboxLockedCount === 1 ? '' : 's') . ' pendiente' . ($assessorInboxLockedCount === 1 ? '' : 's') . ' de Promo Final. Mientras existan pendientes de sustento, los pedidos de Día 1 mantienen el número oculto; cuando ya no queden pendientes, el celular volverá a mostrarse.' : ''; $visibleOrdersTotalCount = count($visibleOrders); @@ -1033,45 +1034,46 @@ try { $todosPageEnd = 0; $todosPaginationPages = []; - if ($view === 'todos') { - $requestedPage = (int) ($_GET['page'] ?? 1); - if ($requestedPage < 1) { - $requestedPage = 1; - } - - $todosTotalPages = max(1, (int) ceil($visibleOrdersTotalCount / $todosPageSize)); - if ($requestedPage > $todosTotalPages) { - $requestedPage = $todosTotalPages; - } - - $todosPage = $requestedPage; - $todosPageStart = ($todosPage - 1) * $todosPageSize; - $visibleOrders = array_slice($visibleOrders, $todosPageStart, $todosPageSize); - $todosPageEnd = $todosPageStart + count($visibleOrders); - - if ($todosTotalPages <= 7) { - $todosPaginationPages = range(1, $todosTotalPages); - } else { - $todosPaginationPages[] = 1; - $windowStart = max(2, $todosPage - 1); - $windowEnd = min($todosTotalPages - 1, $todosPage + 1); - - if ($windowStart > 2) { - $todosPaginationPages[] = 'ellipsis'; - } - - for ($pageNumber = $windowStart; $pageNumber <= $windowEnd; $pageNumber++) { - $todosPaginationPages[] = $pageNumber; - } - - if ($windowEnd < $todosTotalPages - 1) { - $todosPaginationPages[] = 'ellipsis'; - } - - $todosPaginationPages[] = $todosTotalPages; - } + $requestedPage = (int) ($_GET['page'] ?? 1); + if ($requestedPage < 1) { + $requestedPage = 1; } + $todosTotalPages = max(1, (int) ceil($visibleOrdersTotalCount / $todosPageSize)); + if ($requestedPage > $todosTotalPages) { + $requestedPage = $todosTotalPages; + } + + $todosPage = $requestedPage; + $todosPageStart = ($todosPage - 1) * $todosPageSize; + $visibleOrders = array_slice($visibleOrders, $todosPageStart, $todosPageSize); + $todosPageEnd = $todosPageStart + count($visibleOrders); + + if ($isTuaniRecuperablesStore) { + $visibleOrders = cc_test_mark_recoverables_duplicate_orders($pdo, $visibleOrders, $storeKey); + } + + if ($todosTotalPages <= 7) { + $todosPaginationPages = range(1, $todosTotalPages); + } else { + $todosPaginationPages[] = 1; + $windowStart = max(2, $todosPage - 1); + $windowEnd = min($todosTotalPages - 1, $todosPage + 1); + + if ($windowStart > 2) { + $todosPaginationPages[] = 'ellipsis'; + } + + for ($pageNumber = $windowStart; $pageNumber <= $windowEnd; $pageNumber++) { + $todosPaginationPages[] = $pageNumber; + } + + if ($windowEnd < $todosTotalPages - 1) { + $todosPaginationPages[] = 'ellipsis'; + } + + $todosPaginationPages[] = $todosTotalPages; + } } catch (Throwable $exception) { $errorMessage = $exception->getMessage(); } @@ -1118,7 +1120,7 @@ if ($isTuaniRecuperablesStore) { $pageDescription = 'Bandeja compartida para que cualquier asesora gestione carritos recuperables con vistas de seguimiento y observados desde Drive.'; } else { $pageTitle = 'Pedidos Asignados | Bandeja de la asesora'; - $pageDescription = 'Bandeja para que cada asesora gestione sus pedidos asignados con vistas de hoy, últimos 3 días hábiles, estados, historial y acciones.'; + $pageDescription = 'Bandeja para que cada asesora gestione sus pedidos asignados con vistas de hoy, últimos 4 días hábiles, estados, historial y acciones.'; } $callCenterSectionLabel = $isTuaniRecuperablesStore ? 'Carritos recuperables' : 'Pedidos Asignados'; @@ -1495,7 +1497,7 @@ require_once 'layout_header.php'; Pedidos con sustento pendiente para Promo Final - + 1): ?> Página de · 200 por página @@ -1506,9 +1508,9 @@ require_once 'layout_header.php';
Pedidos con sustento pendiente para Promo Final
-
Usa Últimos 3 días hábiles si necesitas completar ese sustento más rápido.
+
Usa Últimos 4 días hábiles si necesitas completar ese sustento más rápido.
- Ir a Últimos 3 días + Ir a Últimos 4 días hábiles
@@ -1558,7 +1560,7 @@ require_once 'layout_header.php'; }; $subirLogisticaButtonLabel = 'Subir pedido'; $subirLogisticaNoteClass = 'alert alert-secondary py-2 px-3 mt-2 mb-0'; - $subirLogisticaNoteHtml = 'Selecciona CONFIRMADO CONTRAENTREGA o CONFIRMADO ENVIO para enviarlo a logística.'; + $subirLogisticaNoteHtml = 'Selecciona CONFIRMADO CONTRAENTREGA o CONFIRMADO ENVIO y completa Confirmación de pedido (producto, cantidad y precio) para enviarlo a logística.'; if ($canShowTuaniLogisticaButton) { if ($order['estado'] === 'CONFIRMADO CONTRAENTREGA') { if (!empty($order['ruta_contraentrega_pedido_id'])) { @@ -1589,7 +1591,7 @@ require_once 'layout_header.php'; $phoneLocked = false; $phoneLockMessage = (string) ($order['llamada_bloqueada_dia3_mensaje'] ?? ''); if ($phoneLocked && $phoneLockMessage === '') { - $phoneLockMessage = 'Celular oculto mientras completas los pendientes del Día 3.'; + $phoneLockMessage = 'Celular oculto mientras completas los pendientes del Día 4.'; } $phoneHiddenByDay1 = cc_test_followup_day1_phone_hidden($order, $pendingPromoFinalCounts); $phoneRowHiddenLabel = 'Número oculto'; @@ -1750,7 +1752,7 @@ require_once 'layout_header.php'; data-phone="" data-order-label="" data-client-name="" - onclick="return registrarLlamada(event, this)"> + onclick="return registrarLlamada(event, this)"> @@ -1809,7 +1811,10 @@ require_once 'layout_header.php'; - + + + +
- + Ver sustento Promo Final
- Promo Final con sustento cargado · . + Sustento de Promo Final cargado · . + + Ya puedes cargar la imagen desde el Día para dejarlo listo; el movimiento a Promo Final sigue desde el Día . - Debes subir una imagen de sustento y luego usar este botón para moverlo a Promo Final. + Ya puedes moverlo a Promo Final; si aún no cargaste la imagen, súbela antes de usar el botón.
@@ -1958,6 +1965,7 @@ require_once 'layout_header.php'; +
Antes de usar Subir pedido, completa producto, cantidad y precio en esta sección.
@@ -2033,12 +2041,14 @@ require_once 'layout_header.php';
- + + + -
+
-
Obligatoria al mover el pedido a Promo Final desde el Día . La supervisora podrá revisarla.
+
Puedes cargarla desde el Día . Para mover el pedido a Promo Final seguirá siendo obligatoria desde el Día . La supervisora podrá revisarla.
Sustento actual: ver imagen · . @@ -2203,7 +2213,7 @@ require_once 'layout_header.php';
+
Antes de usar Subir pedido, completa producto, cantidad y precio en esta sección.
@@ -2496,12 +2504,14 @@ require_once 'layout_header.php';
- + + + -
+
-
Obligatoria al mover el pedido a Promo Final desde el Día . La supervisora podrá revisarla.
+
Puedes cargarla desde el Día . Para mover el pedido a Promo Final seguirá siendo obligatoria desde el Día . La supervisora podrá revisarla.
Sustento actual: ver imagen · . @@ -2661,7 +2671,7 @@ require_once 'layout_header.php';