if (!defined('ABSPATH')) {
$wp_load = dirname(__FILE__) . '/../../../../../../wp-load.php';
if (file_exists($wp_load)) {
require_once($wp_load);
} else {
die('Error: No se puede cargar WordPress');
}
}
// =============================
// REGISTRO DE ACCIONES AJAX - LECTURA
// =============================
add_action('wp_ajax_obtener_vehiculos_cliente', 'ajax_obtener_vehiculos_cliente');
add_action('wp_ajax_nopriv_obtener_vehiculos_cliente', 'ajax_obtener_vehiculos_cliente');
add_action('wp_ajax_obtener_tasaciones_cliente', 'ajax_obtener_tasaciones_cliente');
add_action('wp_ajax_nopriv_obtener_tasaciones_cliente', 'ajax_obtener_tasaciones_cliente');
add_action('wp_ajax_obtener_comprados_cliente', 'ajax_obtener_comprados_cliente');
add_action('wp_ajax_nopriv_obtener_comprados_cliente', 'ajax_obtener_comprados_cliente');
add_action('wp_ajax_eliminar_vehiculo_cliente', 'ajax_eliminar_vehiculo_cliente');
add_action('wp_ajax_nopriv_eliminar_vehiculo_cliente', 'ajax_eliminar_vehiculo_cliente');
add_action('wp_ajax_obtener_vehiculo_detalle', 'ajax_obtener_vehiculo_detalle');
add_action('wp_ajax_nopriv_obtener_vehiculo_detalle', 'ajax_obtener_vehiculo_detalle');
// =============================
// REGISTRO DE ACCIONES AJAX - ACTUALIZACIÓN
// =============================
add_action('wp_ajax_actualizar_vehiculo_vo', 'ajax_actualizar_vehiculo_vo');
add_action('wp_ajax_actualizar_vehiculo_nuevo', 'ajax_actualizar_vehiculo_nuevo');
add_action('wp_ajax_actualizar_vehiculo_definir', 'ajax_actualizar_vehiculo_definir');
add_action('wp_ajax_actualizar_vehiculo_historico', 'ajax_actualizar_vehiculo_historico');
// =============================
// FUNCIONES DE CONEXIÓN
// =============================
function vehiculos_conectar_db() {
static $pdo = null;
if ($pdo !== null) {
return $pdo;
}
$host = 'localhost';
$db = 'clientes_app';
$user = 'user_clientes';
$pass = 'C@rlitos3@@1';
$port = 3306;
try {
$pdo = new PDO(
"mysql:host=$host;port=$port;dbname=$db;charset=utf8mb4",
$user,
$pass,
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4"
]
);
return $pdo;
} catch (PDOException $e) {
error_log('❌ [VEHICULOS] Error conectando BD: ' . $e->getMessage());
throw new Exception('Error de conexión a la base de datos');
}
}
// =============================
// FUNCIONES AUXILIARES
// =============================
function obtener_contadores_vehiculos($cliente_id, $pdo = null) {
if (!$pdo) {
$pdo = vehiculos_conectar_db();
}
$counts = [
'vehiculos' => 0,
'tasaciones' => 0,
'comprados' => 0,
'venta_directa' => 0
];
try {
$stmt = $pdo->prepare("
SELECT COUNT(*) as total
FROM vehiculos_cliente vc
INNER JOIN vehiculos_historico vh ON vc.vehiculo_id = vh.id
WHERE vc.cliente_id = :cliente_id
AND vc.estado_relacion = 'ACTIVA'
");
$stmt->execute(['cliente_id' => $cliente_id]);
$result = $stmt->fetch();
$counts['vehiculos'] = $result ? $result['total'] : 0;
$stmt = $pdo->prepare("
SELECT
COUNT(CASE
WHEN tc.estado_tasacion NOT IN ('FIN_RECHAZADA', 'FIN_CADUCADA')
THEN 1
END) as tasaciones_activas,
COUNT(CASE
WHEN tc.es_venta_directa = 1
THEN 1
END) as venta_directa_count
FROM tasaciones_cliente tc
INNER JOIN vehiculos_cliente vc ON tc.relacion_vehiculo_cliente_id = vc.id
INNER JOIN vehiculos_historico vh ON vc.vehiculo_id = vh.id
WHERE tc.cliente_id = :cliente_id
");
$stmt->execute(['cliente_id' => $cliente_id]);
$result = $stmt->fetch();
$counts['tasaciones'] = $result ? $result['tasaciones_activas'] : 0;
$counts['venta_directa'] = $result ? $result['venta_directa_count'] : 0;
$stmt = $pdo->prepare("
SELECT COUNT(*) as total
FROM vehiculos_comprados
WHERE cliente_id = :cliente_id
");
$stmt->execute(['cliente_id' => $cliente_id]);
$result = $stmt->fetch();
$counts['comprados'] = $result ? $result['total'] : 0;
} catch (Exception $e) {
error_log('❌ Error obteniendo contadores: ' . $e->getMessage());
}
return $counts;
}
// =============================
// FUNCIONES AJAX - LECTURA
// =============================
function ajax_obtener_vehiculos_cliente() {
try {
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'cliente_maestro_nonce')) {
throw new Exception('Error de seguridad - nonce inválido');
}
$cliente_id = isset($_POST['cliente_id']) ? intval($_POST['cliente_id']) : 0;
if (!$cliente_id) {
throw new Exception('ID de cliente inválido');
}
$pdo = vehiculos_conectar_db();
$sql = "SELECT
vc.id, vc.cliente_id, vc.vehiculo_id, vc.origen,
vc.fecha_adquisicion, vc.kilometros_actuales, vc.kilometros_entrega,
vc.estado_relacion, vc.precio_venta_original, vc.fecha_venta_original,
vc.vendedor_original_id, vc.intencion_cambio, vc.momento_optimo_cambio,
vc.alerta_enviada,
vh.marca, vh.modelo, vh.submodelo, vh.matricula, vh.bastidor,
vh.anio, vh.combustible, vh.potencia_cv, vh.color, vh.disponibilidad,
DATEDIFF(CURDATE(), vc.fecha_adquisicion) AS dias_desde_adquisicion,
CASE
WHEN vc.momento_optimo_cambio IS NOT NULL
AND CURDATE() >= vc.momento_optimo_cambio
THEN 'MOMENTO_OPTIMO'
WHEN vc.intencion_cambio = 'alta'
THEN 'PROXIMA_OPORTUNIDAD'
WHEN vc.intencion_cambio = 'media'
THEN 'OPORTUNIDAD_FUTURA'
ELSE 'SEGUIMIENTO'
END AS indicador_oportunidad
FROM vehiculos_cliente vc
INNER JOIN vehiculos_historico vh ON vc.vehiculo_id = vh.id
WHERE vc.cliente_id = :cliente_id
AND vc.estado_relacion = 'ACTIVA'
ORDER BY vc.fecha_adquisicion DESC";
$stmt = $pdo->prepare($sql);
$stmt->execute(['cliente_id' => $cliente_id]);
$vehiculos = $stmt->fetchAll();
if (!$vehiculos) {
$vehiculos = [];
}
$counts = obtener_contadores_vehiculos($cliente_id, $pdo);
wp_send_json_success([
'vehiculos' => $vehiculos,
'counts' => $counts,
'total' => count($vehiculos)
]);
} catch (Exception $e) {
error_log('❌ Error obteniendo vehículos: ' . $e->getMessage());
wp_send_json_error($e->getMessage());
}
}
function ajax_obtener_tasaciones_cliente() {
try {
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'cliente_maestro_nonce')) {
throw new Exception('Error de seguridad');
}
$cliente_id = isset($_POST['cliente_id']) ? intval($_POST['cliente_id']) : 0;
if (!$cliente_id) {
throw new Exception('ID de cliente inválido');
}
$pdo = vehiculos_conectar_db();
$sql = "SELECT
tc.*, tc.estado_tasacion,
vh.marca, vh.modelo, vh.submodelo, vh.version, vh.matricula,
vh.bastidor, vh.fecha_matriculacion, vh.fecha_matriculacion_cliente,
vh.anio, vh.combustible, vh.potencia_cv, vh.cilindrada, vh.color,
vh.puertas, vh.asientos, vh.tipo_cambio, vh.carroceria,
vh.kilometros_actuales as kilometros_vehiculo, vh.disponibilidad,
vh.emisiones_co2,
DATEDIFF(tc.fecha_validez, CURDATE()) AS dias_hasta_vencimiento,
CASE
WHEN tc.estado_tasacion = 'venta_directa' THEN 'venta_directa'
WHEN tc.es_venta_directa = 1 THEN 'venta_directa'
WHEN tc.estado_tasacion LIKE 'BORR_%' THEN 'borrador'
WHEN tc.estado_tasacion LIKE 'ENV_%' THEN 'enviada'
WHEN tc.estado_tasacion LIKE 'NEG_%' THEN 'negociando'
WHEN tc.estado_tasacion LIKE 'FIN_ACEPTADA' THEN 'aceptada'
WHEN tc.estado_tasacion LIKE 'FIN_APLICADA' THEN 'aplicada'
ELSE 'borrador'
END as estado
FROM tasaciones_cliente tc
INNER JOIN vehiculos_cliente vc ON tc.relacion_vehiculo_cliente_id = vc.id
INNER JOIN vehiculos_historico vh ON vc.vehiculo_id = vh.id
WHERE tc.cliente_id = :cliente_id
ORDER BY tc.fecha_tasacion DESC";
$stmt = $pdo->prepare($sql);
$stmt->execute(['cliente_id' => $cliente_id]);
$tasaciones = $stmt->fetchAll();
if (!$tasaciones) {
$tasaciones = [];
}
foreach ($tasaciones as &$tasacion) {
if (!empty($tasacion['evaluacion_carroceria'])) {
$tasacion['evaluacion_carroceria_decoded'] = json_decode($tasacion['evaluacion_carroceria'], true);
}
$descripcion_completa = trim(
$tasacion['marca'] . ' ' .
$tasacion['modelo'] .
($tasacion['submodelo'] ? ' ' . $tasacion['submodelo'] : '') .
($tasacion['version'] ? ' ' . $tasacion['version'] : '')
);
$tasacion['descripcion_vehiculo'] = $descripcion_completa;
}
$counts = obtener_contadores_vehiculos($cliente_id, $pdo);
wp_send_json_success([
'tasaciones' => $tasaciones,
'counts' => $counts,
'total' => count($tasaciones)
]);
} catch (Exception $e) {
error_log('❌ Error obteniendo tasaciones: ' . $e->getMessage());
wp_send_json_error($e->getMessage());
}
}
function ajax_eliminar_vehiculo_cliente() {
try {
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'cliente_maestro_nonce')) {
throw new Exception('Error de seguridad');
}
$vehiculo_id = isset($_POST['vehiculo_id']) ? intval($_POST['vehiculo_id']) : 0;
if (!$vehiculo_id) {
throw new Exception('ID de vehículo no válido');
}
$pdo = vehiculos_conectar_db();
$stmt = $pdo->prepare("
SELECT vc.id, vh.matricula, vh.marca, vh.modelo
FROM vehiculos_cliente vc
INNER JOIN vehiculos_historico vh ON vc.vehiculo_id = vh.id
WHERE vc.id = :id
");
$stmt->execute(['id' => $vehiculo_id]);
$vehiculo = $stmt->fetch();
if (!$vehiculo) {
throw new Exception('Vehículo no encontrado');
}
$stmt = $pdo->prepare("DELETE FROM vehiculos_cliente WHERE id = :id");
$stmt->execute(['id' => $vehiculo_id]);
wp_send_json_success([
'mensaje' => 'Vehículo eliminado correctamente',
'vehiculo_id' => $vehiculo_id
]);
} catch (Exception $e) {
error_log('❌ Error eliminando vehículo: ' . $e->getMessage());
wp_send_json_error($e->getMessage());
}
}
function ajax_obtener_vehiculo_detalle() {
try {
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'cliente_maestro_nonce')) {
throw new Exception('Error de seguridad');
}
$vehiculo_id = isset($_POST['vehiculo_id']) ? intval($_POST['vehiculo_id']) : 0;
if (!$vehiculo_id) {
throw new Exception('ID de vehículo no válido');
}
$pdo = vehiculos_conectar_db();
$sql = "SELECT
vc.*, vh.*,
DATEDIFF(CURDATE(), vc.fecha_adquisicion) AS dias_desde_adquisicion
FROM vehiculos_cliente vc
INNER JOIN vehiculos_historico vh ON vc.vehiculo_id = vh.id
WHERE vc.id = :vehiculo_id";
$stmt = $pdo->prepare($sql);
$stmt->execute(['vehiculo_id' => $vehiculo_id]);
$vehiculo = $stmt->fetch();
if (!$vehiculo) {
throw new Exception('Vehículo no encontrado');
}
wp_send_json_success($vehiculo);
} catch (Exception $e) {
error_log('❌ Error obteniendo detalle vehículo: ' . $e->getMessage());
wp_send_json_error($e->getMessage());
}
}
// =============================
// FUNCIONES AJAX - ACTUALIZACIÓN
// =============================
/**
* Actualizar vehículo VO
*/
function ajax_actualizar_vehiculo_vo() {
try {
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'cliente_maestro_nonce')) {
throw new Exception('Error de seguridad');
}
$vehiculo_id = intval($_POST['vehiculo_id'] ?? 0);
$campos_json = stripslashes($_POST['campos'] ?? '{}');
$campos = json_decode($campos_json, true);
if (!$vehiculo_id || empty($campos)) {
throw new Exception('Datos inválidos');
}
$pdo = vehiculos_conectar_db();
$sets = [];
$params = ['id' => $vehiculo_id];
$campos_permitidos = [
'puertas', 'color', 'combustible', 'transmision', 'carroceria', 'traccion', 'kw',
'emisiones_co2', 'tipo_etiqueta', 'medidas', 'peso',
'bastidor', 'vin_bat', 'vin_bat2', 'inversor_no', 'matricula_tecnica',
'pvp', 'precio_cesion', 'margen'
];
foreach ($campos as $campo => $valor) {
if (in_array($campo, $campos_permitidos)) {
$sets[] = "`$campo` = :$campo";
$params[$campo] = $valor;
}
}
if (empty($sets)) {
throw new Exception('No hay campos válidos');
}
$sql = "UPDATE vehiculos_vo SET " . implode(', ', $sets) . " WHERE id = :id";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
error_log('✅ Vehículo VO #' . $vehiculo_id . ' actualizado');
wp_send_json_success(['mensaje' => 'Actualizado correctamente']);
} catch (Exception $e) {
error_log('❌ Error: ' . $e->getMessage());
wp_send_json_error($e->getMessage());
}
}
/**
* Actualizar vehículo NUEVO
*/
function ajax_actualizar_vehiculo_nuevo() {
try {
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'cliente_maestro_nonce')) {
throw new Exception('Error de seguridad');
}
$vehiculo_id = intval($_POST['vehiculo_id'] ?? 0);
$campos_json = stripslashes($_POST['campos'] ?? '{}');
$campos = json_decode($campos_json, true);
if (!$vehiculo_id || empty($campos)) {
throw new Exception('Datos inválidos');
}
$pdo = vehiculos_conectar_db();
$sets = [];
$params = ['id' => $vehiculo_id];
$campos_permitidos = [
'puertas', 'color', 'combustible', 'transmision', 'carroceria', 'traccion', 'kw',
'emisiones_co2', 'tipo_etiqueta', 'medidas', 'peso',
'bastidor', 'vin_bat', 'vin_bat2', 'inversor_no',
'pvp', 'descuento', 'base_imponible', 'iva'
];
foreach ($campos as $campo => $valor) {
if (in_array($campo, $campos_permitidos)) {
$sets[] = "`$campo` = :$campo";
$params[$campo] = $valor;
}
}
if (empty($sets)) {
throw new Exception('No hay campos válidos');
}
$sql = "UPDATE vehiculos_nuevos SET " . implode(', ', $sets) . " WHERE id = :id";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
error_log('✅ Vehículo NUEVO #' . $vehiculo_id . ' actualizado');
wp_send_json_success(['mensaje' => 'Actualizado correctamente']);
} catch (Exception $e) {
error_log('❌ Error: ' . $e->getMessage());
wp_send_json_error($e->getMessage());
}
}
/**
* Actualizar definir_modelo
*/
function ajax_actualizar_vehiculo_definir() {
try {
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'cliente_maestro_nonce')) {
throw new Exception('Error de seguridad');
}
$vehiculo_id = intval($_POST['vehiculo_id'] ?? 0);
$campos_json = stripslashes($_POST['campos'] ?? '{}');
$campos = json_decode($campos_json, true);
if (!$vehiculo_id || empty($campos)) {
throw new Exception('Datos inválidos');
}
$pdo = vehiculos_conectar_db();
$sets = [];
$params = ['id' => $vehiculo_id];
$campos_permitidos = [
'puertas', 'color', 'combustible', 'cambio', 'carroceria', 'traccion',
'emisiones_co2', 'tipo_etiqueta', 'medidas', 'vin_bat', 'vin_bat2', 'inversor_no',
'precio_venta_publico', 'precio_compra', 'iva', 'descuento', 'pvp_final'
];
foreach ($campos as $campo => $valor) {
if (in_array($campo, $campos_permitidos)) {
$sets[] = "`$campo` = :$campo";
$params[$campo] = $valor;
}
}
if (empty($sets)) {
throw new Exception('No hay campos válidos');
}
$sql = "UPDATE definir_modelo SET " . implode(', ', $sets) . " WHERE id = :id";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
error_log('✅ Definir Modelo #' . $vehiculo_id . ' actualizado');
wp_send_json_success(['mensaje' => 'Actualizado correctamente']);
} catch (Exception $e) {
error_log('❌ Error: ' . $e->getMessage());
wp_send_json_error($e->getMessage());
}
}
/**
* Actualizar vehículo HISTORICO
*/
function ajax_actualizar_vehiculo_historico() {
try {
if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'cliente_maestro_nonce')) {
throw new Exception('Error de seguridad');
}
$vehiculo_id = intval($_POST['vehiculo_id'] ?? 0);
$campos_json = stripslashes($_POST['campos'] ?? '{}');
$campos = json_decode($campos_json, true);
if (!$vehiculo_id || empty($campos)) {
throw new Exception('Datos inválidos');
}
$pdo = vehiculos_conectar_db();
$sets = [];
$params = ['id' => $vehiculo_id];
$campos_permitidos = [
'puertas', 'color', 'combustible', 'tipo_cambio', 'carroceria', 'traccion', 'potencia_cv',
'emisiones_co2', 'tipo_etiqueta', 'medidas', 'peso',
'bastidor', 'vin_bat', 'vin_bat2', 'inversor_no', 'matricula', 'precio_compra'
];
foreach ($campos as $campo => $valor) {
if (in_array($campo, $campos_permitidos)) {
$sets[] = "`$campo` = :$campo";
$params[$campo] = $valor;
}
}
if (empty($sets)) {
throw new Exception('No hay campos válidos');
}
$sql = "UPDATE vehiculos_historico SET " . implode(', ', $sets) . " WHERE id = :id";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
error_log('✅ Vehículo HISTORICO #' . $vehiculo_id . ' actualizado');
wp_send_json_success(['mensaje' => 'Actualizado correctamente']);
} catch (Exception $e) {
error_log('❌ Error: ' . $e->getMessage());
wp_send_json_error($e->getMessage());
}
}
error_log('✅ [VEHICULOS] Módulo AJAX v3.2 cargado - Con actualización');
?>
Warning: Cannot modify header information - headers already sent by (output started at /var/www/vhosts/micro-coches.com/httpdocs/wp-content/themes/astra-child/includes/ajax/vehiculos/ajax_vehiculos.php:749) in /var/www/vhosts/micro-coches.com/httpdocs/wp-includes/pluggable.php on line 1450
Warning: Cannot modify header information - headers already sent by (output started at /var/www/vhosts/micro-coches.com/httpdocs/wp-content/themes/astra-child/includes/ajax/vehiculos/ajax_vehiculos.php:749) in /var/www/vhosts/micro-coches.com/httpdocs/wp-includes/pluggable.php on line 1453