feat: módulos de envío TNS/ERP Lab + sync de médico, empresa y valor total
- Hub /envios/tns con 5 sub-tabs (Terceros, Transacción RIPS, Facturas Venta, Prueba RDA, Automatización) via iframe lazy - Hub /envios/erp con sub-tabs Pacientes y Sync Automático (historial scheduler) - Modo embed (?embed=1) en base.html para cargar páginas sin sidebar/header dentro de iframes - Sidebar simplificado: 6 ítems individuales reemplazados por módulos TNS y ERP Lab - Scheduler y endpoint /pacientes/examenes ahora incluyen médico ordenante (DOCIDMEDICO), empresa/EPS (NIT_EMPRESA) y valor total (VALORTOTAL) desde Firebird Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
31c0b71c90
commit
8e27225326
+163
-149
@@ -1,151 +1,165 @@
|
||||
<!DOCTYPE html>␍
|
||||
<html lang="es" class="h-full bg-gray-50">␍
|
||||
<head>␍
|
||||
<meta charset="UTF-8">␍
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">␍
|
||||
<title>RIPS Manager - {% block title %}Dashboard{% endblock %}</title>␍
|
||||
<script src="https://cdn.tailwindcss.com"></script>␍
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/codemirror.min.css">␍
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/codemirror.min.js"></script>␍
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/sql/sql.min.js"></script>␍
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/addon/hint/show-hint.min.js"></script>␍
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/addon/hint/sql-hint.min.js"></script>␍
|
||||
<style>␍
|
||||
.CodeMirror { border: 1px solid #d1d5db; border-radius: 0.5rem; font-size: 13px; height: auto; min-height: 200px; }␍
|
||||
.CodeMirror-hints { font-size: 12px; }␍
|
||||
</style>␍
|
||||
<script>␍
|
||||
tailwind.config = {␍
|
||||
theme: {␍
|
||||
extend: {␍
|
||||
colors: {␍
|
||||
primary: {'50': '#eff6ff','100': '#dbeafe','200': '#bfdbfe','300': '#93c5fd','400': '#60a5fa','500': '#3b82f6','600': '#2563eb','700': '#1d4ed8','800': '#1e40af','900': '#1e3a8a'}␍
|
||||
}␍
|
||||
}␍
|
||||
}␍
|
||||
}␍
|
||||
</script>␍
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">␍
|
||||
</head>␍
|
||||
<body class="h-full">␍
|
||||
<div class="min-h-full">␍
|
||||
{% if user %}␍
|
||||
<!-- Sidebar -->␍
|
||||
<div class="fixed inset-y-0 left-0 w-64 bg-gray-900 text-white z-30">␍
|
||||
<div class="flex items-center h-16 px-6 border-b border-gray-700">␍
|
||||
<i class="fas fa-file-medical text-blue-400 text-xl mr-3"></i>␍
|
||||
<span class="font-bold text-lg">RIPS Manager</span>␍
|
||||
</div>␍
|
||||
<nav class="mt-4 px-3 space-y-1">␍
|
||||
<a href="/dashboard" class="flex items-center px-3 py-2.5 rounded-lg text-sm font-medium {% if request.url.path == '/dashboard' %}bg-blue-600 text-white{% else %}text-gray-300 hover:bg-gray-700{% endif %}">␍
|
||||
<i class="fas fa-chart-pie w-5 mr-2"></i> Dashboard␍
|
||||
</a>␍
|
||||
<a href="/config" class="flex items-center px-3 py-2.5 rounded-lg text-sm font-medium {% if request.url.path == '/config' %}bg-blue-600 text-white{% else %}text-gray-300 hover:bg-gray-700{% endif %}">␍
|
||||
<i class="fas fa-cog w-5 mr-2"></i> Configuración␍
|
||||
</a>␍
|
||||
<a href="/queries" class="flex items-center px-3 py-2.5 rounded-lg text-sm font-medium {% if request.url.path == '/queries' %}bg-blue-600 text-white{% else %}text-gray-300 hover:bg-gray-700{% endif %}">␍
|
||||
<i class="fas fa-database w-5 mr-2"></i> Consultas SQL␍
|
||||
</a>␍
|
||||
<a href="/contratos" class="flex items-center px-3 py-2.5 rounded-lg text-sm font-medium {% if request.url.path == '/contratos' %}bg-blue-600 text-white{% else %}text-gray-300 hover:bg-gray-700{% endif %}">␍
|
||||
<i class="fas fa-file-contract w-5 mr-2"></i> Contratos␍
|
||||
</a>␍
|
||||
<hr class="my-3 border-gray-700">␍
|
||||
<p class="px-3 text-xs font-semibold text-gray-400 uppercase tracking-wider">Envíos</p>␍
|
||||
<a href="/terceros" class="flex items-center px-3 py-2.5 rounded-lg text-sm font-medium {% if request.url.path == '/terceros' %}bg-blue-600 text-white{% else %}text-gray-300 hover:bg-gray-700{% endif %}">␍
|
||||
<i class="fas fa-user w-5 mr-2"></i> Terceros␍
|
||||
</a>␍
|
||||
<a href="/transaccion" class="flex items-center px-3 py-2.5 rounded-lg text-sm font-medium {% if request.url.path == '/transaccion' %}bg-blue-600 text-white{% else %}text-gray-300 hover:bg-gray-700{% endif %}">␍
|
||||
<i class="fas fa-exchange-alt w-5 mr-2"></i> Transacción RIPS␍
|
||||
</a>␍
|
||||
<a href="/ventas" class="flex items-center px-3 py-2.5 rounded-lg text-sm font-medium {% if request.url.path == '/ventas' %}bg-blue-600 text-white{% else %}text-gray-300 hover:bg-gray-700{% endif %}">
|
||||
<i class="fas fa-file-invoice-dollar w-5 mr-2"></i> Facturas Venta
|
||||
<!DOCTYPE html>
|
||||
<html lang="es" class="h-full bg-gray-50">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>RIPS Manager - {% block title %}Dashboard{% endblock %}</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/codemirror.min.css">
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/codemirror.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/sql/sql.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/addon/hint/show-hint.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/addon/hint/sql-hint.min.js"></script>
|
||||
<style>
|
||||
.CodeMirror { border: 1px solid #d1d5db; border-radius: 0.5rem; font-size: 13px; height: auto; min-height: 200px; }
|
||||
.CodeMirror-hints { font-size: 12px; }
|
||||
</style>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: {'50': '#eff6ff','100': '#dbeafe','200': '#bfdbfe','300': '#93c5fd','400': '#60a5fa','500': '#3b82f6','600': '#2563eb','700': '#1d4ed8','800': '#1e40af','900': '#1e3a8a'}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
||||
</head>
|
||||
<body class="h-full">
|
||||
{% set embedded = request.query_params.get('embed') == '1' %}
|
||||
{% set cur = request.url.path %}
|
||||
<div class="min-h-full">
|
||||
{% if user %}
|
||||
{% if not embedded %}
|
||||
<!-- Sidebar -->
|
||||
<div class="fixed inset-y-0 left-0 w-64 bg-gray-900 text-white z-30">
|
||||
<div class="flex items-center h-16 px-6 border-b border-gray-700">
|
||||
<i class="fas fa-file-medical text-blue-400 text-xl mr-3"></i>
|
||||
<span class="font-bold text-lg">RIPS Manager</span>
|
||||
</div>
|
||||
<nav class="mt-4 px-3 space-y-1 overflow-y-auto" style="max-height: calc(100vh - 130px)">
|
||||
<a href="/dashboard" class="flex items-center px-3 py-2.5 rounded-lg text-sm font-medium {% if cur == '/dashboard' %}bg-blue-600 text-white{% else %}text-gray-300 hover:bg-gray-700{% endif %}">
|
||||
<i class="fas fa-chart-pie w-5 mr-2"></i> Dashboard
|
||||
</a>
|
||||
<a href="/automation" class="flex items-center px-3 py-2.5 rounded-lg text-sm font-medium {% if request.url.path == '/automation' %}bg-blue-600 text-white{% else %}text-gray-300 hover:bg-gray-700{% endif %}">␍
|
||||
<i class="fas fa-robot w-5 mr-2"></i> Automatización␍
|
||||
</a>
|
||||
<a href="/pacientes" class="flex items-center px-3 py-2.5 rounded-lg text-sm font-medium {% if request.url.path == '/pacientes' %}bg-blue-600 text-white{% else %}text-gray-300 hover:bg-gray-700{% endif %}">
|
||||
<i class="fas fa-users w-5 mr-2"></i> Pacientes <span class="ml-auto text-xs bg-green-500 text-white px-1.5 rounded-full">WA</span>
|
||||
<a href="/config" class="flex items-center px-3 py-2.5 rounded-lg text-sm font-medium {% if cur == '/config' %}bg-blue-600 text-white{% else %}text-gray-300 hover:bg-gray-700{% endif %}">
|
||||
<i class="fas fa-cog w-5 mr-2"></i> Configuración
|
||||
</a>
|
||||
<a href="/test-rda" class="flex items-center px-3 py-2.5 rounded-lg text-sm font-medium {% if request.url.path == '/test-rda' %}bg-blue-600 text-white{% else %}text-gray-300 hover:bg-gray-700{% endif %}">
|
||||
<i class="fas fa-flask w-5 mr-2"></i> Prueba RDA
|
||||
</a>␍
|
||||
<hr class="my-3 border-gray-700">␍
|
||||
<a href="/logs" class="flex items-center px-3 py-2.5 rounded-lg text-sm font-medium {% if request.url.path == '/logs' %}bg-blue-600 text-white{% else %}text-gray-300 hover:bg-gray-700{% endif %}">␍
|
||||
<i class="fas fa-history w-5 mr-2"></i> Historial␍
|
||||
</a>␍
|
||||
<a href="/logs/actividad" class="flex items-center px-3 py-2.5 rounded-lg text-sm font-medium {% if request.url.path == '/logs/actividad' %}bg-blue-600 text-white{% else %}text-gray-300 hover:bg-gray-700{% endif %}">␍
|
||||
<i class="fas fa-user-clock w-5 mr-2"></i> Actividad␍
|
||||
</a>␍
|
||||
<a href="/auth/logout" class="flex items-center px-3 py-2.5 rounded-lg text-sm font-medium text-gray-300 hover:bg-gray-700">␍
|
||||
<i class="fas fa-sign-out-alt w-5 mr-2"></i> Salir␍
|
||||
</a>␍
|
||||
</nav>␍
|
||||
<div class="absolute bottom-0 left-0 right-0 px-4 py-3 border-t border-gray-700">␍
|
||||
<div class="flex items-center">␍
|
||||
<div class="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center text-sm font-bold">␍
|
||||
{{ user.username[0]|upper }}␍
|
||||
</div>␍
|
||||
<div class="ml-3">␍
|
||||
<p class="text-sm font-medium text-white">{{ user.username }}</p>␍
|
||||
<p class="text-xs text-gray-400">Sesión activa</p>␍
|
||||
</div>␍
|
||||
</div>␍
|
||||
</div>␍
|
||||
</div>␍
|
||||
␍
|
||||
<!-- Main content -->␍
|
||||
<div class="pl-64">␍
|
||||
<header class="bg-white shadow-sm border-b border-gray-200">␍
|
||||
<div class="flex items-center justify-between h-16 px-8">␍
|
||||
<h1 class="text-xl font-semibold text-gray-800">{% block header %}Dashboard{% endblock %}</h1>␍
|
||||
<div class="flex items-center space-x-4">␍
|
||||
<span class="text-sm text-gray-500">␍
|
||||
<i class="far fa-calendar-alt mr-1"></i>␍
|
||||
<script>document.write(new Date().toLocaleDateString('es-CO', {year:'numeric',month:'long',day:'numeric'}))</script>␍
|
||||
</span>␍
|
||||
</div>␍
|
||||
</div>␍
|
||||
</header>␍
|
||||
<main class="p-8">␍
|
||||
{% block content %}{% endblock %}␍
|
||||
</main>␍
|
||||
</div>␍
|
||||
{% else %}␍
|
||||
<main>␍
|
||||
{% block auth_content %}{% endblock %}␍
|
||||
</main>␍
|
||||
{% endif %}␍
|
||||
</div>␍
|
||||
␍
|
||||
<script>␍
|
||||
console.log('%c RIPS Manager v1.0 ', 'background:#1e3a8a;color:white;font-size:18px;font-weight:bold;padding:8px 12px;border-radius:4px;');␍
|
||||
console.log('%c Desarrollado por U-SITE SAS BIC', 'font-size:14px;');␍
|
||||
console.log('%c https://u-site.app/', 'color:#2563eb;font-size:12px;');␍
|
||||
console.log('%c Sistema de generacion y envio de RIPS (Res. 2275/2023)', 'font-style:italic;font-size:12px;');␍
|
||||
␍
|
||||
async function fetchJSON(url, options = {}) {␍
|
||||
const resp = await fetch(url, options);␍
|
||||
return await resp.json();␍
|
||||
}␍
|
||||
␍
|
||||
function showToast(message, type = 'success') {␍
|
||||
const colors = {success: 'bg-green-500', error: 'bg-red-500', info: 'bg-blue-500', warning: 'bg-yellow-500'};␍
|
||||
const toast = document.createElement('div');␍
|
||||
toast.className = `fixed top-4 right-4 z-50 ${colors[type]} text-white px-6 py-3 rounded-lg shadow-lg transition-all duration-500`;␍
|
||||
toast.textContent = message;␍
|
||||
document.body.appendChild(toast);␍
|
||||
setTimeout(() => { toast.style.opacity = '0'; setTimeout(() => toast.remove(), 500); }, 4000);␍
|
||||
}␍
|
||||
␍
|
||||
function showLoading(btn) {␍
|
||||
btn.disabled = true;␍
|
||||
btn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Procesando...';␍
|
||||
}␍
|
||||
␍
|
||||
function hideLoading(btn, text) {␍
|
||||
btn.disabled = false;␍
|
||||
btn.innerHTML = text;␍
|
||||
}␍
|
||||
</script>␍
|
||||
</body>␍
|
||||
</html>␍
|
||||
<a href="/queries" class="flex items-center px-3 py-2.5 rounded-lg text-sm font-medium {% if cur == '/queries' %}bg-blue-600 text-white{% else %}text-gray-300 hover:bg-gray-700{% endif %}">
|
||||
<i class="fas fa-database w-5 mr-2"></i> Consultas SQL
|
||||
</a>
|
||||
<a href="/contratos" class="flex items-center px-3 py-2.5 rounded-lg text-sm font-medium {% if cur == '/contratos' %}bg-blue-600 text-white{% else %}text-gray-300 hover:bg-gray-700{% endif %}">
|
||||
<i class="fas fa-file-contract w-5 mr-2"></i> Contratos
|
||||
</a>
|
||||
<hr class="my-3 border-gray-700">
|
||||
<p class="px-3 text-xs font-semibold text-gray-400 uppercase tracking-wider mb-1">Módulos de Envío</p>
|
||||
|
||||
<!-- Módulo TNS -->
|
||||
<a href="/envios/tns" class="flex items-center px-3 py-2.5 rounded-lg text-sm font-medium {% if cur == '/envios/tns' %}bg-blue-600 text-white{% else %}text-gray-300 hover:bg-gray-700{% endif %}">
|
||||
<i class="fas fa-paper-plane w-5 mr-2"></i>
|
||||
<span class="flex-1">TNS</span>
|
||||
<span class="text-xs px-1.5 py-0.5 rounded {% if cur == '/envios/tns' %}bg-blue-500 text-blue-100{% else %}bg-gray-700 text-gray-400{% endif %}">5</span>
|
||||
</a>
|
||||
{% if cur == '/envios/tns' %}
|
||||
<div class="ml-4 border-l border-gray-700 pl-3">
|
||||
<p class="text-xs text-gray-500 py-0.5">Terceros · Transacción · Ventas</p>
|
||||
<p class="text-xs text-gray-500 py-0.5">Prueba RDA · Automatización</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Módulo ERP Lab -->
|
||||
<a href="/envios/erp" class="flex items-center px-3 py-2.5 rounded-lg text-sm font-medium {% if cur == '/envios/erp' %}bg-green-700 text-white{% else %}text-gray-300 hover:bg-gray-700{% endif %}">
|
||||
<i class="fas fa-flask w-5 mr-2"></i>
|
||||
<span class="flex-1">ERP Lab</span>
|
||||
<span class="text-xs px-1.5 py-0.5 rounded {% if cur == '/envios/erp' %}bg-green-500 text-green-100{% else %}bg-gray-700 text-gray-400{% endif %}">WA</span>
|
||||
</a>
|
||||
{% if cur == '/envios/erp' %}
|
||||
<div class="ml-4 border-l border-gray-700 pl-3">
|
||||
<p class="text-xs text-gray-500 py-0.5">Pacientes · Sync Automático</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<hr class="my-3 border-gray-700">
|
||||
<a href="/logs" class="flex items-center px-3 py-2.5 rounded-lg text-sm font-medium {% if cur == '/logs' %}bg-blue-600 text-white{% else %}text-gray-300 hover:bg-gray-700{% endif %}">
|
||||
<i class="fas fa-history w-5 mr-2"></i> Historial TNS
|
||||
</a>
|
||||
<a href="/logs/actividad" class="flex items-center px-3 py-2.5 rounded-lg text-sm font-medium {% if cur == '/logs/actividad' %}bg-blue-600 text-white{% else %}text-gray-300 hover:bg-gray-700{% endif %}">
|
||||
<i class="fas fa-user-clock w-5 mr-2"></i> Actividad
|
||||
</a>
|
||||
<a href="/auth/logout" class="flex items-center px-3 py-2.5 rounded-lg text-sm font-medium text-gray-300 hover:bg-gray-700">
|
||||
<i class="fas fa-sign-out-alt w-5 mr-2"></i> Salir
|
||||
</a>
|
||||
</nav>
|
||||
<div class="absolute bottom-0 left-0 right-0 px-4 py-3 border-t border-gray-700">
|
||||
<div class="flex items-center">
|
||||
<div class="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center text-sm font-bold">
|
||||
{{ user.username[0]|upper }}
|
||||
</div>
|
||||
<div class="ml-3">
|
||||
<p class="text-sm font-medium text-white">{{ user.username }}</p>
|
||||
<p class="text-xs text-gray-400">Sesión activa</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Main content -->
|
||||
<div class="{% if not embedded %}pl-64{% endif %}">
|
||||
{% if not embedded %}
|
||||
<header class="bg-white shadow-sm border-b border-gray-200">
|
||||
<div class="flex items-center justify-between h-16 px-8">
|
||||
<h1 class="text-xl font-semibold text-gray-800">{% block header %}Dashboard{% endblock %}</h1>
|
||||
<div class="flex items-center space-x-4">
|
||||
<span class="text-sm text-gray-500">
|
||||
<i class="far fa-calendar-alt mr-1"></i>
|
||||
<script>document.write(new Date().toLocaleDateString('es-CO', {year:'numeric',month:'long',day:'numeric'}))</script>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
{% endif %}
|
||||
<main class="{% if not embedded %}p-8{% else %}p-4{% endif %}">
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
</div>
|
||||
{% else %}
|
||||
<main>
|
||||
{% block auth_content %}{% endblock %}
|
||||
</main>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<script>
|
||||
console.log('%c RIPS Manager v1.0 ', 'background:#1e3a8a;color:white;font-size:18px;font-weight:bold;padding:8px 12px;border-radius:4px;');
|
||||
console.log('%c Desarrollado por U-SITE SAS BIC', 'font-size:14px;');
|
||||
console.log('%c https://u-site.app/', 'color:#2563eb;font-size:12px;');
|
||||
console.log('%c Sistema de generacion y envio de RIPS (Res. 2275/2023)', 'font-style:italic;font-size:12px;');
|
||||
|
||||
async function fetchJSON(url, options = {}) {
|
||||
const resp = await fetch(url, options);
|
||||
return await resp.json();
|
||||
}
|
||||
|
||||
function showToast(message, type = 'success') {
|
||||
const colors = {success: 'bg-green-500', error: 'bg-red-500', info: 'bg-blue-500', warning: 'bg-yellow-500'};
|
||||
const toast = document.createElement('div');
|
||||
toast.className = `fixed top-4 right-4 z-50 ${colors[type]} text-white px-6 py-3 rounded-lg shadow-lg transition-all duration-500`;
|
||||
toast.textContent = message;
|
||||
document.body.appendChild(toast);
|
||||
setTimeout(() => { toast.style.opacity = '0'; setTimeout(() => toast.remove(), 500); }, 4000);
|
||||
}
|
||||
|
||||
function showLoading(btn) {
|
||||
btn.disabled = true;
|
||||
btn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Procesando...';
|
||||
}
|
||||
|
||||
function hideLoading(btn, text) {
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = text;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user