feat: cierre anticipado de tomas prolongadas con justificación

- DB: añade estado 'cerrado_anticipado' al enum de turnero_consentimientos
- ver_formulario_enviado.php: POST handler mp_cerrar_anticipado guarda motivo
  en _cierre_anticipado y cambia estado; botón "Cerrar anticipadamente" con modal
  textarea; bloque display para estado cerrado_anticipado mostrando el motivo;
  modoEditar y check de estado actualizados para excluir cerrado_anticipado
- get_consentimientos.php: expone cierre_anticipado en respuesta; mueve parse
  de datos_respuestas fuera del if(esTomaProg) para ambos loops
- lugar.php: CONSENT_IC/LBL incluye cerrado_anticipado; ya[] lo incluye;
  hayPendientes lo excluye; fila muestra motivo en banner amarillo
- recepcion.php: CONSENT_META incluye cerrado_anticipado; ya[] lo incluye;
  motivo visible en la tarjeta del consentimiento

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-07-28 00:29:32 -05:00
co-authored by Claude Sonnet 4.6
parent 915fa3ba5c
commit c9ea76f782
4 changed files with 139 additions and 22 deletions
+12 -6
View File
@@ -1960,11 +1960,12 @@ async function guardarSolicitud() {
// ── Labels / iconos para estados ─────────────────────────────
const CONSENT_META = {
firmado : { cls:'firmado', ico:'fa-check-circle', lbl:'Firmado' },
enviado : { cls:'enviado', ico:'fa-envelope', lbl:'Enviado' },
visto : { cls:'visto', ico:'fa-eye', lbl:'Visto' },
rechazado : { cls:'rechazado', ico:'fa-ban', lbl:'Rechazado' },
pendiente : { cls:'pendiente', ico:'fa-clock', lbl:'Pendiente' },
firmado : { cls:'firmado', ico:'fa-check-circle', lbl:'Firmado' },
enviado : { cls:'enviado', ico:'fa-envelope', lbl:'Enviado' },
visto : { cls:'visto', ico:'fa-eye', lbl:'Visto' },
rechazado : { cls:'rechazado', ico:'fa-ban', lbl:'Rechazado' },
pendiente : { cls:'pendiente', ico:'fa-clock', lbl:'Pendiente' },
cerrado_anticipado : { cls:'rechazado', ico:'fa-exclamation-triangle', lbl:'Cerrado anticipadamente' },
};
function renderConsentimientos(lista) {
@@ -1977,7 +1978,7 @@ function renderConsentimientos(lista) {
}
el.innerHTML = lista.map(c => {
const m = CONSENT_META[c.estado] || CONSENT_META.pendiente;
const ya = ['firmado','rechazado'].includes(c.estado);
const ya = ['firmado','rechazado','cerrado_anticipado'].includes(c.estado);
const token = escHtml(c.token || '');
const nom = escHtml(c.formulario_nombre || 'Consentimiento');
const fId = c.formulario_id;
@@ -2037,6 +2038,10 @@ function renderConsentimientos(lista) {
}
}
const motivoRec = (c.estado === 'cerrado_anticipado' && c.cierre_anticipado?.motivo)
? `<div style="font-size:.75rem;color:#92400e;background:#fef3c7;border-radius:4px;padding:3px 8px;margin-top:3px;width:100%">
<i class="fas fa-comment-alt me-1"></i>${escHtml(c.cierre_anticipado.motivo)}
</div>` : '';
return `<div class="consent-item ${m.cls}" style="flex-wrap:wrap">
<div style="display:flex;align-items:center;gap:.5rem;width:100%">
<i class="fas ${m.ico}"></i>
@@ -2045,6 +2050,7 @@ function renderConsentimientos(lista) {
<div class="consent-acciones">${btnFirmar}${btnWa}</div>
</div>
${profRow}
${motivoRec}
</div>`;
}).join('');
}