feat: enrich sync log with exams, diagnosis, EPS and valor per patient

- scheduler.py: after sync_todos(), inject diagnostico, nit_empresa,
  valor_total and examenes_det (cups/nombre/precio) into each detalle entry
- whatsapp_sync.py: guardar_sync_log stores full enriched fields in detalle_json
- envios_erp.html: expanded row shows per-patient card with Dx, EPS, valor
  and a CUPS/examen/precio table — scrollable, max-h-96

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-07-17 09:52:08 -05:00
co-authored by Claude Sonnet 4.6
parent e044f21e3e
commit cd63683869
3 changed files with 79 additions and 19 deletions
+53 -16
View File
@@ -254,6 +254,55 @@ async function cargarHistorialScheduler() {
const errDet = r.errores_det ? JSON.parse(r.errores_det) : [];
const pacientes = r.detalle_json ? JSON.parse(r.detalle_json) : [];
const rowId = 'hist-det-' + i;
const detHtml = pacientes.map((p, pi) => {
const badge = p.action === 'created' ? '<span class="bg-blue-100 text-blue-700 px-1.5 py-0.5 rounded">Nuevo</span>'
: p.action === 'updated' ? '<span class="bg-green-100 text-green-700 px-1.5 py-0.5 rounded">Actualizado</span>'
: p.action === 'skipped' ? '<span class="bg-gray-100 text-gray-400 px-1.5 py-0.5 rounded">Omitido</span>'
: `<span class="bg-red-100 text-red-600 px-1.5 py-0.5 rounded">${p.action}</span>`;
const diag = p.diagnostico_cod
? `<span class="text-orange-600">${p.diagnostico_cod}</span>${p.diagnostico_nombre ? ' · ' + p.diagnostico_nombre : ''}`
: '<span class="text-gray-300">Sin diagnóstico</span>';
const empresa = p.nit_empresa
? `<span class="text-teal-600">${p.nit_empresa}</span>`
: '<span class="text-gray-300">Sin empresa</span>';
const valor = p.valor_total > 0
? `<span class="text-yellow-700">$${Number(p.valor_total).toLocaleString('es-CO')}</span>`
: '';
const exams = (p.examenes_det || []).map(e =>
`<tr class="border-b border-gray-50">
<td class="py-0.5 pr-3 font-mono text-purple-600">${e.cups || '—'}</td>
<td class="py-0.5 pr-3 text-gray-600">${e.nombre || '—'}</td>
<td class="py-0.5 text-right text-gray-500">${e.precio != null ? '$' + Number(e.precio).toLocaleString('es-CO') : '—'}</td>
</tr>`
).join('');
return `<div class="mb-3 border border-gray-100 rounded-lg overflow-hidden">
<div class="flex items-center gap-3 px-3 py-2 bg-gray-50 border-b border-gray-100">
<span class="text-gray-400 font-mono text-xs">${p.doc}</span>
<span class="font-medium text-gray-700 flex-1">${p.nombre}</span>
${badge}
</div>
<div class="px-3 py-1.5 flex flex-wrap gap-x-4 gap-y-0.5 text-xs border-b border-gray-50">
<span>Dx: ${diag}</span>
<span>EPS: ${empresa}</span>
${valor ? `<span>Total: ${valor}</span>` : ''}
</div>
${exams ? `<table class="w-full text-xs px-3">
<thead><tr class="text-gray-400 border-b border-gray-100">
<th class="py-1 pr-3 text-left font-medium px-3">CUPS</th>
<th class="py-1 pr-3 text-left font-medium">Examen</th>
<th class="py-1 text-right font-medium pr-3">Precio</th>
</tr></thead>
<tbody class="px-3">${exams}</tbody>
</table>` : '<p class="text-xs text-gray-300 px-3 py-1">Sin exámenes registrados</p>'}
</div>`;
}).join('');
return `
<tr class="hover:bg-gray-50">
<td class="py-2 pr-4 text-gray-500 whitespace-nowrap font-mono text-xs">${fecha}</td>
@@ -273,22 +322,10 @@ async function cargarHistorialScheduler() {
</td>
</tr>
${pacientes.length ? `
<tr id="${rowId}" class="hidden bg-gray-50">
<td colspan="7" class="px-4 pb-3 pt-1">
<div class="text-xs text-gray-500 space-y-0.5 max-h-48 overflow-y-auto">
${pacientes.map(p => {
const badge = p.action === 'created' ? '<span class="text-blue-600">Nuevo</span>'
: p.action === 'updated' ? '<span class="text-green-600">Actualizado</span>'
: p.action === 'skipped' ? '<span class="text-gray-400">Omitido</span>'
: `<span class="text-red-500">${p.action}</span>`;
const exBadge = p.examenes > 0
? `<span class="text-purple-500">${p.examenes} exám.</span>` : '';
return `<div class="flex items-center gap-3 py-0.5 border-b border-gray-100">
<span class="text-gray-400 w-28 shrink-0">${p.doc}</span>
<span class="flex-1 truncate">${p.nombre}</span>
${badge} ${exBadge}
</div>`;
}).join('')}
<tr id="${rowId}" class="hidden">
<td colspan="7" class="px-3 pb-4 pt-2">
<div class="max-h-96 overflow-y-auto space-y-2 text-xs">
${detHtml}
</div>
</td>
</tr>` : ''}`;