Permite anular servicios sin tener que asignártelos primero

solicitar.html: botón "Anular Aviso" en la Bolsa de Trabajo. buscar.html: botón de anular en la pestaña "Sin Asignar" y en "Mis Asignados". asignados.html: botón "Anular Servicio" en la ficha de un servicio ya asignado pero sin cita. En los tres casos se cambia el estado a Anulado directamente, sin tocar assigned_to, para no disparar el WhatsApp de "servicio asignado".
This commit is contained in:
2026-09-07 07:26:24 +00:00
parent 8b2fbe4138
commit 806fa00103
3 changed files with 119 additions and 3 deletions

View File

@@ -193,6 +193,10 @@
<button onclick="saveAppointment()" id="btnSaveAppt" disabled class="w-full bg-slate-300 text-white font-black py-4 rounded-2xl shadow-sm transition-all flex items-center justify-center gap-2 uppercase tracking-widest text-xs cursor-not-allowed">
<i data-lucide="calendar-check" class="w-5 h-5"></i> Confirmar Cita
</button>
<!-- 🆕 Anular un servicio ya asignado pero aún sin cita, sin tener que agendarlo primero -->
<button onclick="anularServicio()" id="btnAnularAsig" class="w-full mt-3 bg-white text-rose-600 font-black py-3 rounded-2xl border border-rose-200 flex items-center justify-center gap-2 uppercase tracking-widest text-xs active:scale-95 transition-transform">
<i data-lucide="ban" class="w-4 h-4"></i> Anular Servicio
</button>
</div>
</div>
</div>
@@ -1029,6 +1033,42 @@ function renderServices(servicesToRender = localServices) {
lucide.createIcons();
}
}
// 🆕 Anula un servicio ya asignado pero todavía sin cita, sin obligar a agendarlo antes.
async function anularServicio() {
const id = document.getElementById('detId').value;
if (!confirm("¿Seguro que quieres anular este servicio? No podrás deshacerlo desde aquí.")) return;
const stAnulado = systemStatuses.find(st => st.name.toLowerCase().includes('anula'));
if (!stAnulado) return alert("El sistema no tiene un estado 'Anulado' configurado. Avisa a la oficina.");
const btn = document.getElementById('btnAnularAsig');
const originalContent = btn.innerHTML;
btn.innerHTML = `<i data-lucide="loader-2" class="w-4 h-4 animate-spin"></i> Anulando...`;
btn.disabled = true;
try {
const res = await fetch(`${API_URL}/services/set-appointment/${id}`, {
method: 'PUT',
headers: { "Content-Type": "application/json", "Authorization": `Bearer ${localStorage.getItem("token")}` },
body: JSON.stringify({ status_operativo: String(stAnulado.id) })
});
if (res.ok) {
showToast("Servicio anulado");
closeModal('actionModal', 'modalContent');
refreshData();
} else {
alert("Error al anular.");
}
} catch (e) {
alert("Error de conexión");
} finally {
btn.innerHTML = originalContent;
btn.disabled = false;
lucide.createIcons();
}
}
function showToast(msg) {
const t = document.getElementById('toast');
document.getElementById('toastMsg').innerText = msg;