feat: sistema de pagos domicilios — cobro enfermero y estado pago admin

- database/07_add_pago_domicilio.sql: 6 columnas nuevas en lab_domicilios
  (pago_estado ENUM, pago_modo, pago_monto, pago_fecha, pago_notas, pago_registrado_por)
- Domicilio::filtrarCampos(): permite guardar campos de pago vía actualizar()
- Enfermera::agenda(): incluye valor_domicilio, valor_copago, pago_estado, pago_modo, pago_monto, pago_notas
- api/lab/registrar_pago.php: endpoint POST para registrar/actualizar pago del domicilio
- enfermero_portal.php: bloque cobro en card, modal registrar pago (efectivo/transferencia/exento), objeto pagoModal JS
- lab_domicilios.php: badge pago //🔵 en fila tabla, sección pago detallada en panel lateral
This commit is contained in:
Lizandro Guarnizo
2026-03-12 22:53:24 -05:00
parent c42e0976d7
commit beb1bbe1d4
6 changed files with 353 additions and 11 deletions
+42 -11
View File
@@ -251,7 +251,16 @@ async function cargarLista(pag = 1) {
<small class="text-muted">${esc(dom.barrio||'')}</small>
</td>
<td>${dom.enfermera_nombre ? `<small>${esc(dom.enfermera_nombre)}</small>` : '<span class="text-danger small"><i class="fas fa-exclamation-triangle me-1"></i>Sin asignar</span>'}</td>
<td><span class="badge bg-${COLOR_DOM[dom.estado]||'secondary'} estado-badge">${esc(dom.estado)}</span></td>
<td>
<span class="badge bg-${COLOR_DOM[dom.estado]||'secondary'} estado-badge">${esc(dom.estado)}</span>
${(dom.pago_estado === 'pagado')
? '<span class="badge rounded-pill ms-1" style="background:#d1fae5;color:#065f46;border:1px solid #34d399">✅ Pagado</span>'
: (dom.pago_estado === 'exento'
? '<span class="badge rounded-pill ms-1" style="background:#e0e7ff;color:#3730a3;border:1px solid #818cf8">🔵 Exento</span>'
: ((parseFloat(dom.valor_domicilio)||0)+(parseFloat(dom.valor_copago)||0) > 0
? '<span class="badge rounded-pill ms-1" style="background:#fff3cd;color:#664d03;border:1px solid #ffc107">⏳ Cobro</span>'
: ''))}
</td>
</tr>
`).join('');
@@ -371,17 +380,39 @@ async function verDomicilio(id) {
<div class="bg-light p-2 rounded small">${esc(dom.examenes_solicitados||'—')}</div>
</div>
</div>
${(dom.valor_domicilio || dom.valor_copago) ? `
<div class="row mt-3">
<div class="col-12">
<div class="d-flex gap-3 flex-wrap p-2 rounded" style="background:#d1fae5;border:1px solid #6ee7b7">
<span class="small fw-semibold text-success"><i class="fas fa-cash-register me-1"></i>Cobro al cliente:</span>
${dom.valor_domicilio ? `<span class="small">Domicilio: <strong>$${Number(dom.valor_domicilio).toLocaleString('es-CO')}</strong></span>` : ''}
${dom.valor_copago ? `<span class="small">Copago: <strong>$${Number(dom.valor_copago).toLocaleString('es-CO')}</strong></span>` : ''}
${ (dom.valor_domicilio && dom.valor_copago) ? `<span class="small fw-bold text-success">Total: $${(Number(dom.valor_domicilio)+Number(dom.valor_copago)).toLocaleString('es-CO')}</span>` : ''}
${(dom.valor_domicilio || dom.valor_copago) ? (() => {
const totalC = (parseFloat(dom.valor_domicilio)||0)+(parseFloat(dom.valor_copago)||0);
const PAGO_INFO = {
pendiente: { bg:'#fff3cd', color:'#664d03', border:'#ffc107', icon:'⏳', txt:'Pago pendiente' },
pagado: { bg:'#d1fae5', color:'#065f46', border:'#34d399', icon:'✅', txt:'Pagado' },
exento: { bg:'#e0e7ff', color:'#3730a3', border:'#818cf8', icon:'🔵', txt:'Exento' },
};
const pEst = dom.pago_estado || 'pendiente';
const pInfo = PAGO_INFO[pEst] || PAGO_INFO.pendiente;
const MODO_LABEL = { efectivo:'💵 Efectivo', transferencia:'📲 Transferencia', otro:'📋 Otro' };
return `
<div class="row mt-3">
<div class="col-12">
<div class="p-2 rounded" style="background:#d1fae5;border:1px solid #6ee7b7">
<div class="d-flex justify-content-between align-items-center mb-1">
<span class="small fw-semibold text-success"><i class="fas fa-cash-register me-1"></i>Cobro al cliente</span>
<span class="badge rounded-pill small" style="background:${pInfo.bg};color:${pInfo.color};border:1px solid ${pInfo.border}">${pInfo.icon} ${pInfo.txt}</span>
</div>
<div class="d-flex gap-3 flex-wrap">
${dom.valor_domicilio ? `<span class="small">Domicilio: <strong>$${Number(dom.valor_domicilio).toLocaleString('es-CO')}</strong></span>` : ''}
${dom.valor_copago ? `<span class="small">Copago: <strong>$${Number(dom.valor_copago).toLocaleString('es-CO')}</strong></span>` : ''}
${totalC > 0 ? `<span class="small fw-bold text-success">Total: $${totalC.toLocaleString('es-CO')}</span>` : ''}
</div>
${dom.pago_estado === 'pagado' ? `
<div class="small mt-1 text-success">
${MODO_LABEL[dom.pago_modo] || (dom.pago_modo||'')}
${dom.pago_monto ? ` · $${Number(dom.pago_monto).toLocaleString('es-CO')} cobrado` : ''}
${dom.pago_notas ? ` · <em>${esc(dom.pago_notas)}</em>` : ''}
</div>` : ''}
</div>
</div>
</div>
</div>` : ''}
</div>`;
})() : ''}
${dom.notas_admin ? `
<div class="row mt-2">
<div class="col-12">