40097-vm/update_callcenter_test_tracking.php
2026-05-26 15:51:40 +00:00

247 lines
9.3 KiB
PHP

<?php
session_start();
require_once 'db/config.php';
require_once 'includes/callcenter_test_helpers.php';
header('Content-Type: application/json; charset=utf-8');
if (!isset($_SESSION['user_id']) || !cc_test_current_user_can_access_module(db())) {
http_response_code(403);
echo json_encode(['success' => false, 'message' => 'No autorizado']);
exit;
}
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode(['success' => false, 'message' => 'Método no permitido']);
exit;
}
function cc_test_normalize_nullable_text(string $key, int $maxLen = 3000): ?string
{
$value = trim((string) ($_POST[$key] ?? ''));
if ($value === '') {
return null;
}
if (mb_strlen($value) > $maxLen) {
throw new RuntimeException('El campo ' . $key . ' es demasiado largo.');
}
return $value;
}
$sourceKey = trim((string) ($_POST['source_key'] ?? ''));
$estado = cc_test_normalize_state(trim((string) ($_POST['estado'] ?? 'POR LLAMAR')));
$validStates = cc_test_valid_states();
if ($sourceKey === '' || !preg_match('/^[a-f0-9]{40}$/', $sourceKey)) {
http_response_code(400);
echo json_encode(['success' => false, 'message' => 'Pedido de prueba inválido']);
exit;
}
if (!in_array($estado, $validStates, true)) {
http_response_code(400);
echo json_encode(['success' => false, 'message' => 'Estado inválido']);
exit;
}
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);
$dni = cc_test_normalize_nullable_text('dni', 40);
$observaciones = cc_test_normalize_nullable_text('observaciones', 3000);
$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);
$confirmacionProductoExtra = cc_test_normalize_nullable_text('confirmacion_producto_extra', 255);
$confirmacionCantidadExtra = cc_test_normalize_nullable_text('confirmacion_cantidad_extra', 50);
$confirmacionPrecioExtra = cc_test_normalize_nullable_text('confirmacion_precio_extra', 80);
$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'] ?? ''));
$proximaLlamada = null;
if ($proximaRaw !== '') {
$proximaLlamada = DateTimeImmutable::createFromFormat('Y-m-d\TH:i', $proximaRaw);
if (!$proximaLlamada) {
throw new RuntimeException('La fecha de próxima llamada no es válida.');
}
$proximaLlamada = $proximaLlamada->format('Y-m-d H:i:s');
}
$fechaEntregaRaw = trim((string) ($_POST['fecha_entrega_programada'] ?? ''));
$fechaEntrega = null;
if ($fechaEntregaRaw !== '') {
$fechaEntregaDate = DateTimeImmutable::createFromFormat('Y-m-d', $fechaEntregaRaw);
if (!$fechaEntregaDate) {
throw new RuntimeException('La fecha de entrega no es válida.');
}
$fechaEntrega = $fechaEntregaDate->format('Y-m-d');
}
if (cc_test_requires_delivery_date($estado) && $fechaEntrega === null) {
throw new RuntimeException('Debes seleccionar la fecha de entrega para CONFIRMADO CONTRAENTREGA.');
}
if (!in_array($estado, cc_test_open_states(), true)) {
$proximaLlamada = null;
}
if (!cc_test_requires_delivery_date($estado)) {
$fechaEntrega = null;
}
$numeroCuentaEnviadoAt = $currentTracking['numero_cuenta_enviado_at'] ?? null;
$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(
'INSERT INTO callcenter_test_tracking (
source_key,
estado,
nota_seguimiento,
user_id,
direccion,
referencia,
agencia,
sede_agencia,
sede,
ciudad,
distrito,
dni,
observaciones,
producto,
cantidad,
precio,
confirmacion_producto,
confirmacion_cantidad,
confirmacion_precio,
confirmacion_producto_extra,
confirmacion_cantidad_extra,
confirmacion_precio_extra,
proxima_llamada_at,
fecha_entrega_programada,
numero_cuenta_enviado_at,
ultima_gestion_at
) VALUES (
:source_key,
:estado,
:nota,
:user_id,
:direccion,
:referencia,
:agencia,
:sede_agencia,
:sede,
:ciudad,
:distrito,
:dni,
:observaciones,
:producto,
:cantidad,
:precio,
:confirmacion_producto,
:confirmacion_cantidad,
:confirmacion_precio,
:confirmacion_producto_extra,
:confirmacion_cantidad_extra,
:confirmacion_precio_extra,
:proxima_llamada_at,
:fecha_entrega_programada,
:numero_cuenta_enviado_at,
CURRENT_TIMESTAMP
)
ON DUPLICATE KEY UPDATE
estado = VALUES(estado),
nota_seguimiento = VALUES(nota_seguimiento),
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),
dni = VALUES(dni),
observaciones = VALUES(observaciones),
producto = VALUES(producto),
cantidad = VALUES(cantidad),
precio = VALUES(precio),
confirmacion_producto = VALUES(confirmacion_producto),
confirmacion_cantidad = VALUES(confirmacion_cantidad),
confirmacion_precio = VALUES(confirmacion_precio),
confirmacion_producto_extra = VALUES(confirmacion_producto_extra),
confirmacion_cantidad_extra = VALUES(confirmacion_cantidad_extra),
confirmacion_precio_extra = VALUES(confirmacion_precio_extra),
proxima_llamada_at = VALUES(proxima_llamada_at),
fecha_entrega_programada = VALUES(fecha_entrega_programada),
numero_cuenta_enviado_at = VALUES(numero_cuenta_enviado_at),
ultima_gestion_at = CURRENT_TIMESTAMP,
updated_at = CURRENT_TIMESTAMP'
);
$stmt->execute([
':source_key' => $sourceKey,
':estado' => $estado,
':nota' => $nota,
':user_id' => (int) $_SESSION['user_id'],
':direccion' => $direccion,
':referencia' => $referencia,
':agencia' => $agencia,
':sede_agencia' => $sedeAgencia,
':sede' => $sede,
':ciudad' => $ciudad,
':distrito' => $distrito,
':dni' => $dni,
':observaciones' => $observaciones,
':producto' => $producto,
':cantidad' => $cantidad,
':precio' => $precio,
':confirmacion_producto' => $confirmacionProducto,
':confirmacion_cantidad' => $confirmacionCantidad,
':confirmacion_precio' => $confirmacionPrecio,
':confirmacion_producto_extra' => $confirmacionProductoExtra,
':confirmacion_cantidad_extra' => $confirmacionCantidadExtra,
':confirmacion_precio_extra' => $confirmacionPrecioExtra,
':proxima_llamada_at' => $proximaLlamada,
':fecha_entrega_programada' => $fechaEntrega,
':numero_cuenta_enviado_at' => $numeroCuentaEnviadoAt,
]);
echo json_encode([
'success' => true,
'message' => 'Gestión actualizada correctamente.',
'estado' => $estado,
'proxima_llamada_at' => $proximaLlamada,
'fecha_entrega_programada' => $fechaEntrega,
'numero_cuenta_enviado_at' => $numeroCuentaEnviadoAt,
]);
} catch (Throwable $exception) {
http_response_code(500);
error_log('update_callcenter_test_tracking.php: ' . $exception->getMessage());
echo json_encode([
'success' => false,
'message' => $exception instanceof RuntimeException ? $exception->getMessage() : 'No se pudo guardar la gestión.',
]);
}