Autosave: 20260731-085103
This commit is contained in:
parent
a902ed41a0
commit
2d3ef7a210
@ -422,7 +422,7 @@ $_SESSION[cc_test_callcenter_view_session_key()] = cc_test_normalize_context_key
|
||||
|
||||
$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.'
|
||||
: '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 desde el Día 3 para pedidos nuevos desde el 29/07/2026 y desde el Día 4 para pedidos anteriores; cuando haya sustento pendiente en ese nuevo flujo, la bandeja principal queda visible pero bloqueada hasta completarlo. 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 3 días hábiles</strong> para concentrar el seguimiento reciente.';
|
||||
: '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 desde el Día 3 para pedidos nuevos desde el 29/07/2026 y desde el Día 4 para pedidos anteriores; cuando haya sustento pendiente en ese nuevo flujo, la tarjeta de Asignados hoy sigue visible y el celular aparece con candado hasta completarlo. 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 3 días hábiles</strong> para concentrar el seguimiento reciente. En las vistas <strong>Todos</strong> y <strong>Últimos 3 días hábiles</strong>, los pedidos del nuevo flujo con sustento pendiente se muestran con candado en el celular hasta completar ese paso; la llamada sigue disponible desde el panel.';
|
||||
|
||||
$errorMessage = null;
|
||||
$noticeMessage = null;
|
||||
@ -702,6 +702,12 @@ try {
|
||||
$order['promo_final_evidencia_cargada'] = trim((string) ($order['promo_final_evidencia_path'] ?? '')) !== '';
|
||||
$order['es_promo_final'] = $order['promo_final_habilitado'] && $order['promo_final_evidencia_cargada'];
|
||||
$order['promo_final_pendiente'] = $order['promo_final_habilitado'] && !$order['promo_final_evidencia_cargada'];
|
||||
$order['llamada_bloqueada_dia3'] = $followupDayInfo !== null
|
||||
&& !empty($order['promo_final_pendiente'])
|
||||
&& (int) ($followupDayInfo['promo_final_threshold_day'] ?? 4) === 3;
|
||||
$order['llamada_bloqueada_dia3_mensaje'] = $order['llamada_bloqueada_dia3']
|
||||
? 'Celular oculto hasta completar el sustento de Día 3.'
|
||||
: '';
|
||||
$order['pendiente_logistica_destino'] = cc_test_is_tuani_store_key($storeKey) ? cc_test_pending_logistica_destination($order) : null;
|
||||
$order['pendiente_logistica'] = $order['pendiente_logistica_destino'] !== null;
|
||||
|
||||
@ -988,9 +994,9 @@ try {
|
||||
}
|
||||
$assessorInboxLockedCount = count($assessorInboxLockedOrders);
|
||||
$assessorInboxLocked = $assessorInboxLockedCount > 0;
|
||||
$assessorInboxLockedView = $assessorInboxLocked && $view === 'pendientes_hoy';
|
||||
$assessorInboxLockedView = $assessorInboxLocked && $view === 'nuevos_hoy';
|
||||
$assessorInboxLockNotice = $assessorInboxLocked
|
||||
? 'Tienes ' . $assessorInboxLockedCount . ' pedido' . ($assessorInboxLockedCount === 1 ? '' : 's') . ' del nuevo flujo con sustento pendiente para Promo Final. La bandeja principal queda bloqueada hasta completar ese paso.'
|
||||
? 'Tienes ' . $assessorInboxLockedCount . ' pedido' . ($assessorInboxLockedCount === 1 ? '' : 's') . ' del nuevo flujo con sustento pendiente para Promo Final. En esos casos, el celular aparece con candado hasta completar ese paso.'
|
||||
: '';
|
||||
|
||||
$visibleOrdersTotalCount = count($visibleOrders);
|
||||
@ -1354,8 +1360,8 @@ require_once 'layout_header.php';
|
||||
<div class="card-body">
|
||||
<div class="small text-uppercase <?php echo htmlspecialchars($labelClass); ?> mb-2"><?php echo htmlspecialchars((string) ($viewCard['label'] ?? $viewKey)); ?></div>
|
||||
<div class="display-6 fw-bold mb-0"><?php echo (int) ($stats[$viewCard['stat_key']] ?? 0); ?></div>
|
||||
<?php if ($viewKey === 'pendientes_hoy' && $assessorInboxLocked): ?>
|
||||
<div class="small fw-semibold text-danger mt-2"><i class="bi bi-lock-fill me-1"></i>Bloqueado</div>
|
||||
<?php if ($viewKey === 'nuevos_hoy' && $assessorInboxLocked): ?>
|
||||
<div class="small fw-semibold text-warning mt-2"><i class="bi bi-lock-fill me-1"></i>Con candado en celulares</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</article>
|
||||
@ -1417,7 +1423,7 @@ require_once 'layout_header.php';
|
||||
<?php endif; ?>
|
||||
<span class="badge bg-light text-dark border"><?php echo (int) $visibleOrdersTotalCount; ?> pedidos únicos en esta bandeja</span>
|
||||
<?php if ($assessorInboxLockedView): ?>
|
||||
<span class="badge bg-danger-subtle text-danger-emphasis border">Bloqueado por sustento de Día 3</span>
|
||||
<span class="badge bg-warning-subtle text-warning-emphasis border">Candado en celulares por sustento de Día 3</span>
|
||||
<?php endif; ?>
|
||||
<?php if ($view === 'todos'): ?>
|
||||
<span class="badge bg-primary-subtle text-primary-emphasis border">Página <?php echo (int) $todosPage; ?> de <?php echo (int) $todosTotalPages; ?> · 200 por página</span>
|
||||
@ -1427,16 +1433,16 @@ require_once 'layout_header.php';
|
||||
<div class="card-body p-0">
|
||||
<?php if ($assessorInboxLockedView): ?>
|
||||
<div class="p-3 pb-0">
|
||||
<div class="alert alert-warning border-warning-subtle d-flex flex-column flex-md-row justify-content-between align-items-md-center gap-3 mb-0">
|
||||
<div class="alert alert-info border-info-subtle d-flex flex-column flex-md-row justify-content-between align-items-md-center gap-3 mb-0">
|
||||
<div>
|
||||
<div class="fw-semibold mb-1"><i class="bi bi-lock-fill me-1"></i>Bandeja bloqueada hasta completar el sustento</div>
|
||||
<div class="small mb-0"><?php echo htmlspecialchars($assessorInboxLockNotice); ?> Usa <strong>Últimos 3 días hábiles</strong> para subir la imagen y mover esos pedidos a Promo Final.</div>
|
||||
<div class="fw-semibold mb-1"><i class="bi bi-lock-fill me-1"></i>Celulares con candado por sustento de Día 3</div>
|
||||
<div class="small mb-0"><?php echo htmlspecialchars($assessorInboxLockNotice); ?> Usa <strong>Últimos 3 días hábiles</strong> si necesitas completar ese sustento más rápido.</div>
|
||||
</div>
|
||||
<a href="<?php echo htmlspecialchars(cc_test_build_url('call_center_pro.php', array_merge($callCenterParams, ['view' => 'ultimos_3_dias']))); ?>" class="btn btn-outline-warning btn-sm text-nowrap">Ir a Últimos 3 días</a>
|
||||
<a href="<?php echo htmlspecialchars(cc_test_build_url('call_center_pro.php', array_merge($callCenterParams, ['view' => 'ultimos_3_dias']))); ?>" class="btn btn-outline-info btn-sm text-nowrap">Ir a Últimos 3 días</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="table-responsive <?php echo $assessorInboxLockedView ? 'opacity-50 pe-none user-select-none' : ''; ?>">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-top mb-0 cc-callcenter-table">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
@ -1524,7 +1530,16 @@ require_once 'layout_header.php';
|
||||
</td>
|
||||
<td>
|
||||
<div class="fw-semibold"><?php echo htmlspecialchars(cc_test_display_value($order['nombre'], 'Sin nombre')); ?></div>
|
||||
<div class="small text-muted mb-1">Celular: <?php echo htmlspecialchars(cc_test_display_value($order['celular'], 'Sin número')); ?></div>
|
||||
<div class="small text-muted mb-1">
|
||||
Celular:
|
||||
<?php if (!empty($order['llamada_bloqueada_dia3'])): ?>
|
||||
<span class="badge bg-warning-subtle text-warning-emphasis border ms-1" title="<?php echo htmlspecialchars((string) ($order['llamada_bloqueada_dia3_mensaje'] ?? 'Celular oculto hasta completar el sustento de Día 3.'), ENT_QUOTES); ?>" aria-label="<?php echo htmlspecialchars((string) ($order['llamada_bloqueada_dia3_mensaje'] ?? 'Celular oculto hasta completar el sustento de Día 3.'), ENT_QUOTES); ?>">
|
||||
<i class="bi bi-lock-fill me-1"></i>Celular oculto
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<?php echo htmlspecialchars(cc_test_display_value($order['celular'], 'Sin número')); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="small text-muted">DNI: <?php echo htmlspecialchars(cc_test_display_value($order['dni'], 'Sin DNI')); ?></div>
|
||||
</td>
|
||||
<td>
|
||||
@ -1641,14 +1656,14 @@ require_once 'layout_header.php';
|
||||
<button type="submit" class="btn btn-sm btn-primary cc-callcenter-assign-submit cc-callcenter-action-btn"><?php echo htmlspecialchars((string) $buttonLabel); ?></button>
|
||||
</div>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($order['telefono_url'])): ?>
|
||||
<?php endif; ?> <?php if (!empty($order['telefono_url'])): ?>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm btn-primary cc-callcenter-action-btn"
|
||||
data-source-key="<?php echo htmlspecialchars($order['source_key']); ?>"
|
||||
data-modal-id="<?php echo htmlspecialchars($modalId); ?>"
|
||||
data-phone="<?php echo htmlspecialchars((string) ($order['celular'] ?? '')); ?>"
|
||||
data-phone-locked="<?php echo !empty($order['llamada_bloqueada_dia3']) ? '1' : '0'; ?>"
|
||||
data-order-label="<?php echo htmlspecialchars(cc_test_order_label($order)); ?>"
|
||||
data-client-name="<?php echo htmlspecialchars(cc_test_display_value($order['nombre'], 'Cliente sin nombre')); ?>"
|
||||
onclick="return registrarLlamada(event, this)">
|
||||
@ -1688,10 +1703,19 @@ require_once 'layout_header.php';
|
||||
<button type="button" class="btn btn-primary btn-sm px-3" id="subir-logistica-<?php echo htmlspecialchars($order['source_key']); ?>" data-route-pedido-id="<?php echo (int) ($order['ruta_contraentrega_pedido_id'] ?? 0); ?>" data-rotulado-pedido-id="<?php echo (int) ($order['pedido_rotulado_pedido_id'] ?? 0); ?>" onclick="guardarGestion('<?php echo htmlspecialchars($order['source_key']); ?>', this, { subirLogistica: true })"><?php echo htmlspecialchars($subirLogisticaButtonLabel); ?></button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="small text-muted mt-1"><?php echo htmlspecialchars(cc_test_display_value($order['producto'], 'Sin producto')); ?> · <?php echo htmlspecialchars(cc_test_display_value($order['celular'], 'Sin celular')); ?></div>
|
||||
<div class="small text-muted mt-1">
|
||||
<?php echo htmlspecialchars(cc_test_display_value($order['producto'], 'Sin producto')); ?> ·
|
||||
<?php if (!empty($order['llamada_bloqueada_dia3'])): ?>
|
||||
<span class="badge bg-warning-subtle text-warning-emphasis border ms-1" title="<?php echo htmlspecialchars((string) ($order['llamada_bloqueada_dia3_mensaje'] ?? 'Celular oculto hasta completar el sustento de Día 3.'), ENT_QUOTES); ?>" aria-label="<?php echo htmlspecialchars((string) ($order['llamada_bloqueada_dia3_mensaje'] ?? 'Celular oculto hasta completar el sustento de Día 3.'), ENT_QUOTES); ?>">
|
||||
<i class="bi bi-lock-fill me-1"></i>Celular oculto
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<?php echo htmlspecialchars(cc_test_display_value($order['celular'], 'Sin celular')); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if ($followupDayInfo !== null): ?>
|
||||
<div class="small mt-2 <?php echo htmlspecialchars(!empty($followupDayInfo['notice_text']) ? $followupDayInfo['text_class'] : 'text-muted'); ?><?php echo !empty($followupDayInfo['notice_text']) ? ' fw-semibold' : ''; ?>">
|
||||
<?php echo htmlspecialchars(!empty($followupDayInfo['notice_text']) ? $followupDayInfo['notice_text'] : ('Seguimiento iniciado el ' . $followupDayInfo['started_at_label'] . '.')); ?>
|
||||
<?php echo htmlspecialchars(!empty($followupDayInfo['notice_text']) ? $followupDayInfo['notice_text'] : ('Seguimiento asignado el ' . $followupDayInfo['started_at_label'] . '.')); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php $promoFinalProofPath = trim((string) ($order['promo_final_evidencia_path'] ?? '')); ?>
|
||||
@ -1730,11 +1754,19 @@ require_once 'layout_header.php';
|
||||
<div class="d-flex flex-wrap justify-content-between align-items-center gap-2">
|
||||
<div>
|
||||
<div class="small text-muted mb-1">Llamar / Gestionar</div>
|
||||
<h4 class="h6 fw-bold mb-2">Número listo para copiar</h4>
|
||||
<div class="fs-4 fw-semibold lh-sm text-primary" id="airDroidPhoneNumber-<?php echo htmlspecialchars($order['source_key']); ?>"><?php echo htmlspecialchars(cc_test_display_value($order['celular'], 'Sin celular')); ?></div>
|
||||
<h4 class="h6 fw-bold mb-2"><?php echo !empty($order['llamada_bloqueada_dia3']) ? 'Celular oculto' : 'Número listo para copiar'; ?></h4>
|
||||
<div class="fs-4 fw-semibold lh-sm text-primary" id="airDroidPhoneNumber-<?php echo htmlspecialchars($order['source_key']); ?>">
|
||||
<?php if (!empty($order['llamada_bloqueada_dia3'])): ?>
|
||||
<span class="badge bg-warning-subtle text-warning-emphasis border" title="<?php echo htmlspecialchars((string) ($order['llamada_bloqueada_dia3_mensaje'] ?? 'Celular oculto hasta completar el sustento de Día 3.'), ENT_QUOTES); ?>" aria-label="<?php echo htmlspecialchars((string) ($order['llamada_bloqueada_dia3_mensaje'] ?? 'Celular oculto hasta completar el sustento de Día 3.'), ENT_QUOTES); ?>">
|
||||
<i class="bi bi-lock-fill me-1"></i>Celular oculto
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<?php echo htmlspecialchars(cc_test_display_value($order['celular'], 'Sin celular')); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-column gap-2">
|
||||
<button type="button" class="btn btn-outline-primary btn-sm" id="airDroidCopyButton-<?php echo htmlspecialchars($order['source_key']); ?>" data-phone="<?php echo htmlspecialchars((string) ($order['celular'] ?? '')); ?>" onclick="copyPhoneToClipboard(this.dataset.phone); return false;">Copiar número</button>
|
||||
<button type="button" class="btn btn-outline-primary btn-sm" id="airDroidCopyButton-<?php echo htmlspecialchars($order['source_key']); ?>" data-phone="<?php echo !empty($order['llamada_bloqueada_dia3']) ? '' : htmlspecialchars((string) ($order['celular'] ?? '')); ?>" onclick="copyPhoneToClipboard(this.dataset.phone); return false;"<?php echo !empty($order['llamada_bloqueada_dia3']) ? ' disabled' : ''; ?>><?php echo !empty($order['llamada_bloqueada_dia3']) ? 'Número oculto' : 'Copiar número'; ?></button>
|
||||
<button type="button" class="btn btn-outline-secondary btn-sm" onclick="openAirDroidWeb()">Abrir AirDroid Web</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -2737,6 +2769,7 @@ function showAirDroidHelper(details) {
|
||||
const registered = !!details.registered;
|
||||
const copied = !!details.copied;
|
||||
const modalId = details.modalId || '';
|
||||
const phoneLocked = !!details.phoneLocked;
|
||||
|
||||
if (modalId) {
|
||||
const modalElement = document.getElementById(modalId);
|
||||
@ -2753,10 +2786,26 @@ function showAirDroidHelper(details) {
|
||||
|
||||
if (orderNode) orderNode.textContent = orderLabel;
|
||||
if (clientNode) clientNode.textContent = clientName;
|
||||
if (phoneNode) phoneNode.textContent = phone;
|
||||
if (phoneNode) {
|
||||
if (phoneLocked) {
|
||||
phoneNode.innerHTML = '<span class="badge bg-warning-subtle text-warning-emphasis border"><i class="bi bi-lock-fill me-1"></i>Celular oculto</span>';
|
||||
} else {
|
||||
phoneNode.textContent = phone;
|
||||
}
|
||||
}
|
||||
|
||||
if (copyButton) {
|
||||
copyButton.dataset.phone = phone !== '-' ? phone : '';
|
||||
if (phoneLocked) {
|
||||
copyButton.dataset.phone = '';
|
||||
copyButton.disabled = true;
|
||||
copyButton.textContent = 'Número oculto';
|
||||
copyButton.setAttribute('title', 'Disponible cuando se complete el sustento de Día 3');
|
||||
} else {
|
||||
copyButton.dataset.phone = phone !== '-' ? phone : '';
|
||||
copyButton.disabled = false;
|
||||
copyButton.textContent = 'Copiar número';
|
||||
copyButton.removeAttribute('title');
|
||||
}
|
||||
}
|
||||
|
||||
if (openButton) {
|
||||
@ -2776,6 +2825,7 @@ function registrarLlamada(event, trigger) {
|
||||
const phone = normalizarNumeroTelefono(trigger?.dataset?.phone || '');
|
||||
const orderLabel = trigger?.dataset?.orderLabel || '';
|
||||
const clientName = trigger?.dataset?.clientName || '';
|
||||
const phoneLocked = trigger?.dataset?.phoneLocked === '1';
|
||||
|
||||
if (!sourceKey) {
|
||||
alert('No se encontró el pedido para registrar la llamada.');
|
||||
@ -2837,6 +2887,7 @@ function registrarLlamada(event, trigger) {
|
||||
sourceKey,
|
||||
modalId,
|
||||
phone,
|
||||
phoneLocked,
|
||||
orderLabel,
|
||||
clientName,
|
||||
registered,
|
||||
|
||||
@ -320,7 +320,7 @@ $_SESSION[cc_test_callcenter_view_session_key()] = cc_test_normalize_context_key
|
||||
|
||||
$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.'
|
||||
: '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 desde el Día 3 para pedidos nuevos desde el 29/07/2026 y desde el Día 4 para pedidos anteriores; exige imagen de sustento para mover el pedido.';
|
||||
: '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 desde el Día 3 para pedidos nuevos desde el 29/07/2026 y desde el Día 4 para pedidos anteriores; exige imagen de sustento para mover el pedido. En las vistas <strong>Todos</strong> y <strong>Últimos 3 días hábiles</strong>, los pedidos del nuevo flujo con sustento pendiente se muestran con candado en el número hasta completar ese paso; la llamada sigue disponible desde el panel.';
|
||||
|
||||
$errorMessage = null;
|
||||
$noticeMessage = null;
|
||||
@ -887,6 +887,12 @@ try {
|
||||
$order['promo_final_evidencia_cargada'] = trim((string) ($order['promo_final_evidencia_path'] ?? '')) !== '';
|
||||
$order['es_promo_final'] = $order['promo_final_habilitado'] && $order['promo_final_evidencia_cargada'];
|
||||
$order['promo_final_pendiente'] = $order['promo_final_habilitado'] && !$order['promo_final_evidencia_cargada'];
|
||||
$order['llamada_bloqueada_dia3'] = $followupDayInfo !== null
|
||||
&& !empty($order['promo_final_pendiente'])
|
||||
&& (int) ($followupDayInfo['promo_final_threshold_day'] ?? 4) === 3;
|
||||
$order['llamada_bloqueada_dia3_mensaje'] = $order['llamada_bloqueada_dia3']
|
||||
? 'Celular oculto hasta completar el sustento de Día 3.'
|
||||
: '';
|
||||
$order['pendiente_logistica_destino'] = cc_test_is_tuani_store_key($storeKey) ? cc_test_pending_logistica_destination($order) : null;
|
||||
$order['pendiente_logistica'] = $order['pendiente_logistica_destino'] !== null;
|
||||
|
||||
@ -2042,14 +2048,14 @@ require_once 'layout_header.php';
|
||||
</div>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
<div class="d-flex flex-column gap-1 align-items-stretch cc-callcenter-actions<?php echo in_array($_SESSION['user_role'] ?? '', ['Administrador', 'admin'], true) ? ' mt-1' : ''; ?>">
|
||||
<?php if (!empty($order['telefono_url'])): ?>
|
||||
<div class="d-flex flex-column gap-1 align-items-stretch cc-callcenter-actions<?php echo in_array($_SESSION['user_role'] ?? '', ['Administrador', 'admin'], true) ? ' mt-1' : ''; ?>"> <?php if (!empty($order['telefono_url'])): ?>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm btn-primary cc-callcenter-action-btn"
|
||||
data-source-key="<?php echo htmlspecialchars($order['source_key']); ?>"
|
||||
data-modal-id="<?php echo htmlspecialchars($modalId); ?>"
|
||||
data-phone="<?php echo htmlspecialchars((string) ($order['celular'] ?? '')); ?>"
|
||||
data-phone-locked="<?php echo !empty($order['llamada_bloqueada_dia3']) ? '1' : '0'; ?>"
|
||||
data-order-label="<?php echo htmlspecialchars(cc_test_order_label($order)); ?>"
|
||||
data-client-name="<?php echo htmlspecialchars(cc_test_display_value($order['nombre'], 'Cliente sin nombre')); ?>"
|
||||
onclick="return registrarLlamada(event, this)">
|
||||
@ -2080,7 +2086,16 @@ require_once 'layout_header.php';
|
||||
</td>
|
||||
<td>
|
||||
<div class="fw-semibold"><?php echo htmlspecialchars(cc_test_display_value($order['nombre'], 'Sin nombre')); ?></div>
|
||||
<div class="small text-muted mb-1">Celular: <?php echo htmlspecialchars(cc_test_display_value($order['celular'], 'Sin número')); ?></div>
|
||||
<div class="small text-muted mb-1">
|
||||
Celular:
|
||||
<?php if (!empty($order['llamada_bloqueada_dia3'])): ?>
|
||||
<span class="badge bg-warning-subtle text-warning-emphasis border ms-1" title="<?php echo htmlspecialchars((string) ($order['llamada_bloqueada_dia3_mensaje'] ?? 'Celular oculto hasta completar el sustento de Día 3.'), ENT_QUOTES); ?>" aria-label="<?php echo htmlspecialchars((string) ($order['llamada_bloqueada_dia3_mensaje'] ?? 'Celular oculto hasta completar el sustento de Día 3.'), ENT_QUOTES); ?>">
|
||||
<i class="bi bi-lock-fill me-1"></i>Celular oculto
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<?php echo htmlspecialchars(cc_test_display_value($order['celular'], 'Sin número')); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="small text-muted">DNI: <?php echo htmlspecialchars(cc_test_display_value($order['dni'], 'Sin DNI')); ?></div>
|
||||
</td>
|
||||
<td>
|
||||
@ -2160,10 +2175,19 @@ require_once 'layout_header.php';
|
||||
<button type="button" class="btn btn-primary btn-sm px-3" id="subir-logistica-<?php echo htmlspecialchars($order['source_key']); ?>" data-route-pedido-id="<?php echo (int) ($order['ruta_contraentrega_pedido_id'] ?? 0); ?>" data-rotulado-pedido-id="<?php echo (int) ($order['pedido_rotulado_pedido_id'] ?? 0); ?>" onclick="guardarGestion('<?php echo htmlspecialchars($order['source_key']); ?>', this, { subirLogistica: true })"><?php echo htmlspecialchars($subirLogisticaButtonLabel); ?></button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="small text-muted mt-1"><?php echo htmlspecialchars(cc_test_display_value($order['producto'], 'Sin producto')); ?> · <?php echo htmlspecialchars(cc_test_display_value($order['celular'], 'Sin celular')); ?></div>
|
||||
<div class="small text-muted mt-1">
|
||||
<?php echo htmlspecialchars(cc_test_display_value($order['producto'], 'Sin producto')); ?> ·
|
||||
<?php if (!empty($order['llamada_bloqueada_dia3'])): ?>
|
||||
<span class="badge bg-warning-subtle text-warning-emphasis border ms-1" title="<?php echo htmlspecialchars((string) ($order['llamada_bloqueada_dia3_mensaje'] ?? 'Celular oculto hasta completar el sustento de Día 3.'), ENT_QUOTES); ?>" aria-label="<?php echo htmlspecialchars((string) ($order['llamada_bloqueada_dia3_mensaje'] ?? 'Celular oculto hasta completar el sustento de Día 3.'), ENT_QUOTES); ?>">
|
||||
<i class="bi bi-lock-fill me-1"></i>Celular oculto
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<?php echo htmlspecialchars(cc_test_display_value($order['celular'], 'Sin celular')); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if ($followupDayInfo !== null): ?>
|
||||
<div class="small mt-2 <?php echo htmlspecialchars(!empty($followupDayInfo['notice_text']) ? $followupDayInfo['text_class'] : 'text-muted'); ?><?php echo !empty($followupDayInfo['notice_text']) ? ' fw-semibold' : ''; ?>">
|
||||
<?php echo htmlspecialchars(!empty($followupDayInfo['notice_text']) ? $followupDayInfo['notice_text'] : ('Seguimiento iniciado el ' . $followupDayInfo['started_at_label'] . '.')); ?>
|
||||
<?php echo htmlspecialchars(!empty($followupDayInfo['notice_text']) ? $followupDayInfo['notice_text'] : ('Seguimiento asignado el ' . $followupDayInfo['started_at_label'] . '.')); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php $promoFinalProofPath = trim((string) ($order['promo_final_evidencia_path'] ?? '')); ?>
|
||||
@ -2202,11 +2226,19 @@ require_once 'layout_header.php';
|
||||
<div class="d-flex flex-wrap justify-content-between align-items-center gap-2">
|
||||
<div>
|
||||
<div class="small text-muted mb-1">Llamar / Gestionar</div>
|
||||
<h4 class="h6 fw-bold mb-2">Número listo para copiar</h4>
|
||||
<div class="fs-4 fw-semibold lh-sm text-primary" id="airDroidPhoneNumber-<?php echo htmlspecialchars($order['source_key']); ?>"><?php echo htmlspecialchars(cc_test_display_value($order['celular'], 'Sin celular')); ?></div>
|
||||
<h4 class="h6 fw-bold mb-2"><?php echo !empty($order['llamada_bloqueada_dia3']) ? 'Celular oculto' : 'Número listo para copiar'; ?></h4>
|
||||
<div class="fs-4 fw-semibold lh-sm text-primary" id="airDroidPhoneNumber-<?php echo htmlspecialchars($order['source_key']); ?>">
|
||||
<?php if (!empty($order['llamada_bloqueada_dia3'])): ?>
|
||||
<span class="badge bg-warning-subtle text-warning-emphasis border" title="<?php echo htmlspecialchars((string) ($order['llamada_bloqueada_dia3_mensaje'] ?? 'Celular oculto hasta completar el sustento de Día 3.'), ENT_QUOTES); ?>" aria-label="<?php echo htmlspecialchars((string) ($order['llamada_bloqueada_dia3_mensaje'] ?? 'Celular oculto hasta completar el sustento de Día 3.'), ENT_QUOTES); ?>">
|
||||
<i class="bi bi-lock-fill me-1"></i>Celular oculto
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<?php echo htmlspecialchars(cc_test_display_value($order['celular'], 'Sin celular')); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-column gap-2">
|
||||
<button type="button" class="btn btn-outline-primary btn-sm" id="airDroidCopyButton-<?php echo htmlspecialchars($order['source_key']); ?>" data-phone="<?php echo htmlspecialchars((string) ($order['celular'] ?? '')); ?>" onclick="copyPhoneToClipboard(this.dataset.phone); return false;">Copiar número</button>
|
||||
<button type="button" class="btn btn-outline-primary btn-sm" id="airDroidCopyButton-<?php echo htmlspecialchars($order['source_key']); ?>" data-phone="<?php echo !empty($order['llamada_bloqueada_dia3']) ? '' : htmlspecialchars((string) ($order['celular'] ?? '')); ?>" onclick="copyPhoneToClipboard(this.dataset.phone); return false;"<?php echo !empty($order['llamada_bloqueada_dia3']) ? ' disabled' : ''; ?>><?php echo !empty($order['llamada_bloqueada_dia3']) ? 'Número oculto' : 'Copiar número'; ?></button>
|
||||
<button type="button" class="btn btn-outline-secondary btn-sm" onclick="openAirDroidWeb()">Abrir AirDroid Web</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -3253,6 +3285,7 @@ function showAirDroidHelper(details) {
|
||||
const registered = !!details.registered;
|
||||
const copied = !!details.copied;
|
||||
const modalId = details.modalId || '';
|
||||
const phoneLocked = !!details.phoneLocked;
|
||||
|
||||
if (modalId) {
|
||||
const modalElement = document.getElementById(modalId);
|
||||
@ -3269,10 +3302,26 @@ function showAirDroidHelper(details) {
|
||||
|
||||
if (orderNode) orderNode.textContent = orderLabel;
|
||||
if (clientNode) clientNode.textContent = clientName;
|
||||
if (phoneNode) phoneNode.textContent = phone;
|
||||
if (phoneNode) {
|
||||
if (phoneLocked) {
|
||||
phoneNode.innerHTML = '<span class="badge bg-warning-subtle text-warning-emphasis border"><i class="bi bi-lock-fill me-1"></i>Celular oculto</span>';
|
||||
} else {
|
||||
phoneNode.textContent = phone;
|
||||
}
|
||||
}
|
||||
|
||||
if (copyButton) {
|
||||
copyButton.dataset.phone = phone !== '-' ? phone : '';
|
||||
if (phoneLocked) {
|
||||
copyButton.dataset.phone = '';
|
||||
copyButton.disabled = true;
|
||||
copyButton.textContent = 'Número oculto';
|
||||
copyButton.setAttribute('title', 'Disponible cuando se complete el sustento de Día 3');
|
||||
} else {
|
||||
copyButton.dataset.phone = phone !== '-' ? phone : '';
|
||||
copyButton.disabled = false;
|
||||
copyButton.textContent = 'Copiar número';
|
||||
copyButton.removeAttribute('title');
|
||||
}
|
||||
}
|
||||
|
||||
if (openButton) {
|
||||
@ -3292,6 +3341,7 @@ function registrarLlamada(event, trigger) {
|
||||
const phone = normalizarNumeroTelefono(trigger?.dataset?.phone || '');
|
||||
const orderLabel = trigger?.dataset?.orderLabel || '';
|
||||
const clientName = trigger?.dataset?.clientName || '';
|
||||
const phoneLocked = trigger?.dataset?.phoneLocked === '1';
|
||||
|
||||
if (!sourceKey) {
|
||||
alert('No se encontró el pedido para registrar la llamada.');
|
||||
@ -3353,6 +3403,7 @@ function registrarLlamada(event, trigger) {
|
||||
sourceKey,
|
||||
modalId,
|
||||
phone,
|
||||
phoneLocked,
|
||||
orderLabel,
|
||||
clientName,
|
||||
registered,
|
||||
|
||||
@ -1320,7 +1320,7 @@ function cc_test_followup_parse_datetime(?string $value): ?DateTimeImmutable
|
||||
|
||||
function cc_test_followup_started_at(array $order): ?DateTimeImmutable
|
||||
{
|
||||
foreach (['drive_imported_at', 'first_seen_at', 'import_id'] as $field) {
|
||||
foreach (['assigned_at', 'drive_imported_at', 'first_seen_at', 'import_id'] as $field) {
|
||||
$date = cc_test_followup_parse_datetime($order[$field] ?? null);
|
||||
if ($date instanceof DateTimeImmutable) {
|
||||
return $date;
|
||||
|
||||
@ -30,10 +30,12 @@ try {
|
||||
|
||||
$role = (string) ($_SESSION['user_role'] ?? '');
|
||||
$isAdmin = in_array($role, ['Administrador', 'admin'], true);
|
||||
$tracking = null;
|
||||
|
||||
if (!$isAdmin) {
|
||||
cc_test_ensure_tracking_table($pdo);
|
||||
|
||||
$stmtTrack = $pdo->prepare('SELECT user_id FROM callcenter_test_tracking WHERE source_key = ? LIMIT 1');
|
||||
$stmtTrack = $pdo->prepare('SELECT user_id, estado, assigned_at, promo_final_evidencia_path FROM callcenter_test_tracking WHERE source_key = ? LIMIT 1');
|
||||
$stmtTrack->execute([$pedido_id]);
|
||||
$tracking = $stmtTrack->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
|
||||
@ -866,7 +866,7 @@ try {
|
||||
$pdo = db();
|
||||
cc_test_ensure_tracking_table($pdo);
|
||||
|
||||
$stmtCurrent = $pdo->prepare('SELECT estado, numero_cuenta_enviado_at, numero_cuenta_sede_id, numero_cuenta_dni, user_id, promo_final_evidencia_path, promo_final_evidencia_subido_at, promo_final_evidencia_subido_por, cancelado_evidencia_path, cancelado_evidencia_subido_at, cancelado_evidencia_subido_por, eliminado_at, eliminado_por, ruta_contraentrega_pedido_id, pedido_rotulado_pedido_id FROM callcenter_test_tracking WHERE source_key = ? LIMIT 1');
|
||||
$stmtCurrent = $pdo->prepare('SELECT estado, numero_cuenta_enviado_at, numero_cuenta_sede_id, numero_cuenta_dni, user_id, assigned_at, promo_final_evidencia_path, promo_final_evidencia_subido_at, promo_final_evidencia_subido_por, cancelado_evidencia_path, cancelado_evidencia_subido_at, cancelado_evidencia_subido_por, eliminado_at, eliminado_por, ruta_contraentrega_pedido_id, pedido_rotulado_pedido_id FROM callcenter_test_tracking WHERE source_key = ? LIMIT 1');
|
||||
$stmtCurrent->execute([$sourceKey]);
|
||||
$currentTracking = $stmtCurrent->fetch(PDO::FETCH_ASSOC) ?: null;
|
||||
|
||||
@ -1071,12 +1071,10 @@ try {
|
||||
throw new RuntimeException('No encontré el pedido base para moverlo a Promo Final.');
|
||||
}
|
||||
|
||||
$promoFinalDayInfo = cc_test_followup_day_info([
|
||||
$promoFinalDayInfo = cc_test_followup_day_info(array_merge($sourceOrderForPromo, [
|
||||
'estado' => $estado,
|
||||
'drive_imported_at' => $sourceOrderForPromo['drive_imported_at'] ?? null,
|
||||
'first_seen_at' => $sourceOrderForPromo['first_seen_at'] ?? null,
|
||||
'import_id' => $sourceOrderForPromo['import_id'] ?? null,
|
||||
]);
|
||||
'assigned_at' => $currentTracking['assigned_at'] ?? null,
|
||||
]));
|
||||
if (empty($promoFinalDayInfo['is_promo_final'])) {
|
||||
$promoFinalThresholdDay = (int) ($promoFinalDayInfo['promo_final_threshold_day'] ?? 4);
|
||||
throw new RuntimeException('Este pedido aún no puede pasar a Promo Final. Recién se habilita desde el Día ' . $promoFinalThresholdDay . '.');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user