Call Center de prueba
+Este panel usa solo los últimos 10 registros de Importar Drive (Test) para confirmar pedidos sin tocar pedidos reales.
+diff --git a/db/migrations/073_create_callcenter_test_tracking_table.sql b/db/migrations/073_create_callcenter_test_tracking_table.sql new file mode 100644 index 00000000..2df8af09 --- /dev/null +++ b/db/migrations/073_create_callcenter_test_tracking_table.sql @@ -0,0 +1,11 @@ +CREATE TABLE IF NOT EXISTS `callcenter_test_tracking` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `source_key` CHAR(40) NOT NULL, + `estado` VARCHAR(40) NOT NULL DEFAULT 'POR LLAMAR', + `nota_seguimiento` TEXT NULL, + `user_id` INT NULL, + `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `uniq_callcenter_test_tracking_source_key` (`source_key`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/gestiones_callcenter.php b/gestiones_callcenter.php index d3f1f0b6..934c3c13 100644 --- a/gestiones_callcenter.php +++ b/gestiones_callcenter.php @@ -1,301 +1,475 @@ prepare("SELECT - COUNT(*) as total, - SUM(CASE WHEN estado = 'Gestion' THEN 1 ELSE 0 END) as pendientes, - SUM(CASE WHEN estado = 'NO CONTESTO, DEVOLVER LLAMADA' THEN 1 ELSE 0 END) as reintentos, - SUM(CASE WHEN estado = 'COMPLETADO ✅' THEN 1 ELSE 0 END) as cerrados -FROM pedidos WHERE asesor_id = ?"); -$stmt_stats->execute([$mi_id_asesora]); -$stats = $stmt_stats->fetch(PDO::FETCH_ASSOC); - -// 2. Determinar qué vista mostrar $view = $_GET['view'] ?? 'pendientes'; -$where_clause = "AND estado = 'Gestion'"; -$titulo_tabla = "Pedidos Pendientes de Atención"; +$allowedViews = [ + 'pendientes' => ['estado' => 'POR LLAMAR', 'titulo' => 'Pedidos por llamar'], + 'reintentos' => ['estado' => 'REINTENTO', 'titulo' => 'Pedidos en reintento'], + 'confirmados' => ['estado' => 'CONFIRMADO', 'titulo' => 'Pedidos confirmados'], + 'todos' => ['estado' => null, 'titulo' => 'Todos los pedidos de prueba'], +]; -if ($view === 'reintentos') { - $where_clause = "AND estado = 'NO CONTESTO, DEVOLVER LLAMADA'"; - $titulo_tabla = "Reintentos (No contestaron)"; -} elseif ($view === 'cerrados') { - $where_clause = "AND estado = 'COMPLETADO ✅'"; - $titulo_tabla = "Ventas Cerradas (Confirmadas)"; -} elseif ($view === 'todos') { - $where_clause = ""; - $titulo_tabla = "Todos mis Pedidos Asignados"; +if (!isset($allowedViews[$view])) { + $view = 'pendientes'; } -// 3. Obtener la lista de pedidos según el filtro -$stmt_pedidos = $db->prepare("SELECT * FROM pedidos - WHERE asesor_id = ? - $where_clause - ORDER BY created_at DESC"); -$stmt_pedidos->execute([$mi_id_asesora]); -$pedidos = $stmt_pedidos->fetchAll(PDO::FETCH_ASSOC); +$errorMessage = null; +$orders = []; +$stats = [ + 'total' => 0, + 'pendientes' => 0, + 'reintentos' => 0, + 'confirmados' => 0, +]; +$visibleOrders = []; +$totalRows = 0; -include 'layout_header.php'; +try { + $preview = drive_test_fetch_orders(10); + $totalRows = (int) ($preview['total_rows'] ?? 0); + $orders = $preview['orders'] ?? []; + + $tracking = drive_test_fetch_tracking(db(), array_column($orders, 'source_key')); + $orders = drive_test_merge_tracking($orders, $tracking); + + // Obtener conteo de llamadas + $sourceKeys = array_column($orders, 'source_key'); + $callCounts = []; + if (!empty($sourceKeys)) { + $placeholders = implode(',', array_fill(0, count($sourceKeys), '?')); + $stmtCalls = db()->prepare("SELECT pedido_id, COUNT(*) as total FROM historial_llamadas WHERE pedido_id IN ($placeholders) GROUP BY pedido_id"); + $stmtCalls->execute($sourceKeys); + $callCounts = $stmtCalls->fetchAll(PDO::FETCH_KEY_PAIR); + } + + foreach ($orders as &$order) { + $order['total_llamadas'] = $callCounts[$order['source_key']] ?? 0; + $stats['total']++; + if ($order['estado'] === 'POR LLAMAR') { + $stats['pendientes']++; + } elseif ($order['estado'] === 'REINTENTO') { + $stats['reintentos']++; + } elseif ($order['estado'] === 'CONFIRMADO') { + $stats['confirmados']++; + } + } + + $expectedState = $allowedViews[$view]['estado']; + if ($expectedState === null) { + $visibleOrders = $orders; + } else { + $visibleOrders = array_values(array_filter($orders, static function (array $order) use ($expectedState): bool { + return ($order['estado'] ?? '') === $expectedState; + })); + } +} catch (Throwable $exception) { + $errorMessage = $exception->getMessage(); +} + +function cc_test_badge_class(string $estado): string +{ + return match ($estado) { + 'CONFIRMADO' => 'bg-success-subtle text-success-emphasis', + 'REINTENTO' => 'bg-info-subtle text-info-emphasis', + default => 'bg-warning-subtle text-warning-emphasis', + }; +} + +function cc_test_display_value(?string $value, string $fallback = 'No registrado'): string +{ + $value = trim((string) $value); + return $value !== '' ? $value : $fallback; +} + +function cc_test_format_price(?string $value): string +{ + $value = trim((string) $value); + return $value !== '' ? 'S/ ' . $value : 'No registrado'; +} + +function cc_test_format_drive_datetime(?string $value): string +{ + $value = trim((string) $value); + if ($value === '') { + return 'No registrada'; + } + + try { + return (new DateTimeImmutable($value))->format('d/m/Y h:i A'); + } catch (Throwable $exception) { + return $value; + } +} + +require_once 'layout_header.php'; ?> -
Haz clic en las tarjetas para filtrar los pedidos por estado.
+Este panel usa solo los últimos 10 registros de Importar Drive (Test) para confirmar pedidos sin tocar pedidos reales.
+| Cliente / Celular | -Ubicación | -Producto | -Monto | -Estado Actual | -Acciones de Gestión | -|||||
|---|---|---|---|---|---|---|---|---|---|---|
| - - No hay pedidos en esta categoría. - | +Cliente y contacto | +Ubicación | +Pedido | +Seguimiento | +Acciones | |||||
|---|---|---|---|---|---|---|---|---|---|---|
|
-
- DNI:
-
-
-
+ | + + No hay pedidos en esta vista del módulo de prueba. | -
-
-
-
-
- |
-
-
- Cant:
- |
- - S/ - | -- - - - - | -
-
-
-
-
+ | ||||
|
+
+ Pedido:
+ Drive:
+ DNI:
+
+
+
+
+
+ Celular: No registrado
-
-
-
-
-
+ |
+
+
+
+ Ref.:
+ ·
+
+ Ver ubicación
+
+ |
+
+
+ Cantidad: · Precio:
+ Método:
+ Sede / ID:
+ |
+
+
+ 0): ?>
+
+
+ llamadas
+
+
+
+ Obs. Drive:
+ Nota interna:
+ |
+
+
+
+
+
+ Llamar
+
+
+
+
+ WhatsApp
+
+
+
+ |
+ ||||||