Files
MVE/app/controllers/proveedores.php

283 lines
9.1 KiB
PHP

<?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
*/
/**
* Obtiene (y cachea) el JWT de la API usando credenciales de $_ENV
* Gestiona expiración: asume 1 hora de vida y renueva si ha pasado.
*/
function getApiToken(): ?string
{
// Duración en segundos del token (60 min)
$ttl = 3600;
// 1) Si ya tenemos token y no ha expirado, lo devolvemos
if (!empty($_SESSION['api_token']) && !empty($_SESSION['api_token_time'])) {
$age = time() - $_SESSION['api_token_time'];
if ($age < $ttl) {
error_log("[getApiToken] Usando token en caché (edad: {$age}s)");
return $_SESSION['api_token'];
}
error_log("[getApiToken] Token expirado (edad: {$age}s), obteniendo uno nuevo");
}
// 2) Sí o sí hacemos login en la API
$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");
$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);
// Construir dirección
$direccion = trim(implode(', ', array_filter([
$p['Calles'] ?? '',
'Num. Ext: ' . ($p['NumExt'] ?? ''),
'Num. Int: ' . ($p['NumInt'] ?? ''),
$p['Colonia'] ?? '',
$p['Municipio'] ?? '',
$p['Ciudad'] ?? '',
'C.P. ' . ($p['CodigoPostal'] ?? ''),
$p['EntidadFederativa'] ?? '',
$p['Pais'] ?? ''
])));
$dataList[] = [
$clave,
htmlspecialchars($p['Nombre'] ?? '', ENT_QUOTES),
htmlspecialchars($p['RFC'] ?? '', ENT_QUOTES),
htmlspecialchars($p['Ciudad'] ?? '', ENT_QUOTES),
htmlspecialchars($p['Telefono']?? '', ENT_QUOTES),
htmlspecialchars($direccion ?? '', 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: $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;
}
}