539 lines
19 KiB
PHP
539 lines
19 KiB
PHP
<?php
|
|
require_once __DIR__ . '/drive_test_orders.php';
|
|
|
|
function cc_test_allowed_states(): array
|
|
{
|
|
return [
|
|
'POR LLAMAR',
|
|
'NO CONTESTA',
|
|
'DEVOLVER LLAMADA',
|
|
'REPROGRAMADO',
|
|
'CONFIRMADO',
|
|
'NO INTERESADO',
|
|
'NUMERO EQUIVOCADO',
|
|
'DUPLICADO',
|
|
];
|
|
}
|
|
|
|
function cc_test_open_states(): array
|
|
{
|
|
return ['POR LLAMAR', 'NO CONTESTA', 'DEVOLVER LLAMADA', 'REPROGRAMADO'];
|
|
}
|
|
|
|
function cc_test_closed_states(): array
|
|
{
|
|
return ['NO INTERESADO', 'NUMERO EQUIVOCADO', 'DUPLICADO'];
|
|
}
|
|
|
|
function cc_test_state_badge_class(string $estado): string
|
|
{
|
|
return match ($estado) {
|
|
'CONFIRMADO' => 'bg-success-subtle text-success-emphasis',
|
|
'DEVOLVER LLAMADA', 'REPROGRAMADO' => 'bg-info-subtle text-info-emphasis',
|
|
'NO CONTESTA' => 'bg-secondary-subtle text-secondary-emphasis',
|
|
'NO INTERESADO', 'NUMERO EQUIVOCADO', 'DUPLICADO' => 'bg-danger-subtle text-danger-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_parse_datetime(?string $value): ?string
|
|
{
|
|
$value = trim((string) $value);
|
|
if ($value === '') {
|
|
return null;
|
|
}
|
|
|
|
$formats = [
|
|
'Y-m-d\\TH:i',
|
|
'Y-m-d H:i:s',
|
|
'Y-m-d H:i',
|
|
DateTimeInterface::ATOM,
|
|
'Y-m-d',
|
|
];
|
|
|
|
foreach ($formats as $format) {
|
|
$date = DateTimeImmutable::createFromFormat($format, $value);
|
|
if ($date instanceof DateTimeImmutable) {
|
|
return $date->format('Y-m-d H:i:s');
|
|
}
|
|
}
|
|
|
|
try {
|
|
return (new DateTimeImmutable($value))->format('Y-m-d H:i:s');
|
|
} catch (Throwable $exception) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function cc_test_format_datetime(?string $value, string $fallback = 'Sin programar'): string
|
|
{
|
|
$parsed = cc_test_parse_datetime($value);
|
|
if ($parsed === null) {
|
|
return $fallback;
|
|
}
|
|
|
|
try {
|
|
return (new DateTimeImmutable($parsed))->format('d/m/Y h:i A');
|
|
} catch (Throwable $exception) {
|
|
return $fallback;
|
|
}
|
|
}
|
|
|
|
function cc_test_format_datetime_local(?string $value): string
|
|
{
|
|
$parsed = cc_test_parse_datetime($value);
|
|
if ($parsed === null) {
|
|
return '';
|
|
}
|
|
|
|
try {
|
|
return (new DateTimeImmutable($parsed))->format('Y-m-d\\TH:i');
|
|
} catch (Throwable $exception) {
|
|
return '';
|
|
}
|
|
}
|
|
|
|
function cc_test_table_exists(PDO $pdo, string $tableName): bool
|
|
{
|
|
static $cache = [];
|
|
|
|
if (array_key_exists($tableName, $cache)) {
|
|
return $cache[$tableName];
|
|
}
|
|
|
|
$stmt = $pdo->prepare('SHOW TABLES LIKE ?');
|
|
$stmt->execute([$tableName]);
|
|
$cache[$tableName] = (bool) $stmt->fetchColumn();
|
|
|
|
return $cache[$tableName];
|
|
}
|
|
|
|
function cc_test_column_exists(PDO $pdo, string $tableName, string $columnName): bool
|
|
{
|
|
static $cache = [];
|
|
$cacheKey = $tableName . '.' . $columnName;
|
|
|
|
if (array_key_exists($cacheKey, $cache)) {
|
|
return $cache[$cacheKey];
|
|
}
|
|
|
|
$stmt = $pdo->prepare("SHOW COLUMNS FROM `{$tableName}` LIKE ?");
|
|
$stmt->execute([$columnName]);
|
|
$cache[$cacheKey] = (bool) $stmt->fetchColumn();
|
|
|
|
return $cache[$cacheKey];
|
|
}
|
|
|
|
function cc_test_add_column_if_missing(PDO $pdo, string $tableName, string $columnName, string $definition): void
|
|
{
|
|
if (!cc_test_column_exists($pdo, $tableName, $columnName)) {
|
|
$pdo->exec("ALTER TABLE `{$tableName}` ADD COLUMN `{$columnName}` {$definition}");
|
|
}
|
|
}
|
|
|
|
function cc_test_ensure_schema(PDO $pdo): void
|
|
{
|
|
static $checked = false;
|
|
if ($checked) {
|
|
return;
|
|
}
|
|
|
|
$pdo->exec("CREATE TABLE IF NOT EXISTS `callcenter_test_orders` (
|
|
`id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
|
`source_key` CHAR(40) NOT NULL,
|
|
`codigo` VARCHAR(80) DEFAULT NULL,
|
|
`import_id` VARCHAR(120) DEFAULT NULL,
|
|
`drive_imported_at` DATETIME NULL,
|
|
`nombre` VARCHAR(255) DEFAULT NULL,
|
|
`direccion_drive` TEXT NULL,
|
|
`referencia_drive` TEXT NULL,
|
|
`sede_drive` VARCHAR(120) NULL,
|
|
`ciudad_drive` VARCHAR(120) NULL,
|
|
`distrito_drive` VARCHAR(120) NULL,
|
|
`dni_drive` VARCHAR(40) NULL,
|
|
`observaciones_drive` TEXT NULL,
|
|
`celular` VARCHAR(40) DEFAULT NULL,
|
|
`producto` TEXT NULL,
|
|
`cantidad` VARCHAR(60) NULL,
|
|
`precio` VARCHAR(60) NULL,
|
|
`pais` VARCHAR(80) NULL,
|
|
`coordenadas` VARCHAR(255) NULL,
|
|
`metodo` VARCHAR(120) NULL,
|
|
`first_seen_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
`last_seen_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
UNIQUE KEY `uniq_callcenter_test_orders_source_key` (`source_key`),
|
|
KEY `idx_callcenter_test_orders_drive_imported_at` (`drive_imported_at`),
|
|
KEY `idx_callcenter_test_orders_last_seen_at` (`last_seen_at`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci");
|
|
|
|
$pdo->exec("CREATE TABLE IF NOT EXISTS `callcenter_test_tracking` (
|
|
`id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
|
`source_key` CHAR(40) NOT NULL,
|
|
`estado` VARCHAR(40) NOT NULL DEFAULT 'POR LLAMAR',
|
|
`nota_seguimiento` TEXT NULL,
|
|
`proxima_llamada` DATETIME NULL,
|
|
`fecha_ultimo_contacto` DATETIME NULL,
|
|
`direccion_editada` TEXT NULL,
|
|
`referencia_editada` TEXT NULL,
|
|
`sede_editada` VARCHAR(120) NULL,
|
|
`ciudad_editada` VARCHAR(120) NULL,
|
|
`distrito_editado` VARCHAR(120) NULL,
|
|
`dni_editado` VARCHAR(40) NULL,
|
|
`observaciones_editadas` 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,
|
|
UNIQUE KEY `uniq_callcenter_test_tracking_source_key` (`source_key`),
|
|
KEY `idx_callcenter_test_tracking_estado` (`estado`),
|
|
KEY `idx_callcenter_test_tracking_proxima` (`proxima_llamada`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci");
|
|
|
|
cc_test_add_column_if_missing($pdo, 'callcenter_test_tracking', 'proxima_llamada', 'DATETIME NULL AFTER `nota_seguimiento`');
|
|
cc_test_add_column_if_missing($pdo, 'callcenter_test_tracking', 'fecha_ultimo_contacto', 'DATETIME NULL AFTER `proxima_llamada`');
|
|
cc_test_add_column_if_missing($pdo, 'callcenter_test_tracking', 'direccion_editada', 'TEXT NULL AFTER `fecha_ultimo_contacto`');
|
|
cc_test_add_column_if_missing($pdo, 'callcenter_test_tracking', 'referencia_editada', 'TEXT NULL AFTER `direccion_editada`');
|
|
cc_test_add_column_if_missing($pdo, 'callcenter_test_tracking', 'sede_editada', 'VARCHAR(120) NULL AFTER `referencia_editada`');
|
|
cc_test_add_column_if_missing($pdo, 'callcenter_test_tracking', 'ciudad_editada', 'VARCHAR(120) NULL AFTER `sede_editada`');
|
|
cc_test_add_column_if_missing($pdo, 'callcenter_test_tracking', 'distrito_editado', 'VARCHAR(120) NULL AFTER `ciudad_editada`');
|
|
cc_test_add_column_if_missing($pdo, 'callcenter_test_tracking', 'dni_editado', 'VARCHAR(40) NULL AFTER `distrito_editado`');
|
|
cc_test_add_column_if_missing($pdo, 'callcenter_test_tracking', 'observaciones_editadas', 'TEXT NULL AFTER `dni_editado`');
|
|
|
|
if (cc_test_table_exists($pdo, 'historial_llamadas')) {
|
|
cc_test_add_column_if_missing($pdo, 'historial_llamadas', 'pedido_id', 'VARCHAR(80) NULL');
|
|
cc_test_add_column_if_missing($pdo, 'historial_llamadas', 'asesor_id', 'INT NULL');
|
|
cc_test_add_column_if_missing($pdo, 'historial_llamadas', 'resultado', 'VARCHAR(120) NULL');
|
|
cc_test_add_column_if_missing($pdo, 'historial_llamadas', 'observacion', 'TEXT NULL');
|
|
cc_test_add_column_if_missing($pdo, 'historial_llamadas', 'fecha_llamada', 'DATETIME NULL DEFAULT CURRENT_TIMESTAMP');
|
|
} else {
|
|
$pdo->exec("CREATE TABLE IF NOT EXISTS `historial_llamadas` (
|
|
`id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
|
`pedido_id` VARCHAR(80) NOT NULL,
|
|
`asesor_id` INT NULL,
|
|
`resultado` VARCHAR(120) NOT NULL,
|
|
`observacion` TEXT NULL,
|
|
`fecha_llamada` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
INDEX `idx_historial_llamadas_pedido` (`pedido_id`),
|
|
INDEX `idx_historial_llamadas_asesor` (`asesor_id`),
|
|
INDEX `idx_historial_llamadas_fecha` (`fecha_llamada`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci");
|
|
}
|
|
|
|
$checked = true;
|
|
}
|
|
|
|
function cc_test_sync_orders_from_drive(PDO $pdo, int $limit = 250): array
|
|
{
|
|
cc_test_ensure_schema($pdo);
|
|
|
|
$preview = drive_test_fetch_orders($limit);
|
|
$orders = $preview['orders'] ?? [];
|
|
|
|
if (empty($orders)) {
|
|
return [
|
|
'synced_count' => 0,
|
|
'total_rows' => (int) ($preview['total_rows'] ?? 0),
|
|
];
|
|
}
|
|
|
|
$stmt = $pdo->prepare(
|
|
'INSERT INTO callcenter_test_orders (
|
|
source_key, codigo, import_id, drive_imported_at, nombre,
|
|
direccion_drive, referencia_drive, sede_drive, ciudad_drive, distrito_drive,
|
|
dni_drive, observaciones_drive, celular, producto, cantidad, precio,
|
|
pais, coordenadas, metodo
|
|
) VALUES (
|
|
:source_key, :codigo, :import_id, :drive_imported_at, :nombre,
|
|
:direccion_drive, :referencia_drive, :sede_drive, :ciudad_drive, :distrito_drive,
|
|
:dni_drive, :observaciones_drive, :celular, :producto, :cantidad, :precio,
|
|
:pais, :coordenadas, :metodo
|
|
)
|
|
ON DUPLICATE KEY UPDATE
|
|
codigo = VALUES(codigo),
|
|
import_id = VALUES(import_id),
|
|
drive_imported_at = VALUES(drive_imported_at),
|
|
nombre = VALUES(nombre),
|
|
direccion_drive = VALUES(direccion_drive),
|
|
referencia_drive = VALUES(referencia_drive),
|
|
sede_drive = VALUES(sede_drive),
|
|
ciudad_drive = VALUES(ciudad_drive),
|
|
distrito_drive = VALUES(distrito_drive),
|
|
dni_drive = VALUES(dni_drive),
|
|
observaciones_drive = VALUES(observaciones_drive),
|
|
celular = VALUES(celular),
|
|
producto = VALUES(producto),
|
|
cantidad = VALUES(cantidad),
|
|
precio = VALUES(precio),
|
|
pais = VALUES(pais),
|
|
coordenadas = VALUES(coordenadas),
|
|
metodo = VALUES(metodo),
|
|
last_seen_at = CURRENT_TIMESTAMP'
|
|
);
|
|
|
|
foreach ($orders as $order) {
|
|
$stmt->execute([
|
|
':source_key' => $order['source_key'],
|
|
':codigo' => $order['codigo'] ?: null,
|
|
':import_id' => $order['import_id'] ?: null,
|
|
':drive_imported_at' => cc_test_parse_datetime($order['import_id'] ?? ''),
|
|
':nombre' => $order['nombre'] ?: null,
|
|
':direccion_drive' => $order['direccion'] ?: null,
|
|
':referencia_drive' => $order['referencia'] ?: null,
|
|
':sede_drive' => $order['sede'] ?: null,
|
|
':ciudad_drive' => $order['ciudad'] ?: null,
|
|
':distrito_drive' => $order['distrito'] ?: null,
|
|
':dni_drive' => $order['dni'] ?: null,
|
|
':observaciones_drive' => $order['observaciones'] ?: null,
|
|
':celular' => $order['celular'] ?: null,
|
|
':producto' => $order['producto'] ?: null,
|
|
':cantidad' => $order['cantidad'] ?: null,
|
|
':precio' => $order['precio'] ?: null,
|
|
':pais' => $order['pais'] ?: null,
|
|
':coordenadas' => $order['coordenadas'] ?: null,
|
|
':metodo' => $order['metodo'] ?: null,
|
|
]);
|
|
}
|
|
|
|
return [
|
|
'synced_count' => count($orders),
|
|
'total_rows' => (int) ($preview['total_rows'] ?? 0),
|
|
];
|
|
}
|
|
|
|
function cc_test_fetch_dashboard_orders(PDO $pdo): array
|
|
{
|
|
cc_test_ensure_schema($pdo);
|
|
|
|
$sql = "SELECT
|
|
o.source_key,
|
|
o.codigo,
|
|
o.import_id,
|
|
o.drive_imported_at,
|
|
o.nombre,
|
|
o.celular,
|
|
o.producto,
|
|
o.cantidad,
|
|
o.precio,
|
|
o.pais,
|
|
o.coordenadas,
|
|
o.metodo,
|
|
o.direccion_drive,
|
|
o.referencia_drive,
|
|
o.sede_drive,
|
|
o.ciudad_drive,
|
|
o.distrito_drive,
|
|
o.dni_drive,
|
|
o.observaciones_drive,
|
|
o.first_seen_at,
|
|
o.last_seen_at,
|
|
COALESCE(NULLIF(t.estado, ''), 'POR LLAMAR') AS estado,
|
|
COALESCE(t.nota_seguimiento, '') AS nota_seguimiento,
|
|
t.proxima_llamada,
|
|
t.fecha_ultimo_contacto,
|
|
t.user_id,
|
|
t.updated_at AS tracking_updated_at,
|
|
t.direccion_editada,
|
|
t.referencia_editada,
|
|
t.sede_editada,
|
|
t.ciudad_editada,
|
|
t.distrito_editado,
|
|
t.dni_editado,
|
|
t.observaciones_editadas,
|
|
COALESCE(NULLIF(t.direccion_editada, ''), NULLIF(o.direccion_drive, '')) AS direccion_final,
|
|
COALESCE(NULLIF(t.referencia_editada, ''), NULLIF(o.referencia_drive, '')) AS referencia_final,
|
|
COALESCE(NULLIF(t.sede_editada, ''), NULLIF(o.sede_drive, '')) AS sede_final,
|
|
COALESCE(NULLIF(t.ciudad_editada, ''), NULLIF(o.ciudad_drive, '')) AS ciudad_final,
|
|
COALESCE(NULLIF(t.distrito_editado, ''), NULLIF(o.distrito_drive, '')) AS distrito_final,
|
|
COALESCE(NULLIF(t.dni_editado, ''), NULLIF(o.dni_drive, '')) AS dni_final,
|
|
COALESCE(NULLIF(t.observaciones_editadas, ''), NULLIF(o.observaciones_drive, '')) AS observaciones_final,
|
|
IFNULL(c.total_llamadas, 0) AS total_llamadas,
|
|
c.ultima_llamada,
|
|
COALESCE(u.nombre_asesor, u.username, '') AS gestor
|
|
FROM callcenter_test_orders o
|
|
LEFT JOIN callcenter_test_tracking t ON t.source_key = o.source_key
|
|
LEFT JOIN (
|
|
SELECT pedido_id, COUNT(*) AS total_llamadas, MAX(fecha_llamada) AS ultima_llamada
|
|
FROM historial_llamadas
|
|
GROUP BY pedido_id
|
|
) c ON c.pedido_id = o.source_key
|
|
LEFT JOIN users u ON u.id = t.user_id
|
|
ORDER BY COALESCE(o.drive_imported_at, o.first_seen_at) DESC, o.id DESC";
|
|
|
|
$stmt = $pdo->query($sql);
|
|
$orders = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
foreach ($orders as &$order) {
|
|
$digits = preg_replace('/\D+/', '', (string) ($order['celular'] ?? ''));
|
|
$order['telefono_url'] = $digits !== '' ? 'tel:' . $digits : '';
|
|
$order['whatsapp_url'] = $digits !== '' ? 'https://wa.me/' . $digits : '';
|
|
}
|
|
unset($order);
|
|
|
|
return $orders;
|
|
}
|
|
|
|
function cc_test_is_same_day(?string $value, DateTimeImmutable $day): bool
|
|
{
|
|
$parsed = cc_test_parse_datetime($value);
|
|
if ($parsed === null) {
|
|
return false;
|
|
}
|
|
|
|
try {
|
|
return (new DateTimeImmutable($parsed))->format('Y-m-d') === $day->format('Y-m-d');
|
|
} catch (Throwable $exception) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function cc_test_is_due_today(array $order, DateTimeImmutable $endOfToday): bool
|
|
{
|
|
if (!in_array($order['estado'] ?? '', cc_test_open_states(), true)) {
|
|
return false;
|
|
}
|
|
|
|
$nextCall = cc_test_parse_datetime($order['proxima_llamada'] ?? null);
|
|
if ($nextCall === null) {
|
|
return true;
|
|
}
|
|
|
|
try {
|
|
return new DateTimeImmutable($nextCall) <= $endOfToday;
|
|
} catch (Throwable $exception) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
function cc_test_matches_search(array $order, string $search): bool
|
|
{
|
|
$search = trim($search);
|
|
if ($search === '') {
|
|
return true;
|
|
}
|
|
|
|
$haystack = mb_strtolower(implode(' ', [
|
|
$order['codigo'] ?? '',
|
|
$order['nombre'] ?? '',
|
|
$order['celular'] ?? '',
|
|
$order['dni_final'] ?? '',
|
|
$order['direccion_final'] ?? '',
|
|
$order['distrito_final'] ?? '',
|
|
$order['ciudad_final'] ?? '',
|
|
$order['producto'] ?? '',
|
|
]));
|
|
|
|
return str_contains($haystack, mb_strtolower($search));
|
|
}
|
|
|
|
function cc_test_build_dashboard(array $orders, string $view, string $search = ''): array
|
|
{
|
|
$today = new DateTimeImmutable('today');
|
|
$endOfToday = $today->setTime(23, 59, 59);
|
|
$stats = [
|
|
'todos' => count($orders),
|
|
'nuevos_hoy' => 0,
|
|
'pendientes_hoy' => 0,
|
|
'confirmados' => 0,
|
|
'cerrados' => 0,
|
|
];
|
|
$visibleOrders = [];
|
|
|
|
foreach ($orders as $order) {
|
|
$createdReference = $order['drive_imported_at'] ?: $order['first_seen_at'];
|
|
$isNewToday = cc_test_is_same_day($createdReference, $today);
|
|
$isConfirmed = ($order['estado'] ?? '') === 'CONFIRMADO';
|
|
$isClosed = in_array($order['estado'] ?? '', cc_test_closed_states(), true);
|
|
$isPendingToday = cc_test_is_due_today($order, $endOfToday);
|
|
|
|
if ($isNewToday) {
|
|
$stats['nuevos_hoy']++;
|
|
}
|
|
if ($isPendingToday) {
|
|
$stats['pendientes_hoy']++;
|
|
}
|
|
if ($isConfirmed) {
|
|
$stats['confirmados']++;
|
|
}
|
|
if ($isClosed) {
|
|
$stats['cerrados']++;
|
|
}
|
|
|
|
$order['is_new_today'] = $isNewToday;
|
|
$order['is_pending_today'] = $isPendingToday;
|
|
$order['is_confirmed'] = $isConfirmed;
|
|
$order['is_closed'] = $isClosed;
|
|
|
|
$matchesView = match ($view) {
|
|
'nuevos_hoy' => $isNewToday,
|
|
'confirmados' => $isConfirmed,
|
|
'cerrados' => $isClosed,
|
|
'todos' => true,
|
|
default => $isPendingToday,
|
|
};
|
|
|
|
if ($matchesView && cc_test_matches_search($order, $search)) {
|
|
$visibleOrders[] = $order;
|
|
}
|
|
}
|
|
|
|
usort($visibleOrders, static function (array $a, array $b) use ($view): int {
|
|
$aNext = cc_test_parse_datetime($a['proxima_llamada'] ?? null);
|
|
$bNext = cc_test_parse_datetime($b['proxima_llamada'] ?? null);
|
|
|
|
if ($view === 'pendientes_hoy') {
|
|
if ($aNext === null && $bNext !== null) {
|
|
return -1;
|
|
}
|
|
if ($aNext !== null && $bNext === null) {
|
|
return 1;
|
|
}
|
|
if ($aNext !== null && $bNext !== null && $aNext !== $bNext) {
|
|
return strcmp($aNext, $bNext);
|
|
}
|
|
}
|
|
|
|
$aBase = cc_test_parse_datetime($a['drive_imported_at'] ?? null) ?: cc_test_parse_datetime($a['first_seen_at'] ?? null) ?: '';
|
|
$bBase = cc_test_parse_datetime($b['drive_imported_at'] ?? null) ?: cc_test_parse_datetime($b['first_seen_at'] ?? null) ?: '';
|
|
return strcmp($bBase, $aBase);
|
|
});
|
|
|
|
return [
|
|
'stats' => $stats,
|
|
'visible_orders' => $visibleOrders,
|
|
];
|
|
}
|
|
|
|
function cc_test_fetch_histories(PDO $pdo, array $sourceKeys): array
|
|
{
|
|
if (empty($sourceKeys)) {
|
|
return [];
|
|
}
|
|
|
|
$placeholders = implode(',', array_fill(0, count($sourceKeys), '?'));
|
|
$sql = "SELECT h.*, COALESCE(u.nombre_asesor, u.username, CONCAT('Asesor #', h.asesor_id)) AS asesor
|
|
FROM historial_llamadas h
|
|
LEFT JOIN users u ON u.id = h.asesor_id
|
|
WHERE h.pedido_id IN ($placeholders)
|
|
ORDER BY h.fecha_llamada DESC, h.id DESC";
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->execute($sourceKeys);
|
|
|
|
$histories = [];
|
|
foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
|
|
$histories[$row['pedido_id']][] = $row;
|
|
}
|
|
|
|
return $histories;
|
|
}
|