conexion con api winsaai

This commit is contained in:
2025-05-12 12:09:10 -06:00
parent 722f7fbb5f
commit 485e249dab
4 changed files with 288 additions and 8 deletions

5
.env
View File

@@ -10,3 +10,8 @@ ENCRYPTION_IV=7c9f4a2d1e3b5f7a
RECAPTCHA_SECRET=6LfkMB8rAAAAAFWMAZmIqtN0ocDzg9t1g0_xbkkN RECAPTCHA_SECRET=6LfkMB8rAAAAAFWMAZmIqtN0ocDzg9t1g0_xbkkN
SMTP_PASS=N036p7y! SMTP_PASS=N036p7y!
API_URL=http://50.21.176.205:3000
API_USER=adminAS
API_PASS=zC?K.Z5o2tiLN4gE

View File

@@ -0,0 +1,163 @@
<?php
// app/controllers/proveedores.php
session_start();
// 1) Composer autoload (phpdotenv y demás libs)
require_once __DIR__ . '/../../vendor/autoload.php';
// 2) Carga nuestro helper de entorno y dispara la carga de .env
require_once __DIR__ . '/../helpers/env.php';
loadEnv();
/**
* Obtiene (y cachea en sesión) el JWT de la API usando las credenciales de $_ENV
*/
function getApiToken(): ?string
{
if (!empty($_SESSION['api_token'])) {
return $_SESSION['api_token'];
}
$url = rtrim($_ENV['API_URL'] ?? '', '/') . '/auth/login';
$user = $_ENV['API_USER'] ?? '';
$pass = $_ENV['API_PASS'] ?? '';
$body = json_encode(['username'=>$user,'password'=>$pass]);
error_log("[getApiToken] POST $url → body: $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: $resp");
if ($http === 200 && ($data = json_decode($resp, true)) && !empty($data['token'])) {
$_SESSION['api_token'] = $data['token'];
return $data['token'];
}
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
"<a href=\"/IMPORTADORES/proveedores/editar?clave=" . rawurlencode($clave) . "\" class=\"btn btn-sm btn-primary\">✏️</a>
<button class=\"btn btn-sm btn-danger\" onclick=\"confirmDelete('{$clave}')\">🗑️</button>"
];
}
} 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: Bearer $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;
}

View File

@@ -93,30 +93,31 @@ if (!isset($_SESSION['usuario_id']) || $_SESSION['tipo_usuario'] !== 'importador
</div> </div>
<!-- Proveedores --> <!-- Proveedores -->
<a <a
class="nav-link px-3 py-2 d-flex justify-content-between align-items-center <?= str_contains($_SERVER['REQUEST_URI'], '/proveedores') ? 'active' : '' ?>" class="nav-link px-3 py-2 d-flex justify-content-between align-items-center
<?= str_contains($_SERVER['REQUEST_URI'], '/IMPORTADORES/proveedores') ? 'active' : '' ?>"
data-bs-toggle="collapse" data-bs-toggle="collapse"
href="#submenuProveedores" href="#submenuProveedores"
role="button" role="button"
aria-expanded="<?= str_contains($_SERVER['REQUEST_URI'], '/proveedores') ? 'true' : 'false' ?>" aria-expanded="<?= str_contains($_SERVER['REQUEST_URI'], '/IMPORTADORES/proveedores') ? 'true' : 'false' ?>"
aria-controls="submenuProveedores" aria-controls="submenuProveedores"
> >
🏭 Proveedores 🏭 Proveedores
<span class="badge bg-secondary">2</span> <span class="badge bg-secondary">2</span>
</a> </a>
<div <div
class="collapse <?= str_contains($_SERVER['REQUEST_URI'], '/proveedores') ? 'show' : '' ?>" class="collapse <?= str_contains($_SERVER['REQUEST_URI'], '/IMPORTADORES/proveedores') ? 'show' : '' ?>"
id="submenuProveedores" id="submenuProveedores"
> >
<nav class="nav flex-column ms-3"> <nav class="nav flex-column ms-3">
<a <a
href="/importadores/proveedores" href="/IMPORTADORES/proveedores"
class="nav-link px-3 py-1 <?= $_SERVER['REQUEST_URI'] === '/importadores/proveedores' ? 'active' : '' ?>" class="nav-link px-3 py-1 <?= $_SERVER['REQUEST_URI'] === '/IMPORTADORES/proveedores' ? 'active' : '' ?>"
> >
• Lista de Proveedores • Lista de Proveedores
</a> </a>
<a <a
href="/importadores/proveedores/crear" href="/IMPORTADORES/proveedores/crear"
class="nav-link px-3 py-1 <?= str_contains($_SERVER['REQUEST_URI'], '/proveedores/crear') ? 'active' : '' ?>" class="nav-link px-3 py-1 <?= str_contains($_SERVER['REQUEST_URI'], '/IMPORTADORES/proveedores/crear') ? 'active' : '' ?>"
> >
• Registro de Proveedor • Registro de Proveedor
</a> </a>
@@ -124,6 +125,7 @@ if (!isset($_SESSION['usuario_id']) || $_SESSION['tipo_usuario'] !== 'importador
</div> </div>
<!-- SOLICITUDES DE IMPORTACIÓN --> <!-- SOLICITUDES DE IMPORTACIÓN -->
<a class="nav-link px-3 py-2 d-flex justify-content-between align-items-center <a class="nav-link px-3 py-2 d-flex justify-content-between align-items-center
<?= str_contains($_SERVER['REQUEST_URI'], '/solicitud_importacion') ? 'active' : '' ?>" <?= str_contains($_SERVER['REQUEST_URI'], '/solicitud_importacion') ? 'active' : '' ?>"

110
views/proveedores/lista.php Normal file
View File

@@ -0,0 +1,110 @@
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>📄 Listado de Proveedores</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap y DataTables CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.min.css" rel="stylesheet">
<style>
body { background: #f4f6f9; font-family: 'Segoe UI', sans-serif; }
.sidebar { width: 220px; position: fixed; height: 100vh; background: #343a40; padding-top: 60px; }
.sidebar .nav-link { color: #ccc; padding: 12px 20px; }
.sidebar .nav-link.active,
.sidebar .nav-link:hover { background: #495057; color: #fff; }
.content { margin-left: 220px; padding: 40px 20px; }
.card { border-radius: 12px; }
table.dataTable thead th { background: #343a40; color: #fff; }
</style>
</head>
<body>
<?php include __DIR__ . '/../partials/sidebar_importador.php'; ?>
<div class="content">
<br> <br>
<h4 class="mb-4">📄 Listado de Proveedores</h4>
<div class="card p-3 shadow-sm">
<table id="proveedores-table" class="display nowrap" style="width:100%">
<thead>
<tr>
<th>Clave</th>
<th>Nombre</th>
<th>RFC</th>
<th>Ciudad</th>
<th>Teléfono</th>
<th>Acciones</th>
</tr>
</thead>
</table>
</div>
</div>
<!-- JS: jQuery, DataTables, Bootstrap, SweetAlert2 -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script>
$(function(){
$('#proveedores-table').DataTable({
serverSide: true,
processing: true,
ajax: {
url: '/IMPORTADORES/proveedores/ajax_lista',
type: 'GET',
dataSrc: function(json) {
if (!json || !Array.isArray(json.data)) {
console.error('Respuesta inválida de ajax_lista:', json);
return [];
}
return json.data;
},
error: function(xhr, status, error) {
console.error('Error Ajax:', status, error, '\nResponse:', xhr.responseText);
Swal.fire({
icon: 'error',
title: 'Error al cargar proveedores',
text: 'Revisa la consola para más detalles.',
});
}
},
columns: [
{ data: 0 }, { data: 1 }, { data: 2 },
{ data: 3 }, { data: 4 }, { data: 5 }
],
language: {
url: '//cdn.datatables.net/plug-ins/1.13.4/i18n/es-ES.json'
}
});
});
function confirmDelete(clave) {
Swal.fire({
title: '¿Desactivar proveedor?',
text: 'No podrá volver a usarse hasta reactivarlo.',
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Sí, desactivar',
cancelButtonText: 'Cancelar',
confirmButtonColor: '#d33'
}).then(result => {
if (result.isConfirmed) {
window.location = `/IMPORTADORES/proveedores/eliminar?clave=${clave}`;
}
});
}
<?php if (isset($_GET['deleted']) && $_GET['deleted']==='ok'): ?>
Swal.fire({
icon: 'success',
title: 'Proveedor desactivado',
confirmButtonColor: '#198754'
});
<?php endif; ?>
</script>
</body>
</html>