From 2abce6d4c240163b6de99d80f705fb775577ad60 Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Tue, 24 Mar 2026 21:51:29 -0500 Subject: [PATCH] =?UTF-8?q?feat:=20multi-archivo=20=C3=B3rdenes=20visible?= =?UTF-8?q?=20en=20enfermero,=20domicilios=20y=20=C3=B3rdenes=20m=C3=A9dic?= =?UTF-8?q?as?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- api/lab/link_ordenes_domicilio.php | 50 +++++++++++++ classes/lab/Domicilio.php | 20 ++++- classes/lab/Enfermera.php | 48 +++++++++++- classes/lab/OrdenMedica.php | 2 +- conversations.php | 17 ++++- enfermero_portal.php | 46 +++++++----- lab_domicilios.php | 73 ++++++++++++------- lab_ordenes.php | 8 ++ .../20260324_lab_11_ordenes_domicilio_id.sql | 11 +++ .../run_20260324_ordenes_domicilio_id.php | 38 ++++++++++ 10 files changed, 262 insertions(+), 51 deletions(-) create mode 100644 api/lab/link_ordenes_domicilio.php create mode 100644 migrations/20260324_lab_11_ordenes_domicilio_id.sql create mode 100644 migrations/run_20260324_ordenes_domicilio_id.php diff --git a/api/lab/link_ordenes_domicilio.php b/api/lab/link_ordenes_domicilio.php new file mode 100644 index 0000000..753df4f --- /dev/null +++ b/api/lab/link_ordenes_domicilio.php @@ -0,0 +1,50 @@ + false, 'error' => 'Método no permitido']); + exit; +} + +$input = json_decode(file_get_contents('php://input'), true); +if (empty($input['domicilio_id']) || empty($input['orden_ids']) || !is_array($input['orden_ids'])) { + echo json_encode(['success' => false, 'error' => 'domicilio_id y orden_ids[] requeridos']); + exit; +} + +$domicilioId = (int)$input['domicilio_id']; +$ordenIds = array_map('intval', $input['orden_ids']); +$ordenIds = array_filter($ordenIds, fn($v) => $v > 0); + +if (!$domicilioId || empty($ordenIds)) { + echo json_encode(['success' => false, 'error' => 'Valores inválidos']); + exit; +} + +try { + $db = Database::getInstance(); + $placeholders = implode(',', array_fill(0, count($ordenIds), '?')); + $params = array_merge([$domicilioId], array_values($ordenIds)); + + $db->execute( + "UPDATE lab_ordenes_medicas SET domicilio_id = ? WHERE id IN ($placeholders)", + $params + ); + + echo json_encode(['success' => true, 'vinculadas' => count($ordenIds)]); +} catch (Exception $e) { + error_log('[link_ordenes_domicilio] ' . $e->getMessage()); + echo json_encode(['success' => false, 'error' => 'Error interno']); +} diff --git a/classes/lab/Domicilio.php b/classes/lab/Domicilio.php index 967e760..0055d5c 100644 --- a/classes/lab/Domicilio.php +++ b/classes/lab/Domicilio.php @@ -111,7 +111,7 @@ class Domicilio { * Domicilio por ID con todos los datos relacionados. */ public function obtener(int $id): ?array { - return $this->db->fetch(" + $dom = $this->db->fetch(" SELECT d.*, p.nombre_completo AS paciente_nombre, @@ -133,7 +133,23 @@ class Domicilio { LEFT JOIN lab_enfermeras e ON e.id = a.enfermera_id LEFT JOIN admin_users adm ON adm.id = d.creado_por WHERE d.id = ? - ", [$id]) ?: null; + ", [$id]); + if (!$dom) return null; + + // Todos los archivos de órdenes vinculados a este domicilio + $archivos = $this->db->fetchAll( + "SELECT id AS orden_id, local_file + FROM lab_ordenes_medicas + WHERE domicilio_id = ? AND local_file IS NOT NULL + ORDER BY id ASC", + [$id] + ); + // Fallback para domicilios creados antes de la migración (usan orden_id FK) + if (empty($archivos) && !empty($dom['orden_local_file'])) { + $archivos = [['orden_id' => $dom['orden_id'], 'local_file' => $dom['orden_local_file']]]; + } + $dom['archivos_ordenes'] = $archivos; + return $dom; } /** diff --git a/classes/lab/Enfermera.php b/classes/lab/Enfermera.php index 1ab0d37..31204cf 100644 --- a/classes/lab/Enfermera.php +++ b/classes/lab/Enfermera.php @@ -91,7 +91,7 @@ class Enfermera { */ public function agenda(int $enfermeraId, string $fecha = ''): array { $fecha = $fecha ?: date('Y-m-d'); - return $this->db->fetchAll(" + $rows = $this->db->fetchAll(" SELECT d.id AS domicilio_id, d.fecha_programada, @@ -151,6 +151,52 @@ class Enfermera { AND d.fecha_programada = ? ORDER BY d.hora_programada ASC ", [$enfermeraId, $fecha]); + + // Bulk-load todos los archivos de órdenes vinculados a estos domicilios + $domIds = array_values(array_filter(array_column($rows, 'domicilio_id'))); + if (!empty($domIds)) { + $ph = implode(',', array_fill(0, count($domIds), '?')); + $archivos = $this->db->fetchAll( + "SELECT domicilio_id, id AS orden_id, local_file + FROM lab_ordenes_medicas + WHERE domicilio_id IN ($ph) AND local_file IS NOT NULL + ORDER BY id ASC", + $domIds + ); + $archivosPorDom = []; + foreach ($archivos as $a) { + $archivosPorDom[$a['domicilio_id']][] = $a; + } + foreach ($rows as &$row) { + $did = $row['domicilio_id']; + if (!empty($archivosPorDom[$did])) { + $row['archivos_ordenes'] = $archivosPorDom[$did]; + } elseif (!empty($row['orden_local_file'])) { + // Fallback: domicilio creado antes de la migración + $row['archivos_ordenes'] = [[ + 'orden_id' => $row['orden_id_display'] ?? $row['orden_id'], + 'local_file' => $row['orden_local_file'], + ]]; + } else { + $row['archivos_ordenes'] = []; + } + } + unset($row); + } else { + foreach ($rows as &$row) { + if (!empty($row['orden_local_file'])) { + $row['archivos_ordenes'] = [[ + 'orden_id' => $row['orden_id_display'] ?? $row['orden_id'], + 'local_file' => $row['orden_local_file'], + ]]; + } else { + $row['archivos_ordenes'] = []; + } + } + unset($row); + } + + return $rows; } /** diff --git a/classes/lab/OrdenMedica.php b/classes/lab/OrdenMedica.php index e9fa6a9..c5a7660 100644 --- a/classes/lab/OrdenMedica.php +++ b/classes/lab/OrdenMedica.php @@ -306,7 +306,7 @@ class OrdenMedica { private function filtrarCampos(array $datos): array { $permitidos = [ 'paciente_id', 'conversation_id', 'whatsapp_media_id', 'local_file', - 'estado', 'medico_nombre', 'medico_registro', 'fecha_orden', + 'domicilio_id', 'estado', 'medico_nombre', 'medico_registro', 'fecha_orden', 'diagnostico', 'examenes_solicitados', 'requiere_ayuno', 'horas_ayuno', 'indicaciones', 'revisada_por', 'revisada_at', 'autorizada_por', 'autorizada_at', 'comentario_revision', 'notas_admin', diff --git a/conversations.php b/conversations.php index c619528..81bb0da 100644 --- a/conversations.php +++ b/conversations.php @@ -7439,6 +7439,7 @@ const labDomicilio = (() => { try { const convIdNum = (_convId && !String(_convId).startsWith('__user:')) ? parseInt(_convId) : null; + const allOrdenIds = []; for (let _fi = 0; _fi < _localFiles.length; _fi++) { const orRes = await fetch('api/lab/crear_desde_whatsapp.php', { method: 'POST', @@ -7453,10 +7454,12 @@ const labDomicilio = (() => { }), }); const orData = await orRes.json(); - if (orData.success && orData.orden_id && _fi === 0) { - datos.orden_id = orData.orden_id; + if (orData.success && orData.orden_id) { + allOrdenIds.push(orData.orden_id); + if (_fi === 0) datos.orden_id = orData.orden_id; } } + datos._allOrdenIds = allOrdenIds; } catch (_) { /* no bloquea */ } } @@ -7469,6 +7472,16 @@ const labDomicilio = (() => { const d = await r.json(); if (d.success) { + // Vincular todas las órdenes al domicilio recién creado + const _oids = datos._allOrdenIds; + if (Array.isArray(_oids) && _oids.length > 0 && d.id) { + fetch('api/lab/link_ordenes_domicilio.php', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ domicilio_id: d.id, orden_ids: _oids }), + }).catch(() => {}); + } + // Actualizar _pacNombre si el usuario editó el nombre en el input const _editedNombre = fv('labdom-pac-nombre'); if (_editedNombre) _pacNombre = _editedNombre; diff --git a/enfermero_portal.php b/enfermero_portal.php index b91e5fd..961d9a6 100644 --- a/enfermero_portal.php +++ b/enfermero_portal.php @@ -531,23 +531,8 @@ const portal = { ${cobroHtml} - - ${item.orden_local_file ? ` -
` : ''} + + ${renderOrdenesEnfermero(item)} ${seSuf ? `