diff --git a/call_center_pro.php b/call_center_pro.php
index 297a72fb..687cfd99 100644
--- a/call_center_pro.php
+++ b/call_center_pro.php
@@ -340,6 +340,9 @@ if ($isTuaniRecuperablesStore && trim((string) ($_GET['view'] ?? '')) === '') {
$view = 'todos';
}
$canShowTuaniLogisticaButton = $isMainTuaniStore || $isTuaniRecuperablesStore;
+$postedAction = trim((string) ($_POST['action'] ?? ''));
+$recoverablesResyncRequested = $isTuaniRecuperablesStore && $postedAction === 'reimport_recoverables_queue';
+$recoverablesResyncRow = $isTuaniRecuperablesStore ? (int) ($storeConfig['startRow'] ?? 2000) : null;
$viewCardColumnClass = $isTuaniRecuperablesStore ? 'col-md-6 col-xl-2' : 'col-md-6 col-xl-2';
$defaultView = cc_test_callcenter_pro_default_view_key($storeKey);
@@ -482,6 +485,7 @@ $lastProcessedRow = null;
$recoverablesImportCount = 0;
$recoverablesFirstSourceRow = null;
$recoverablesLastSourceRow = null;
+$recoverablesNotice = null;
$startRow = (int) ($storeConfig['startRow'] ?? 0);
$recoverablesMinimumSourceRow = $isTuaniRecuperablesStore ? (int) ($storeConfig['startRow'] ?? 0) : 0;
$catalogoProductos = [];
@@ -538,7 +542,7 @@ try {
}
if ($usesIncrementalSync) {
- $syncInfo = drive_test_sync_orders_incremental($pdo, $storeKey, 0);
+ $syncInfo = drive_test_sync_orders_incremental($pdo, $storeKey, 0, $recoverablesResyncRequested ? $recoverablesResyncRow : null);
$totalRows = (int) ($syncInfo['drive_rows_total'] ?? 0);
$lastProcessedRow = (int) ($syncInfo['last_processed_row'] ?? 0);
$startRow = (int) ($syncInfo['next_start_row'] ?? $startRow);
@@ -563,6 +567,10 @@ try {
}
}
+ if ($recoverablesResyncRequested) {
+ $noticeMessage = 'Reimportación desde fila ' . $recoverablesResyncRow . ' completada. La cola volvió a contrastarse sin duplicar pedidos ya cargados.';
+ }
+
$tracking = drive_test_fetch_tracking($pdo, array_column($orders, 'source_key'));
$orders = drive_test_merge_tracking($orders, $tracking);
$orders = array_values(array_filter($orders, static function (array $order): bool {
@@ -573,6 +581,18 @@ try {
}));
if ($isTuaniRecuperablesStore) {
$orders = cc_test_filter_recoverables_orders($orders, $recoverablesMinimumSourceRow);
+ $recoverablesSummary = cc_test_recoverables_summary($orders);
+ if ($recoverablesSummary !== null) {
+ $recoverablesImportCount = (int) ($recoverablesSummary['import_count'] ?? count($orders));
+ $recoverablesFirstSourceRow = $recoverablesSummary['first_source_row'] !== null ? (int) $recoverablesSummary['first_source_row'] : null;
+ $recoverablesLastSourceRow = $recoverablesSummary['last_source_row'] !== null ? (int) $recoverablesSummary['last_source_row'] : null;
+ $recoverablesNotice = $recoverablesSummary['notice'] ?? null;
+ } else {
+ $recoverablesImportCount = count($orders);
+ $recoverablesFirstSourceRow = null;
+ $recoverablesLastSourceRow = null;
+ $recoverablesNotice = null;
+ }
}
$postedAction = trim((string) ($_POST['action'] ?? ''));
@@ -1069,26 +1089,6 @@ try {
? '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.'
: '';
- if ($isTuaniRecuperablesStore) {
- $recoverablesImportCount = count($orders);
- $recoverablesFirstSourceRow = null;
- $recoverablesLastSourceRow = null;
-
- foreach ($orders as $recoverablesOrder) {
- $recoverablesSourceRow = (int) ($recoverablesOrder['source_row'] ?? 0);
- if ($recoverablesSourceRow <= 0) {
- continue;
- }
-
- if ($recoverablesFirstSourceRow === null || $recoverablesSourceRow < $recoverablesFirstSourceRow) {
- $recoverablesFirstSourceRow = $recoverablesSourceRow;
- }
- if ($recoverablesLastSourceRow === null || $recoverablesSourceRow > $recoverablesLastSourceRow) {
- $recoverablesLastSourceRow = $recoverablesSourceRow;
- }
- }
- }
-
$visibleOrdersTotalCount = count($visibleOrders);
$todosPageSize = 200;
$todosPage = 1;
@@ -1435,10 +1435,17 @@ require_once 'layout_header.php';
Drive detectado: filas
Agregados:
-
: distribución desde fila · último procesado Extracción: desde fila
+
: última fila del Drive · último pedido : distribución desde fila · último procesado Extracción: desde fila
Actualización en vivo cada 5 min
Ver vista previa Drive
Actualizar pedidos
+
+
+
@@ -1490,6 +1497,25 @@ require_once 'layout_header.php';
+
+
+
+
+
Aviso rápido
+
+ Última fila real del Drive:
+
+ · Último pedido detectado:
+
+
+
+
+ Te ayuda a comprobar de un vistazo si la cola llegó al final.
+
+
+
+
+
diff --git a/gestiones_callcenter.php b/gestiones_callcenter.php
index 8cb6d296..09a2f75c 100644
--- a/gestiones_callcenter.php
+++ b/gestiones_callcenter.php
@@ -237,6 +237,9 @@ if ($isTuaniRecuperablesStore && trim((string) ($_GET['view'] ?? '')) === '') {
$view = 'todos';
}
$canShowTuaniLogisticaButton = $isMainTuaniStore || $isTuaniRecuperablesStore;
+$postedAction = trim((string) ($_POST['action'] ?? ''));
+$recoverablesResyncRequested = $isTuaniRecuperablesStore && $postedAction === 'reimport_recoverables_queue';
+$recoverablesResyncRow = $isTuaniRecuperablesStore ? (int) ($storeConfig['startRow'] ?? 2000) : null;
$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;
@@ -374,6 +377,7 @@ $lastProcessedRow = null;
$recoverablesImportCount = 0;
$recoverablesFirstSourceRow = null;
$recoverablesLastSourceRow = null;
+$recoverablesNotice = null;
$selectedAssessorFilter = '';
$selectedAssessorFilterLabel = '';
$persistedAssessorParams = [];
@@ -469,7 +473,7 @@ try {
}
if ($usesIncrementalSync) {
- $syncInfo = drive_test_sync_orders_incremental($pdo, $storeKey, 0);
+ $syncInfo = drive_test_sync_orders_incremental($pdo, $storeKey, 0, $recoverablesResyncRequested ? $recoverablesResyncRow : null);
$totalRows = (int) ($syncInfo['drive_rows_total'] ?? 0);
$lastProcessedRow = (int) ($syncInfo['last_processed_row'] ?? 0);
$startRow = (int) ($syncInfo['next_start_row'] ?? $startRow);
@@ -494,6 +498,10 @@ try {
}
}
+ if ($recoverablesResyncRequested) {
+ $noticeMessage = 'Reimportación desde fila ' . $recoverablesResyncRow . ' completada. La cola volvió a contrastarse sin duplicar pedidos ya cargados.';
+ }
+
$tracking = drive_test_fetch_tracking($pdo, array_column($orders, 'source_key'));
$orders = drive_test_merge_tracking($orders, $tracking);
$orders = array_values(array_filter($orders, static function (array $order): bool {
@@ -501,6 +509,18 @@ try {
}));
if ($isTuaniRecuperablesStore) {
$orders = cc_test_filter_recoverables_orders($orders, $recoverablesMinimumSourceRow);
+ $recoverablesSummary = cc_test_recoverables_summary($orders);
+ if ($recoverablesSummary !== null) {
+ $recoverablesImportCount = (int) ($recoverablesSummary['import_count'] ?? count($orders));
+ $recoverablesFirstSourceRow = $recoverablesSummary['first_source_row'] !== null ? (int) $recoverablesSummary['first_source_row'] : null;
+ $recoverablesLastSourceRow = $recoverablesSummary['last_source_row'] !== null ? (int) $recoverablesSummary['last_source_row'] : null;
+ $recoverablesNotice = $recoverablesSummary['notice'] ?? null;
+ } else {
+ $recoverablesImportCount = count($orders);
+ $recoverablesFirstSourceRow = null;
+ $recoverablesLastSourceRow = null;
+ $recoverablesNotice = null;
+ }
}
if ($_SERVER['REQUEST_METHOD'] === 'POST' && ($_POST['action'] ?? '') === 'assign_assessor') {
@@ -1237,26 +1257,6 @@ try {
return cc_test_order_time($b) <=> cc_test_order_time($a);
});
- if ($isTuaniRecuperablesStore) {
- $recoverablesImportCount = count($orders);
- $recoverablesFirstSourceRow = null;
- $recoverablesLastSourceRow = null;
-
- foreach ($orders as $recoverablesOrder) {
- $recoverablesSourceRow = (int) ($recoverablesOrder['source_row'] ?? 0);
- if ($recoverablesSourceRow <= 0) {
- continue;
- }
-
- if ($recoverablesFirstSourceRow === null || $recoverablesSourceRow < $recoverablesFirstSourceRow) {
- $recoverablesFirstSourceRow = $recoverablesSourceRow;
- }
- if ($recoverablesLastSourceRow === null || $recoverablesSourceRow > $recoverablesLastSourceRow) {
- $recoverablesLastSourceRow = $recoverablesSourceRow;
- }
- }
- }
-
$visibleOrdersTotalCount = count($visibleOrders);
$todosPageSize = 200;
$todosPage = 1;
@@ -1689,7 +1689,7 @@ require_once 'layout_header.php';
Drive detectado: filas
Agregados:
-
: distribución desde fila · último procesado Extracción: desde fila
+
: última fila del Drive · último pedido : distribución desde fila · último procesado Extracción: desde fila
Actualización manual
Asesora:
@@ -1697,6 +1697,13 @@ require_once 'layout_header.php';
Ver vista previa Drive
Actualizar pedidos
+
+
+
@@ -1713,6 +1720,25 @@ require_once 'layout_header.php';
+
+
+
+
+
Aviso rápido
+
+ Última fila real del Drive:
+
+ · Último pedido detectado:
+
+
+
+
+ Te ayuda a comprobar de un vistazo si la cola llegó al final.
+
+
+
+
+
diff --git a/includes/callcenter_test_helpers.php b/includes/callcenter_test_helpers.php
index 402701af..f39500b5 100644
--- a/includes/callcenter_test_helpers.php
+++ b/includes/callcenter_test_helpers.php
@@ -1147,6 +1147,70 @@ function cc_test_compare_recoverables_orders_desc(array $a, array $b): int
return strcmp((string) ($a['source_key'] ?? ''), (string) ($b['source_key'] ?? ''));
}
+function cc_test_recoverables_summary(array $orders): ?array
+{
+ $importCount = count($orders);
+ $firstSourceRow = null;
+ $lastSourceRow = null;
+ $latestOrder = null;
+ $latestRow = null;
+
+ foreach ($orders as $order) {
+ $sourceRow = (int) ($order['source_row'] ?? 0);
+ if ($sourceRow <= 0) {
+ continue;
+ }
+
+ if ($firstSourceRow === null || $sourceRow < $firstSourceRow) {
+ $firstSourceRow = $sourceRow;
+ }
+ if ($lastSourceRow === null || $sourceRow > $lastSourceRow) {
+ $lastSourceRow = $sourceRow;
+ }
+
+ if ($latestRow === null || $sourceRow > $latestRow) {
+ $latestRow = $sourceRow;
+ $latestOrder = $order;
+ continue;
+ }
+
+ if ($latestOrder !== null && $sourceRow === $latestRow) {
+ $currentValue = cc_test_recoverables_order_sort_value($order);
+ $bestValue = cc_test_recoverables_order_sort_value($latestOrder);
+ if ($currentValue > $bestValue) {
+ $latestOrder = $order;
+ }
+ }
+ }
+
+ $notice = null;
+ if ($latestRow !== null) {
+ $label = 'Sin pedido detectado';
+ if ($latestOrder !== null) {
+ $codigo = trim((string) ($latestOrder['codigo'] ?? ''));
+ if ($codigo !== '') {
+ $label = '#' . ltrim($codigo, '#');
+ } elseif (!empty($latestOrder['is_agregado'])) {
+ $label = 'AGREGADOS';
+ } else {
+ $label = 'Sin número';
+ }
+ }
+
+ $notice = [
+ 'row_label' => (string) $latestRow,
+ 'label' => $label,
+ ];
+ }
+
+ return [
+ 'import_count' => $importCount,
+ 'first_source_row' => $firstSourceRow,
+ 'last_source_row' => $lastSourceRow,
+ 'notice' => $notice,
+ ];
+}
+
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();
diff --git a/includes/drive_test_orders.php b/includes/drive_test_orders.php
index 19ecdc59..9433ca7b 100644
--- a/includes/drive_test_orders.php
+++ b/includes/drive_test_orders.php
@@ -45,13 +45,19 @@ function drive_test_available_stores(): array
'delivery_sync_start_row' => 7291,
'delivery_sync_column' => 'W',
],
- // Bandeja compartida de carritos recuperables: misma estructura, pero desde la fila 2000.
+ // Bandeja compartida de carritos recuperables/abandonados: misma estructura, pero desde la fila 2000.
'tuani_recuperables' => [
'label' => 'Carritos recuperables',
'sheet_title' => 'easysell_abandoneds',
'spreadsheet_id' => '1QYKeBJIIqYm6yW6Ka-5gKdxhUHwXOAc0No7RjnimxTw',
'sheet_gid' => 965530888,
'startRow' => 2000,
+ 'status_sync_start_row' => 2000,
+ 'status_sync_column' => 'V',
+ 'advisor_sync_start_row' => 2000,
+ 'advisor_sync_column' => 'X',
+ 'delivery_sync_start_row' => 2000,
+ 'delivery_sync_column' => 'W',
'enforce_db_start_row' => true,
'incremental_sync' => true,
],
@@ -902,11 +908,12 @@ function drive_test_ensure_import_checkpoints_table(PDO $pdo): void
$checked = true;
}
-function drive_test_sync_orders_incremental(PDO $pdo, string $storeKey, int $overlapRows = 50): array
+function drive_test_sync_orders_incremental(PDO $pdo, string $storeKey, int $overlapRows = 50, ?int $forcedStartRow = null): array
{
$storeKey = mb_strtolower(trim($storeKey));
$storeConfig = drive_test_get_store_config($storeKey);
$baselineStartRow = (int) ($storeConfig['startRow'] ?? 0);
+ $forcedStartRow = $forcedStartRow !== null && $forcedStartRow > 0 ? $forcedStartRow : null;
drive_test_ensure_orders_table($pdo);
drive_test_ensure_import_checkpoints_table($pdo);
@@ -920,19 +927,21 @@ function drive_test_sync_orders_incremental(PDO $pdo, string $storeKey, int $ove
$storedBaselineStartRow = (int) ($checkpointData['baseline_start_row'] ?? 0);
$overlapRows = max(0, $overlapRows);
- $mustResetToBaseline = $storedBaselineStartRow !== $baselineStartRow;
- $effectiveStartRow = $mustResetToBaseline
- ? $baselineStartRow
- : ($checkpointRow > 0
- ? max($baselineStartRow, $checkpointRow - $overlapRows + 1)
- : $baselineStartRow);
+ $mustResetToBaseline = $forcedStartRow !== null || $storedBaselineStartRow !== $baselineStartRow;
+ $effectiveStartRow = $forcedStartRow !== null
+ ? $forcedStartRow
+ : ($mustResetToBaseline
+ ? $baselineStartRow
+ : ($checkpointRow > 0
+ ? max($baselineStartRow, $checkpointRow - $overlapRows + 1)
+ : $baselineStartRow));
$preview = drive_test_fetch_orders(0, $effectiveStartRow, $storeKey);
$driveOrders = $preview['orders'] ?? [];
$driveTotalRows = (int) ($preview['total_rows'] ?? 0);
$sheetLastRow = ($effectiveStartRow - 1) + $driveTotalRows;
- $newCheckpointRow = $mustResetToBaseline
+ $newCheckpointRow = ($forcedStartRow !== null || $mustResetToBaseline)
? (int) $sheetLastRow
: max($checkpointRow, (int) $sheetLastRow);