feat: olvidar firma, editar tiempos tomas, obs en header, fix dispositivos
- feat(turnero): Botón "Olvidar" en lugar.php y recepcion.php para descartar firma de consentimiento completo (nuevo endpoint resetear_consentimiento.php) - feat(turnero): Botón "Olvidar" por toma individual en prolongadas para borrar firma+hora de una toma específica (nuevo endpoint resetear_toma.php) - feat(turnero): Editar tiempos en tomas en_progreso: hora_campo signed muestra readonly con botón olvidar, permite re-editar tras olvidar - feat(turnero): Guardar tiempos (draft save) también en estado en_progreso - feat(turnero): Observaciones de tomas prolongadas se muestran en header de tarjeta firmada (campo obs_campo en _mpMap) - fix(turnero): Token del equipo se sobreescribía en tabla — ip permitía solo un registro con ip='' (UNIQUE); ahora ip es nullable Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
8e9d7750a7
commit
ff52fa5ba7
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* POST /modules/turnero/api/resetear_consentimiento.php
|
||||
* Descarta firma y datos de un consentimiento → estado 'enviado' para re-firma.
|
||||
* Body JSON: { token: string }
|
||||
*/
|
||||
require_once __DIR__ . '/_helpers.php';
|
||||
requireMethod('POST');
|
||||
requireTurnero();
|
||||
|
||||
$body = inputJson();
|
||||
$token = trim($body['token'] ?? '');
|
||||
if (!$token) jsonError('token requerido.');
|
||||
|
||||
$pdo = db();
|
||||
$stmt = $pdo->prepare(
|
||||
"SELECT tc.id, t.sesion_id
|
||||
FROM turnero_consentimientos tc
|
||||
JOIN turnero_turnos t ON t.id = tc.turno_id
|
||||
WHERE tc.token = ? LIMIT 1"
|
||||
);
|
||||
$stmt->execute([$token]);
|
||||
$tc = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if (!$tc) jsonError('Consentimiento no encontrado.', 404);
|
||||
|
||||
$pdo->prepare(
|
||||
"UPDATE turnero_consentimientos
|
||||
SET estado = 'enviado',
|
||||
firma_svg = NULL,
|
||||
firmado_at = NULL,
|
||||
firma_profesional_svg = NULL,
|
||||
firmado_profesional_at = NULL,
|
||||
datos_respuestas = NULL,
|
||||
siguiente_toma_at = NULL,
|
||||
toma_inicio_at = NULL
|
||||
WHERE token = ?"
|
||||
)->execute([$token]);
|
||||
|
||||
notificarSSE((int)$tc['sesion_id']);
|
||||
jsonOk([], 'Consentimiento reiniciado correctamente.');
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* POST /modules/turnero/api/resetear_toma.php
|
||||
* Borra campos específicos de datos_respuestas (firma + hora de una toma).
|
||||
* Body JSON: { token: string, campos: string[] }
|
||||
*/
|
||||
require_once __DIR__ . '/_helpers.php';
|
||||
requireMethod('POST');
|
||||
requireTurnero();
|
||||
|
||||
$body = inputJson();
|
||||
$token = trim($body['token'] ?? '');
|
||||
$campos = $body['campos'] ?? [];
|
||||
|
||||
if (!$token) jsonError('token requerido.');
|
||||
if (!is_array($campos) || empty($campos)) jsonError('campos requerido.');
|
||||
|
||||
$pdo = db();
|
||||
$stmt = $pdo->prepare(
|
||||
"SELECT tc.id, tc.datos_respuestas, tc.estado, t.sesion_id
|
||||
FROM turnero_consentimientos tc
|
||||
JOIN turnero_turnos t ON t.id = tc.turno_id
|
||||
WHERE tc.token = ? LIMIT 1"
|
||||
);
|
||||
$stmt->execute([$token]);
|
||||
$tc = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if (!$tc) jsonError('Consentimiento no encontrado.', 404);
|
||||
if ($tc['estado'] !== 'en_progreso') jsonError('Solo se pueden olvidar tomas en estado en_progreso.');
|
||||
|
||||
$dr = json_decode($tc['datos_respuestas'] ?? '{}', true) ?? [];
|
||||
foreach ($campos as $campo) {
|
||||
unset($dr[$campo]);
|
||||
}
|
||||
$pdo->prepare(
|
||||
"UPDATE turnero_consentimientos SET datos_respuestas=? WHERE token=?"
|
||||
)->execute([json_encode($dr, JSON_UNESCAPED_UNICODE), $token]);
|
||||
|
||||
notificarSSE((int)$tc['sesion_id']);
|
||||
jsonOk([], 'Toma olvidada.');
|
||||
@@ -19,7 +19,7 @@ if ($delete) {
|
||||
jsonOk([], 'Dispositivo eliminado');
|
||||
}
|
||||
|
||||
$ip = trim($input['ip'] ?? '');
|
||||
$ip = trim($input['ip'] ?? '') ?: null;
|
||||
$nombre = trim($input['nombre'] ?? '');
|
||||
$lugarId = (int)($input['lugar_id'] ?? 0);
|
||||
$activo = (int)($input['activo'] ?? 1);
|
||||
@@ -27,7 +27,7 @@ $token = trim($input['token'] ?? '') ?: null;
|
||||
|
||||
if ($nombre === '') jsonError('El nombre es requerido');
|
||||
if ($lugarId <= 0) jsonError('Debes asignar un lugar');
|
||||
if ($ip === '' && $token === null) jsonError('Se requiere IP o token de dispositivo');
|
||||
if ($ip === null && $token === null) jsonError('Se requiere IP o token de dispositivo');
|
||||
|
||||
if ($id) {
|
||||
$stmt = db()->prepare(
|
||||
|
||||
@@ -1633,6 +1633,12 @@ function renderConsentimientos(lista) {
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>`;
|
||||
|
||||
const btnOlvidar = (ya && c.token && c.estado !== 'rechazado')
|
||||
? `<button class="btn btn-outline-warning" title="Olvidar firma — permite re-firmar"
|
||||
onclick="_olvidarConsentimiento('${token}', ${nomJs.replace(/"/g,'"')})">
|
||||
<i class="fas fa-undo"></i>
|
||||
</button>` : '';
|
||||
|
||||
const motivoRow = (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)}
|
||||
@@ -1644,13 +1650,27 @@ function renderConsentimientos(lista) {
|
||||
${progresoBadge}
|
||||
${countdownEl}
|
||||
<span class="c-badge">${label}</span>
|
||||
<div class="acciones-consent">${btnAccion}${btnVer}${btnQuitar}</div>
|
||||
<div class="acciones-consent">${btnAccion}${btnVer}${btnOlvidar}${btnQuitar}</div>
|
||||
</div>
|
||||
${motivoRow}
|
||||
</div>`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
// ── Olvidar (resetear) consentimiento ────────────────────────
|
||||
async function _olvidarConsentimiento(token, nombre) {
|
||||
if (!confirm(`¿Seguro que deseas descartar la firma de "${nombre}"?\nEl paciente podrá volver a firmarlo.`)) return;
|
||||
try {
|
||||
const r = await fetch(API + 'resetear_consentimiento.php', {
|
||||
method: 'POST', headers: {'Content-Type':'application/json'},
|
||||
body: JSON.stringify({ token })
|
||||
});
|
||||
const j = await r.json();
|
||||
if (!j.ok) { mostrarError(j.error || 'Error al resetear'); return; }
|
||||
cargarConsentimientos();
|
||||
} catch(e) { mostrarError(e.message); }
|
||||
}
|
||||
|
||||
// ── Quitar consentimiento ─────────────────────────────────────
|
||||
let _mqcConsentId = null;
|
||||
function _abrirModalQuitarConsent(consentId, formNombre) {
|
||||
|
||||
@@ -2016,6 +2016,12 @@ function renderConsentimientos(lista) {
|
||||
<i class="fab fa-whatsapp"></i> WhatsApp
|
||||
</button>`;
|
||||
|
||||
const btnOlvidar = (ya && c.token && c.estado !== 'rechazado')
|
||||
? `<button class="btn btn-outline-warning btn-sm" title="Olvidar firma — permite re-firmar"
|
||||
onclick="_olvidarConsentimientoRec('${token}', '${escHtml(c.formulario_nombre || '')}')">
|
||||
<i class="fas fa-undo"></i>
|
||||
</button>` : '';
|
||||
|
||||
// Fila de firma del profesional (solo si el formulario la requiere y el paciente ya firmó)
|
||||
let profRow = '';
|
||||
if (c.estado === 'firmado' && c.requiere_firma_profesional) {
|
||||
@@ -2047,7 +2053,7 @@ function renderConsentimientos(lista) {
|
||||
<i class="fas ${m.ico}"></i>
|
||||
<span class="c-nom">${nom}</span>
|
||||
<span class="c-badge">${m.lbl}</span>
|
||||
<div class="consent-acciones">${btnFirmar}${btnWa}</div>
|
||||
<div class="consent-acciones">${btnFirmar}${btnWa}${btnOlvidar}</div>
|
||||
</div>
|
||||
${profRow}
|
||||
${motivoRec}
|
||||
@@ -2206,6 +2212,20 @@ async function enviarConsentimientoUno(turnoId) {
|
||||
// ── Enviar consentimientos (legacy — usado por btn-enviar-consent) ──
|
||||
async function enviarConsentimientos() { return enviarConsentimientosTodos(); }
|
||||
|
||||
// ── Olvidar (resetear) consentimiento ────────────────────────
|
||||
async function _olvidarConsentimientoRec(token, nombre) {
|
||||
if (!confirm(`¿Seguro que deseas descartar la firma de "${nombre}"?\nEl paciente podrá volver a firmarlo.`)) return;
|
||||
try {
|
||||
const r = await fetch('modules/turnero/api/resetear_consentimiento.php', {
|
||||
method: 'POST', headers: {'Content-Type':'application/json'},
|
||||
body: JSON.stringify({ token })
|
||||
});
|
||||
const j = await r.json();
|
||||
if (!j.ok) { alert(j.error || 'Error al resetear'); return; }
|
||||
await cargarConsentimientos();
|
||||
} catch(e) { alert(e.message); }
|
||||
}
|
||||
|
||||
// ── Pasar a lugar ─────────────────────────────────────────────
|
||||
async function pasarALugar() {
|
||||
if (!turnoActivo || !solicitudActiva) return;
|
||||
|
||||
+155
-5
@@ -86,10 +86,14 @@ if ($modoTurnero) {
|
||||
echo json_encode(['ok' => true, 'mp_completado' => true]); exit;
|
||||
}
|
||||
if (!array_key_exists('firma_svg', $input) && isset($input['datos_respuestas']) && is_array($input['datos_respuestas'])) {
|
||||
$existing = json_decode($tcRow['datos_respuestas'] ?? '{}', true) ?: [];
|
||||
$db->getConnection()
|
||||
->prepare("UPDATE turnero_consentimientos SET datos_respuestas=? WHERE token=? AND estado='pendiente'")
|
||||
->execute([json_encode(array_merge($existing, $input['datos_respuestas']), JSON_UNESCAPED_UNICODE), $tokenTurnero]);
|
||||
$existing = json_decode($tcRow['datos_respuestas'] ?? '{}', true) ?: [];
|
||||
$allowSave = $tcRow['estado'] === 'pendiente'
|
||||
|| ($modoTurnero && $tcRow['estado'] === 'en_progreso');
|
||||
if ($allowSave) {
|
||||
$db->getConnection()
|
||||
->prepare("UPDATE turnero_consentimientos SET datos_respuestas=? WHERE token=?")
|
||||
->execute([json_encode(array_merge($existing, $input['datos_respuestas']), JSON_UNESCAPED_UNICODE), $tokenTurnero]);
|
||||
}
|
||||
echo json_encode(['ok' => true, 'draft' => true]); exit;
|
||||
}
|
||||
$firmaSvg = trim($input['firma_svg'] ?? '');
|
||||
@@ -389,6 +393,46 @@ if (!empty($_mpMap)) {
|
||||
}
|
||||
}
|
||||
|
||||
// Mapa firma_id → obs_campo_id (campo texto/textarea que acompaña cada firma)
|
||||
$_mpFirmaObs = [];
|
||||
if (!empty($esquema) && !empty($_mpMap)) {
|
||||
$_prevFirma = null; $_pendingObs = null;
|
||||
foreach ($esquema as $_oc) {
|
||||
$_ot = $_oc['tipo'] ?? '';
|
||||
if ($_ot === 'separador') {
|
||||
$_prevFirma = null; $_pendingObs = null;
|
||||
} elseif (($_ot === 'texto' || $_ot === 'textarea') && isset($_oc['id'])) {
|
||||
if ($_prevFirma !== null) {
|
||||
$_mpFirmaObs[$_prevFirma] = $_oc['id'];
|
||||
$_prevFirma = null;
|
||||
} else {
|
||||
$_pendingObs = $_oc['id'];
|
||||
}
|
||||
} elseif ($_ot === 'firma_profesional' && isset($_oc['id']) && isset($_mpMap[$_oc['id']])) {
|
||||
if ($_pendingObs !== null) { $_mpFirmaObs[$_oc['id']] = $_pendingObs; }
|
||||
$_prevFirma = $_oc['id']; $_pendingObs = null;
|
||||
} elseif (!in_array($_ot, ['hora'])) {
|
||||
$_prevFirma = null;
|
||||
}
|
||||
}
|
||||
foreach ($_mpFirmaObs as $_fid => $_obsId) {
|
||||
if (isset($_mpMap[$_fid])) $_mpMap[$_fid]['obs_campo'] = $_obsId;
|
||||
}
|
||||
}
|
||||
|
||||
// Horas de tomas ya firmadas → read-only en edición (no se pueden corregir si ya se firmó esa toma)
|
||||
$_signedHoraCampos = [];
|
||||
foreach ($_mpMap as $_fid => $_mpe) {
|
||||
if ((!empty($datosCliente[$_fid]) && strlen($datosCliente[$_fid]) > 10)
|
||||
|| (!empty($datosCliente[$_fid . '_svg']) && strlen($datosCliente[$_fid . '_svg']) > 10)) {
|
||||
if (!empty($_mpe['hora_campo'])) $_signedHoraCampos[$_mpe['hora_campo']] = true;
|
||||
}
|
||||
}
|
||||
$_hcToFirmaIds = [];
|
||||
foreach ($_mpMap as $_fid => $_mpe) {
|
||||
if (!empty($_mpe['hora_campo'])) $_hcToFirmaIds[$_mpe['hora_campo']][] = $_fid;
|
||||
}
|
||||
|
||||
// siguiente_toma_at para recuperar countdown si el modal fue cerrado y reabierto
|
||||
$_mpSiguienteTomAt = null;
|
||||
if ($modoTurnero && $embebido && !empty($_mpMap) && $_mpPrimeraPendiente !== null) {
|
||||
@@ -717,6 +761,7 @@ function _addExamWizardHtml(string $cid): string {
|
||||
.toma-card--locked .toma-card-num { background:#e2e8f0;color:#94a3b8; }
|
||||
.toma-card-lbl { font-weight:700;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap; }
|
||||
.toma-card-hora { font-size:.75rem;opacity:.75;white-space:nowrap; }
|
||||
.toma-card-obs { font-size:.72rem;opacity:.65;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:120px; }
|
||||
.toma-card-badge { font-size:.7rem;padding:2px 8px;border-radius:20px;white-space:nowrap;flex-shrink:0; }
|
||||
.toma-badge-done { background:#dcfce7;color:#166534; }
|
||||
.toma-badge-active { background:rgba(255,255,255,.2);color:#fff;border:1px solid rgba(255,255,255,.35); }
|
||||
@@ -1242,12 +1287,30 @@ function _addExamWizardHtml(string $cid): string {
|
||||
$inputFullClass = ($compact && $tipo === 'texto') ? ' campo-full' : '';
|
||||
$extraClase = htmlspecialchars($campo['clase'] ?? '', ENT_QUOTES);
|
||||
?>
|
||||
<?php if ($inputType === 'time' && isset($_signedHoraCampos[$cid])): ?>
|
||||
<div class="campo-edit<?= $inputFullClass ?><?= $extraClase ? ' '.$extraClase : '' ?>" data-campo-id="<?= esc2($cid) ?>">
|
||||
<label><?= $label ?></label>
|
||||
<div class="d-flex gap-1 align-items-center">
|
||||
<input type="time" class="form-control form-control-sm" readonly
|
||||
value="<?= esc2($todos[$cid] ?? '') ?>" style="background:#f1f5f9;color:#64748b;cursor:not-allowed">
|
||||
<?php if ($modoTurnero && isset($_hcToFirmaIds[$cid])): ?>
|
||||
<button type="button" class="btn btn-outline-warning btn-sm flex-shrink-0 btn-olvidar-toma"
|
||||
data-hc="<?= esc2($cid) ?>"
|
||||
data-fids="<?= esc2(json_encode($_hcToFirmaIds[$cid])) ?>"
|
||||
title="Olvidar firma — permite editar este tiempo">
|
||||
<i class="fas fa-undo"></i>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="campo-edit<?= $inputFullClass ?><?= $extraClase ? ' '.$extraClase : '' ?>" data-campo-id="<?= esc2($cid) ?>">
|
||||
<label><?= $label ?></label>
|
||||
<input type="<?= $inputType ?>" class="form-control form-control-sm"
|
||||
name="<?= esc2($cid) ?>" value="<?= esc2($prefill) ?>"<?= $req ?>
|
||||
<?= in_array($tipo, ['edad']) ? 'min="0" max="120"' : '' ?>>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php continue;
|
||||
endif; // modoEditar
|
||||
|
||||
@@ -1406,6 +1469,13 @@ function _addExamWizardHtml(string $cid): string {
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($modoTurnero && $embebido && !empty($_mpMap) && $envio['estado'] === 'en_progreso'): ?>
|
||||
<div class="mt-2 no-print text-end">
|
||||
<button class="btn btn-outline-primary btn-sm" id="btn-guardar-tiempos">
|
||||
<i class="fas fa-save me-1"></i>Guardar tiempos
|
||||
</button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ($modoTurnero && $embebido && !empty($_mpMap) && !in_array($envio['estado'], ['firmado','cerrado_anticipado'])): ?>
|
||||
<div class="mt-3 no-print text-end">
|
||||
<button class="btn btn-outline-danger btn-sm" id="btn-cerrar-anticip">
|
||||
@@ -1928,9 +1998,10 @@ function _mpCardHdrHtml(fid, num, label, state) {
|
||||
: '<span class="toma-card-badge toma-badge-wait"><i class="fas fa-hourglass-half me-1"></i>En espera</span>';
|
||||
var extra = state === 'locked' ? '<span class="toma-card-cd" id="tc-cd-' + fid + '"></span>' : '';
|
||||
var hora = state === 'signed' ? '<span class="toma-card-hora"></span>' : '';
|
||||
var obs = state === 'signed' ? '<span class="toma-card-obs" id="tc-obs-' + fid + '"></span>' : '';
|
||||
return '<span class="toma-card-num">' + num + '</span>'
|
||||
+ '<span class="toma-card-lbl">' + label + '</span>'
|
||||
+ hora + extra + badge;
|
||||
+ hora + obs + extra + badge;
|
||||
}
|
||||
|
||||
function _mpRenderCards() {
|
||||
@@ -1997,6 +2068,12 @@ function _mpRenderCards() {
|
||||
var horaEl = null;
|
||||
if (entry.hora_campo) seg.nodes.forEach(function(n) { if (!horaEl) horaEl = n.querySelector ? n.querySelector('[name="' + entry.hora_campo + '"]') : null; });
|
||||
if (horaEl && horaEl.value) { var hs = hdr.querySelector('.toma-card-hora'); if (hs) hs.textContent = horaEl.value; }
|
||||
// Fill obs in header
|
||||
if (entry.obs_campo) {
|
||||
var obsEl = null;
|
||||
seg.nodes.forEach(function(n) { if (!obsEl && n.querySelector) obsEl = n.querySelector('[name="' + entry.obs_campo + '"]'); });
|
||||
if (obsEl && obsEl.value) { var os = hdr.querySelector('.toma-card-obs'); if (os) os.textContent = obsEl.value; }
|
||||
}
|
||||
hdr.addEventListener('click', function() { card.classList.toggle('tc-expanded'); });
|
||||
}
|
||||
|
||||
@@ -2039,6 +2116,7 @@ function _mpRefreshCards(signedFid, nextFid) {
|
||||
var se = window._muestrasMap[signedFid] || {}, snum = (sc.querySelector('.toma-card-num') || {}).textContent || '1';
|
||||
shdr.innerHTML = _mpCardHdrHtml(signedFid, parseInt(snum), _mpEffectiveLabel(se.label || ''), 'signed');
|
||||
if (se.hora_campo) { var horaEl = sc.querySelector('[name="' + se.hora_campo + '"]'); if (horaEl && horaEl.value) { var hs = shdr.querySelector('.toma-card-hora'); if (hs) hs.textContent = horaEl.value; } }
|
||||
if (se.obs_campo) { var obsEl = sc.querySelector('[name="' + se.obs_campo + '"]'); if (obsEl && obsEl.value) { var os = shdr.querySelector('.toma-card-obs'); if (os) os.textContent = obsEl.value; } }
|
||||
shdr.addEventListener('click', function() { sc.classList.toggle('tc-expanded'); });
|
||||
}
|
||||
}
|
||||
@@ -2638,6 +2716,78 @@ document.querySelectorAll('.turnero-firma-item').forEach(function(widget) {
|
||||
});
|
||||
})();
|
||||
<?php endif; ?>
|
||||
<?php if ($modoTurnero && $embebido && !empty($_mpMap) && $envio['estado'] === 'en_progreso'): ?>
|
||||
(function() {
|
||||
var btn = document.getElementById('btn-guardar-tiempos');
|
||||
if (!btn) return;
|
||||
btn.addEventListener('click', function() {
|
||||
var dr = {};
|
||||
document.querySelectorAll('[name]').forEach(function(el) {
|
||||
var n = el.name.endsWith('[]') ? el.name.slice(0,-2) : el.name;
|
||||
if (el.type==='checkbox'){ if(el.checked){ if(!Array.isArray(dr[n]))dr[n]=[]; dr[n].push(el.value); } }
|
||||
else if (el.type==='radio'){ if(el.checked) dr[n]=el.value; }
|
||||
else if (el.value!=='') dr[n]=el.value;
|
||||
});
|
||||
btn.disabled = true;
|
||||
btn.innerHTML = '<i class="fas fa-spinner fa-spin me-1"></i>Guardando...';
|
||||
fetch(window.location.href, {
|
||||
method: 'POST', headers: {'Content-Type':'application/json'},
|
||||
body: JSON.stringify({ datos_respuestas: dr })
|
||||
})
|
||||
.then(function(r){ return r.json(); })
|
||||
.then(function(d) {
|
||||
if (d.ok) {
|
||||
// Actualizar obs en headers de tarjetas firmadas
|
||||
if (window._muestrasMap) {
|
||||
document.querySelectorAll('.toma-card--signed').forEach(function(card) {
|
||||
var fid = card.getAttribute('data-firma');
|
||||
var se = fid && window._muestrasMap[fid];
|
||||
if (se && se.obs_campo) {
|
||||
var obsEl = card.querySelector('[name="' + se.obs_campo + '"]');
|
||||
var os = card.querySelector('.toma-card-obs');
|
||||
if (obsEl && os) os.textContent = obsEl.value || '';
|
||||
}
|
||||
});
|
||||
}
|
||||
btn.innerHTML = '<i class="fas fa-check me-1"></i>Guardado';
|
||||
setTimeout(function(){ btn.disabled=false; btn.innerHTML='<i class="fas fa-save me-1"></i>Guardar tiempos'; }, 2000);
|
||||
} else {
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = '<i class="fas fa-save me-1"></i>Guardar tiempos';
|
||||
}
|
||||
})
|
||||
.catch(function(){ btn.disabled=false; btn.innerHTML='<i class="fas fa-save me-1"></i>Guardar tiempos'; });
|
||||
});
|
||||
})();
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($modoTurnero && $embebido && !empty($_mpMap) && $envio['estado'] === 'en_progreso'): ?>
|
||||
(function() {
|
||||
var base = window.location.href.split('/ver_formulario_enviado.php')[0];
|
||||
var token = <?= json_encode($tokenTurnero) ?>;
|
||||
document.querySelectorAll('.btn-olvidar-toma').forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
var hc = btn.dataset.hc;
|
||||
var fids = JSON.parse(btn.dataset.fids || '[]');
|
||||
var campos = [hc];
|
||||
fids.forEach(function(fid) { campos.push(fid); campos.push(fid + '_svg'); });
|
||||
if (!confirm('¿Olvidar esta toma? Se borrará la firma y podrás editar el tiempo.')) return;
|
||||
btn.disabled = true;
|
||||
fetch(base + '/modules/turnero/api/resetear_toma.php', {
|
||||
method: 'POST', headers: {'Content-Type':'application/json'},
|
||||
body: JSON.stringify({ token: token, campos: campos })
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(d) {
|
||||
if (d.ok) { window.location.reload(); }
|
||||
else { alert(d.error || 'Error al olvidar'); btn.disabled = false; }
|
||||
})
|
||||
.catch(function(e) { alert(e.message); btn.disabled = false; });
|
||||
});
|
||||
});
|
||||
})();
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($modoTurnero && $embebido && !empty($_mpMap) && !in_array($envio['estado'], ['firmado','cerrado_anticipado'])): ?>
|
||||
(function() {
|
||||
var btn = document.getElementById('btn-cerrar-anticip');
|
||||
|
||||
Reference in New Issue
Block a user