Files
MVE/app/controllers/templates_rapidos.php
2025-10-21 11:41:30 -06:00

913 lines
31 KiB
PHP

<?php
require_once __DIR__ . '/../helpers/session.php';
require_once __DIR__ . '/../../config/database.php';
function index()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
include __DIR__ . '/../../views/templates_rapidos/index.php';
}
function lista()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
include __DIR__ . '/../../views/templates_rapidos/lista.php';
}
function crear()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
$conn = getConnection();
// Obtener datos para los selects
$aduanas = obtenerAduanas($conn);
$patentes = obtenerPatentes($conn);
$incoterms = obtenerIncoterms($conn);
$paises = obtenerPaises($conn);
$transportistas = obtenerTransportistas($conn);
$choferes = obtenerChoferes($conn);
$unidades_medida = obtenerUnidadesMedida($conn);
include __DIR__ . '/../../views/templates_rapidos/crear.php';
}
function guardar()
{
if (!($_SESSION['usuario_id'] ?? false)) {
die("⚠️ No autorizado.");
}
$conn = getConnection();
$id_usuario = $_SESSION['usuario_id'];
$id_agencia = $_SESSION['id_agencia_en_uso'] ?? null;
// Obtener datos del formulario
$nombre = trim($_POST['nombre'] ?? '');
$descripcion = trim($_POST['descripcion'] ?? '');
$icono = trim($_POST['icono'] ?? '🏢');
// Configuración del template
$config = [
'tipo_moneda' => $_POST['tipo_moneda'] ?? '',
'incoterm' => $_POST['incoterm'] ?? '',
'vinculacion' => $_POST['vinculacion'] ?? '',
'pais_proveedor' => $_POST['pais_proveedor'] ?? '',
'pais_proveedor_texto' => $_POST['pais_proveedor_texto'] ?? '',
'anexo22_apendice' => $_POST['anexo22_apendice'] ?? '',
'patente' => $_POST['patente'] ?? '',
'transportista_id' => $_POST['transportista_id'] ?? '',
'chofer_id' => $_POST['chofer_id'] ?? '',
'tasa_preferencial' => $_POST['tasa_preferencial'] ?? '',
'unidad_comercial_id' => $_POST['unidad_comercial_id'] ?? ''
];
$config_json = json_encode($config, JSON_UNESCAPED_UNICODE);
// Validaciones
if (empty($nombre)) {
die("❌ El nombre del template es obligatorio.");
}
if (strlen($nombre) > 100) {
die("❌ El nombre del template es muy largo (máximo 100 caracteres).");
}
$sql = "INSERT INTO dbo.templates_rapidos
(nombre, descripcion, icono, config_json, tipo_moneda, incoterm,
vinculacion, pais_proveedor, tasa_preferencial, id_agencia, id_usuario_creador)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$params = [
$nombre,
$descripcion,
$icono,
$config_json,
$config['tipo_moneda'],
$config['incoterm'],
$config['vinculacion'] ?: null,
$config['pais_proveedor'],
$config['tasa_preferencial'],
$id_agencia,
$id_usuario
];
$stmt = sqlsrv_query($conn, $sql, $params);
if ($stmt === false) {
die("❌ Error al guardar template: " . print_r(sqlsrv_errors(), true));
}
header('Location: /IMPORTADORES/templates_rapidos/lista?created=ok');
exit;
}
function editar()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
$id = $_GET['id'] ?? null;
if (!$id || !is_numeric($id)) {
die("❌ ID inválido.");
}
$conn = getConnection();
$id_usuario = $_SESSION['usuario_id'];
$id_agencia = $_SESSION['id_agencia_en_uso'] ?? null;
// Obtener el template
$sql = "SELECT * FROM dbo.templates_rapidos
WHERE id = ? AND (id_usuario_creador = ? OR id_agencia = ? OR id_agencia IS NULL)";
$stmt = sqlsrv_query($conn, $sql, [$id, $id_usuario, $id_agencia]);
if ($stmt === false) {
die("❌ Error en consulta: " . print_r(sqlsrv_errors(), true));
}
$template = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if (!$template) {
die("❌ Template no encontrado o sin permisos.");
}
// Decodificar configuración JSON
$template['config'] = json_decode($template['config_json'], true) ?: [];
// Obtener datos para los selects
$conn = getConnection();
$aduanas = obtenerAduanas($conn);
$patentes = obtenerPatentes($conn);
$incoterms = obtenerIncoterms($conn);
$paises = obtenerPaises($conn);
$transportistas = obtenerTransportistas($conn);
$choferes = obtenerChoferes($conn);
$unidades_medida = obtenerUnidadesMedida($conn);
include __DIR__ . '/../../views/templates_rapidos/editar.php';
}
function actualizar()
{
if (!($_SESSION['usuario_id'] ?? false)) {
die("⚠️ No autorizado.");
}
$conn = getConnection();
$id_usuario = $_SESSION['usuario_id'];
$id_agencia = $_SESSION['id_agencia_en_uso'] ?? null;
$id = $_POST['id'] ?? null;
$nombre = trim($_POST['nombre'] ?? '');
$descripcion = trim($_POST['descripcion'] ?? '');
$icono = trim($_POST['icono'] ?? '🏢');
if (!$id || !is_numeric($id)) {
die("❌ ID inválido.");
}
// Configuración del template
$config = [
'tipo_moneda' => $_POST['tipo_moneda'] ?? '',
'incoterm' => $_POST['incoterm'] ?? '',
'vinculacion' => $_POST['vinculacion'] ?? '',
'pais_proveedor' => $_POST['pais_proveedor'] ?? '',
'pais_proveedor_texto' => $_POST['pais_proveedor_texto'] ?? '',
'anexo22_apendice' => $_POST['anexo22_apendice'] ?? '',
'patente' => $_POST['patente'] ?? '',
'transportista_id' => $_POST['transportista_id'] ?? '',
'chofer_id' => $_POST['chofer_id'] ?? '',
'tasa_preferencial' => $_POST['tasa_preferencial'] ?? '',
'unidad_comercial_id' => $_POST['unidad_comercial_id'] ?? ''
];
$config_json = json_encode($config, JSON_UNESCAPED_UNICODE);
// Validaciones
if (empty($nombre)) {
die("❌ El nombre del template es obligatorio.");
}
// Verificar permisos
$sqlCheck = "SELECT id FROM dbo.templates_rapidos
WHERE id = ? AND (id_usuario_creador = ? OR id_agencia = ?)";
$stmtCheck = sqlsrv_query($conn, $sqlCheck, [$id, $id_usuario, $id_agencia]);
$exists = sqlsrv_fetch_array($stmtCheck, SQLSRV_FETCH_ASSOC);
if (!$exists) {
die("❌ Template no encontrado o sin permisos para editarlo.");
}
$sql = "UPDATE dbo.templates_rapidos SET
nombre = ?, descripcion = ?, icono = ?, config_json = ?,
tipo_moneda = ?, incoterm = ?, vinculacion = ?,
pais_proveedor = ?, tasa_preferencial = ?, fecha_modificacion = GETDATE()
WHERE id = ?";
$params = [
$nombre,
$descripcion,
$icono,
$config_json,
$config['tipo_moneda'],
$config['incoterm'],
$config['vinculacion'] ?: null,
$config['pais_proveedor'],
$config['tasa_preferencial'],
$id
];
$stmt = sqlsrv_query($conn, $sql, $params);
if ($stmt === false) {
die("❌ Error al actualizar template: " . print_r(sqlsrv_errors(), true));
}
header('Location: /IMPORTADORES/templates_rapidos/lista?updated=ok');
exit;
}
function eliminar()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
$id = $_GET['id'] ?? null;
if (!$id || !is_numeric($id)) {
die("❌ ID inválido.");
}
$conn = getConnection();
$id_usuario = $_SESSION['usuario_id'];
$id_agencia = $_SESSION['id_agencia_en_uso'] ?? null;
// Verificar permisos
$sqlCheck = "SELECT id FROM dbo.templates_rapidos
WHERE id = ? AND (id_usuario_creador = ? OR id_agencia = ?)";
$stmtCheck = sqlsrv_query($conn, $sqlCheck, [$id, $id_usuario, $id_agencia]);
$exists = sqlsrv_fetch_array($stmtCheck, SQLSRV_FETCH_ASSOC);
if (!$exists) {
die("❌ Template no encontrado o sin permisos para eliminarlo.");
}
$sql = "UPDATE dbo.templates_rapidos SET activo = 0 WHERE id = ?";
$stmt = sqlsrv_query($conn, $sql, [$id]);
if ($stmt === false) {
die("❌ Error al eliminar template: " . print_r(sqlsrv_errors(), true));
}
header('Location: /IMPORTADORES/templates_rapidos/lista?deleted=ok');
exit;
}
function ajax_lista()
{
if (!($_SESSION['usuario_id'] ?? false)) {
http_response_code(403);
echo json_encode([]);
exit;
}
$id_usuario = $_SESSION['usuario_id'];
$id_agencia = $_SESSION['id_agencia_en_uso'] ?? null;
$conn = getConnection();
// Parámetros de DataTables
$draw = intval($_GET['draw'] ?? 0);
$start = intval($_GET['start'] ?? 0);
$length = intval($_GET['length'] ?? 10);
$search = $_GET['search']['value'] ?? '';
// Construir condiciones de filtro
$where = "activo = 1 AND (id_agencia IS NULL OR id_agencia = ? OR id_usuario_creador = ?)";
$params = [$id_agencia, $id_usuario];
if ($search !== '') {
$where .= " AND (nombre LIKE ? OR descripcion LIKE ?)";
$like = "%{$search}%";
$params = array_merge($params, [$like, $like]);
}
// Total registros filtrados
$sqlFiltered = "SELECT COUNT(*) AS total FROM dbo.templates_rapidos WHERE $where";
$stmtF = sqlsrv_query($conn, $sqlFiltered, $params);
$rowF = sqlsrv_fetch_array($stmtF, SQLSRV_FETCH_ASSOC);
$recordsFiltered = (int)($rowF['total'] ?? 0);
// Total registros sin filtro
$sqlTotal = "SELECT COUNT(*) AS total FROM dbo.templates_rapidos WHERE activo = 1 AND (id_agencia IS NULL OR id_agencia = ? OR id_usuario_creador = ?)";
$stmtT = sqlsrv_query($conn, $sqlTotal, [$id_agencia, $id_usuario]);
$rowT = sqlsrv_fetch_array($stmtT, SQLSRV_FETCH_ASSOC);
$recordsTotal = (int)($rowT['total'] ?? 0);
// Consulta principal con paginación
$sql = "SELECT t.id, t.nombre, t.descripcion, t.icono, t.tipo_moneda, t.incoterm,
t.vinculacion, t.pais_proveedor, t.tasa_preferencial, t.fecha_creacion,
u.nombre_usuario AS usuario_creador,
CASE WHEN t.id_agencia IS NULL THEN 'Sistema' ELSE a.nombre END AS ambito
FROM dbo.templates_rapidos t
LEFT JOIN dbo.usuarios u ON t.id_usuario_creador = u.id
LEFT JOIN dbo.agencias a ON t.id_agencia = a.id
WHERE $where
ORDER BY t.fecha_creacion DESC
OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
$paramsData = array_merge($params, [$start, $length]);
$stmt = sqlsrv_query($conn, $sql, $paramsData);
$data = [];
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$fecha = $row['fecha_creacion'] instanceof DateTime
? $row['fecha_creacion']->format('d/m/Y H:i')
: 'N/A';
$data[] = [
'id' => $row['id'],
'icono' => htmlspecialchars($row['icono'] ?? '🏢'),
'nombre' => htmlspecialchars($row['nombre']),
'descripcion' => htmlspecialchars($row['descripcion'] ?? ''),
'tipo_moneda' => htmlspecialchars($row['tipo_moneda'] ?? ''),
'incoterm' => htmlspecialchars($row['incoterm'] ?? ''),
'pais_proveedor' => htmlspecialchars($row['pais_proveedor'] ?? ''),
'ambito' => htmlspecialchars($row['ambito'] ?? ''),
'usuario_creador' => htmlspecialchars($row['usuario_creador'] ?? ''),
'fecha_creacion' => $fecha
];
}
echo json_encode([
'draw' => $draw,
'recordsTotal' => $recordsTotal,
'recordsFiltered' => $recordsFiltered,
'data' => $data
]);
}
function ajax_obtener_templates_debug()
{
header('Content-Type: application/json; charset=UTF-8');
if (!($_SESSION['usuario_id'] ?? false)) {
echo json_encode(['error' => 'Usuario no autenticado']);
exit;
}
$id_usuario = $_SESSION['usuario_id'];
$id_agencia = $_SESSION['id_agencia_en_uso'] ?? null;
try {
$conn = getConnection();
// ✅ CONSULTA SIN FILTROS para debug
$sql = "SELECT id, nombre, descripcion, icono, config_json,
ISNULL(veces_usado, 0) as veces_usado,
id_usuario_creador, id_agencia, activo,
fecha_creacion
FROM dbo.templates_rapidos
ORDER BY fecha_creacion DESC";
$stmt = sqlsrv_query($conn, $sql);
if ($stmt === false) {
$errors = sqlsrv_errors();
echo json_encode([
'error' => 'Error en consulta SQL',
'message' => $errors[0]['message'] ?? 'Error desconocido',
'sql_errors' => $errors
]);
exit;
}
$templates = [];
$debug_info = [
'usuario_actual' => $id_usuario,
'agencia_actual' => $id_agencia,
'todos_los_templates' => []
];
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
// Info completa para debug
$template_debug = [
'id' => $row['id'],
'nombre' => $row['nombre'],
'id_usuario_creador' => $row['id_usuario_creador'],
'id_agencia' => $row['id_agencia'],
'activo' => $row['activo'],
'fecha_creacion' => $row['fecha_creacion'] instanceof DateTime
? $row['fecha_creacion']->format('Y-m-d H:i:s')
: $row['fecha_creacion'],
'es_del_usuario_actual' => ($row['id_usuario_creador'] == $id_usuario),
'es_de_la_agencia' => ($row['id_agencia'] == $id_agencia),
'deberia_mostrarse' => (
$row['activo'] == 1 && (
$row['id_agencia'] === null ||
$row['id_agencia'] == $id_agencia ||
$row['id_usuario_creador'] == $id_usuario
)
)
];
$debug_info['todos_los_templates'][] = $template_debug;
// Solo agregar a templates para mostrar si cumple condiciones
if ($template_debug['deberia_mostrarse']) {
$config = [];
if (!empty($row['config_json'])) {
$decoded = json_decode($row['config_json'], true);
$config = is_array($decoded) ? $decoded : [];
}
$templates[] = [
'id' => (int)$row['id'],
'nombre' => $row['nombre'],
'descripcion' => $row['descripcion'] ?? '',
'icono' => $row['icono'] ?? '📋',
'config' => $config,
'veces_usado' => (int)$row['veces_usado'],
'id_usuario_creador' => $row['id_usuario_creador'],
'es_mio' => ($row['id_usuario_creador'] == $id_usuario)
];
}
}
echo json_encode([
'success' => true,
'count' => count($templates),
'templates' => $templates,
'debug_info' => $debug_info
], JSON_UNESCAPED_UNICODE);
} catch (Exception $e) {
echo json_encode([
'error' => 'Error interno del servidor',
'message' => $e->getMessage()
]);
}
exit;
}
function ajax_obtener_templates()
{
// ✅ VERSIÓN CORREGIDA: Función simplificada sin filtros complejos
header('Content-Type: application/json; charset=UTF-8');
if (!($_SESSION['usuario_id'] ?? false)) {
http_response_code(403);
echo json_encode(['error' => 'Usuario no autenticado', 'templates' => []]);
exit;
}
$id_usuario = $_SESSION['usuario_id'];
$id_agencia = $_SESSION['id_agencia_en_uso'] ?? null;
try {
$conn = getConnection();
// ✅ CONSULTA SIMPLIFICADA: Mostrar todos los templates activos del usuario o agencia
$sql = "SELECT id, nombre, descripcion, icono, config_json,
ISNULL(veces_usado, 0) as veces_usado,
id_usuario_creador, id_agencia
FROM dbo.templates_rapidos
WHERE activo = 1
AND (id_usuario_creador = ? OR id_agencia = ? OR id_agencia IS NULL)
ORDER BY
CASE WHEN id_usuario_creador = ? THEN 0 ELSE 1 END,
veces_usado DESC,
nombre ASC";
$params = [$id_usuario, $id_agencia, $id_usuario];
$stmt = sqlsrv_query($conn, $sql, $params);
if ($stmt === false) {
$errors = sqlsrv_errors();
echo json_encode([
'error' => 'Error en consulta SQL',
'message' => $errors[0]['message'] ?? 'Error desconocido',
'templates' => []
]);
exit;
}
$templates = [];
$templates_personales = [];
$templates_otros = [];
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
// Decodificar JSON con manejo de errores
$config = [];
if (!empty($row['config_json'])) {
$decoded = json_decode($row['config_json'], true);
$config = is_array($decoded) ? $decoded : [];
}
$template = [
'id' => (int)$row['id'],
'nombre' => $row['nombre'],
'descripcion' => $row['descripcion'] ?? '',
'icono' => $row['icono'] ?? '📋',
'config' => $config,
'veces_usado' => (int)$row['veces_usado'],
'id_usuario_creador' => $row['id_usuario_creador'],
'id_agencia' => $row['id_agencia'],
'es_mio' => ($row['id_usuario_creador'] == $id_usuario),
'ambito' => ($row['id_usuario_creador'] == $id_usuario) ? 'personal' :
(($row['id_agencia'] == $id_agencia) ? 'agencia' : 'sistema')
];
// Separar templates personales de otros
if ($template['es_mio']) {
$templates_personales[] = $template;
} else {
$templates_otros[] = $template;
}
$templates[] = $template;
}
// Respuesta con información detallada
echo json_encode([
'success' => true,
'count' => count($templates),
'count_personales' => count($templates_personales),
'count_otros' => count($templates_otros),
'usuario_id' => $id_usuario,
'agencia_id' => $id_agencia,
'templates' => $templates,
'templates_personales' => $templates_personales,
'templates_otros' => $templates_otros
], JSON_UNESCAPED_UNICODE);
} catch (Exception $e) {
echo json_encode([
'error' => 'Error interno del servidor',
'message' => $e->getMessage(),
'templates' => []
]);
}
exit;
}
function ajax_lista_por_seccion()
{
if (!($_SESSION['usuario_id'] ?? false)) {
die(json_encode(['error' => 'No autorizado']));
}
$conn = getConnection();
$id_usuario = $_SESSION['usuario_id'];
$id_agencia = $_SESSION['id_agencia_en_uso'] ?? null;
$seccion = $_GET['seccion'] ?? 'personal';
$data = [];
try {
switch($seccion) {
case 'personal':
// Solo templates creados por el usuario actual
$sql = "SELECT id, nombre, descripcion, icono, config_json,
veces_usado, fecha_creacion, id_usuario_creador
FROM dbo.templates_rapidos
WHERE id_usuario_creador = ? AND estado = 1
ORDER BY veces_usado DESC, fecha_creacion DESC";
$params = [$id_usuario];
break;
case 'agencia':
// Templates de la agencia (excluyendo los personales ya mostrados)
$sql = "SELECT id, nombre, descripcion, icono, config_json,
veces_usado, fecha_creacion, id_usuario_creador
FROM dbo.templates_rapidos
WHERE id_agencia = ? AND id_usuario_creador != ? AND estado = 1
ORDER BY veces_usado DESC, fecha_creacion DESC";
$params = [$id_agencia, $id_usuario];
break;
case 'global':
// Templates globales del sistema (solo si se solicitan explícitamente)
$sql = "SELECT id, nombre, descripcion, icono, config_json,
veces_usado, fecha_creacion, id_usuario_creador
FROM dbo.templates_rapidos
WHERE id_agencia IS NULL AND id_usuario_creador IS NULL AND estado = 1
ORDER BY veces_usado DESC, fecha_creacion DESC";
$params = [];
break;
default:
throw new Exception('Sección inválida');
}
$stmt = sqlsrv_query($conn, $sql, $params);
if ($stmt === false) {
throw new Exception('Error en consulta: ' . print_r(sqlsrv_errors(), true));
}
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
// Formatear fecha
$fecha = $row['fecha_creacion'] instanceof DateTime
? $row['fecha_creacion']->format('d/m/Y')
: date('d/m/Y', strtotime($row['fecha_creacion']));
// Determinar acciones según el tipo de template
$acciones = '';
$esPropio = ($row['id_usuario_creador'] == $id_usuario);
$esAgencia = ($seccion === 'agencia');
$esGlobal = ($seccion === 'global');
if ($esPropio) {
$acciones = '
<div class="btn-group" role="group">
<a href="/IMPORTADORES/templates_rapidos/editar?id=' . $row['id'] . '"
class="btn btn-sm btn-outline-primary" title="Editar">
<i class="fas fa-edit"></i>
</a>
<button onclick="duplicarTemplate(' . $row['id'] . ')"
class="btn btn-sm btn-outline-info" title="Duplicar">
<i class="fas fa-copy"></i>
</button>
<button onclick="eliminarTemplate(' . $row['id'] . ')"
class="btn btn-sm btn-outline-danger" title="Eliminar">
<i class="fas fa-trash"></i>
</button>
</div>';
} elseif ($esAgencia) {
$acciones = '
<div class="btn-group" role="group">
<button onclick="mostrarVistaPrevia(' . $row['id'] . ')"
class="btn btn-sm btn-outline-info" title="Ver">
<i class="fas fa-eye"></i>
</button>
<button onclick="duplicarTemplate(' . $row['id'] . ')"
class="btn btn-sm btn-outline-success" title="Duplicar">
<i class="fas fa-copy"></i>
</button>
</div>';
} else { // Global
$acciones = '
<button onclick="mostrarVistaPrevia(' . $row['id'] . ')"
class="btn btn-sm btn-outline-info" title="Ver detalles">
<i class="fas fa-eye"></i>
</button>';
}
// Construir nombre con icono
$nombreConIcono = '<span class="d-flex align-items-center">
<span class="me-2" style="font-size: 18px;">' . htmlspecialchars($row['icono']) . '</span>
<div>
<strong>' . htmlspecialchars($row['nombre']) . '</strong>';
// Agregar badge según el tipo
if ($esPropio) {
$nombreConIcono .= ' <span class="badge bg-primary scope-badge ms-2">Mío</span>';
} elseif ($esAgencia) {
$nombreConIcono .= ' <span class="badge bg-info scope-badge ms-2">Agencia</span>';
} else {
$nombreConIcono .= ' <span class="badge bg-secondary scope-badge ms-2">Global</span>';
}
$nombreConIcono .= '</div></span>';
$data[] = [
$row['id'],
$nombreConIcono,
htmlspecialchars($row['descripcion'] ?? 'Sin descripción'),
'<span class="badge bg-success">' . ($row['veces_usado'] ?? 0) . '</span>',
$fecha,
$acciones
];
}
echo json_encode([
'success' => true,
'data' => $data,
'count' => count($data)
]);
} catch (Exception $e) {
echo json_encode([
'success' => false,
'error' => $e->getMessage(),
'data' => []
]);
}
}
function duplicar()
{
if (!($_SESSION['usuario_id'] ?? false)) {
die("⚠️ No autorizado.");
}
$conn = getConnection();
$id_usuario = $_SESSION['usuario_id'];
$id_agencia = $_SESSION['id_agencia_en_uso'] ?? null;
$template_id = $_POST['template_id'] ?? null;
if (!$template_id || !is_numeric($template_id)) {
die("❌ ID de template inválido.");
}
// Obtener template original
$sql = "SELECT * FROM dbo.templates_rapidos WHERE id = ?";
$stmt = sqlsrv_query($conn, $sql, [$template_id]);
if ($stmt === false) {
die("❌ Error al buscar template: " . print_r(sqlsrv_errors(), true));
}
$original = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if (!$original) {
die("❌ Template no encontrado.");
}
// Crear duplicado con nuevo nombre
$nuevo_nombre = $original['nombre'] . ' (Copia)';
$sql_insert = "INSERT INTO dbo.templates_rapidos
(nombre, descripcion, icono, config_json, tipo_moneda, incoterm,
vinculacion, pais_proveedor, tasa_preferencial, id_agencia, id_usuario_creador)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$params_insert = [
$nuevo_nombre,
$original['descripcion'],
$original['icono'],
$original['config_json'],
$original['tipo_moneda'],
$original['incoterm'],
$original['vinculacion'],
$original['pais_proveedor'],
$original['tasa_preferencial'],
$id_agencia,
$id_usuario
];
$stmt_insert = sqlsrv_query($conn, $sql_insert, $params_insert);
if ($stmt_insert === false) {
die("❌ Error al duplicar: " . print_r(sqlsrv_errors(), true));
}
echo "✅ Template duplicado correctamente como '{$nuevo_nombre}'.";
}
function ajax_usar_template()
{
if (!($_SESSION['usuario_id'] ?? false)) {
http_response_code(403);
echo json_encode(['success' => false, 'message' => 'No autorizado']);
exit;
}
$id_template = intval($_POST['id_template'] ?? 0);
$id_usuario = $_SESSION['usuario_id'];
if ($id_template <= 0) {
echo json_encode(['success' => false, 'message' => 'ID de template inválido']);
exit;
}
$conn = getConnection();
// Incrementar contador de uso
$sql = "UPDATE dbo.templates_rapidos
SET veces_usado = veces_usado + 1, ultima_vez_usado = GETDATE()
WHERE id = ? AND activo = 1";
$stmt = sqlsrv_query($conn, $sql, [$id_template]);
if ($stmt === false) {
echo json_encode(['success' => false, 'message' => 'Error al actualizar estadísticas']);
exit;
}
echo json_encode(['success' => true]);
exit;
}
// Funciones auxiliares
function obtenerAduanas($conn) {
$sql = "SELECT DISTINCT RIGHT(REPLICATE('0', 3) + CAST(aduana_seccion AS VARCHAR), 3) AS aduana_seccion, nombre FROM dbo.aduanas ORDER BY aduana_seccion";
$stmt = sqlsrv_query($conn, $sql);
$result = [];
if ($stmt !== false) {
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$result[] = $row;
}
}
return $result;
}
function obtenerPatentes($conn) {
$id_agencia = $_SESSION['id_agencia_en_uso'] ?? null;
if (!$id_agencia) {
return [];
}
$sql = "SELECT id_agente, patente, agente_aduanal FROM dbo.agentes_aduanales WHERE id_agencia = ? AND activo = 1 ORDER BY patente";
$stmt = sqlsrv_query($conn, $sql, [$id_agencia]);
$result = [];
if ($stmt !== false) {
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$result[] = $row;
}
}
return $result;
}
function obtenerIncoterms($conn) {
$sql = "SELECT INCOTERM, DESCESPANOL FROM dbo.gIncoterms ORDER BY INCOTERM";
$stmt = sqlsrv_query($conn, $sql);
$result = [];
if ($stmt !== false) {
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$result[] = $row;
}
}
return $result;
}
function obtenerPaises($conn) {
$sql = "SELECT id_pais, nombre FROM dbo.paises ORDER BY nombre";
$stmt = sqlsrv_query($conn, $sql);
$result = [];
if ($stmt !== false) {
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$result[] = $row;
}
}
return $result;
}
function obtenerTransportistas($conn) {
$id_usuario = $_SESSION['usuario_id'] ?? null;
if (!$id_usuario) {
return [];
}
$sql = "SELECT id_transportista, clave_identificador, nombre FROM dbo.transportistas WHERE id_usuario = ? AND activo = 1 ORDER BY nombre";
$stmt = sqlsrv_query($conn, $sql, [$id_usuario]);
$result = [];
if ($stmt !== false) {
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$result[] = $row;
}
}
return $result;
}
function obtenerChoferes($conn) {
$id_usuario = $_SESSION['usuario_id'] ?? null;
if (!$id_usuario) {
return [];
}
$sql = "SELECT c.id_chofer, c.nombre+' '+c.apellido AS nombre, c.transportista_id
FROM dbo.choferes c
JOIN dbo.transportistas t ON c.transportista_id = t.id_transportista
WHERE t.id_usuario = ? AND c.status = 1
ORDER BY c.nombre";
$stmt = sqlsrv_query($conn, $sql, [$id_usuario]);
$result = [];
if ($stmt !== false) {
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$result[] = $row;
}
}
return $result;
}
function obtenerUnidadesMedida($conn) {
$sql = "SELECT id, descripcion FROM dbo.unidades_medida_apendice7 ORDER BY id";
$stmt = sqlsrv_query($conn, $sql);
$result = [];
if ($stmt !== false) {
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$result[] = $row;
}
}
return $result;
}