Autosave: 20260525-104355

This commit is contained in:
Flatlogic Bot 2026-05-25 10:43:59 +00:00
parent 2c651b72fb
commit 10a0221760
4 changed files with 131 additions and 14 deletions

View File

@ -126,6 +126,7 @@ $visibleOrders = [];
$modalsHtml = [];
$totalRows = 0;
$loadLimit = 10;
$catalogoProductos = [];
$stats = [
'total' => 0,
'pendientes_hoy' => 0,
@ -141,6 +142,13 @@ try {
cc_test_ensure_tracking_table($pdo);
cc_test_ensure_historial_llamadas_table($pdo);
try {
$stmtProductos = $pdo->query("SELECT id, nombre FROM products ORDER BY nombre ASC");
$catalogoProductos = $stmtProductos->fetchAll(PDO::FETCH_ASSOC);
} catch (Throwable $exception) {
$catalogoProductos = [];
}
$preview = drive_test_fetch_orders($loadLimit);
$totalRows = (int) ($preview['total_rows'] ?? 0);
$orders = $preview['orders'] ?? [];
@ -483,26 +491,56 @@ require_once 'layout_header.php';
</div>
</div>
<div class="border border-success-subtle rounded-4 bg-white p-3 mb-4 shadow-sm">
<div class="border border-success-subtle rounded-4 bg-white p-3 mb-4 shadow-sm cc-readonly-block" aria-disabled="true" style="user-select:none; -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none;">
<div class="d-flex flex-wrap justify-content-between align-items-center gap-2 mb-3">
<div>
<div class="small text-muted mb-1">Se abre primero</div>
<h4 class="h6 fw-bold mb-0">Pedido</h4>
<div class="small text-muted mb-1">Origen del cliente</div>
<h4 class="h6 fw-bold mb-0">Pedido del cliente</h4>
</div>
<span class="badge bg-success-subtle text-success-emphasis">Producto, cantidad y precio</span>
<span class="badge bg-success-subtle text-success-emphasis">Solo lectura / origen</span>
</div>
<div class="row g-3">
<div class="col-lg-6">
<div class="col-12">
<label for="producto-<?php echo htmlspecialchars($order['source_key']); ?>" class="form-label">Producto</label>
<input type="text" class="form-control" id="producto-<?php echo htmlspecialchars($order['source_key']); ?>" value="<?php echo htmlspecialchars((string) ($order['producto'] ?? '')); ?>" placeholder="Escriba el producto">
<textarea class="form-control bg-light text-muted" id="producto-<?php echo htmlspecialchars($order['source_key']); ?>" readonly tabindex="-1" aria-readonly="true" spellcheck="false" rows="2" style="pointer-events:none; user-select:none; -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; caret-color:transparent; resize:none; overflow-wrap:anywhere; white-space:pre-wrap; line-height:1.35;"><?php echo htmlspecialchars((string) ($order['producto'] ?? '')); ?></textarea>
</div>
<div class="col-sm-6 col-lg-3">
<label for="cantidad-<?php echo htmlspecialchars($order['source_key']); ?>" class="form-label">Cantidad</label>
<input type="text" class="form-control" id="cantidad-<?php echo htmlspecialchars($order['source_key']); ?>" value="<?php echo htmlspecialchars((string) ($order['cantidad'] ?? '')); ?>" placeholder="Cantidad">
<input type="text" class="form-control bg-light text-muted" id="cantidad-<?php echo htmlspecialchars($order['source_key']); ?>" value="<?php echo htmlspecialchars((string) ($order['cantidad'] ?? '')); ?>" placeholder="Cantidad" readonly tabindex="-1" aria-readonly="true" style="pointer-events:none; user-select:none; -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; caret-color:transparent;">
</div>
<div class="col-sm-6 col-lg-3">
<label for="precio-<?php echo htmlspecialchars($order['source_key']); ?>" class="form-label">Precio</label>
<input type="text" class="form-control" id="precio-<?php echo htmlspecialchars($order['source_key']); ?>" value="<?php echo htmlspecialchars((string) ($order['precio'] ?? '')); ?>" placeholder="S/ 0.00" inputmode="decimal">
<input type="text" class="form-control bg-light text-muted" id="precio-<?php echo htmlspecialchars($order['source_key']); ?>" value="<?php echo htmlspecialchars((string) ($order['precio'] ?? '')); ?>" placeholder="S/ 0.00" inputmode="decimal" readonly tabindex="-1" aria-readonly="true" style="pointer-events:none; user-select:none; -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; caret-color:transparent;">
</div>
</div>
</div>
<div class="border border-info-subtle rounded-4 bg-white p-3 mb-4 shadow-sm">
<div class="d-flex flex-wrap justify-content-between align-items-center gap-2 mb-3">
<div>
<div class="small text-muted mb-1">Se confirma después</div>
<h4 class="h6 fw-bold mb-0">Confirmación de pedido</h4>
</div>
<span class="badge bg-info-subtle text-info-emphasis">Producto del sistema, cantidad y precio</span>
</div>
<div class="row g-3">
<div class="col-12">
<label for="confirmacion_producto-<?php echo htmlspecialchars($order['source_key']); ?>" class="form-label">Producto</label>
<select class="form-select w-100" id="confirmacion_producto-<?php echo htmlspecialchars($order['source_key']); ?>" title="Seleccione un producto del sistema">
<option value="">Seleccione un producto del sistema</option>
<?php foreach ($catalogoProductos as $catalogoProducto): ?>
<option value="<?php echo htmlspecialchars((string) ($catalogoProducto['nombre'] ?? '')); ?>" <?php echo ((string) ($order['confirmacion_producto'] ?? '') === (string) ($catalogoProducto['nombre'] ?? '')) ? 'selected' : ''; ?>><?php echo htmlspecialchars((string) ($catalogoProducto['nombre'] ?? '')); ?></option>
<?php endforeach; ?>
</select>
<div class="form-text text-break" id="confirmacion_producto_resumen-<?php echo htmlspecialchars($order['source_key']); ?>">Producto seleccionado: <?php echo htmlspecialchars((string) ($order['confirmacion_producto'] ?? 'Sin producto seleccionado')); ?></div>
</div>
<div class="col-sm-6 col-lg-3">
<label for="confirmacion_cantidad-<?php echo htmlspecialchars($order['source_key']); ?>" class="form-label">Cantidad</label>
<input type="text" class="form-control" id="confirmacion_cantidad-<?php echo htmlspecialchars($order['source_key']); ?>" value="<?php echo htmlspecialchars((string) ($order['confirmacion_cantidad'] ?? '')); ?>" placeholder="Cantidad">
</div>
<div class="col-sm-6 col-lg-3">
<label for="confirmacion_precio-<?php echo htmlspecialchars($order['source_key']); ?>" class="form-label">Precio</label>
<input type="text" class="form-control" id="confirmacion_precio-<?php echo htmlspecialchars($order['source_key']); ?>" value="<?php echo htmlspecialchars((string) ($order['confirmacion_precio'] ?? '')); ?>" placeholder="S/ 0.00" inputmode="decimal">
</div>
</div>
</div>
@ -583,6 +621,8 @@ require_once 'layout_header.php';
<label for="referencia-<?php echo htmlspecialchars($order['source_key']); ?>" class="form-label">Referencia</label>
<textarea class="form-control" id="referencia-<?php echo htmlspecialchars($order['source_key']); ?>" rows="2"><?php echo htmlspecialchars((string) ($order['referencia'] ?? '')); ?></textarea>
</div>
<?php $agenciaSeleccionada = strtoupper(trim((string) ($order['agencia'] ?? ''))); ?>
<?php $sedeAgenciaSeleccionada = trim((string) ($order['sede_agencia'] ?? '')); ?>
<div class="col-md-4">
<label for="sede-<?php echo htmlspecialchars($order['source_key']); ?>" class="form-label">Departamento</label>
<select class="form-select js-location-department" id="sede-<?php echo htmlspecialchars($order['source_key']); ?>">
@ -634,11 +674,31 @@ require_once 'layout_header.php';
<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 class="col-md-4">
<label for="agencia-<?php echo htmlspecialchars($order['source_key']); ?>" class="form-label">Agencia</label>
<select class="form-select" id="agencia-<?php echo htmlspecialchars($order['source_key']); ?>">
<option value="">Seleccione agencia</option>
<?php foreach (['SHALOM', 'OLVA COURIER', 'OTROS'] as $agenciaOption): ?>
<option value="<?php echo htmlspecialchars($agenciaOption); ?>" <?php echo $agenciaSeleccionada === $agenciaOption ? 'selected' : ''; ?>>
<?php echo htmlspecialchars($agenciaOption); ?>
</option>
<?php endforeach; ?>
<?php if ($agenciaSeleccionada !== '' && !in_array($agenciaSeleccionada, ['SHALOM', 'OLVA COURIER', 'OTROS'], true)): ?>
<option value="<?php echo htmlspecialchars($agenciaSeleccionada); ?>" selected>
<?php echo htmlspecialchars($agenciaSeleccionada); ?>
</option>
<?php endif; ?>
</select>
</div>
<div class="col-md-4">
<label for="sede_agencia-<?php echo htmlspecialchars($order['source_key']); ?>" class="form-label">Sede</label>
<input type="text" class="form-control" id="sede_agencia-<?php echo htmlspecialchars($order['source_key']); ?>" placeholder="Escriba la sede para envío por agencia" value="<?php echo htmlspecialchars($sedeAgenciaSeleccionada); ?>">
</div>
<div class="col-md-4">
<label for="dni-<?php echo htmlspecialchars($order['source_key']); ?>" class="form-label">DNI</label>
<input type="text" class="form-control" id="dni-<?php echo htmlspecialchars($order['source_key']); ?>" value="<?php echo htmlspecialchars((string) ($order['dni'] ?? '')); ?>">
</div>
<div class="col-md-8">
<div class="col-12">
<label for="observaciones-<?php echo htmlspecialchars($order['source_key']); ?>" class="form-label">Observaciones del pedido</label>
<textarea class="form-control" id="observaciones-<?php echo htmlspecialchars($order['source_key']); ?>" rows="2"><?php echo htmlspecialchars((string) ($order['observaciones'] ?? '')); ?></textarea>
</div>
@ -907,6 +967,21 @@ document.addEventListener('DOMContentLoaded', () => {
syncDistrictHidden(sourceKey, input.value);
});
});
document.querySelectorAll('select[id^="confirmacion_producto-"]').forEach(select => {
const sourceKey = select.id.replace('confirmacion_producto-', '');
const resumen = document.getElementById('confirmacion_producto_resumen-' + sourceKey);
const syncResumen = () => {
const selectedOption = select.selectedOptions && select.selectedOptions[0] ? select.selectedOptions[0] : null;
const label = selectedOption && selectedOption.textContent ? selectedOption.textContent.trim() : (select.value || 'Sin producto seleccionado');
if (resumen) {
resumen.textContent = 'Producto seleccionado: ' + label;
}
select.title = label;
};
syncResumen();
select.addEventListener('change', syncResumen);
});
});
function guardarGestion(sourceKey, trigger) {
@ -918,6 +993,8 @@ function guardarGestion(sourceKey, trigger) {
nota_seguimiento: document.getElementById('nota-' + sourceKey)?.value || '',
direccion: document.getElementById('direccion-' + sourceKey)?.value || '',
referencia: document.getElementById('referencia-' + sourceKey)?.value || '',
agencia: document.getElementById('agencia-' + sourceKey)?.value || '',
sede_agencia: document.getElementById('sede_agencia-' + sourceKey)?.value || '',
sede: document.getElementById('sede-' + sourceKey)?.value || '',
ciudad: document.getElementById('ciudad-' + sourceKey)?.value || '',
distrito: document.getElementById('distrito-' + sourceKey)?.value || '',
@ -925,7 +1002,10 @@ function guardarGestion(sourceKey, trigger) {
observaciones: document.getElementById('observaciones-' + sourceKey)?.value || '',
producto: document.getElementById('producto-' + sourceKey)?.value || '',
cantidad: document.getElementById('cantidad-' + sourceKey)?.value || '',
precio: document.getElementById('precio-' + sourceKey)?.value || ''
precio: document.getElementById('precio-' + sourceKey)?.value || '',
confirmacion_producto: document.getElementById('confirmacion_producto-' + sourceKey)?.value || '',
confirmacion_cantidad: document.getElementById('confirmacion_cantidad-' + sourceKey)?.value || '',
confirmacion_precio: document.getElementById('confirmacion_precio-' + sourceKey)?.value || ''
});
if (trigger) {

View File

@ -32,6 +32,8 @@ function cc_test_ensure_tracking_table(PDO $pdo): void
`user_id` INT NULL,
`direccion` TEXT NULL,
`referencia` TEXT NULL,
`agencia` VARCHAR(80) NULL,
`sede_agencia` VARCHAR(120) NULL,
`sede` VARCHAR(120) NULL,
`ciudad` VARCHAR(120) NULL,
`distrito` VARCHAR(120) NULL,
@ -40,6 +42,9 @@ function cc_test_ensure_tracking_table(PDO $pdo): void
`producto` VARCHAR(255) NULL,
`cantidad` VARCHAR(50) NULL,
`precio` VARCHAR(80) NULL,
`confirmacion_producto` VARCHAR(255) NULL,
`confirmacion_cantidad` VARCHAR(50) NULL,
`confirmacion_precio` VARCHAR(80) NULL,
`proxima_llamada_at` DATETIME NULL,
`fecha_entrega_programada` DATE NULL,
`numero_cuenta_enviado_at` DATETIME NULL,
@ -54,7 +59,9 @@ function cc_test_ensure_tracking_table(PDO $pdo): void
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'direccion', 'TEXT NULL AFTER `user_id`');
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'referencia', 'TEXT NULL AFTER `direccion`');
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'sede', 'VARCHAR(120) NULL AFTER `referencia`');
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'agencia', 'VARCHAR(80) NULL AFTER `referencia`');
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'sede_agencia', 'VARCHAR(120) NULL AFTER `agencia`');
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'sede', 'VARCHAR(120) NULL AFTER `sede_agencia`');
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'ciudad', 'VARCHAR(120) NULL AFTER `sede`');
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'distrito', 'VARCHAR(120) NULL AFTER `ciudad`');
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'dni', 'VARCHAR(40) NULL AFTER `distrito`');
@ -62,7 +69,10 @@ function cc_test_ensure_tracking_table(PDO $pdo): void
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'producto', 'VARCHAR(255) NULL AFTER `observaciones`');
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'cantidad', 'VARCHAR(50) NULL AFTER `producto`');
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'precio', 'VARCHAR(80) NULL AFTER `cantidad`');
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'proxima_llamada_at', 'DATETIME NULL AFTER `precio`');
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'confirmacion_producto', 'VARCHAR(255) NULL AFTER `precio`');
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'confirmacion_cantidad', 'VARCHAR(50) NULL AFTER `confirmacion_producto`');
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'confirmacion_precio', 'VARCHAR(80) NULL AFTER `confirmacion_cantidad`');
cc_test_ensure_column($pdo, 'callcenter_test_tracking', 'proxima_llamada_at', 'DATETIME NULL AFTER `confirmacion_precio`');
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', '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`');

View File

@ -89,6 +89,8 @@ function drive_test_fetch_orders(int $limit = 10): array
'nombre' => $nombre,
'direccion' => $direccion,
'referencia' => $referencia,
'agencia' => '',
'sede_agencia' => '',
'distrito' => $distrito,
'celular' => $celular,
'producto' => $producto,
@ -120,7 +122,7 @@ function drive_test_fetch_tracking(PDO $pdo, array $sourceKeys): array
cc_test_ensure_tracking_table($pdo);
$placeholders = implode(',', array_fill(0, count($sourceKeys), '?'));
$stmt = $pdo->prepare("SELECT source_key, estado, nota_seguimiento, direccion, referencia, sede, ciudad, distrito, dni, observaciones, producto, cantidad, precio, 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 = $pdo->prepare("SELECT source_key, estado, nota_seguimiento, direccion, referencia, agencia, sede_agencia, sede, ciudad, distrito, dni, observaciones, producto, cantidad, precio, confirmacion_producto, confirmacion_cantidad, confirmacion_precio, 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);
$tracking = [];
@ -133,7 +135,7 @@ function drive_test_fetch_tracking(PDO $pdo, array $sourceKeys): array
function drive_test_merge_tracking(array $orders, array $tracking): array
{
$editableFields = ['direccion', 'referencia', 'sede', 'ciudad', 'distrito', 'dni', 'observaciones', 'producto', 'cantidad', 'precio'];
$editableFields = ['direccion', 'referencia', 'agencia', 'sede_agencia', 'sede', 'ciudad', 'distrito', 'dni', 'observaciones', 'producto', 'cantidad', 'precio', 'confirmacion_producto', 'confirmacion_cantidad', 'confirmacion_precio'];
foreach ($orders as &$order) {
$current = $tracking[$order['source_key']] ?? null;

View File

@ -51,6 +51,8 @@ try {
$nota = cc_test_normalize_nullable_text('nota_seguimiento', 3000);
$direccion = cc_test_normalize_nullable_text('direccion', 1000);
$referencia = cc_test_normalize_nullable_text('referencia', 1000);
$agencia = cc_test_normalize_nullable_text('agencia', 80);
$sedeAgencia = cc_test_normalize_nullable_text('sede_agencia', 120);
$sede = cc_test_normalize_nullable_text('sede', 120);
$ciudad = cc_test_normalize_nullable_text('ciudad', 120);
$distrito = cc_test_normalize_nullable_text('distrito', 120);
@ -59,6 +61,9 @@ try {
$producto = cc_test_normalize_nullable_text('producto', 255);
$cantidad = cc_test_normalize_nullable_text('cantidad', 50);
$precio = cc_test_normalize_nullable_text('precio', 80);
$confirmacionProducto = cc_test_normalize_nullable_text('confirmacion_producto', 255);
$confirmacionCantidad = cc_test_normalize_nullable_text('confirmacion_cantidad', 50);
$confirmacionPrecio = cc_test_normalize_nullable_text('confirmacion_precio', 80);
$pdo = db();
cc_test_ensure_tracking_table($pdo);
@ -115,6 +120,8 @@ try {
user_id,
direccion,
referencia,
agencia,
sede_agencia,
sede,
ciudad,
distrito,
@ -123,6 +130,9 @@ try {
producto,
cantidad,
precio,
confirmacion_producto,
confirmacion_cantidad,
confirmacion_precio,
proxima_llamada_at,
fecha_entrega_programada,
numero_cuenta_enviado_at,
@ -134,6 +144,8 @@ try {
:user_id,
:direccion,
:referencia,
:agencia,
:sede_agencia,
:sede,
:ciudad,
:distrito,
@ -142,6 +154,9 @@ try {
:producto,
:cantidad,
:precio,
:confirmacion_producto,
:confirmacion_cantidad,
:confirmacion_precio,
:proxima_llamada_at,
:fecha_entrega_programada,
:numero_cuenta_enviado_at,
@ -153,6 +168,8 @@ try {
user_id = VALUES(user_id),
direccion = VALUES(direccion),
referencia = VALUES(referencia),
agencia = VALUES(agencia),
sede_agencia = VALUES(sede_agencia),
sede = VALUES(sede),
ciudad = VALUES(ciudad),
distrito = VALUES(distrito),
@ -161,6 +178,9 @@ try {
producto = VALUES(producto),
cantidad = VALUES(cantidad),
precio = VALUES(precio),
confirmacion_producto = VALUES(confirmacion_producto),
confirmacion_cantidad = VALUES(confirmacion_cantidad),
confirmacion_precio = VALUES(confirmacion_precio),
proxima_llamada_at = VALUES(proxima_llamada_at),
fecha_entrega_programada = VALUES(fecha_entrega_programada),
numero_cuenta_enviado_at = VALUES(numero_cuenta_enviado_at),
@ -175,6 +195,8 @@ try {
':user_id' => (int) $_SESSION['user_id'],
':direccion' => $direccion,
':referencia' => $referencia,
':agencia' => $agencia,
':sede_agencia' => $sedeAgencia,
':sede' => $sede,
':ciudad' => $ciudad,
':distrito' => $distrito,
@ -183,6 +205,9 @@ try {
':producto' => $producto,
':cantidad' => $cantidad,
':precio' => $precio,
':confirmacion_producto' => $confirmacionProducto,
':confirmacion_cantidad' => $confirmacionCantidad,
':confirmacion_precio' => $confirmacionPrecio,
':proxima_llamada_at' => $proximaLlamada,
':fecha_entrega_programada' => $fechaEntrega,
':numero_cuenta_enviado_at' => $numeroCuentaEnviadoAt,