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:
co-authored by
Claude Sonnet 4.6
parent
e044f21e3e
commit
cd63683869
@@ -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>` : ''}`;
|
||||
|
||||
Reference in New Issue
Block a user