Autosave: 20260724-052546
This commit is contained in:
parent
4a8c7a39ad
commit
cfd8e99b49
@ -1,5 +1,8 @@
|
||||
<?php
|
||||
session_start();
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Pragma: no-cache');
|
||||
header('Expires: 0');
|
||||
require_once 'db/config.php';
|
||||
require_once 'includes/callcenter_test_helpers.php';
|
||||
require_once 'includes/drive_test_orders.php';
|
||||
@ -415,7 +418,7 @@ $selectedAssessorFilterLabel = '';
|
||||
$totalRows = 0;
|
||||
$agregadosCount = 0;
|
||||
$lastProcessedRow = null;
|
||||
$startRow = (int) ($storeConfig['startRow'] ?? 5552);
|
||||
$startRow = (int) ($storeConfig['startRow'] ?? 0);
|
||||
$catalogoProductos = [];
|
||||
$stats = [
|
||||
'total' => 0,
|
||||
@ -627,8 +630,10 @@ try {
|
||||
$role = (string) ($_SESSION['user_role'] ?? '');
|
||||
$currentUserId = (int) ($_SESSION['user_id'] ?? 0);
|
||||
$isAdmin = in_array($role, ['Administrador', 'admin'], true);
|
||||
$selectedAssessorFilter = cc_test_normalize_user_key($_GET['assessor'] ?? '');
|
||||
if (!$isAdmin || ($selectedAssessorFilter !== '' && !isset($assessors[$selectedAssessorFilter]))) {
|
||||
if ($isAdmin) {
|
||||
$selectedAssessorFilter = cc_test_resolve_callcenter_assessor_filter($assessors, $_GET['assessor'] ?? null, true, true);
|
||||
} else {
|
||||
unset($_SESSION[cc_test_callcenter_assessor_filter_session_key()]);
|
||||
$selectedAssessorFilter = '';
|
||||
}
|
||||
$selectedAssessorFilterLabel = $selectedAssessorFilter !== ''
|
||||
@ -1151,7 +1156,7 @@ require_once 'layout_header.php';
|
||||
<div class="col-12 col-lg-4">
|
||||
<label for="assessorFilter" class="form-label small text-uppercase text-muted fw-semibold mb-1">Filtrar por asesora</label>
|
||||
<select name="assessor" id="assessorFilter" class="form-select">
|
||||
<option value="">Todas las asesoras</option>
|
||||
<option value="TODAS"<?php echo $selectedAssessorFilter === "" ? ' selected' : ''; ?>>Todas las asesoras</option>
|
||||
<?php foreach ($assessors as $assessorKey => $assessor): ?>
|
||||
<option value="<?php echo htmlspecialchars((string) $assessorKey); ?>"<?php echo $selectedAssessorFilter === $assessorKey ? ' selected' : ''; ?>><?php echo htmlspecialchars((string) ($assessor['label'] ?? $assessorKey)); ?></option>
|
||||
<?php endforeach; ?>
|
||||
@ -1161,7 +1166,7 @@ require_once 'layout_header.php';
|
||||
<div class="col-auto d-flex gap-2">
|
||||
<button type="submit" class="btn btn-primary">Aplicar filtro</button>
|
||||
<?php if ($selectedAssessorFilter !== ''): ?>
|
||||
<a href="<?php echo htmlspecialchars(cc_test_build_url('call_center_pro.php', $callCenterBaseParams)); ?>" class="btn btn-outline-secondary">Ver todas</a>
|
||||
<a href="<?php echo htmlspecialchars(cc_test_build_url('call_center_pro.php', array_merge($callCenterBaseParams, ['assessor' => 'TODAS']))); ?>" class="btn btn-outline-secondary">Ver todas</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
<?php
|
||||
session_start();
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Pragma: no-cache');
|
||||
header('Expires: 0');
|
||||
require_once 'db/config.php';
|
||||
require_once 'includes/callcenter_test_helpers.php';
|
||||
require_once 'includes/drive_test_orders.php';
|
||||
@ -321,6 +324,9 @@ $modalsHtml = [];
|
||||
$totalRows = 0;
|
||||
$agregadosCount = 0;
|
||||
$lastProcessedRow = null;
|
||||
$selectedAssessorFilter = '';
|
||||
$selectedAssessorFilterLabel = '';
|
||||
$persistedAssessorParams = [];
|
||||
|
||||
$repartoSettings = [
|
||||
'store_key' => $storeKey,
|
||||
@ -350,7 +356,7 @@ $cupoObjetivoPorAsesora = 10;
|
||||
$advisorOpenCounts = [];
|
||||
$advisorTotalCounts = [];
|
||||
$recommendedAssessorKey = null;
|
||||
$startRow = (int) ($storeConfig['startRow'] ?? 5552);
|
||||
$startRow = (int) ($storeConfig['startRow'] ?? 0);
|
||||
$catalogoProductos = [];
|
||||
$stats = [
|
||||
'total' => 0,
|
||||
@ -369,6 +375,16 @@ try {
|
||||
cc_test_ensure_tracking_table($pdo);
|
||||
cc_test_ensure_historial_llamadas_table($pdo);
|
||||
$assessors = cc_test_fetch_assessors($pdo);
|
||||
$selectedAssessorFilter = cc_test_resolve_callcenter_assessor_filter($assessors, $_GET['assessor'] ?? null, true, true);
|
||||
$selectedAssessorFilterLabel = $selectedAssessorFilter !== ''
|
||||
? (string) ($assessors[$selectedAssessorFilter]['label'] ?? $selectedAssessorFilter)
|
||||
: '';
|
||||
$persistedAssessorParams = $selectedAssessorFilter !== ''
|
||||
? ['assessor' => $selectedAssessorFilter]
|
||||
: [];
|
||||
if ($selectedAssessorFilterLabel !== '') {
|
||||
$pageTitle = 'Base de Datos Pedidos | Asignación · ' . $selectedAssessorFilterLabel;
|
||||
}
|
||||
if ($isMainTuaniStore) {
|
||||
$repartoSettings = cc_test_fetch_reparto_settings($pdo, $storeKey, $assessors);
|
||||
}
|
||||
@ -866,6 +882,15 @@ try {
|
||||
$order['es_nuevo_hoy'] = $firstSeenDate ? $firstSeenDate->format('Y-m-d') === $todayStart->format('Y-m-d') : false;
|
||||
$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_dashboard_bucket_key($order, $assessors, false);
|
||||
$order['assessor_label'] = $order['assessor_key'] !== ''
|
||||
? (string) ($assessors[$order['assessor_key']]['label'] ?? $order['assessor_key'])
|
||||
: 'Sin asignar';
|
||||
$order['matches_assessor_filter'] = $selectedAssessorFilter === '' || $order['assessor_key'] === $selectedAssessorFilter;
|
||||
|
||||
if ($selectedAssessorFilter !== '' && !($order['matches_assessor_filter'] ?? false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($order['user_id'] !== null) {
|
||||
$userId = (int) $order['user_id'];
|
||||
@ -907,7 +932,13 @@ try {
|
||||
|
||||
$orders = cc_test_mark_recoverables_duplicate_orders($pdo, $orders, $storeKey);
|
||||
|
||||
$performanceDashboard = cc_test_build_performance_dashboard($orders, $assessors, 7);
|
||||
$performanceOrders = $selectedAssessorFilter !== ''
|
||||
? array_values(array_filter($orders, static function (array $order) use ($selectedAssessorFilter): bool {
|
||||
return ($order['matches_assessor_filter'] ?? false) === true;
|
||||
}))
|
||||
: $orders;
|
||||
|
||||
$performanceDashboard = cc_test_build_performance_dashboard($performanceOrders, $assessors, 7);
|
||||
$performanceDashboardHtml = cc_test_render_performance_dashboard($performanceDashboard, [
|
||||
'title' => 'KPI diario por asesora',
|
||||
'subtitle' => 'Confirmación = pedidos asignados hoy confirmados hoy. Recuperación = pedidos asignados antes de hoy confirmados hoy. Rendimiento del día = confirmados totales (nuevos + recuperados) sobre asignados hoy.',
|
||||
@ -985,7 +1016,7 @@ try {
|
||||
];
|
||||
}
|
||||
|
||||
$visibleOrders = array_values(array_filter($orders, static function (array $order) use ($view, $todayStart): bool {
|
||||
$visibleOrders = array_values(array_filter($performanceOrders, static function (array $order) use ($view, $todayStart): bool {
|
||||
return match ($view) {
|
||||
'pendientes_hoy' => (bool) ($order['es_pendiente_hoy'] ?? false),
|
||||
'nuevos_hoy' => (bool) ($order['es_nuevo_hoy'] ?? false),
|
||||
@ -1330,14 +1361,14 @@ require_once 'layout_header.php';
|
||||
<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-3">
|
||||
<a href="?view=pendientes_hoy&store=<?php echo htmlspecialchars($storeKey); ?>" class="btn btn-sm <?php echo $view !== 'todos' ? 'btn-primary' : 'btn-outline-primary'; ?>">Bandeja principal</a>
|
||||
<a href="call_center_pro.php?view=<?php echo urlencode($view); ?>&store=<?php echo htmlspecialchars($storeKey); ?>" class="btn btn-sm btn-outline-dark"><?php echo htmlspecialchars($callCenterSectionLabel); ?></a>
|
||||
<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' => $view, 'store' => $storeKey], $persistedAssessorParams))); ?>" class="btn btn-sm btn-outline-dark"><?php echo htmlspecialchars($callCenterSectionLabel); ?></a>
|
||||
</div>
|
||||
<ul class="nav nav-pills mt-3 flex-wrap gap-2" role="tablist" aria-label="Selector de tienda">
|
||||
<?php foreach ($storeNavGroups as $groupKey => $group): ?>
|
||||
<?php $groupConfig = $group['config'] ?? []; ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link <?php echo $activeStoreGroupKey === $groupKey ? 'active' : ''; ?>" href="<?php echo htmlspecialchars(cc_test_build_url('gestiones_callcenter.php', ['view' => $view, 'store' => $groupKey])); ?>">
|
||||
<a class="nav-link <?php echo $activeStoreGroupKey === $groupKey ? 'active' : ''; ?>" href="<?php echo htmlspecialchars(cc_test_build_url('gestiones_callcenter.php', array_merge(['view' => $view, 'store' => $groupKey], $persistedAssessorParams))); ?>">
|
||||
<?php echo htmlspecialchars((string) ($groupConfig['label'] ?? strtoupper((string) $groupKey))); ?>
|
||||
</a>
|
||||
</li>
|
||||
@ -1347,9 +1378,9 @@ require_once 'layout_header.php';
|
||||
<div class="mt-3 p-3 rounded-4 border bg-light">
|
||||
<div class="small text-uppercase text-muted fw-semibold mb-2">Dentro de <?php echo htmlspecialchars($activeStoreGroupLabel); ?></div>
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<a class="btn btn-sm <?php echo $storeKey === $activeStoreGroupKey ? 'btn-primary' : 'btn-outline-primary'; ?>" href="<?php echo htmlspecialchars(cc_test_build_url('gestiones_callcenter.php', ['view' => $view, 'store' => $activeStoreGroupKey])); ?>">Pedidos <?php echo htmlspecialchars($activeStoreGroupLabel); ?></a>
|
||||
<a class="btn btn-sm <?php echo $storeKey === $activeStoreGroupKey ? 'btn-primary' : 'btn-outline-primary'; ?>" href="<?php echo htmlspecialchars(cc_test_build_url('gestiones_callcenter.php', array_merge(['view' => $view, 'store' => $activeStoreGroupKey], $persistedAssessorParams))); ?>">Pedidos <?php echo htmlspecialchars($activeStoreGroupLabel); ?></a>
|
||||
<?php foreach ($activeStoreGroupChildren as $childKey => $childConfig): ?>
|
||||
<a class="btn btn-sm <?php echo $storeKey === $childKey ? 'btn-primary' : 'btn-outline-primary'; ?>" href="<?php echo htmlspecialchars(cc_test_build_url('gestiones_callcenter.php', ['view' => $view, 'store' => $childKey])); ?>">
|
||||
<a class="btn btn-sm <?php echo $storeKey === $childKey ? 'btn-primary' : 'btn-outline-primary'; ?>" href="<?php echo htmlspecialchars(cc_test_build_url('gestiones_callcenter.php', array_merge(['view' => $view, 'store' => $childKey], $persistedAssessorParams))); ?>">
|
||||
<?php echo htmlspecialchars((string) ($childConfig['label'] ?? strtoupper((string) $childKey))); ?>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
@ -1362,6 +1393,10 @@ require_once 'layout_header.php';
|
||||
<span class="badge rounded-pill text-bg-light border px-3 py-2">Agregados: <?php echo (int) $agregadosCount; ?></span>
|
||||
<span class="badge rounded-pill text-bg-light border px-3 py-2"><?php if ($usesIncrementalSync && $lastProcessedRow !== null): ?><?php echo htmlspecialchars(mb_strtoupper($storeLabel)); ?>: distribución desde fila <?php echo (int) ($storeConfig['startRow'] ?? $startRow); ?> · último procesado <?php echo (int) $lastProcessedRow; ?><?php else: ?>Extracción: desde fila <?php echo (int) $startRow; ?><?php endif; ?></span>
|
||||
<span class="badge rounded-pill text-bg-light border px-3 py-2">Auto actualización: cada 10 min</span>
|
||||
<?php if ($selectedAssessorFilterLabel !== ''): ?>
|
||||
<span class="badge rounded-pill bg-primary-subtle text-primary-emphasis border px-3 py-2">Asesora: <?php echo htmlspecialchars($selectedAssessorFilterLabel); ?></span>
|
||||
<a href="<?php echo htmlspecialchars(cc_test_build_url('gestiones_callcenter.php', ['view' => $view, 'store' => $storeKey, 'assessor' => 'TODAS'])); ?>" class="btn btn-outline-secondary btn-sm">Ver todas</a>
|
||||
<?php endif; ?>
|
||||
<a href="test_importar_drive.php?store=<?php echo htmlspecialchars($storeKey); ?>" class="btn btn-outline-primary btn-sm">Ver vista previa Drive</a>
|
||||
</div>
|
||||
</div>
|
||||
@ -1429,7 +1464,7 @@ require_once 'layout_header.php';
|
||||
<?php $cardClass = $isActiveCard ? $viewCard['active_class'] : 'bg-white'; ?>
|
||||
<?php $labelClass = $isActiveCard && str_contains((string) ($viewCard['active_class'] ?? ''), 'text-white') ? 'opacity-75' : 'text-muted'; ?>
|
||||
<div class="<?php echo htmlspecialchars($viewCardColumnClass); ?>">
|
||||
<a href="<?php echo htmlspecialchars(cc_test_build_url('gestiones_callcenter.php', ['view' => $viewKey, 'store' => $storeKey])); ?>" class="text-decoration-none">
|
||||
<a href="<?php echo htmlspecialchars(cc_test_build_url('gestiones_callcenter.php', array_merge(['view' => $viewKey, 'store' => $storeKey], $persistedAssessorParams))); ?>" class="text-decoration-none">
|
||||
<article class="card border-0 shadow-sm h-100 <?php echo htmlspecialchars($cardClass); ?>">
|
||||
<div class="card-body">
|
||||
<div class="small text-uppercase <?php echo htmlspecialchars($labelClass); ?> mb-2"><?php echo htmlspecialchars((string) ($viewCard['label'] ?? $viewKey)); ?></div>
|
||||
|
||||
@ -812,6 +812,53 @@ function cc_test_normalize_user_key(?string $value): string
|
||||
return mb_strtoupper($value);
|
||||
}
|
||||
|
||||
function cc_test_callcenter_assessor_filter_session_key(): string
|
||||
{
|
||||
return 'callcenter_assessor_filter';
|
||||
}
|
||||
|
||||
function cc_test_callcenter_assessor_filter_clear_values(): array
|
||||
{
|
||||
return ['ALL', 'TODAS', 'TODOS', '__ALL__'];
|
||||
}
|
||||
|
||||
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();
|
||||
$incomingFilter = cc_test_normalize_user_key($incomingFilter ?? '');
|
||||
$sessionFilter = cc_test_normalize_user_key($_SESSION[$sessionKey] ?? '');
|
||||
|
||||
if ($incomingFilter !== '') {
|
||||
if (in_array($incomingFilter, cc_test_callcenter_assessor_filter_clear_values(), true)) {
|
||||
unset($_SESSION[$sessionKey]);
|
||||
return '';
|
||||
}
|
||||
|
||||
if (isset($assessors[$incomingFilter])) {
|
||||
if ($persistSession) {
|
||||
$_SESSION[$sessionKey] = $incomingFilter;
|
||||
}
|
||||
return $incomingFilter;
|
||||
}
|
||||
|
||||
if ($persistSession) {
|
||||
unset($_SESSION[$sessionKey]);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($useSessionFallback && $sessionFilter !== '' && isset($assessors[$sessionFilter])) {
|
||||
return $sessionFilter;
|
||||
}
|
||||
|
||||
if (!$persistSession) {
|
||||
unset($_SESSION[$sessionKey]);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
function cc_test_allowed_module_user_keys(): array
|
||||
{
|
||||
return cc_test_default_assessor_keys();
|
||||
|
||||
@ -29,8 +29,8 @@ function drive_test_available_stores(): array
|
||||
'sheet_title' => 'TUANI PEDIDOS',
|
||||
'spreadsheet_id' => '1QYKeBJIIqYm6yW6Ka-5gKdxhUHwXOAc0No7RjnimxTw',
|
||||
'sheet_gid' => 1523126328,
|
||||
'startRow' => 5552,
|
||||
'enforce_db_start_row' => false,
|
||||
'startRow' => 6804,
|
||||
'enforce_db_start_row' => true,
|
||||
'incremental_sync' => true,
|
||||
],
|
||||
// Bandeja compartida de carritos recuperables: misma estructura, pero desde la fila 2000.
|
||||
@ -202,9 +202,12 @@ function drive_test_extract_codigo_number(?string $codigo): ?int
|
||||
return (int) $digits;
|
||||
}
|
||||
|
||||
function drive_test_fetch_orders(int $limit = 10, int $startRow = 5552, string $storeKey = 'flower'): array
|
||||
function drive_test_fetch_orders(int $limit = 10, ?int $startRow = null, string $storeKey = 'flower'): array
|
||||
{
|
||||
$storeConfig = drive_test_get_store_config($storeKey);
|
||||
if ($startRow === null || $startRow <= 0) {
|
||||
$startRow = (int) ($storeConfig['startRow'] ?? 0);
|
||||
}
|
||||
|
||||
$credentialsPath = __DIR__ . '/../google_credentials.json';
|
||||
$spreadsheetId = (string) ($storeConfig['spreadsheet_id'] ?? '');
|
||||
@ -612,7 +615,7 @@ function drive_test_sync_orders_incremental(PDO $pdo, string $storeKey, int $ove
|
||||
{
|
||||
$storeKey = mb_strtolower(trim($storeKey));
|
||||
$storeConfig = drive_test_get_store_config($storeKey);
|
||||
$baselineStartRow = (int) ($storeConfig['startRow'] ?? 5552);
|
||||
$baselineStartRow = (int) ($storeConfig['startRow'] ?? 0);
|
||||
|
||||
drive_test_ensure_orders_table($pdo);
|
||||
drive_test_ensure_import_checkpoints_table($pdo);
|
||||
|
||||
@ -33,6 +33,23 @@ if ($currentUserId > 0 && !in_array($userRole, ['Administrador', 'admin'], true)
|
||||
}
|
||||
|
||||
$canAccessTestModule = cc_test_is_allowed_module_user($userRole, $currentUserUsername, $currentUserNombreAsesor);
|
||||
$currentAssessorFilter = cc_test_normalize_user_key($_GET['assessor'] ?? ($_SESSION[cc_test_callcenter_assessor_filter_session_key()] ?? ''));
|
||||
if (in_array($currentAssessorFilter, cc_test_callcenter_assessor_filter_clear_values(), true)) {
|
||||
$currentAssessorFilter = '';
|
||||
}
|
||||
$shouldPersistAssessor = $currentAssessorFilter !== '';
|
||||
$callCenterPersistentParams = $shouldPersistAssessor ? ['assessor' => $currentAssessorFilter] : [];
|
||||
$appendCallCenterParams = static function (string $url) use ($callCenterPersistentParams): string {
|
||||
if (empty($callCenterPersistentParams)) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
if (!in_array($url, ['gestiones_callcenter.php', 'call_center_pro.php'], true)) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
return $url . '?' . http_build_query($callCenterPersistentParams);
|
||||
};
|
||||
|
||||
// Define navigation items for each role
|
||||
$navItems = [
|
||||
@ -451,7 +468,7 @@ $navItems = [
|
||||
$isActive = $currentPage == $sub_item['url'] ? 'active' : '';
|
||||
?>
|
||||
<li class="nav-item">
|
||||
<a href="<?php echo $sub_item['url']; ?>" class="nav-link <?php echo $isActive; ?>"><i class="fas <?php echo $sub_item['icon']; ?>"></i> <?php echo $sub_item['text']; ?></a>
|
||||
<a href="<?php echo htmlspecialchars($appendCallCenterParams($sub_item['url'])); ?>" class="nav-link <?php echo $isActive; ?>"><i class="fas <?php echo $sub_item['icon']; ?>"></i> <?php echo $sub_item['text']; ?></a>
|
||||
</li>
|
||||
<?php
|
||||
endif;
|
||||
@ -462,7 +479,7 @@ $navItems = [
|
||||
$isActive = $currentPage == $item['url'] ? 'active' : '';
|
||||
?>
|
||||
<li class="nav-item">
|
||||
<a href="<?php echo $item['url']; ?>" class="nav-link <?php echo $isActive; ?>"><i class="fas <?php echo $item['icon']; ?>"></i> <?php echo $item['text']; ?></a>
|
||||
<a href="<?php echo htmlspecialchars($appendCallCenterParams($item['url'])); ?>" class="nav-link <?php echo $isActive; ?>"><i class="fas <?php echo $item['icon']; ?>"></i> <?php echo $item['text']; ?></a>
|
||||
</li>
|
||||
<?php endif;
|
||||
endif;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user