Commit Graph
39 Commits
Author SHA1 Message Date
Lizandro GuarnizoandClaude Opus 5 2b1f08b03f Evitar teléfonos falsos en la historia clínica, y pedir el número a quien lo oculta
El arreglo anterior dejó un defecto: obtenerOCrearDesdeWhatsapp() copiaba
users.phone_number al teléfono de la ficha, y para quien oculta su número ahí
va el BSUID. normalizarTelefono() le quitaba el punto y las letras, así que
"CO.1761088155094242" quedaba guardado como "1761088155094242": un número de
16 dígitos, falso, con apariencia de real, dentro de una historia clínica y
sin que nadie lo notara. Ahora esa ficha se crea sin teléfono, que es la
verdad: no lo tenemos.

- esBsuid() queda definido una sola vez, en config.php, que es donde lo ven
  tanto el servicio de WhatsApp como las clases del laboratorio.
- La lista y el detalle de pacientes dicen "Solo por WhatsApp" en vez de
  mostrar el identificador crudo: recepción necesita entender por qué no
  puede llamar, no ver un código.
- Al crear la ficha desde una conversación se le pide el número con el botón
  de Meta, una sola vez (users.contacto_pedido_at). El texto es editable
  desde configuración. Solo se marca como pedido si Meta aceptó el envío,
  para poder reintentar si falló.
- tests/test_bsuid.php: 30 verificaciones sobre identidad, envío, vinculación
  y creación de fichas.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 20:26:31 -05:00
Lizandro GuarnizoandClaude Opus 5 57818b180a Estación de muestras: corregir la ficha del paciente desde el turno
Los campos del formulario F-LAB-08 son vinculados: leen de la ficha del
paciente. Si el dato está mal, no había forma de arreglarlo desde la estación
—el modal era de solo lectura— y corregirlo únicamente en el documento habría
dejado la ficha equivocada, reapareciendo en el próximo turno, orden o
consentimiento. Por eso se corrige la ficha y no el documento: el dato queda
bien en todo el sistema y el formulario, al ser automático, lo toma solo.

La edición tiene dos niveles de fricción. Teléfono, dirección y EPS se editan
directo: cambian seguido y el error es de bajo riesgo. Nombre, tipo y número
de documento y fecha de nacimiento quedan tras un botón aparte con
confirmación, porque identifican al paciente en toda su historia clínica.

Si el turno ya tiene documentos firmados se advierte que corregir la ficha no
los modifica y que hay que emitirlos de nuevo, para que nadie espere que un
PDF ya firmado se actualice solo.

Paciente::actualizar registraba en la bitácora solo el valor nuevo, lo que
impedía reconstruir el anterior si la corrección resultaba equivocada —justo
cuando hace falta consultarlo. Ahora guarda antes y después, y únicamente de
los campos que realmente cambiaron.

La validación del servidor ya cubría nombre, celular, documento y correo, y la
cédula tiene índice único, así que no hizo falta agregar validación.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 09:05:48 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 ecc9b74247 fix: mostrar consentimientos del turnero en lab_formularios.php
- fecha usa COALESCE(firmado_at, enviado_at, t.creado_at) porque
  turnero siempre deja enviado_at en NULL
- filtro por fecha también usa ese COALESCE para no excluir registros
- total_envios y total_completados suman turnero_consentimientos

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 07:44:16 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 912798fbcc feat(pacientes): origen 'lab' en vez de 'rips' + tabla ampliada + proteger origen en update
- Valor de BD cambia de 'rips' a 'lab' (más genérico)
- ingest_paciente: en UPDATE nunca pisa origen (conserva manual/whatsapp/lab)
- Badge muestra 'Resultados Lab' con ícono matraz; retrocompat con valor 'rips'
- Tabla agrega: teléfono+WA, email, EPS, género en nombre
- filtro dropdown usa 'lab' en lugar de 'rips'

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-09 11:34:03 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 828e323eba feat(lab_pacientes): columna origen + vista mejorada con stats y filtros
- Migration: columna 'origen' (manual|rips|whatsapp) en lab_pacientes
- ingest_paciente.php: guarda origen='rips' en cada paciente importado
- Paciente::listar(): filtro por origen + orden por created_at DESC
- Paciente::stats(): conteo total/importados/con_wa/manuales
- get_pacientes.php: expone ?origen= y ?stats=1
- lab_pacientes.php: cards de stats clicables, badge origen por fila,
  columna ciudad, columna fecha registro, dropdown filtro por origen

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-09 11:16:52 -05:00
Lizandro GuarnizoandClaude Sonnet 4.6 f4da864db7 feat(turnero): toma prolongada secuencial + bloqueo muestras/cierre
- ver_formulario_enviado: auto-fill médico (nombres/especialidad/código) en datos_prefilled desde solicitud
- ver_formulario_enviado: canvases de toma progresiva bloqueados secuencialmente — solo el turno activo es firmable, los siguientes aparecen al expirar el countdown
- ver_formulario_enviado: countdown prominente con reloj grande, color dinámico, sonido (Web Audio) y vibración al llegar la hora
- lugar: bloquear cierre del modal durante toma progresiva activa (botón X deshabilitado hasta mp_completar)
- lugar: bloquear Finalizar atención si hay muestras pendientes sin decisión (recibida/rechazada)
- lugar: _syncBtnFinalizar combina consentimientos + muestras para el aviso y estado del botón
- lugar: restricción de usuario a lugar específico via turnero_lugar_id (admin_users) + bloqueo JS en confirmarLugar()
- migrations: turnero_lugar_id en admin_users para restringir bacteriólogos por usuario

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-08 21:16:07 -05:00
Lizandro Guarnizo ebbf4ac6cf Update Enfermera.php 2026-06-18 14:27:58 -05:00
Lizandro Guarnizo 415ea3ef56 up 2026-06-16 12:06:26 -05:00
Lizandro Guarnizo 4e6913c41e up 2026-06-01 09:16:03 -05:00
Lizandro Guarnizo 2f72d87c3b cambios 2026-05-27 20:40:17 -05:00
Lizandro Guarnizo 8f0b28fc7c 8 2026-04-18 13:13:34 -05:00
Lizandro Guarnizo 1b441461ad up 2026-04-18 13:10:47 -05:00
Lizandro Guarnizo c8bef9d9c4 up 2026-04-10 23:04:28 -05:00
Lizandro Guarnizo 485404814b Update ActividadAdmin.php 2026-04-08 09:16:53 -05:00
Lizandro Guarnizo d38b5936ca actividades 2026-04-08 09:02:32 -05:00
Lizandro Guarnizo cbf7a8c296 up 2026-04-08 08:31:21 -05:00
Lizandro Guarnizo 4f1b2e146c up 2026-04-07 15:57:53 -05:00
Lizandro Guarnizo ded060e161 lab_formularios 2026-04-07 15:12:22 -05:00
Lizandro Guarnizo 8e89775e9e up 2026-04-07 09:15:09 -05:00
Lizandro Guarnizo e1241a42ed cambios 2026-04-06 17:06:58 -05:00
Lizandro Guarnizo 619deac7cb up 2026-04-06 17:02:15 -05:00
Lizandro Guarnizo ca90f79625 up 2026-04-06 12:30:37 -05:00
Lizandro Guarnizo 052a263659 Fix: normalize empty numeric fields to null in lab domicilios 2026-03-27 16:17:03 -05:00
Lizandro Guarnizo 0a3f4ffae0 Fix: normalize empty datetime/time fields to null in lab domicilios 2026-03-27 16:04:46 -05:00
Lizandro Guarnizo 3b92f47b54 feat: enlaces de formulario sin vencimiento + PDF descargable sin sesión vía token público 2026-03-25 16:14:26 -05:00
Lizandro Guarnizo 4ba890a0d5 feat: métricas completas, export Excel domicilios con filtros, hora llegada/salida visible 2026-03-25 11:48:24 -05:00
Lizandro Guarnizo 2abce6d4c2 feat: multi-archivo órdenes visible en enfermero, domicilios y órdenes médicas
- OrdenMedica::filtrarCampos(): agrega domicilio_id al whitelist
- Domicilio::obtener(): consulta secundaria archivos_ordenes[] con fallback
- Enfermera::agenda(): bulk-query archivos_ordenes[] por domicilio_id
- api/lab/link_ordenes_domicilio.php: API POST vincula orden_ids a domicilio_id
- conversations.php guardar(): trackea allOrdenIds[], llama link API post-save
- lab_domicilios.php: renderOrdenesDetail() multi-archivo en detalle
- enfermero_portal.php: renderOrdenesEnfermero() multi-archivo en cards
- lab_ordenes.php: botón 'Ver domicilio' cuando domicilio_id está vinculado
- migrations/: ALTER TABLE lab_ordenes_medicas ADD domicilio_id + índice
2026-03-24 21:51:29 -05:00
Lizandro Guarnizo 4106840a39 up 2026-03-16 21:33:01 -05:00
Lizandro Guarnizo fe1d3c31b3 foto 2026-03-16 21:00:39 -05:00
Lizandro Guarnizo 79bcc5e4bf up 2026-03-16 20:46:54 -05:00
Lizandro Guarnizo 3b834bc24b up 2026-03-16 20:35:02 -05:00
Lizandro Guarnizo 5f7cc67dd9 up 2026-03-16 20:29:21 -05:00
Lizandro Guarnizo ded19cbb8d Cambios 2026-03-16 18:36:11 -05:00
Lizandro Guarnizo 730e1e9636 fix: accion ENUM en lab_autorizaciones al crear orden
El metodo registrarCambioEstado usaba estadoNuevo ('pendiente')
como valor de accion, pero pendiente no es un valor valido del
ENUM de lab_autorizaciones.accion.

Se pasa 'creada' explicitamente al crear una orden nueva, que si
es un valor valido del ENUM ('creada','en_revision','autorizada',
'rechazada','en_domicilio','completada','editada').
2026-03-13 15:53:42 -05:00
Lizandro Guarnizo beb1bbe1d4 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
2026-03-12 22:53:24 -05:00
Lizandro Guarnizo c42e0976d7 fix: enfermero_portal - mostrar imagen de la orden aunque no esté vinculada al domicilio
Si lab_domicilios.orden_id es NULL (domicilio creado antes del fix
o desde otro flujo), usa subquery para encontrar la orden más reciente
del mismo paciente que tenga local_file.

Así el enfermero siempre ve la imagen de la orden del paciente
independientemente de cómo se agendó el domicilio.
2026-03-12 22:38:48 -05:00
Lizandro Guarnizo d362598a70 feat: relacionar imagen de WhatsApp con orden médica al agendar domicilio
Al abrir el modal desde una imagen en el chat:
- guardar() crea primero la OrdenMedica via crear_desde_whatsapp.php
  y pasa el orden_id resultante a save_domicilio.php
- Enfermera::agenda() hace LEFT JOIN a lab_ordenes_medicas para traer
  local_file de la orden asociada (as orden_local_file)
- enfermero_portal._cardHTML() muestra la imagen de la orden médica
  con link para ampliar
2026-03-12 22:14:04 -05:00
Lizandro Guarnizo 12e7b411d7 feat: enfermero_portal - mostrar todos los datos del paciente en tarjeta de domicilio
La tarjeta ahora muestra: documento, fecha de nacimiento, EPS,
teléfono (clickeable), correo (clickeable), exámenes solicitados
y tipo de cliente (particular/seguro con nombre del seguro).

Cambios:
- Enfermera::agenda() amplía SELECT con email, fecha_nacimiento,
  numero_documento, tipo_documento, eps, examenes_solicitados,
  tipo_cliente, seguro_nombre, ciudad, indicaciones_dir, notas_admin
- my_agenda.php simplificado: ya no re-consulta lab_domicilios por
  los campos que ahora vienen directo en la query
- enfermero_portal.php _cardHTML() muestra todos los campos nuevos
2026-03-12 22:05:47 -05:00
Lizandro Guarnizo db469b2134 up 2026-03-10 18:42:51 -05:00