Autosave: 20260807-012847
This commit is contained in:
parent
4471779478
commit
87af7beac5
@ -317,11 +317,10 @@ function cc_test_panel_orders_signature(array $orders): string
|
||||
return sha1(json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
||||
}
|
||||
|
||||
$view = trim((string) ($_GET['view'] ?? ''));
|
||||
$view = cc_test_resolve_callcenter_context_key($_GET['view'] ?? '', cc_test_callcenter_view_session_key());
|
||||
|
||||
$storeKey = trim((string) ($_GET['store'] ?? 'flower'));
|
||||
$storeKey = mb_strtolower($storeKey);
|
||||
$availableStores = drive_test_available_stores();
|
||||
$storeKey = cc_test_resolve_callcenter_context_key($_GET['store'] ?? '', cc_test_callcenter_store_session_key(), 'flower');
|
||||
if (!isset($availableStores[$storeKey])) {
|
||||
$storeKey = 'flower';
|
||||
}
|
||||
@ -337,6 +336,9 @@ $parentStoreLabel = (string) ($storeNav['parent_label'] ?? '');
|
||||
|
||||
$isMainTuaniStore = cc_test_is_tuani_main_store_key($storeKey);
|
||||
$isTuaniRecuperablesStore = $storeKey === 'tuani_recuperables';
|
||||
if ($isTuaniRecuperablesStore && trim((string) ($_GET['view'] ?? '')) === '') {
|
||||
$view = 'todos';
|
||||
}
|
||||
$canShowTuaniLogisticaButton = $isMainTuaniStore || $isTuaniRecuperablesStore;
|
||||
$viewCardColumnClass = $isTuaniRecuperablesStore ? 'col-md-6 col-xl-2' : 'col-md-6 col-xl-2';
|
||||
$defaultView = cc_test_callcenter_pro_default_view_key($storeKey);
|
||||
@ -456,7 +458,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: <strong>Carritos recuperables</strong>, <strong>Seguimiento</strong>, <strong>Observados</strong>, <strong>Confirmados</strong>, <strong>Recuperados</strong> y <strong>Todos</strong>. 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 <strong>TUANI principal</strong>, se marca en gris como <strong>Pedido repetido en tienda</strong> solo en esta bandeja. La vista <strong>Todos</strong> arranca en la fila 2000 y se pagina en bloques de 200 pedidos.'
|
||||
? 'Estados disponibles: <strong>Carritos recuperables</strong>, <strong>Seguimiento</strong>, <strong>Observados</strong>, <strong>Confirmados</strong>, <strong>Recuperados</strong> y <strong>Todos</strong>. 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 <strong>TUANI principal</strong>, se marca en gris como <strong>Pedido repetido en tienda</strong> solo en esta bandeja. Las vistas <strong>Carritos recuperables</strong> y <strong>Todos</strong> arrancan en la fila 2000, solo toman pedidos desde esa fila y se ordenan por el número <strong>#D</strong> 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. <strong>Promo Final</strong> 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 <strong>Últimos 4 días hábiles</strong> para concentrar el seguimiento reciente.';
|
||||
|
||||
$errorMessage = null;
|
||||
@ -475,6 +477,7 @@ $recoverablesImportCount = 0;
|
||||
$recoverablesFirstSourceRow = null;
|
||||
$recoverablesLastSourceRow = null;
|
||||
$startRow = (int) ($storeConfig['startRow'] ?? 0);
|
||||
$recoverablesMinimumSourceRow = $isTuaniRecuperablesStore ? (int) ($storeConfig['startRow'] ?? 0) : 0;
|
||||
$catalogoProductos = [];
|
||||
$stats = [
|
||||
'total' => 0,
|
||||
@ -562,6 +565,9 @@ try {
|
||||
$orders = array_values(array_filter($orders, static function (array $order): bool {
|
||||
return empty($order['eliminado']);
|
||||
}));
|
||||
if ($isTuaniRecuperablesStore) {
|
||||
$orders = cc_test_filter_recoverables_orders($orders, $recoverablesMinimumSourceRow);
|
||||
}
|
||||
|
||||
$postedAction = trim((string) ($_POST['action'] ?? ''));
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
@ -868,6 +874,10 @@ try {
|
||||
$aImport = cc_test_import_time($a);
|
||||
$bImport = cc_test_import_time($b);
|
||||
|
||||
if (cc_test_is_tuani_recoverables_store_key($storeKey) && in_array($view, ['pendientes_hoy', 'todos'], true)) {
|
||||
return cc_test_compare_recoverables_orders_desc($a, $b);
|
||||
}
|
||||
|
||||
if ($view === 'nuevos_hoy') {
|
||||
$aOrderNumberValue = cc_test_order_priority_value($a);
|
||||
$bOrderNumberValue = cc_test_order_priority_value($b);
|
||||
@ -984,6 +994,10 @@ try {
|
||||
}
|
||||
|
||||
if ($view === 'todos') {
|
||||
if (cc_test_is_tuani_recoverables_store_key($storeKey)) {
|
||||
return cc_test_compare_recoverables_orders_desc($a, $b);
|
||||
}
|
||||
|
||||
if ($aImport !== $bImport) {
|
||||
return $bImport <=> $aImport;
|
||||
}
|
||||
@ -991,9 +1005,7 @@ try {
|
||||
$aSourceRow = (int) ($a['source_row'] ?? 0);
|
||||
$bSourceRow = (int) ($b['source_row'] ?? 0);
|
||||
if ($aSourceRow !== $bSourceRow) {
|
||||
return cc_test_is_tuani_recoverables_store_key($storeKey)
|
||||
? ($aSourceRow <=> $bSourceRow)
|
||||
: ($bSourceRow <=> $aSourceRow);
|
||||
return $bSourceRow <=> $aSourceRow;
|
||||
}
|
||||
|
||||
$aId = (int) ($a['id'] ?? 0);
|
||||
@ -1354,6 +1366,14 @@ require_once 'layout_header.php';
|
||||
<div class="d-flex flex-column flex-xl-row justify-content-between align-items-xl-center gap-3">
|
||||
<div>
|
||||
<h1 class="h2 fw-bold mb-1"><i class="bi bi-headset text-primary"></i> <?php echo htmlspecialchars($callCenterSectionLabel); ?></h1>
|
||||
<div class="d-flex flex-wrap gap-2 mt-2">
|
||||
<span class="badge rounded-pill bg-primary-subtle text-primary-emphasis border px-3 py-2">Tienda activa: <?php echo htmlspecialchars($storeLabel); ?></span>
|
||||
<?php if ($isTuaniRecuperablesStore): ?>
|
||||
<span class="badge rounded-pill bg-success-subtle text-success-emphasis border px-3 py-2">Solo pedidos válidos: IDs #D...</span>
|
||||
<?php else: ?>
|
||||
<a href="<?php echo htmlspecialchars(cc_test_build_url('call_center_pro.php', ['store' => 'tuani_recuperables', 'view' => 'todos'])); ?>" class="btn btn-sm btn-outline-success">Abrir Carritos recuperables (#D...)</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="d-flex flex-wrap gap-2 mt-3">
|
||||
<?php if ($isAdmin): ?>
|
||||
<a href="<?php echo htmlspecialchars(cc_test_build_url('gestiones_callcenter.php', $callCenterDatabaseParams)); ?>" class="btn btn-sm btn-outline-primary">Base de Datos Pedidos</a>
|
||||
|
||||
@ -214,11 +214,10 @@ function cc_test_followup_semaforo(array $order): ?array
|
||||
}
|
||||
|
||||
$defaultView = 'todos';
|
||||
$view = trim((string) ($_GET['view'] ?? $defaultView));
|
||||
$view = cc_test_resolve_callcenter_context_key($_GET['view'] ?? '', cc_test_callcenter_view_session_key());
|
||||
|
||||
$storeKey = trim((string) ($_GET['store'] ?? 'flower'));
|
||||
$storeKey = mb_strtolower($storeKey);
|
||||
$availableStores = drive_test_available_stores();
|
||||
$storeKey = cc_test_resolve_callcenter_context_key($_GET['store'] ?? '', cc_test_callcenter_store_session_key(), 'flower');
|
||||
if (!isset($availableStores[$storeKey])) {
|
||||
$storeKey = 'flower';
|
||||
}
|
||||
@ -234,6 +233,9 @@ $parentStoreLabel = (string) ($storeNav['parent_label'] ?? '');
|
||||
|
||||
$isMainTuaniStore = cc_test_is_tuani_main_store_key($storeKey);
|
||||
$isTuaniRecuperablesStore = $storeKey === 'tuani_recuperables';
|
||||
if ($isTuaniRecuperablesStore && trim((string) ($_GET['view'] ?? '')) === '') {
|
||||
$view = 'todos';
|
||||
}
|
||||
$canShowTuaniLogisticaButton = $isMainTuaniStore || $isTuaniRecuperablesStore;
|
||||
$viewCardColumnClass = $isTuaniRecuperablesStore ? 'col-md-6 col-xl-2' : 'col-md-6 col-xl-2';
|
||||
$callCenterDefaultView = ($isMainTuaniStore || $isTuaniRecuperablesStore) ? cc_test_callcenter_pro_default_view_key($storeKey) : $view;
|
||||
@ -347,7 +349,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: <strong>Carritos recuperables</strong>, <strong>Seguimiento</strong>, <strong>Observados</strong>, <strong>Confirmados</strong>, <strong>Recuperados</strong> y <strong>Todos</strong>. 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 <strong>TUANI principal</strong>, se marca en gris como <strong>Pedido repetido en tienda</strong> solo en esta bandeja. La vista <strong>Todos</strong> arranca en la fila 2000 y se pagina en bloques de 200 pedidos.'
|
||||
? 'Estados disponibles: <strong>Carritos recuperables</strong>, <strong>Seguimiento</strong>, <strong>Observados</strong>, <strong>Confirmados</strong>, <strong>Recuperados</strong> y <strong>Todos</strong>. 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 <strong>TUANI principal</strong>, se marca en gris como <strong>Pedido repetido en tienda</strong> solo en esta bandeja. Las vistas <strong>Carritos recuperables</strong> y <strong>Todos</strong> arrancan en la fila 2000, solo toman pedidos desde esa fila y se ordenan por el número <strong>#D</strong> 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. <strong>Promo Final</strong> 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 <strong>Todos</strong> y <strong>Últimos 4 días hábiles</strong>, la llamada y la gestión siguen disponibles desde el panel.';
|
||||
|
||||
$errorMessage = null;
|
||||
@ -399,6 +401,7 @@ $advisorOpenCounts = [];
|
||||
$advisorTotalCounts = [];
|
||||
$recommendedAssessorKey = null;
|
||||
$startRow = (int) ($storeConfig['startRow'] ?? 0);
|
||||
$recoverablesMinimumSourceRow = $isTuaniRecuperablesStore ? (int) ($storeConfig['startRow'] ?? 0) : 0;
|
||||
$catalogoProductos = [];
|
||||
$stats = [
|
||||
'total' => 0,
|
||||
@ -488,6 +491,9 @@ try {
|
||||
$orders = array_values(array_filter($orders, static function (array $order): bool {
|
||||
return empty($order['eliminado']);
|
||||
}));
|
||||
if ($isTuaniRecuperablesStore) {
|
||||
$orders = cc_test_filter_recoverables_orders($orders, $recoverablesMinimumSourceRow);
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'assign_assessor') {
|
||||
$sourceKey = trim((string) ($_POST['source_key'] ?? ''));
|
||||
@ -1095,6 +1101,10 @@ try {
|
||||
$aImport = cc_test_import_time($a);
|
||||
$bImport = cc_test_import_time($b);
|
||||
|
||||
if (cc_test_is_tuani_recoverables_store_key($storeKey) && in_array($view, ['pendientes_hoy', 'todos'], true)) {
|
||||
return cc_test_compare_recoverables_orders_desc($a, $b);
|
||||
}
|
||||
|
||||
if ($view === 'promo_final') {
|
||||
$aDays = (int) ($a['dias_seguimiento'] ?? 0);
|
||||
$bDays = (int) ($b['dias_seguimiento'] ?? 0);
|
||||
@ -1169,6 +1179,10 @@ try {
|
||||
}
|
||||
|
||||
if ($view === 'todos') {
|
||||
if (cc_test_is_tuani_recoverables_store_key($storeKey)) {
|
||||
return cc_test_compare_recoverables_orders_desc($a, $b);
|
||||
}
|
||||
|
||||
if ($aImport !== $bImport) {
|
||||
return $bImport <=> $aImport;
|
||||
}
|
||||
@ -1176,9 +1190,7 @@ try {
|
||||
$aSourceRow = (int) ($a['source_row'] ?? 0);
|
||||
$bSourceRow = (int) ($b['source_row'] ?? 0);
|
||||
if ($aSourceRow !== $bSourceRow) {
|
||||
return cc_test_is_tuani_recoverables_store_key($storeKey)
|
||||
? ($aSourceRow <=> $bSourceRow)
|
||||
: ($bSourceRow <=> $aSourceRow);
|
||||
return $bSourceRow <=> $aSourceRow;
|
||||
}
|
||||
|
||||
$aId = (int) ($a['id'] ?? 0);
|
||||
@ -1610,6 +1622,14 @@ require_once 'layout_header.php';
|
||||
<div class="d-flex flex-column flex-xl-row justify-content-between align-items-xl-center gap-3">
|
||||
<div>
|
||||
<h1 class="h2 fw-bold mb-1"><i class="bi bi-headset text-primary"></i> Base de Datos Pedidos</h1>
|
||||
<div class="d-flex flex-wrap gap-2 mt-2">
|
||||
<span class="badge rounded-pill bg-primary-subtle text-primary-emphasis border px-3 py-2">Tienda activa: <?php echo htmlspecialchars($storeLabel); ?></span>
|
||||
<?php if ($isTuaniRecuperablesStore): ?>
|
||||
<span class="badge rounded-pill bg-success-subtle text-success-emphasis border px-3 py-2">Solo pedidos válidos: IDs #D...</span>
|
||||
<?php else: ?>
|
||||
<a href="<?php echo htmlspecialchars(cc_test_build_url('gestiones_callcenter.php', ['store' => 'tuani_recuperables', 'view' => 'todos'])); ?>" class="btn btn-sm btn-outline-success">Abrir Carritos recuperables (#D...)</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="d-flex flex-wrap gap-2 mt-3">
|
||||
<a href="<?php echo htmlspecialchars(cc_test_build_url('gestiones_callcenter.php', array_merge(['view' => 'pendientes_hoy', 'store' => $storeKey], $persistedAssessorParams))); ?>" class="btn btn-sm <?php echo $view !== 'todos' ? 'btn-primary' : 'btn-outline-primary'; ?>">Bandeja principal</a>
|
||||
<a href="<?php echo htmlspecialchars(cc_test_build_url('call_center_pro.php', array_merge(['view' => $callCenterDefaultView, 'store' => $storeKey], $persistedAssessorParams))); ?>" class="btn btn-sm btn-outline-dark"><?php echo htmlspecialchars($callCenterSectionLabel); ?></a>
|
||||
|
||||
@ -1065,6 +1065,88 @@ function cc_test_normalize_context_key(?string $value): string
|
||||
return mb_strtolower($value);
|
||||
}
|
||||
|
||||
function cc_test_resolve_callcenter_context_key(?string $incomingValue, string $sessionKey, string $fallback = ''): string
|
||||
{
|
||||
$incomingValue = cc_test_normalize_context_key($incomingValue ?? '');
|
||||
if ($incomingValue !== '') {
|
||||
return $incomingValue;
|
||||
}
|
||||
|
||||
$sessionValue = cc_test_normalize_context_key($_SESSION[$sessionKey] ?? '');
|
||||
if ($sessionValue !== '') {
|
||||
return $sessionValue;
|
||||
}
|
||||
|
||||
return cc_test_normalize_context_key($fallback);
|
||||
}
|
||||
|
||||
function cc_test_is_recoverables_order_code(?string $codigo): bool
|
||||
{
|
||||
$codigo = trim((string) $codigo);
|
||||
if ($codigo === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$codigo = ltrim($codigo, '#');
|
||||
return preg_match('/^D\d+$/i', $codigo) === 1;
|
||||
}
|
||||
|
||||
function cc_test_recoverables_order_sort_value(array $order): int
|
||||
{
|
||||
$codigo = trim((string) ($order['codigo'] ?? ''));
|
||||
if ($codigo !== '' && preg_match('/^#?D(\d+)$/i', $codigo, $matches) === 1) {
|
||||
return (int) ($matches[1] ?? 0);
|
||||
}
|
||||
|
||||
$sourceRow = (int) ($order['source_row'] ?? 0);
|
||||
if ($sourceRow > 0) {
|
||||
return $sourceRow;
|
||||
}
|
||||
|
||||
return (int) ($order['id'] ?? 0);
|
||||
}
|
||||
|
||||
function cc_test_filter_recoverables_orders(array $orders, int $minimumSourceRow = 0): array
|
||||
{
|
||||
$minimumSourceRow = max(0, $minimumSourceRow);
|
||||
|
||||
return array_values(array_filter($orders, static function (array $order) use ($minimumSourceRow): bool {
|
||||
if (!cc_test_is_recoverables_order_code($order['codigo'] ?? '')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$sourceRow = (int) ($order['source_row'] ?? 0);
|
||||
if ($minimumSourceRow > 0 && $sourceRow < $minimumSourceRow) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
|
||||
function cc_test_compare_recoverables_orders_desc(array $a, array $b): int
|
||||
{
|
||||
$aValue = cc_test_recoverables_order_sort_value($a);
|
||||
$bValue = cc_test_recoverables_order_sort_value($b);
|
||||
if ($aValue !== $bValue) {
|
||||
return $bValue <=> $aValue;
|
||||
}
|
||||
|
||||
$aSourceRow = (int) ($a['source_row'] ?? 0);
|
||||
$bSourceRow = (int) ($b['source_row'] ?? 0);
|
||||
if ($aSourceRow !== $bSourceRow) {
|
||||
return $bSourceRow <=> $aSourceRow;
|
||||
}
|
||||
|
||||
$aId = (int) ($a['id'] ?? 0);
|
||||
$bId = (int) ($b['id'] ?? 0);
|
||||
if ($aId !== $bId) {
|
||||
return $bId <=> $aId;
|
||||
}
|
||||
|
||||
return strcmp((string) ($a['source_key'] ?? ''), (string) ($b['source_key'] ?? ''));
|
||||
}
|
||||
|
||||
function cc_test_resolve_callcenter_assessor_filter(array $assessors, ?string $incomingFilter = null, bool $useSessionFallback = true, bool $persistSession = true): string
|
||||
{
|
||||
$sessionKey = cc_test_callcenter_assessor_filter_session_key();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user