Autosave: 20260525-090633
This commit is contained in:
parent
891893f221
commit
bd9aa664a9
@ -3,6 +3,11 @@ session_start();
|
|||||||
require_once 'db/config.php';
|
require_once 'db/config.php';
|
||||||
require_once 'includes/callcenter_test_helpers.php';
|
require_once 'includes/callcenter_test_helpers.php';
|
||||||
require_once 'includes/drive_test_orders.php';
|
require_once 'includes/drive_test_orders.php';
|
||||||
|
require_once 'includes/contraentrega_cobertura.php';
|
||||||
|
|
||||||
|
$provinciasPorDepartamentoContraentrega = contraentregaProvinciasPorDepartamento();
|
||||||
|
$distritosPorProvinciaContraentrega = contraentregaDistritosPorProvincia();
|
||||||
|
$departamentosContraentrega = array_keys($provinciasPorDepartamentoContraentrega);
|
||||||
|
|
||||||
$pageTitle = 'Call Center de Prueba | Bandejas de gestión';
|
$pageTitle = 'Call Center de Prueba | Bandejas de gestión';
|
||||||
$pageDescription = 'Bandejas diarias de Call Center con estados reales, próxima llamada, fecha de entrega, historial y edición de datos del pedido importado desde Drive.';
|
$pageDescription = 'Bandejas diarias de Call Center con estados reales, próxima llamada, fecha de entrega, historial y edición de datos del pedido importado desde Drive.';
|
||||||
@ -69,12 +74,12 @@ function cc_test_order_label(array $order): string
|
|||||||
|
|
||||||
function cc_test_badge_class(string $estado): string
|
function cc_test_badge_class(string $estado): string
|
||||||
{
|
{
|
||||||
return match ($estado) {
|
return match (cc_test_normalize_state($estado)) {
|
||||||
'CONFIRMADO CONTRAENTREGA', 'CONFIRMADO CONTRAENTREGA FECHA', 'CONFIRMADO ENVIO', 'CONFIRMADO FECHA', 'CONTRAENTREGA CONFIRMADO' => 'bg-success-subtle text-success-emphasis',
|
'CONFIRMADO CONTRAENTREGA', 'CONFIRMADO ENVIO' => 'bg-success-subtle text-success-emphasis',
|
||||||
'DEVOLVER LLAMADA' => 'bg-info-subtle text-info-emphasis',
|
'DEVOLVER LLAMADA' => 'bg-info-subtle text-info-emphasis',
|
||||||
'OBSERVADO' => 'bg-warning-subtle text-warning-emphasis',
|
'OBSERVADO' => 'bg-warning-subtle text-warning-emphasis',
|
||||||
'CANCELADO' => 'bg-danger-subtle text-danger-emphasis',
|
'CANCELADO' => 'bg-danger-subtle text-danger-emphasis',
|
||||||
'REPETIDO', 'ENVIO REPETIDO' => 'bg-secondary-subtle text-secondary-emphasis',
|
'REPETIDO' => 'bg-secondary-subtle text-secondary-emphasis',
|
||||||
'SE ENVIO NUMERO DE CUENTA' => 'bg-primary-subtle text-primary-emphasis',
|
'SE ENVIO NUMERO DE CUENTA' => 'bg-primary-subtle text-primary-emphasis',
|
||||||
default => 'bg-dark-subtle text-dark-emphasis',
|
default => 'bg-dark-subtle text-dark-emphasis',
|
||||||
};
|
};
|
||||||
@ -82,7 +87,7 @@ function cc_test_badge_class(string $estado): string
|
|||||||
|
|
||||||
function cc_test_order_time(array $order): int
|
function cc_test_order_time(array $order): int
|
||||||
{
|
{
|
||||||
foreach (['proxima_llamada_at', 'ultima_gestion_at', 'seguimiento_actualizado', 'import_id'] as $field) {
|
foreach (['proxima_llamada_at', 'numero_cuenta_enviado_at', 'ultima_gestion_at', 'seguimiento_actualizado', 'import_id'] as $field) {
|
||||||
$date = cc_test_parse_datetime($order[$field] ?? null);
|
$date = cc_test_parse_datetime($order[$field] ?? null);
|
||||||
if ($date) {
|
if ($date) {
|
||||||
return $date->getTimestamp();
|
return $date->getTimestamp();
|
||||||
@ -92,6 +97,15 @@ function cc_test_order_time(array $order): int
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cc_test_followup_semaforo(array $order): ?array
|
||||||
|
{
|
||||||
|
if (cc_test_normalize_state((string) ($order['estado'] ?? '')) !== 'SE ENVIO NUMERO DE CUENTA') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cc_test_account_followup_semaforo($order['numero_cuenta_enviado_at'] ?? null);
|
||||||
|
}
|
||||||
|
|
||||||
$view = $_GET['view'] ?? 'pendientes_hoy';
|
$view = $_GET['view'] ?? 'pendientes_hoy';
|
||||||
$allowedViews = [
|
$allowedViews = [
|
||||||
'pendientes_hoy' => 'Pendientes de hoy',
|
'pendientes_hoy' => 'Pendientes de hoy',
|
||||||
@ -147,6 +161,7 @@ try {
|
|||||||
$closedStates = cc_test_closed_states();
|
$closedStates = cc_test_closed_states();
|
||||||
|
|
||||||
foreach ($orders as &$order) {
|
foreach ($orders as &$order) {
|
||||||
|
$order['estado'] = cc_test_normalize_state((string) ($order['estado'] ?? ''));
|
||||||
$order['total_llamadas'] = (int) ($callCounts[$order['source_key']] ?? 0);
|
$order['total_llamadas'] = (int) ($callCounts[$order['source_key']] ?? 0);
|
||||||
$importDate = cc_test_parse_datetime($order['import_id'] ?? null);
|
$importDate = cc_test_parse_datetime($order['import_id'] ?? null);
|
||||||
$proximaDate = cc_test_parse_datetime($order['proxima_llamada_at'] ?? null);
|
$proximaDate = cc_test_parse_datetime($order['proxima_llamada_at'] ?? null);
|
||||||
@ -239,7 +254,7 @@ require_once 'layout_header.php';
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-lg-4">
|
<div class="col-lg-4">
|
||||||
<div class="small text-muted">Campos editables del módulo</div>
|
<div class="small text-muted">Campos editables del módulo</div>
|
||||||
<div class="fw-semibold">Dirección, referencia, sede / ID, ciudad, distrito, DNI y observaciones</div>
|
<div class="fw-semibold">Dirección, referencia, departamento, provincia, distrito, DNI y observaciones</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@ -311,7 +326,7 @@ require_once 'layout_header.php';
|
|||||||
<div class="card-header bg-white py-3 d-flex flex-column flex-lg-row justify-content-between align-items-lg-center gap-2">
|
<div class="card-header bg-white py-3 d-flex flex-column flex-lg-row justify-content-between align-items-lg-center gap-2">
|
||||||
<div>
|
<div>
|
||||||
<h2 class="h5 fw-bold mb-1"><?php echo htmlspecialchars($allowedViews[$view]); ?></h2>
|
<h2 class="h5 fw-bold mb-1"><?php echo htmlspecialchars($allowedViews[$view]); ?></h2>
|
||||||
<p class="text-muted small mb-1">Estados disponibles: Por llamar, Devolver llamada, Observado, Se envió número de cuenta, Confirmado contraentrega 📅, Confirmado envío, Cancelado y Repetido.</p>
|
<p class="text-muted small mb-1">Estados disponibles: Por llamar, Devolver llamada, Observado, Se envió número de cuenta, Confirmado contraentrega, Confirmado envío, Cancelado y Repetido.</p>
|
||||||
<p class="small text-primary mb-0"><i class="bi bi-phone"></i> El botón <strong>Llamar / AirDroid</strong> registra el intento, copia el número y muestra la ayuda visual para pegar en tu app de AirDroid.</p>
|
<p class="small text-primary mb-0"><i class="bi bi-phone"></i> El botón <strong>Llamar / AirDroid</strong> registra el intento, copia el número y muestra la ayuda visual para pegar en tu app de AirDroid.</p>
|
||||||
</div>
|
</div>
|
||||||
<span class="badge bg-light text-dark border"><?php echo count($visibleOrders); ?> pedidos en esta bandeja</span>
|
<span class="badge bg-light text-dark border"><?php echo count($visibleOrders); ?> pedidos en esta bandeja</span>
|
||||||
@ -340,8 +355,14 @@ require_once 'layout_header.php';
|
|||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<?php foreach ($visibleOrders as $order): ?>
|
<?php foreach ($visibleOrders as $order): ?>
|
||||||
<?php
|
<?php
|
||||||
|
$departamentoSeleccionado = trim((string) ($order['sede'] ?? ''));
|
||||||
|
$provinciaSeleccionada = trim((string) ($order['ciudad'] ?? ''));
|
||||||
|
$distritoSeleccionado = trim((string) ($order['distrito'] ?? ''));
|
||||||
|
$provinciasSeleccionadas = $provinciasPorDepartamentoContraentrega[$departamentoSeleccionado] ?? [];
|
||||||
|
$distritosSeleccionados = $distritosPorProvinciaContraentrega[$provinciaSeleccionada] ?? [];
|
||||||
$modalId = 'modalDriveTest' . $order['source_key'];
|
$modalId = 'modalDriveTest' . $order['source_key'];
|
||||||
$badgeClass = cc_test_badge_class($order['estado']);
|
$badgeClass = cc_test_badge_class($order['estado']);
|
||||||
|
$semaforoCuenta = cc_test_followup_semaforo($order);
|
||||||
$historial = cc_test_fetch_historial(db(), $order['source_key']);
|
$historial = cc_test_fetch_historial(db(), $order['source_key']);
|
||||||
ob_start();
|
ob_start();
|
||||||
?>
|
?>
|
||||||
@ -358,8 +379,12 @@ require_once 'layout_header.php';
|
|||||||
<td>
|
<td>
|
||||||
<div class="small"><strong>Dirección:</strong> <?php echo htmlspecialchars(cc_test_display_value($order['direccion'])); ?></div>
|
<div class="small"><strong>Dirección:</strong> <?php echo htmlspecialchars(cc_test_display_value($order['direccion'])); ?></div>
|
||||||
<div class="small"><strong>Referencia:</strong> <?php echo htmlspecialchars(cc_test_display_value($order['referencia'])); ?></div>
|
<div class="small"><strong>Referencia:</strong> <?php echo htmlspecialchars(cc_test_display_value($order['referencia'])); ?></div>
|
||||||
<div class="small"><strong>Ciudad / Distrito:</strong> <?php echo htmlspecialchars(cc_test_display_value(trim(($order['ciudad'] ?? '') . ' / ' . ($order['distrito'] ?? '')), 'No registrado')); ?></div>
|
<div class="small"><strong>Departamento:</strong> <?php echo htmlspecialchars(cc_test_display_value($order['sede'])); ?></div>
|
||||||
<div class="small"><strong>Sede / ID:</strong> <?php echo htmlspecialchars(cc_test_display_value($order['sede'])); ?></div>
|
<div class="small"><strong>Provincia:</strong> <?php echo htmlspecialchars(cc_test_display_value($order['ciudad'])); ?></div>
|
||||||
|
<div class="small"><strong>Distrito:</strong> <?php echo htmlspecialchars(cc_test_display_value($order['distrito'])); ?></div>
|
||||||
|
<?php if (!empty(trim((string) ($order['distrito_drive'] ?? '')))): ?>
|
||||||
|
<div class="small"><strong>DISTRITO 1:</strong> <?php echo htmlspecialchars(cc_test_display_value($order['distrito_drive'])); ?></div>
|
||||||
|
<?php endif; ?>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="fw-semibold"><?php echo htmlspecialchars(cc_test_display_value($order['producto'], 'Sin producto')); ?></div>
|
<div class="fw-semibold"><?php echo htmlspecialchars(cc_test_display_value($order['producto'], 'Sin producto')); ?></div>
|
||||||
@ -371,10 +396,16 @@ require_once 'layout_header.php';
|
|||||||
<div class="d-flex flex-wrap gap-2 mb-2">
|
<div class="d-flex flex-wrap gap-2 mb-2">
|
||||||
<span class="badge rounded-pill <?php echo htmlspecialchars($badgeClass); ?>"><?php echo htmlspecialchars(cc_test_state_label($order['estado'])); ?></span>
|
<span class="badge rounded-pill <?php echo htmlspecialchars($badgeClass); ?>"><?php echo htmlspecialchars(cc_test_state_label($order['estado'])); ?></span>
|
||||||
<span class="badge rounded-pill bg-light text-dark border"><span class="js-call-count-number" data-source-key="<?php echo htmlspecialchars($order['source_key']); ?>"><?php echo (int) $order['total_llamadas']; ?></span> llamadas</span>
|
<span class="badge rounded-pill bg-light text-dark border"><span class="js-call-count-number" data-source-key="<?php echo htmlspecialchars($order['source_key']); ?>"><?php echo (int) $order['total_llamadas']; ?></span> llamadas</span>
|
||||||
|
<?php if ($semaforoCuenta !== null): ?>
|
||||||
|
<span class="badge rounded-pill <?php echo htmlspecialchars($semaforoCuenta['class']); ?>">Seguimiento <?php echo htmlspecialchars($semaforoCuenta['label']); ?></span>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
|
<?php if ($semaforoCuenta !== null): ?>
|
||||||
|
<div class="small text-muted mb-1">Número de cuenta enviado hace <?php echo (int) $semaforoCuenta['days']; ?> día<?php echo ((int) $semaforoCuenta['days'] === 1) ? '' : 's'; ?> · <?php echo htmlspecialchars($semaforoCuenta['range']); ?></div>
|
||||||
|
<?php endif; ?>
|
||||||
<div class="small text-muted">Próxima llamada: <?php echo htmlspecialchars(cc_test_format_datetime($order['proxima_llamada_at'] ?? null)); ?></div>
|
<div class="small text-muted">Próxima llamada: <?php echo htmlspecialchars(cc_test_format_datetime($order['proxima_llamada_at'] ?? null)); ?></div>
|
||||||
<?php if (!empty($order['fecha_entrega_programada'])): ?>
|
<?php if (!empty($order['fecha_entrega_programada'])): ?>
|
||||||
<div class="small text-muted">Entrega programada 📅: <?php echo htmlspecialchars(cc_test_format_date($order['fecha_entrega_programada'] ?? null)); ?></div>
|
<div class="small text-muted">Entrega programada: <?php echo htmlspecialchars(cc_test_format_date($order['fecha_entrega_programada'] ?? null)); ?></div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<div class="small text-muted">Última gestión: <?php echo htmlspecialchars(cc_test_format_datetime($order['ultima_gestion_at'] ?? ($order['seguimiento_actualizado'] ?? null), 'Aún no gestionado')); ?></div>
|
<div class="small text-muted">Última gestión: <?php echo htmlspecialchars(cc_test_format_datetime($order['ultima_gestion_at'] ?? ($order['seguimiento_actualizado'] ?? null), 'Aún no gestionado')); ?></div>
|
||||||
<div class="small text-muted mt-1">Nota: <?php echo htmlspecialchars(cc_test_display_value($order['nota_seguimiento'], 'Sin nota interna')); ?></div>
|
<div class="small text-muted mt-1">Nota: <?php echo htmlspecialchars(cc_test_display_value($order['nota_seguimiento'], 'Sin nota interna')); ?></div>
|
||||||
@ -426,6 +457,14 @@ require_once 'layout_header.php';
|
|||||||
<div class="border rounded p-3 h-100 bg-light-subtle">
|
<div class="border rounded p-3 h-100 bg-light-subtle">
|
||||||
<div class="small text-muted">Estado actual</div>
|
<div class="small text-muted">Estado actual</div>
|
||||||
<div class="fw-semibold"><?php echo htmlspecialchars(cc_test_state_label($order['estado'])); ?></div>
|
<div class="fw-semibold"><?php echo htmlspecialchars(cc_test_state_label($order['estado'])); ?></div>
|
||||||
|
<?php if ($semaforoCuenta !== null): ?>
|
||||||
|
<div class="mt-2">
|
||||||
|
<span class="badge rounded-pill <?php echo htmlspecialchars($semaforoCuenta['class']); ?>">Seguimiento <?php echo htmlspecialchars($semaforoCuenta['label']); ?></span>
|
||||||
|
</div>
|
||||||
|
<div class="small text-muted mt-2">Enviado hace <?php echo (int) $semaforoCuenta['days']; ?> día<?php echo ((int) $semaforoCuenta['days'] === 1) ? '' : 's'; ?> · <?php echo htmlspecialchars($semaforoCuenta['description']); ?></div>
|
||||||
|
<?php else: ?>
|
||||||
|
<div class="small text-muted mt-2">El semáforo se activa cuando marques “Se envió número de cuenta”.</div>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-3 col-md-6">
|
<div class="col-lg-3 col-md-6">
|
||||||
@ -467,13 +506,13 @@ require_once 'layout_header.php';
|
|||||||
<input type="datetime-local" class="form-control" id="proxima-<?php echo htmlspecialchars($order['source_key']); ?>" value="<?php echo htmlspecialchars(cc_test_format_datetime_input($order['proxima_llamada_at'] ?? null)); ?>">
|
<input type="datetime-local" class="form-control" id="proxima-<?php echo htmlspecialchars($order['source_key']); ?>" value="<?php echo htmlspecialchars(cc_test_format_datetime_input($order['proxima_llamada_at'] ?? null)); ?>">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4 js-delivery-group <?php echo cc_test_requires_delivery_date($order['estado']) ? '' : 'd-none'; ?>" id="delivery-group-<?php echo htmlspecialchars($order['source_key']); ?>">
|
<div class="col-md-4 js-delivery-group <?php echo cc_test_requires_delivery_date($order['estado']) ? '' : 'd-none'; ?>" id="delivery-group-<?php echo htmlspecialchars($order['source_key']); ?>">
|
||||||
<label for="fecha-entrega-<?php echo htmlspecialchars($order['source_key']); ?>" class="form-label">Fecha de entrega 📅</label>
|
<label for="fecha-entrega-<?php echo htmlspecialchars($order['source_key']); ?>" class="form-label">Fecha de entrega</label>
|
||||||
<input type="date" class="form-control" id="fecha-entrega-<?php echo htmlspecialchars($order['source_key']); ?>" value="<?php echo htmlspecialchars(cc_test_format_date_input($order['fecha_entrega_programada'] ?? null)); ?>">
|
<input type="date" class="form-control" id="fecha-entrega-<?php echo htmlspecialchars($order['source_key']); ?>" value="<?php echo htmlspecialchars(cc_test_format_date_input($order['fecha_entrega_programada'] ?? null)); ?>">
|
||||||
<div class="form-text">Úsalo cuando el cliente quede en Confirmado fecha.</div>
|
<div class="form-text">Úsalo cuando el cliente quede en Confirmado fecha.</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label class="form-label">Resumen</label>
|
<label class="form-label">Resumen</label>
|
||||||
<div class="border rounded px-3 py-2 bg-light-subtle small h-100 d-flex align-items-center">Los estados abiertos vuelven a <strong class="ms-1">Pendientes de hoy</strong>; Confirmado contraentrega 📅 te permite programar la entrega.</div>
|
<div class="border rounded px-3 py-2 bg-light-subtle small h-100 d-flex align-items-center">Los estados abiertos vuelven a <strong class="ms-1">Pendientes de hoy</strong>; Confirmado contraentrega te permite programar la entrega.</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<label for="nota-<?php echo htmlspecialchars($order['source_key']); ?>" class="form-label">Nota interna</label>
|
<label for="nota-<?php echo htmlspecialchars($order['source_key']); ?>" class="form-label">Nota interna</label>
|
||||||
@ -494,16 +533,55 @@ require_once 'layout_header.php';
|
|||||||
<textarea class="form-control" id="referencia-<?php echo htmlspecialchars($order['source_key']); ?>" rows="2"><?php echo htmlspecialchars((string) ($order['referencia'] ?? '')); ?></textarea>
|
<textarea class="form-control" id="referencia-<?php echo htmlspecialchars($order['source_key']); ?>" rows="2"><?php echo htmlspecialchars((string) ($order['referencia'] ?? '')); ?></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label for="sede-<?php echo htmlspecialchars($order['source_key']); ?>" class="form-label">Sede / ID</label>
|
<label for="sede-<?php echo htmlspecialchars($order['source_key']); ?>" class="form-label">Departamento</label>
|
||||||
<input type="text" class="form-control" id="sede-<?php echo htmlspecialchars($order['source_key']); ?>" value="<?php echo htmlspecialchars((string) ($order['sede'] ?? '')); ?>">
|
<select class="form-select js-location-department" id="sede-<?php echo htmlspecialchars($order['source_key']); ?>">
|
||||||
|
<option value="">Seleccione departamento</option>
|
||||||
|
<?php foreach ($departamentosContraentrega as $departamentoOption): ?>
|
||||||
|
<option value="<?php echo htmlspecialchars($departamentoOption); ?>" <?php echo $departamentoSeleccionado === $departamentoOption ? 'selected' : ''; ?>>
|
||||||
|
<?php echo htmlspecialchars($departamentoOption); ?>
|
||||||
|
</option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php if ($departamentoSeleccionado !== '' && !in_array($departamentoSeleccionado, $departamentosContraentrega, true)): ?>
|
||||||
|
<option value="<?php echo htmlspecialchars($departamentoSeleccionado); ?>" selected>
|
||||||
|
<?php echo htmlspecialchars($departamentoSeleccionado); ?>
|
||||||
|
</option>
|
||||||
|
<?php endif; ?>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label for="ciudad-<?php echo htmlspecialchars($order['source_key']); ?>" class="form-label">Ciudad</label>
|
<label for="ciudad-<?php echo htmlspecialchars($order['source_key']); ?>" class="form-label">Provincia</label>
|
||||||
<input type="text" class="form-control" id="ciudad-<?php echo htmlspecialchars($order['source_key']); ?>" value="<?php echo htmlspecialchars((string) ($order['ciudad'] ?? '')); ?>">
|
<select class="form-select js-location-province" id="ciudad-<?php echo htmlspecialchars($order['source_key']); ?>">
|
||||||
|
<option value="">Seleccione provincia</option>
|
||||||
|
<?php foreach ($provinciasSeleccionadas as $provinciaOption): ?>
|
||||||
|
<option value="<?php echo htmlspecialchars($provinciaOption); ?>" <?php echo $provinciaSeleccionada === $provinciaOption ? 'selected' : ''; ?>>
|
||||||
|
<?php echo htmlspecialchars($provinciaOption); ?>
|
||||||
|
</option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php if ($provinciaSeleccionada !== '' && !in_array($provinciaSeleccionada, $provinciasSeleccionadas, true)): ?>
|
||||||
|
<option value="<?php echo htmlspecialchars($provinciaSeleccionada); ?>" selected>
|
||||||
|
<?php echo htmlspecialchars($provinciaSeleccionada); ?>
|
||||||
|
</option>
|
||||||
|
<?php endif; ?>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label for="distrito-<?php echo htmlspecialchars($order['source_key']); ?>" class="form-label">Distrito</label>
|
<label for="distrito_select-<?php echo htmlspecialchars($order['source_key']); ?>" class="form-label">Distrito</label>
|
||||||
<input type="text" class="form-control" id="distrito-<?php echo htmlspecialchars($order['source_key']); ?>" value="<?php echo htmlspecialchars((string) ($order['distrito'] ?? '')); ?>">
|
<select class="form-select js-location-district <?php echo empty($distritosSeleccionados) ? 'd-none' : ''; ?>" id="distrito_select-<?php echo htmlspecialchars($order['source_key']); ?>">
|
||||||
|
<option value="">Seleccione primero provincia</option>
|
||||||
|
<?php foreach ($distritosSeleccionados as $distritoOption): ?>
|
||||||
|
<option value="<?php echo htmlspecialchars($distritoOption); ?>" <?php echo $distritoSeleccionado === $distritoOption ? 'selected' : ''; ?>>
|
||||||
|
<?php echo htmlspecialchars($distritoOption); ?>
|
||||||
|
</option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php if ($distritoSeleccionado !== '' && !in_array($distritoSeleccionado, $distritosSeleccionados, true)): ?>
|
||||||
|
<option value="<?php echo htmlspecialchars($distritoSeleccionado); ?>" selected>
|
||||||
|
<?php echo htmlspecialchars($distritoSeleccionado); ?>
|
||||||
|
</option>
|
||||||
|
<?php endif; ?>
|
||||||
|
</select>
|
||||||
|
<input type="text" class="form-control mt-2 js-location-district-manual <?php echo empty($distritosSeleccionados) ? '' : 'd-none'; ?>" id="distrito_manual-<?php echo htmlspecialchars($order['source_key']); ?>" placeholder="Escriba el distrito si aún no está en cobertura" value="<?php echo htmlspecialchars($distritoSeleccionado); ?>">
|
||||||
|
<input type="hidden" id="distrito-<?php echo htmlspecialchars($order['source_key']); ?>" value="<?php echo htmlspecialchars($distritoSeleccionado); ?>">
|
||||||
|
<div class="form-text">Si la provincia aún no tiene cobertura cargada, podrás escribir el distrito manualmente.</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<label for="dni-<?php echo htmlspecialchars($order['source_key']); ?>" class="form-label">DNI</label>
|
<label for="dni-<?php echo htmlspecialchars($order['source_key']); ?>" class="form-label">DNI</label>
|
||||||
@ -541,6 +619,8 @@ require_once 'layout_header.php';
|
|||||||
<div class="fw-semibold mb-2">Origen vs edición</div>
|
<div class="fw-semibold mb-2">Origen vs edición</div>
|
||||||
<div><strong>Dirección Drive:</strong> <?php echo htmlspecialchars(cc_test_display_value($order['direccion_drive'] ?? null)); ?></div>
|
<div><strong>Dirección Drive:</strong> <?php echo htmlspecialchars(cc_test_display_value($order['direccion_drive'] ?? null)); ?></div>
|
||||||
<div><strong>Referencia Drive:</strong> <?php echo htmlspecialchars(cc_test_display_value($order['referencia_drive'] ?? null)); ?></div>
|
<div><strong>Referencia Drive:</strong> <?php echo htmlspecialchars(cc_test_display_value($order['referencia_drive'] ?? null)); ?></div>
|
||||||
|
<div><strong>Distrito 1:</strong> <?php echo htmlspecialchars(cc_test_display_value($order['distrito_drive'] ?? null)); ?></div>
|
||||||
|
<div><strong>Distrito:</strong> <?php echo htmlspecialchars(cc_test_display_value($order['distrito'] ?? null)); ?></div>
|
||||||
<div><strong>Observación Drive:</strong> <?php echo htmlspecialchars(cc_test_display_value($order['observaciones_drive'] ?? null)); ?></div>
|
<div><strong>Observación Drive:</strong> <?php echo htmlspecialchars(cc_test_display_value($order['observaciones_drive'] ?? null)); ?></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -610,13 +690,134 @@ require_once 'layout_header.php';
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
const provinciasPorDepartamento = <?php echo json_encode($provinciasPorDepartamentoContraentrega, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ?>;
|
||||||
|
const distritosPorProvincia = <?php echo json_encode($distritosPorProvinciaContraentrega, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ?>;
|
||||||
|
|
||||||
|
function getLocationControls(sourceKey) {
|
||||||
|
return {
|
||||||
|
department: document.getElementById('sede-' + sourceKey),
|
||||||
|
province: document.getElementById('ciudad-' + sourceKey),
|
||||||
|
districtSelect: document.getElementById('distrito_select-' + sourceKey),
|
||||||
|
districtManual: document.getElementById('distrito_manual-' + sourceKey),
|
||||||
|
districtHidden: document.getElementById('distrito-' + sourceKey)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncDistrictHidden(sourceKey, value) {
|
||||||
|
const controls = getLocationControls(sourceKey);
|
||||||
|
if (controls.districtHidden) {
|
||||||
|
controls.districtHidden.value = value || '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderDistrictOptions(sourceKey, preserveSelection = true) {
|
||||||
|
const controls = getLocationControls(sourceKey);
|
||||||
|
if (!controls.province || !controls.districtSelect || !controls.districtManual || !controls.districtHidden) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const province = controls.province.value || '';
|
||||||
|
const currentValue = preserveSelection ? (controls.districtHidden.value || controls.districtSelect.value || controls.districtManual.value || '') : '';
|
||||||
|
const districts = province ? (distritosPorProvincia[province] || []) : [];
|
||||||
|
|
||||||
|
controls.districtSelect.innerHTML = '';
|
||||||
|
|
||||||
|
const emptyOption = document.createElement('option');
|
||||||
|
emptyOption.value = '';
|
||||||
|
emptyOption.textContent = province ? (districts.length ? 'Seleccione distrito' : 'Sin cobertura registrada') : 'Seleccione primero provincia';
|
||||||
|
controls.districtSelect.appendChild(emptyOption);
|
||||||
|
|
||||||
|
if (!province) {
|
||||||
|
controls.districtSelect.classList.remove('d-none');
|
||||||
|
controls.districtSelect.disabled = true;
|
||||||
|
controls.districtManual.classList.add('d-none');
|
||||||
|
controls.districtManual.value = '';
|
||||||
|
syncDistrictHidden(sourceKey, '');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (districts.length > 0) {
|
||||||
|
districts.forEach(function(distrito) {
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.value = distrito;
|
||||||
|
option.textContent = distrito;
|
||||||
|
if (distrito === currentValue) {
|
||||||
|
option.selected = true;
|
||||||
|
}
|
||||||
|
controls.districtSelect.appendChild(option);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (currentValue && !districts.includes(currentValue)) {
|
||||||
|
const legacyOption = document.createElement('option');
|
||||||
|
legacyOption.value = currentValue;
|
||||||
|
legacyOption.textContent = currentValue + ' (actual)';
|
||||||
|
legacyOption.selected = true;
|
||||||
|
controls.districtSelect.appendChild(legacyOption);
|
||||||
|
}
|
||||||
|
|
||||||
|
controls.districtSelect.classList.remove('d-none');
|
||||||
|
controls.districtSelect.disabled = false;
|
||||||
|
controls.districtManual.classList.add('d-none');
|
||||||
|
controls.districtManual.value = '';
|
||||||
|
controls.districtSelect.value = currentValue || controls.districtSelect.value || '';
|
||||||
|
syncDistrictHidden(sourceKey, controls.districtSelect.value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
controls.districtSelect.classList.add('d-none');
|
||||||
|
controls.districtSelect.disabled = true;
|
||||||
|
controls.districtManual.classList.remove('d-none');
|
||||||
|
controls.districtManual.value = currentValue;
|
||||||
|
syncDistrictHidden(sourceKey, currentValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderProvinceOptions(sourceKey, preserveSelection = true) {
|
||||||
|
const controls = getLocationControls(sourceKey);
|
||||||
|
if (!controls.department || !controls.province) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const department = controls.department.value || '';
|
||||||
|
const currentValue = preserveSelection ? (controls.province.value || '') : '';
|
||||||
|
const provinces = department ? (provinciasPorDepartamento[department] || []) : [];
|
||||||
|
|
||||||
|
controls.province.innerHTML = '';
|
||||||
|
|
||||||
|
const emptyOption = document.createElement('option');
|
||||||
|
emptyOption.value = '';
|
||||||
|
emptyOption.textContent = department ? (provinces.length ? 'Seleccione provincia' : 'Sin cobertura registrada') : 'Seleccione primero departamento';
|
||||||
|
controls.province.appendChild(emptyOption);
|
||||||
|
|
||||||
|
provinces.forEach(function(provincia) {
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.value = provincia;
|
||||||
|
option.textContent = provincia;
|
||||||
|
if (provincia === currentValue) {
|
||||||
|
option.selected = true;
|
||||||
|
}
|
||||||
|
controls.province.appendChild(option);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (currentValue && !provinces.includes(currentValue)) {
|
||||||
|
const legacyOption = document.createElement('option');
|
||||||
|
legacyOption.value = currentValue;
|
||||||
|
legacyOption.textContent = currentValue + ' (actual)';
|
||||||
|
legacyOption.selected = true;
|
||||||
|
controls.province.appendChild(legacyOption);
|
||||||
|
}
|
||||||
|
|
||||||
|
controls.province.disabled = !department && currentValue === '';
|
||||||
|
controls.province.value = currentValue || controls.province.value || '';
|
||||||
|
renderDistrictOptions(sourceKey, preserveSelection);
|
||||||
|
}
|
||||||
|
|
||||||
function toggleAgendaFields(sourceKey) {
|
function toggleAgendaFields(sourceKey) {
|
||||||
const estado = document.getElementById('estado-' + sourceKey)?.value || '';
|
const estado = document.getElementById('estado-' + sourceKey)?.value || '';
|
||||||
const nextCallGroup = document.getElementById('next-call-group-' + sourceKey);
|
const nextCallGroup = document.getElementById('next-call-group-' + sourceKey);
|
||||||
const deliveryGroup = document.getElementById('delivery-group-' + sourceKey);
|
const deliveryGroup = document.getElementById('delivery-group-' + sourceKey);
|
||||||
const nextCallInput = document.getElementById('proxima-' + sourceKey);
|
const nextCallInput = document.getElementById('proxima-' + sourceKey);
|
||||||
const deliveryInput = document.getElementById('fecha-entrega-' + sourceKey);
|
const deliveryInput = document.getElementById('fecha-entrega-' + sourceKey);
|
||||||
const needsDeliveryDate = estado === 'CONFIRMADO CONTRAENTREGA' || estado === 'CONFIRMADO CONTRAENTREGA FECHA' || estado === 'CONFIRMADO FECHA';
|
const needsDeliveryDate = estado === 'CONFIRMADO CONTRAENTREGA';
|
||||||
const needsNextCall = ['POR LLAMAR', 'DEVOLVER LLAMADA', 'OBSERVADO'].includes(estado);
|
const needsNextCall = ['POR LLAMAR', 'DEVOLVER LLAMADA', 'OBSERVADO'].includes(estado);
|
||||||
|
|
||||||
if (nextCallGroup) {
|
if (nextCallGroup) {
|
||||||
@ -637,6 +838,35 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
document.querySelectorAll('select[id^="estado-"]').forEach(select => {
|
document.querySelectorAll('select[id^="estado-"]').forEach(select => {
|
||||||
toggleAgendaFields(select.id.replace('estado-', ''));
|
toggleAgendaFields(select.id.replace('estado-', ''));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.querySelectorAll('select[id^="sede-"]').forEach(select => {
|
||||||
|
const sourceKey = select.id.replace('sede-', '');
|
||||||
|
renderProvinceOptions(sourceKey, true);
|
||||||
|
select.addEventListener('change', () => {
|
||||||
|
renderProvinceOptions(sourceKey, false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
document.querySelectorAll('select[id^="ciudad-"]').forEach(select => {
|
||||||
|
const sourceKey = select.id.replace('ciudad-', '');
|
||||||
|
select.addEventListener('change', () => {
|
||||||
|
renderDistrictOptions(sourceKey, false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
document.querySelectorAll('select[id^="distrito_select-"]').forEach(select => {
|
||||||
|
const sourceKey = select.id.replace('distrito_select-', '');
|
||||||
|
select.addEventListener('change', () => {
|
||||||
|
syncDistrictHidden(sourceKey, select.value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
document.querySelectorAll('input[id^="distrito_manual-"]').forEach(input => {
|
||||||
|
const sourceKey = input.id.replace('distrito_manual-', '');
|
||||||
|
input.addEventListener('input', () => {
|
||||||
|
syncDistrictHidden(sourceKey, input.value);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function guardarGestion(sourceKey, trigger) {
|
function guardarGestion(sourceKey, trigger) {
|
||||||
|
|||||||
@ -39,6 +39,7 @@ function cc_test_ensure_tracking_table(PDO $pdo): void
|
|||||||
`observaciones` TEXT NULL,
|
`observaciones` TEXT NULL,
|
||||||
`proxima_llamada_at` DATETIME NULL,
|
`proxima_llamada_at` DATETIME NULL,
|
||||||
`fecha_entrega_programada` DATE NULL,
|
`fecha_entrega_programada` DATE NULL,
|
||||||
|
`numero_cuenta_enviado_at` DATETIME NULL,
|
||||||
`ultima_gestion_at` DATETIME NULL,
|
`ultima_gestion_at` DATETIME NULL,
|
||||||
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
@ -57,7 +58,8 @@ function cc_test_ensure_tracking_table(PDO $pdo): void
|
|||||||
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'observaciones', 'TEXT NULL AFTER `dni`');
|
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'observaciones', 'TEXT NULL AFTER `dni`');
|
||||||
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'proxima_llamada_at', 'DATETIME NULL AFTER `observaciones`');
|
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'proxima_llamada_at', 'DATETIME NULL AFTER `observaciones`');
|
||||||
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'fecha_entrega_programada', 'DATE NULL AFTER `proxima_llamada_at`');
|
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'fecha_entrega_programada', 'DATE NULL AFTER `proxima_llamada_at`');
|
||||||
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'ultima_gestion_at', 'DATETIME NULL AFTER `fecha_entrega_programada`');
|
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'numero_cuenta_enviado_at', 'DATETIME NULL AFTER `fecha_entrega_programada`');
|
||||||
|
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'ultima_gestion_at', 'DATETIME NULL AFTER `numero_cuenta_enviado_at`');
|
||||||
|
|
||||||
$checked = true;
|
$checked = true;
|
||||||
}
|
}
|
||||||
@ -84,6 +86,17 @@ function cc_test_ensure_historial_llamadas_table(PDO $pdo): void
|
|||||||
$checked = true;
|
$checked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cc_test_normalize_state(string $estado): string
|
||||||
|
{
|
||||||
|
$estado = trim($estado);
|
||||||
|
|
||||||
|
return match ($estado) {
|
||||||
|
'CONFIRMADO CONTRAENTREGA FECHA', 'CONFIRMADO FECHA', 'CONTRAENTREGA CONFIRMADO' => 'CONFIRMADO CONTRAENTREGA',
|
||||||
|
'ENVIO REPETIDO' => 'REPETIDO',
|
||||||
|
default => $estado,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function cc_test_valid_states(): array
|
function cc_test_valid_states(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
@ -105,7 +118,7 @@ function cc_test_open_states(): array
|
|||||||
|
|
||||||
function cc_test_confirmed_states(): array
|
function cc_test_confirmed_states(): array
|
||||||
{
|
{
|
||||||
return ['CONFIRMADO CONTRAENTREGA', 'CONFIRMADO ENVIO', 'CONFIRMADO FECHA', 'CONTRAENTREGA CONFIRMADO'];
|
return ['CONFIRMADO CONTRAENTREGA', 'CONFIRMADO ENVIO'];
|
||||||
}
|
}
|
||||||
|
|
||||||
function cc_test_closed_states(): array
|
function cc_test_closed_states(): array
|
||||||
@ -115,20 +128,58 @@ function cc_test_closed_states(): array
|
|||||||
|
|
||||||
function cc_test_requires_delivery_date(string $estado): bool
|
function cc_test_requires_delivery_date(string $estado): bool
|
||||||
{
|
{
|
||||||
return in_array($estado, ['CONFIRMADO CONTRAENTREGA', 'CONFIRMADO FECHA'], true);
|
return cc_test_normalize_state($estado) === 'CONFIRMADO CONTRAENTREGA';
|
||||||
|
}
|
||||||
|
|
||||||
|
function cc_test_account_followup_semaforo(?string $value): ?array
|
||||||
|
{
|
||||||
|
$date = cc_test_parse_datetime($value);
|
||||||
|
if (!$date) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$now = new DateTimeImmutable('now');
|
||||||
|
$days = (int) $date->diff($now)->format('%a');
|
||||||
|
if ($date > $now) {
|
||||||
|
$days = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($days <= 1) {
|
||||||
|
return [
|
||||||
|
'class' => 'bg-success-subtle text-success-emphasis',
|
||||||
|
'label' => 'Verde',
|
||||||
|
'range' => '0–1 días',
|
||||||
|
'days' => $days,
|
||||||
|
'description' => 'Aún está en ventana de seguimiento amable.',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($days === 2) {
|
||||||
|
return [
|
||||||
|
'class' => 'bg-warning-subtle text-warning-emphasis',
|
||||||
|
'label' => 'Amarillo',
|
||||||
|
'range' => '2 días',
|
||||||
|
'days' => $days,
|
||||||
|
'description' => 'Ya conviene insistir con llamada o WhatsApp.',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'class' => 'bg-danger-subtle text-danger-emphasis',
|
||||||
|
'label' => 'Rojo',
|
||||||
|
'range' => '3+ días',
|
||||||
|
'days' => $days,
|
||||||
|
'description' => 'Necesita seguimiento urgente para no perder el pedido.',
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function cc_test_state_label(string $estado): string
|
function cc_test_state_label(string $estado): string
|
||||||
{
|
{
|
||||||
return match ($estado) {
|
return match (cc_test_normalize_state($estado)) {
|
||||||
'SE ENVIO NUMERO DE CUENTA' => 'SE ENVIÓ NÚMERO DE CUENTA',
|
'SE ENVIO NUMERO DE CUENTA' => 'SE ENVIÓ NÚMERO DE CUENTA',
|
||||||
'CONFIRMADO CONTRAENTREGA' => 'CONFIRMADO CONTRAENTREGA 📅',
|
'CONFIRMADO CONTRAENTREGA' => 'CONFIRMADO CONTRAENTREGA',
|
||||||
'CONFIRMADO CONTRAENTREGA FECHA' => 'CONFIRMADO CONTRAENTREGA 📅',
|
|
||||||
'CONFIRMADO FECHA' => 'CONFIRMADO CONTRAENTREGA 📅',
|
|
||||||
'CONFIRMADO ENVIO' => 'CONFIRMADO ENVIO',
|
'CONFIRMADO ENVIO' => 'CONFIRMADO ENVIO',
|
||||||
'CONTRAENTREGA CONFIRMADO' => 'CONFIRMADO ENVIO',
|
|
||||||
'REPETIDO' => 'REPETIDO',
|
'REPETIDO' => 'REPETIDO',
|
||||||
'ENVIO REPETIDO' => 'REPETIDO',
|
|
||||||
default => $estado,
|
default => $estado,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -120,7 +120,7 @@ function drive_test_fetch_tracking(PDO $pdo, array $sourceKeys): array
|
|||||||
cc_test_ensure_tracking_table($pdo);
|
cc_test_ensure_tracking_table($pdo);
|
||||||
|
|
||||||
$placeholders = implode(',', array_fill(0, count($sourceKeys), '?'));
|
$placeholders = implode(',', array_fill(0, count($sourceKeys), '?'));
|
||||||
$stmt = $pdo->prepare("SELECT source_key, estado, nota_seguimiento, direccion, referencia, sede, ciudad, distrito, dni, observaciones, proxima_llamada_at, fecha_entrega_programada, ultima_gestion_at, updated_at FROM callcenter_test_tracking WHERE source_key IN ($placeholders)");
|
$stmt = $pdo->prepare("SELECT source_key, estado, nota_seguimiento, direccion, referencia, sede, ciudad, distrito, dni, observaciones, proxima_llamada_at, fecha_entrega_programada, numero_cuenta_enviado_at, ultima_gestion_at, updated_at FROM callcenter_test_tracking WHERE source_key IN ($placeholders)");
|
||||||
$stmt->execute($sourceKeys);
|
$stmt->execute($sourceKeys);
|
||||||
|
|
||||||
$tracking = [];
|
$tracking = [];
|
||||||
@ -142,6 +142,7 @@ function drive_test_merge_tracking(array $orders, array $tracking): array
|
|||||||
$order['seguimiento_actualizado'] = $current['updated_at'] ?? null;
|
$order['seguimiento_actualizado'] = $current['updated_at'] ?? null;
|
||||||
$order['proxima_llamada_at'] = $current['proxima_llamada_at'] ?? null;
|
$order['proxima_llamada_at'] = $current['proxima_llamada_at'] ?? null;
|
||||||
$order['fecha_entrega_programada'] = $current['fecha_entrega_programada'] ?? null;
|
$order['fecha_entrega_programada'] = $current['fecha_entrega_programada'] ?? null;
|
||||||
|
$order['numero_cuenta_enviado_at'] = $current['numero_cuenta_enviado_at'] ?? null;
|
||||||
$order['ultima_gestion_at'] = $current['ultima_gestion_at'] ?? ($current['updated_at'] ?? null);
|
$order['ultima_gestion_at'] = $current['ultima_gestion_at'] ?? ($current['updated_at'] ?? null);
|
||||||
|
|
||||||
foreach ($editableFields as $field) {
|
foreach ($editableFields as $field) {
|
||||||
|
|||||||
@ -32,7 +32,7 @@ function cc_test_normalize_nullable_text(string $key, int $maxLen = 3000): ?stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
$sourceKey = trim((string) ($_POST['source_key'] ?? ''));
|
$sourceKey = trim((string) ($_POST['source_key'] ?? ''));
|
||||||
$estado = trim((string) ($_POST['estado'] ?? 'POR LLAMAR'));
|
$estado = cc_test_normalize_state(trim((string) ($_POST['estado'] ?? 'POR LLAMAR')));
|
||||||
$validStates = cc_test_valid_states();
|
$validStates = cc_test_valid_states();
|
||||||
|
|
||||||
if ($sourceKey === '' || !preg_match('/^[a-f0-9]{40}$/', $sourceKey)) {
|
if ($sourceKey === '' || !preg_match('/^[a-f0-9]{40}$/', $sourceKey)) {
|
||||||
@ -57,6 +57,13 @@ try {
|
|||||||
$dni = cc_test_normalize_nullable_text('dni', 40);
|
$dni = cc_test_normalize_nullable_text('dni', 40);
|
||||||
$observaciones = cc_test_normalize_nullable_text('observaciones', 3000);
|
$observaciones = cc_test_normalize_nullable_text('observaciones', 3000);
|
||||||
|
|
||||||
|
$pdo = db();
|
||||||
|
cc_test_ensure_tracking_table($pdo);
|
||||||
|
|
||||||
|
$stmtCurrent = $pdo->prepare('SELECT estado, numero_cuenta_enviado_at FROM callcenter_test_tracking WHERE source_key = ? LIMIT 1');
|
||||||
|
$stmtCurrent->execute([$sourceKey]);
|
||||||
|
$currentTracking = $stmtCurrent->fetch(PDO::FETCH_ASSOC) ?: null;
|
||||||
|
|
||||||
$proximaRaw = trim((string) ($_POST['proxima_llamada_at'] ?? ''));
|
$proximaRaw = trim((string) ($_POST['proxima_llamada_at'] ?? ''));
|
||||||
$proximaLlamada = null;
|
$proximaLlamada = null;
|
||||||
if ($proximaRaw !== '') {
|
if ($proximaRaw !== '') {
|
||||||
@ -78,7 +85,7 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cc_test_requires_delivery_date($estado) && $fechaEntrega === null) {
|
if (cc_test_requires_delivery_date($estado) && $fechaEntrega === null) {
|
||||||
throw new RuntimeException('Debes seleccionar la fecha de entrega para CONFIRMADO CONTRAENTREGA 📅.');
|
throw new RuntimeException('Debes seleccionar la fecha de entrega para CONFIRMADO CONTRAENTREGA.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in_array($estado, cc_test_open_states(), true)) {
|
if (!in_array($estado, cc_test_open_states(), true)) {
|
||||||
@ -89,8 +96,13 @@ try {
|
|||||||
$fechaEntrega = null;
|
$fechaEntrega = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$pdo = db();
|
$numeroCuentaEnviadoAt = $currentTracking['numero_cuenta_enviado_at'] ?? null;
|
||||||
cc_test_ensure_tracking_table($pdo);
|
$currentState = cc_test_normalize_state((string) ($currentTracking['estado'] ?? ''));
|
||||||
|
if ($estado === 'SE ENVIO NUMERO DE CUENTA') {
|
||||||
|
if ($currentState !== 'SE ENVIO NUMERO DE CUENTA' || trim((string) $numeroCuentaEnviadoAt) === '') {
|
||||||
|
$numeroCuentaEnviadoAt = (new DateTimeImmutable('now'))->format('Y-m-d H:i:s');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$stmt = $pdo->prepare(
|
$stmt = $pdo->prepare(
|
||||||
'INSERT INTO callcenter_test_tracking (
|
'INSERT INTO callcenter_test_tracking (
|
||||||
@ -107,6 +119,7 @@ try {
|
|||||||
observaciones,
|
observaciones,
|
||||||
proxima_llamada_at,
|
proxima_llamada_at,
|
||||||
fecha_entrega_programada,
|
fecha_entrega_programada,
|
||||||
|
numero_cuenta_enviado_at,
|
||||||
ultima_gestion_at
|
ultima_gestion_at
|
||||||
) VALUES (
|
) VALUES (
|
||||||
:source_key,
|
:source_key,
|
||||||
@ -122,6 +135,7 @@ try {
|
|||||||
:observaciones,
|
:observaciones,
|
||||||
:proxima_llamada_at,
|
:proxima_llamada_at,
|
||||||
:fecha_entrega_programada,
|
:fecha_entrega_programada,
|
||||||
|
:numero_cuenta_enviado_at,
|
||||||
CURRENT_TIMESTAMP
|
CURRENT_TIMESTAMP
|
||||||
)
|
)
|
||||||
ON DUPLICATE KEY UPDATE
|
ON DUPLICATE KEY UPDATE
|
||||||
@ -137,6 +151,7 @@ try {
|
|||||||
observaciones = VALUES(observaciones),
|
observaciones = VALUES(observaciones),
|
||||||
proxima_llamada_at = VALUES(proxima_llamada_at),
|
proxima_llamada_at = VALUES(proxima_llamada_at),
|
||||||
fecha_entrega_programada = VALUES(fecha_entrega_programada),
|
fecha_entrega_programada = VALUES(fecha_entrega_programada),
|
||||||
|
numero_cuenta_enviado_at = VALUES(numero_cuenta_enviado_at),
|
||||||
ultima_gestion_at = CURRENT_TIMESTAMP,
|
ultima_gestion_at = CURRENT_TIMESTAMP,
|
||||||
updated_at = CURRENT_TIMESTAMP'
|
updated_at = CURRENT_TIMESTAMP'
|
||||||
);
|
);
|
||||||
@ -155,6 +170,7 @@ try {
|
|||||||
':observaciones' => $observaciones,
|
':observaciones' => $observaciones,
|
||||||
':proxima_llamada_at' => $proximaLlamada,
|
':proxima_llamada_at' => $proximaLlamada,
|
||||||
':fecha_entrega_programada' => $fechaEntrega,
|
':fecha_entrega_programada' => $fechaEntrega,
|
||||||
|
':numero_cuenta_enviado_at' => $numeroCuentaEnviadoAt,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
echo json_encode([
|
echo json_encode([
|
||||||
@ -163,6 +179,7 @@ try {
|
|||||||
'estado' => $estado,
|
'estado' => $estado,
|
||||||
'proxima_llamada_at' => $proximaLlamada,
|
'proxima_llamada_at' => $proximaLlamada,
|
||||||
'fecha_entrega_programada' => $fechaEntrega,
|
'fecha_entrega_programada' => $fechaEntrega,
|
||||||
|
'numero_cuenta_enviado_at' => $numeroCuentaEnviadoAt,
|
||||||
]);
|
]);
|
||||||
} catch (Throwable $exception) {
|
} catch (Throwable $exception) {
|
||||||
http_response_code(500);
|
http_response_code(500);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user