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>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
68cf64edf7
commit
912798fbcc
@@ -20,7 +20,7 @@ try {
|
||||
$busqueda = trim($_GET['busqueda'] ?? $_GET['search'] ?? '');
|
||||
$pagina = max(1, (int)($_GET['page'] ?? $_GET['pagina'] ?? 1));
|
||||
$por = max(1, min(100, (int)($_GET['limit'] ?? $_GET['por_pagina'] ?? 30)));
|
||||
$origen = in_array($_GET['origen'] ?? '', ['manual', 'rips', 'whatsapp'], true)
|
||||
$origen = in_array($_GET['origen'] ?? '', ['manual', 'lab', 'whatsapp'], true)
|
||||
? $_GET['origen'] : '';
|
||||
|
||||
jsonOk($pac->listar($busqueda, $pagina, $por, $origen));
|
||||
|
||||
@@ -121,9 +121,10 @@ if (!empty($data['ciudad'])) {
|
||||
if (!empty($data['eps'])) {
|
||||
$campos['eps'] = trim($data['eps']);
|
||||
}
|
||||
$origenValidos = ['manual', 'rips', 'whatsapp'];
|
||||
// origen solo se aplica en creación, nunca en update
|
||||
$origenValidos = ['manual', 'lab', 'whatsapp'];
|
||||
$campos['origen'] = in_array($data['origen'] ?? '', $origenValidos, true)
|
||||
? $data['origen'] : 'rips';
|
||||
? $data['origen'] : 'lab';
|
||||
|
||||
// ── Modo: "insertar" (solo nuevos) | "upsert" (crea o actualiza) ─────────────
|
||||
$modo = trim($data['modo'] ?? 'upsert');
|
||||
@@ -151,6 +152,8 @@ try {
|
||||
'message' => 'Paciente ya existe',
|
||||
]);
|
||||
} else {
|
||||
// Nunca pisar origen en update — conservar el que ya tiene en BD
|
||||
unset($campos['origen']);
|
||||
$pac->actualizar($existente['id'], $campos, null);
|
||||
echo json_encode([
|
||||
'ok' => true,
|
||||
|
||||
@@ -78,7 +78,7 @@ class Paciente {
|
||||
return $this->db->fetch("
|
||||
SELECT
|
||||
COUNT(*) AS total,
|
||||
SUM(origen = 'rips') AS importados,
|
||||
SUM(origen = 'lab') AS importados,
|
||||
SUM(origen = 'manual') AS manuales,
|
||||
SUM(origen = 'whatsapp') AS whatsapp,
|
||||
SUM(user_id IS NOT NULL) AS con_wa
|
||||
|
||||
+14
-7
@@ -197,7 +197,7 @@ require_once __DIR__ . '/shared/components/sidebar.php';
|
||||
<div class="col-md-3">
|
||||
<select id="filtro-origen" class="form-select" onchange="cargarLista(1)">
|
||||
<option value="">Todos los orígenes</option>
|
||||
<option value="rips">Importados RIPS</option>
|
||||
<option value="lab">Resultados Lab</option>
|
||||
<option value="manual">Manuales</option>
|
||||
<option value="whatsapp">Desde WhatsApp</option>
|
||||
</select>
|
||||
@@ -220,7 +220,10 @@ require_once __DIR__ . '/shared/components/sidebar.php';
|
||||
<tr>
|
||||
<th class="ps-3">Paciente</th>
|
||||
<th>Documento</th>
|
||||
<th>Teléfono</th>
|
||||
<th>Email</th>
|
||||
<th>Ciudad</th>
|
||||
<th>EPS</th>
|
||||
<th>Origen</th>
|
||||
<th>Registro</th>
|
||||
<th>Órd.</th>
|
||||
@@ -228,7 +231,7 @@ require_once __DIR__ . '/shared/components/sidebar.php';
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="tabla-body">
|
||||
<tr><td colspan="7" class="text-center py-4 text-muted">
|
||||
<tr><td colspan="10" class="text-center py-4 text-muted">
|
||||
<i class="fas fa-spinner fa-spin me-2"></i>Cargando...
|
||||
</td></tr>
|
||||
</tbody>
|
||||
@@ -431,9 +434,10 @@ function filtrarOrigen(origen) {
|
||||
|
||||
// ── Lista ──────────────────────────────────────────────────────────────────
|
||||
const _origenBadge = {
|
||||
rips: '<span class="badge" style="background:#e3f2fd;color:#1565c0;font-size:.7rem"><i class="fas fa-database me-1"></i>RIPS</span>',
|
||||
whatsapp: '<span class="badge" style="background:#e8f5e9;color:#2e7d32;font-size:.7rem"><i class="fab fa-whatsapp me-1"></i>WA</span>',
|
||||
lab: '<span class="badge" style="background:#e3f2fd;color:#1565c0;font-size:.7rem"><i class="fas fa-flask me-1"></i>Resultados Lab</span>',
|
||||
whatsapp: '<span class="badge" style="background:#e8f5e9;color:#2e7d32;font-size:.7rem"><i class="fab fa-whatsapp me-1"></i>WhatsApp</span>',
|
||||
manual: '<span class="badge bg-secondary bg-opacity-10 text-secondary" style="font-size:.7rem"><i class="fas fa-pen me-1"></i>Manual</span>',
|
||||
rips: '<span class="badge" style="background:#e3f2fd;color:#1565c0;font-size:.7rem"><i class="fas fa-flask me-1"></i>Resultados Lab</span>',
|
||||
};
|
||||
|
||||
function origenBadge(origen) {
|
||||
@@ -456,7 +460,7 @@ async function cargarLista(pag = 1) {
|
||||
|
||||
const tbody = document.getElementById('tabla-body');
|
||||
if (!d.data?.length) {
|
||||
tbody.innerHTML = '<tr><td colspan="7" class="text-center py-4 text-muted">Sin resultados</td></tr>';
|
||||
tbody.innerHTML = '<tr><td colspan="10" class="text-center py-4 text-muted">Sin resultados</td></tr>';
|
||||
document.getElementById('paginacion').innerHTML = '';
|
||||
return;
|
||||
}
|
||||
@@ -465,10 +469,13 @@ async function cargarLista(pag = 1) {
|
||||
<tr style="cursor:pointer" onclick="verDetalle(${p.id})">
|
||||
<td class="ps-3">
|
||||
<div class="fw-semibold">${esc(p.nombre_completo)}</div>
|
||||
${p.telefono ? `<small class="text-muted">${esc(p.telefono)}</small>` : ''}
|
||||
${p.genero ? `<small class="text-muted">${p.genero==='M'?'Masculino':p.genero==='F'?'Femenino':'Otro'}</small>` : ''}
|
||||
</td>
|
||||
<td class="small">${tipoDocLabel(p.tipo_documento)} ${esc(p.numero_documento||'—')}</td>
|
||||
<td class="small">${tipoDocLabel(p.tipo_documento)}<br><span class="fw-semibold">${esc(p.numero_documento||'—')}</span></td>
|
||||
<td class="small">${esc(p.telefono||'—')}${p.phone_number ? `<br><i class="fab fa-whatsapp text-success"></i> <small class="text-muted">${esc(p.phone_number)}</small>` : ''}</td>
|
||||
<td class="small text-muted">${esc(p.email||'—')}</td>
|
||||
<td class="small text-muted">${esc(p.ciudad||'—')}</td>
|
||||
<td class="small text-muted">${esc(p.eps||'—')}</td>
|
||||
<td>${origenBadge(p.origen)}</td>
|
||||
<td class="small text-muted">${fmtFecha(p.created_at)}</td>
|
||||
<td><span class="badge bg-primary hist-badge">${p.total_ordenes||0}</span></td>
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ if (!defined('MIGRATION_TOKEN') || ($_GET['token'] ?? '') !== MIGRATION_TOKEN) {
|
||||
$pdo = Database::getInstance()->getConnection();
|
||||
|
||||
$steps = [
|
||||
"ALTER TABLE lab_pacientes ADD COLUMN IF NOT EXISTS origen VARCHAR(20) NOT NULL DEFAULT 'manual' COMMENT 'Origen: manual | rips | whatsapp' AFTER notas_admin",
|
||||
"ALTER TABLE lab_pacientes ADD COLUMN IF NOT EXISTS origen VARCHAR(20) NOT NULL DEFAULT 'manual' COMMENT 'Origen: manual | lab | whatsapp' AFTER notas_admin",
|
||||
"UPDATE lab_pacientes SET origen = 'whatsapp' WHERE user_id IS NOT NULL AND origen = 'manual'",
|
||||
"CREATE INDEX IF NOT EXISTS idx_pac_origen ON lab_pacientes (origen)",
|
||||
];
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
ALTER TABLE `lab_pacientes`
|
||||
ADD COLUMN `origen` VARCHAR(20) NOT NULL DEFAULT 'manual'
|
||||
COMMENT 'Origen del registro: manual | rips | whatsapp'
|
||||
COMMENT 'Origen del registro: manual | lab | whatsapp'
|
||||
AFTER `notas_admin`;
|
||||
|
||||
-- Los pacientes con user_id ya vinculado se marcan como whatsapp
|
||||
|
||||
@@ -11,7 +11,7 @@ require_once __DIR__ . '/classes/Database.php';
|
||||
$pdo = Database::getInstance()->getConnection();
|
||||
|
||||
$steps = [
|
||||
"ALTER TABLE lab_pacientes ADD COLUMN IF NOT EXISTS origen VARCHAR(20) NOT NULL DEFAULT 'manual' COMMENT 'Origen: manual | rips | whatsapp' AFTER notas_admin",
|
||||
"ALTER TABLE lab_pacientes ADD COLUMN IF NOT EXISTS origen VARCHAR(20) NOT NULL DEFAULT 'manual' COMMENT 'Origen: manual | lab | whatsapp' AFTER notas_admin",
|
||||
"UPDATE lab_pacientes SET origen = 'whatsapp' WHERE user_id IS NOT NULL AND origen = 'manual'",
|
||||
"CREATE INDEX IF NOT EXISTS idx_pac_origen ON lab_pacientes (origen)",
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user