$user, 'password' => $pass]); error_log("[getApiToken] POST $url → $body"); $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_POSTFIELDS => $body, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 5, ]); $resp = curl_exec($ch); $http = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); error_log("[getApiToken] HTTP $http → $resp"); if ($http === 200 && ($data = json_decode($resp, true)) && !empty($data['token'])) { // 3) Guardamos token y tiempo actual $_SESSION['api_token'] = $data['token']; $_SESSION['api_token_time'] = time(); return $data['token']; } // 4) Si no se pudo obtener, devolvemos null error_log('[getApiToken] No se pudo obtener token de la API'); return null; } /** * GET /IMPORTADORES/proveedores * Muestra la vista de listado */ function index() { lista(); } function lista() { if (empty($_SESSION['usuario_id'])) { header('Location: /IMPORTADORES/login'); exit; } include __DIR__ . '/../../views/proveedores/lista.php'; } /** * GET /IMPORTADORES/proveedores/ajax_lista * Devuelve JSON para DataTables */ /** * GET /IMPORTADORES/proveedores/ajax_lista * Devuelve JSON para DataTables (siempre HTTP 200) */ function ajax_lista() { // 1) Fijamos el header JSON header('Content-Type: application/json; charset=utf-8'); // 2) Obtener o renovar token $token = getApiToken(); if (!$token) { error_log('[ajax_lista] Sin token válido'); // Devolvemos estructura vacía echo json_encode(['data' => []]); return; } // 3) Construimos la URL de la API $apiBase = rtrim($_ENV['API_URL'] ?? '', '/'); $url = $apiBase . '/proveedores'; error_log("[ajax_lista] GET $url"); // 4) Ejecutamos cURL $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_HTTPHEADER => ["Authorization: $token", 'Accept: application/json'], CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 5, ]); $resp = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); error_log("[ajax_lista] HTTP $status → $resp"); // 5) Parseamos y formateamos $dataList = []; if ($status === 200 && ($json = json_decode($resp, true)) && is_array($json)) { foreach ($json as $p) { $clave = htmlspecialchars($p['Clave'] ?? '', ENT_QUOTES); $dataList[] = [ $clave, htmlspecialchars($p['Nombre'] ?? '', ENT_QUOTES), htmlspecialchars($p['RFC'] ?? '', ENT_QUOTES), htmlspecialchars($p['Ciudad'] ?? '', ENT_QUOTES), htmlspecialchars($p['Telefono']?? '', ENT_QUOTES), // Acciones "✏️ " ]; } } else { error_log('[ajax_lista] Respuesta inválida o status != 200'); } // 6) Devolvemos siempre HTTP 200 con data (posiblemente vacío) echo json_encode(['data' => $dataList]); } /** * GET /IMPORTADORES/proveedores/eliminar * Llama a DELETE /api/proveedores/:clave y redirige */ function eliminar() { $token = getApiToken(); $clave = $_GET['clave'] ?? ''; if (!$token || !$clave) { header('Location: /IMPORTADORES/proveedores'); exit; } $url = rtrim($_ENV['API_URL'] ?? '', '/') . '/api/proveedores/' . urlencode($clave); error_log("[eliminar] DELETE $url"); $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => 'DELETE', CURLOPT_HTTPHEADER => ["Authorization: $token",'Accept: application/json'], CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 5, ]); curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); header('Location: /IMPORTADORES/proveedores?deleted=' . ($status===200||$status===204 ? 'ok':'error')); exit; } function crear() { // 1) Aseguramos que el usuario esté logueado if (empty($_SESSION['usuario_id'])) { header('Location: /IMPORTADORES/login'); exit; } // 2) Cargamos la vista include __DIR__ . '/../../views/proveedores/crear.php'; } /** * POST /IMPORTADORES/proveedores/guardar * Procesa el alta de un nuevo proveedor contra la API WinSAAI. */ function guardar() { // 1) Validar sesión if (empty($_SESSION['usuario_id'])) { header('Location: /IMPORTADORES/login'); exit; } // 2) Recoger datos del formulario $payload = [ 'Clave' => trim($_POST['Clave'] ?? ''), 'Nombre' => trim($_POST['Nombre'] ?? ''), 'RFC' => trim($_POST['RFC'] ?? ''), 'Ciudad' => trim($_POST['Ciudad'] ?? ''), 'Telefono' => trim($_POST['Telefono'] ?? ''), 'Pais' => trim($_POST['Pais'] ?? ''), 'Colonia' => trim($_POST['Colonia'] ?? ''), 'Municipio' => trim($_POST['Municipio'] ?? ''), 'CodigoPostal' => trim($_POST['CodigoPostal'] ?? ''), 'EntidadFederativa' => trim($_POST['EntidadFederativa'] ?? ''), ]; // 3) Validar campos obligatorios if ($payload['Clave']==='' || $payload['Nombre']==='' || $payload['RFC']==='' || $payload['Ciudad']==='') { $_SESSION['flash_error'] = 'Clave, Nombre, RFC y Ciudad son obligatorios.'; header('Location: /IMPORTADORES/proveedores/crear'); exit; } // 4) Obtener JWT $token = getApiToken(); if (!$token) { $_SESSION['flash_error'] = 'No fue posible autenticar contra la API.'; header('Location: /IMPORTADORES/proveedores/crear'); exit; } // 5) Llamada a la API para crear el proveedor $url = rtrim($_ENV['API_URL'] ?? '', '/') . '/api/proveedores'; $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer $token", 'Content-Type: application/json' ], CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 10, ]); $resp = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); // 6) Manejar respuesta if ($status === 201) { // Éxito header('Location: /IMPORTADORES/proveedores?created=ok'); exit; } else { // Error, opcionalmente parsear mensaje $msg = ''; if ($json = json_decode($resp, true)) { $msg = $json['mensaje'] ?? $json['error'] ?? ''; } $_SESSION['flash_error'] = "Error al crear proveedor (HTTP $status) $msg"; header('Location: /IMPORTADORES/proveedores/crear'); exit; } }