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