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 = 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); $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); $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; } $pdo = db(); cc_test_ensure_tracking_table($pdo); $stmt = $pdo->prepare( 'INSERT INTO callcenter_test_tracking ( source_key, estado, nota_seguimiento, user_id, direccion, referencia, sede, ciudad, distrito, dni, observaciones, proxima_llamada_at, fecha_entrega_programada, ultima_gestion_at ) VALUES ( :source_key, :estado, :nota, :user_id, :direccion, :referencia, :sede, :ciudad, :distrito, :dni, :observaciones, :proxima_llamada_at, :fecha_entrega_programada, 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), sede = VALUES(sede), ciudad = VALUES(ciudad), distrito = VALUES(distrito), dni = VALUES(dni), observaciones = VALUES(observaciones), proxima_llamada_at = VALUES(proxima_llamada_at), fecha_entrega_programada = VALUES(fecha_entrega_programada), 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, ':sede' => $sede, ':ciudad' => $ciudad, ':distrito' => $distrito, ':dni' => $dni, ':observaciones' => $observaciones, ':proxima_llamada_at' => $proximaLlamada, ':fecha_entrega_programada' => $fechaEntrega, ]); echo json_encode([ 'success' => true, 'message' => 'Gestión actualizada correctamente.', 'estado' => $estado, 'proxima_llamada_at' => $proximaLlamada, 'fecha_entrega_programada' => $fechaEntrega, ]); } 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.', ]); }