feat(lis): migración completa Firebird→MySQL + tracking de muestras en turnero

- Migraciones LIS 01-08: schema completo del nuevo LIS (secciones, protocolos,
  ítems de resultado, perfiles, tarifas, empresas, histórico transaccional)
- ETL Firebird→MySQL: script CLI con conversión WIN1252→UTF-8, batches de 500,
  resolución de FKs y deduplicación de pacientes
- turnero_muestras: tracking pendiente/recibida/rechazada por tipo de tubo
- lugar.php: widget de recepción de muestras (solo tipo=muestras)
- update_muestra_estado.php: API para marcar estado de muestra
- create_solicitud.php: auto-crea muestras al guardar solicitud
- get_consentimientos.php: incluye muestras[] en el response
- 6 vistas SQL: v_muestras_hoy, v_recepcion_completa, v_examen_precio, etc.
- numero_orden en encabezado del formulario firmado (D-/F- color diferenciado)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-07-04 21:44:22 -05:00
co-authored by Claude Sonnet 4.6
parent 86ed70db34
commit 5fedd233f4
18 changed files with 1754 additions and 4 deletions
+30 -3
View File
@@ -36,7 +36,8 @@ if ($modoTurnero) {
p.nombre_completo AS paciente_nombre,
p.numero_documento, p.tipo_documento,
p.fecha_nacimiento, p.telefono AS paciente_telefono, p.eps,
t.sesion_id
t.sesion_id,
ts.numero_orden
FROM turnero_consentimientos tc
JOIN lab_formularios f ON f.id = tc.formulario_id
JOIN turnero_turnos t ON t.id = tc.turno_id
@@ -128,11 +129,13 @@ if ($modoTurnero) {
f.doc_encabezado, f.doc_subtitulo, f.doc_logo_base64, f.doc_color, f.doc_pie_pagina,
p.nombre_completo AS paciente_nombre, p.numero_documento, p.tipo_documento,
p.fecha_nacimiento, p.telefono AS paciente_telefono, p.eps,
u.full_name AS enviado_por_nombre, u.email AS enviado_por_email
u.full_name AS enviado_por_nombre, u.email AS enviado_por_email,
ld.numero_orden
FROM lab_form_envios e
JOIN lab_formularios f ON f.id = e.formulario_id
LEFT JOIN lab_pacientes p ON p.id = e.paciente_id
LEFT JOIN admin_users u ON u.id = e.enviado_por
LEFT JOIN lab_domicilios ld ON ld.id = e.domicilio_id
WHERE e.token = ?",
[$tokenPublico]
);
@@ -150,11 +153,13 @@ if ($modoTurnero) {
f.doc_encabezado, f.doc_subtitulo, f.doc_logo_base64, f.doc_color, f.doc_pie_pagina,
p.nombre_completo AS paciente_nombre, p.numero_documento, p.tipo_documento,
p.fecha_nacimiento, p.telefono AS paciente_telefono, p.eps,
u.full_name AS enviado_por_nombre, u.email AS enviado_por_email
u.full_name AS enviado_por_nombre, u.email AS enviado_por_email,
ld.numero_orden
FROM lab_form_envios e
JOIN lab_formularios f ON f.id = e.formulario_id
LEFT JOIN lab_pacientes p ON p.id = e.paciente_id
LEFT JOIN admin_users u ON u.id = e.enviado_por
LEFT JOIN lab_domicilios ld ON ld.id = e.domicilio_id
WHERE e.id = ?",
[$id]
);
@@ -167,6 +172,11 @@ if ($modoTurnero) {
}
}
// ── Consecutivo de orden (D-... domicilio | F-... turnero) ────────────
$numeroOrden = $modoTurnero
? ($tcRow['numero_orden'] ?? null)
: ($envio['numero_orden'] ?? null);
// ── Config global del lab ─────────────────────────────────────────────
$cfgRows = $db->fetchAll('SELECT clave, valor FROM lab_config WHERE valor != ""');
$cfg = [];
@@ -442,6 +452,20 @@ function esc2(mixed $v): string {
<?php endif; ?>
</div>
<div class="doc-header-badge" style="text-align:right">
<?php if ($numeroOrden): ?>
<?php
$esDomicilio = str_starts_with($numeroOrden, 'D-');
$ordenColor = $esDomicilio ? '#bbf7d0' : '#bfdbfe';
$ordenTxt = $esDomicilio ? '#14532d' : '#1e3a8a';
$ordenLabel = $esDomicilio ? 'Domicilio' : 'Turnero';
?>
<div style="background:<?= $ordenColor ?>;color:<?= $ordenTxt ?>;border-radius:8px;
padding:4px 10px;font-size:12px;font-weight:700;letter-spacing:.03em;
margin-bottom:6px;font-family:monospace">
<?= esc2($numeroOrden) ?>
</div>
<div style="font-size:10px;opacity:.75;margin-bottom:4px"><?= $ordenLabel ?></div>
<?php endif; ?>
<?php
$eBadge = match($envio['estado']) {
'firmado' => 'estado-firmado',
@@ -877,6 +901,9 @@ function esc2(mixed $v): string {
<?= esc2($docPiePagina) ?> &nbsp;&bull;&nbsp;
<?php endif; ?>
<i class="fas fa-shield-alt me-1"></i>Generado el <?= date('d/m/Y H:i') ?> &nbsp;&bull;&nbsp; ID #<?= $envio['id'] ?>
<?php if ($numeroOrden): ?>
&nbsp;&bull;&nbsp; Orden: <strong><?= esc2($numeroOrden) ?></strong>
<?php endif; ?>
</span>
<?php if ($envio['hash_verificacion']): ?>
<span class="hash-short" title="Hash SHA-256"><?= substr($envio['hash_verificacion'],0,16) ?>...</span>