From 1ff44b1654f1f82ba8e6e45247e201202f6d0a86 Mon Sep 17 00:00:00 2001 From: Luis Ernesto Portillo Zaldivar Date: Mon, 21 Jul 2025 14:36:18 -0600 Subject: [PATCH] =?UTF-8?q?feat(#71):=20Agregar=20DUI=20salvadore=C3=B1o?= =?UTF-8?q?=20y=20n=C3=BAmeros=20de=20tel=C3=A9fono=20de=20El=20Salvador?= =?UTF-8?q?=20a=20pacientes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plan_issue_11_informe_resultados_pdf.md | 0 issue_body.txt | 24 - issue_content.txt | 38 -- lims_management/data/lims_sequence.xml | 9 + lims_management/demo/z_lims_demo.xml | 572 +++++++++++++++++- pr_body_10.txt | 32 - pr_body_54.txt | 74 --- pr_body_9.txt | 48 -- test/create_lab_requests.py | 199 ++++++ 9 files changed, 774 insertions(+), 222 deletions(-) rename {planes => documents/plans}/plan_issue_11_informe_resultados_pdf.md (100%) delete mode 100644 issue_body.txt delete mode 100644 issue_content.txt delete mode 100644 pr_body_10.txt delete mode 100644 pr_body_54.txt delete mode 100644 pr_body_9.txt diff --git a/planes/plan_issue_11_informe_resultados_pdf.md b/documents/plans/plan_issue_11_informe_resultados_pdf.md similarity index 100% rename from planes/plan_issue_11_informe_resultados_pdf.md rename to documents/plans/plan_issue_11_informe_resultados_pdf.md diff --git a/issue_body.txt b/issue_body.txt deleted file mode 100644 index 7cf6864..0000000 --- a/issue_body.txt +++ /dev/null @@ -1,24 +0,0 @@ -## Descripción - -Actualmente, cuando se cancela una orden de laboratorio, las muestras asociadas permanecen activas y no se descartan automáticamente. Esto puede causar confusión ya que quedan muestras "huérfanas" en el sistema que ya no tienen una orden válida. - -## Comportamiento esperado - -Cuando se cancela una orden de laboratorio: -1. Todas las muestras generadas asociadas a esa orden deben cambiar automáticamente su estado a "cancelled" -2. Si hay pruebas (lims.test) asociadas a esas muestras, también deben cancelarse -3. Se debe registrar en el chatter de la muestra que fue cancelada debido a la cancelación de la orden - -## Criterios de aceptación - -- [ ] Al cancelar una orden de laboratorio, todas sus muestras asociadas se marcan como canceladas -- [ ] Las pruebas asociadas a las muestras también se cancelan -- [ ] Se registra un mensaje en el chatter de cada muestra indicando la razón de cancelación -- [ ] Si una muestra ya estaba cancelada o completada, no se modifica -- [ ] La acción es reversible: si se vuelve a poner la orden en borrador, las muestras NO deben reactivarse automáticamente - -## Notas técnicas - -- El método a modificar es `action_cancel()` en el modelo `sale.order` -- Verificar el campo `generated_sample_ids` para obtener las muestras asociadas -- Solo cancelar muestras que estén en estados: 'pending_collection', 'collected', 'in_analysis' \ No newline at end of file diff --git a/issue_content.txt b/issue_content.txt deleted file mode 100644 index 59ced20..0000000 --- a/issue_content.txt +++ /dev/null @@ -1,38 +0,0 @@ -**Contexto:** -Para poder implementar la automatización de generación de muestras (Issue #32), es necesario establecer una relación entre los productos tipo análisis y los tipos de muestra que requieren. - -**Problema Actual:** -- Los productos tipo test (is_analysis=True) no tienen campo que indique qué tipo de muestra requieren -- Los productos tipo muestra (is_sample_type=True) no están relacionados con los tests -- El modelo stock.lot tiene container_type como Selection hardcodeado, no como relación - -**Tareas Requeridas:** - -1. **Modificar product.template:** - - Agregar campo Many2one 'required_sample_type_id' que relacione análisis con tipo de muestra - - Domain: [('is_sample_type', '=', True)] - -2. **Actualizar stock.lot:** - - Opción A: Cambiar container_type de Selection a Many2one hacia product.template - - Opción B: Agregar nuevo campo sample_type_product_id - - Mantener compatibilidad con datos existentes - -3. **Actualizar vistas:** - - Agregar campo en formulario de productos cuando is_analysis=True - - Mostrar tipo de muestra requerida en vistas de análisis - -4. **Migración de datos:** - - Mapear valores actuales de container_type a productos tipo muestra - - Actualizar registros existentes - -5. **Actualizar demo data:** - - Asignar tipos de muestra correctos a cada análisis - - Ejemplo: Hemograma → Tubo EDTA, Glucosa → Tubo Suero - -**Beneficios:** -- Permitirá automatizar la generación de muestras al confirmar órdenes -- Evitará errores al saber exactamente qué contenedor usar para cada test -- Facilitará la agrupación de análisis que usan el mismo tipo de muestra - -**Dependencia:** -Este issue es prerequisito para poder implementar el Issue #32 \ No newline at end of file diff --git a/lims_management/data/lims_sequence.xml b/lims_management/data/lims_sequence.xml index 8179dbc..88df11a 100644 --- a/lims_management/data/lims_sequence.xml +++ b/lims_management/data/lims_sequence.xml @@ -11,5 +11,14 @@ + + + Secuencia de Muestras de Laboratorio + stock.lot.serial + M-%(year)s%(month)s%(day)s- + 6 + + + \ No newline at end of file diff --git a/lims_management/demo/z_lims_demo.xml b/lims_management/demo/z_lims_demo.xml index 3559a36..6159f77 100644 --- a/lims_management/demo/z_lims_demo.xml +++ b/lims_management/demo/z_lims_demo.xml @@ -10,8 +10,9 @@ Carga Inicial 1985-05-15 female - +1-202-555-0174 + +503 7234-5678 ana.torres@example.com + 03245678-9 @@ -21,8 +22,9 @@ Carga Inicial 1992-11-20 male - +1-202-555-0192 + +503 7892-3456 carlos.ruiz@example.com + 04567890-1 @@ -32,8 +34,9 @@ Carga Inicial 1978-03-10 female - +1-202-555-0201 + +503 7345-6789 maria.gonzalez@example.com + 01234567-8 @@ -41,7 +44,7 @@ Dr. Luis Herrera L-98765 - +1-202-555-0145 + +503 2234-5678 luis.herrera@hospital.com @@ -49,14 +52,14 @@ Dra. Sofia Vargas L-54321 - +1-202-555-0133 + +503 2345-6789 sofia.vargas@clinic.com Laura Mendoza - +1-202-555-0188 + +503 7456-7890 laura.mendoza@example.com @@ -70,5 +73,562 @@ + + + Sofía Jiménez + + P-S45F04 + Carga Inicial + + female + +503 7567-8901 + + + + Diego Morales + + P-D78M05 + Carga Inicial + + male + +503 7678-9012 + + + + Valentina Castro + + P-V23F06 + Carga Inicial + + female + +503 7789-0123 + + + + + Santiago Pérez + + P-S90M07 + Carga Inicial + + male + +503 7890-1234 + + + + Isabella Rodríguez + + P-I34F08 + Carga Inicial + + female + +503 7901-2345 + + + + + Camila Fernández + + P-C67F09 + Carga Inicial + 1995-07-22 + female + + +503 7012-3456 + camila.fernandez@example.com + 05678901-2 + + + + Alejandro Gutiérrez + + P-A12M10 + Carga Inicial + 1990-02-14 + male + +503 7123-4567 + alejandro.gutierrez@example.com + 06789012-3 + + + + Lucía Mendoza + + P-L89F11 + Carga Inicial + 1992-09-30 + female + + +503 7234-5678 + 07890123-4 + + + + Miguel Ángel Silva + + P-M45M12 + Carga Inicial + 1988-11-05 + male + +503 7345-6789 + 08901234-5 + + + + Natalia Vargas + + P-N78F13 + Carga Inicial + 1996-04-18 + female + +503 7456-7890 + 09012345-6 + + + + + Roberto Martínez + + P-R23M14 + Carga Inicial + 1975-06-12 + male + +503 7567-8901 + 00123456-7 + + + + Patricia López + + P-P56F15 + Carga Inicial + 1972-12-25 + female + +503 7678-9012 + 01234567-8 + + + + Fernando Díaz + + P-F90M16 + Carga Inicial + 1980-03-08 + male + +503 7789-0123 + 02345678-9 + + + + Andrea Herrera + + P-A34F17 + Carga Inicial + 1978-08-17 + female + + +503 7890-1234 + 03456789-0 + + + + + José Luis Ramírez + + P-J67M18 + Carga Inicial + 1965-01-20 + male + +503 7901-2345 + 04567890-1 + + + + Carmen Sánchez + + P-C12F19 + Carga Inicial + 1958-10-15 + female + +503 7012-3456 + 05678901-2 + + + + Ricardo Flores + + P-R89M20 + Carga Inicial + 1960-05-28 + male + +503 7123-4567 + 06789012-3 + + + + + Esperanza Romero + + P-E45F21 + Carga Inicial + 1945-12-03 + female + +503 7234-5678 + 07890123-4 + + + + Francisco Aguilar + + P-F78M22 + Carga Inicial + 1943-07-19 + male + +503 7345-6789 + 08901234-5 + + + + + Daniela Cortés + + P-D23F23 + Carga Inicial + 1998-02-11 + female + +503 7456-7890 + 09012345-6 + + + + Gabriel Moreno + + P-G56M24 + Carga Inicial + + male + +503 7567-8901 + + + + Valeria Ruiz + + P-V90F25 + Carga Inicial + 1987-09-24 + female + + +503 7678-9012 + 00123456-7 + + + + Eduardo Navarro + + P-E34M26 + Carga Inicial + 1970-11-30 + male + +503 7789-0123 + 01234568-8 + + + + Mariana Delgado + + P-M67F27 + Carga Inicial + 1999-06-07 + female + +503 7890-1234 + 02345679-9 + + + + Andrés Jiménez + + P-A12M28 + Carga Inicial + 1955-08-21 + male + +503 7901-2345 + 03456780-0 + + + + Paola Méndez + + P-P89F29 + Carga Inicial + 1991-03-16 + female + + +503 7012-3456 + 04567891-1 + + + + Sebastián Vega + + P-S45M30 + Carga Inicial + + male + +503 7123-4567 + + + + Claudia Paredes + + P-C78F31 + Carga Inicial + 1982-10-09 + female + +503 7234-5678 + 05678902-2 + + + + Raúl Castro + + P-R23M32 + Carga Inicial + 1948-04-27 + male + +503 7345-6789 + 06789013-3 + + + + Adriana Guerrero + + P-A56F33 + Carga Inicial + 1994-12-13 + female + + +503 7456-7890 + 07890124-4 + + + + Javier Molina + + P-J90M34 + Carga Inicial + + male + +503 7567-8901 + + + + Rosa María Ochoa + + P-R34F35 + Carga Inicial + 1962-01-05 + female + +503 7678-9012 + 08901235-5 + + + + Manuel Reyes + + P-M67M36 + Carga Inicial + 1976-07-31 + male + +503 7789-0123 + 09012346-6 + + + + Teresa Campos + + P-T12F37 + Carga Inicial + 1940-09-18 + female + +503 7890-1234 + 00123457-7 + + + + Pablo Espinoza + + P-P89M38 + Carga Inicial + 1989-05-03 + male + +503 7901-2345 + 01234569-8 + + + + Mónica Villanueva + + P-M45F39 + Carga Inicial + 1985-11-26 + female + + +503 7012-3456 + 02345670-9 + + + + Diego Alejandro Luna + + P-D78M40 + Carga Inicial + + male + +503 7123-4567 + + + + Beatriz Salazar + + P-B23F41 + Carga Inicial + 1968-02-14 + female + +503 7234-5678 + 03456781-0 + + + + Héctor Valdés + + P-H56M42 + Carga Inicial + 1973-06-29 + male + +503 7345-6789 + 04567892-1 + + + + Silvia Peña + + P-S90F43 + Carga Inicial + 1997-08-11 + female + +503 7456-7890 + 05678903-2 + + + + Arturo Domínguez + + P-A34M44 + Carga Inicial + 1951-12-07 + male + +503 7567-8901 + 06789014-3 + + + + Gloria Ríos + + P-G67F45 + Carga Inicial + 1983-04-22 + female + + +503 7678-9012 + 07890125-4 + + + + Emilio Núñez + + P-E12M46 + Carga Inicial + + male + +503 7789-0123 + + + + Laura Patricia Ibarra + + P-L89F47 + Carga Inicial + 1979-10-16 + female + +503 7890-1234 + 08901236-5 + + + + Óscar Medina + + P-O45M48 + Carga Inicial + 1966-03-25 + male + +503 7901-2345 + 09012347-6 + + + + Verónica Soto + + P-V78F49 + Carga Inicial + 1993-07-08 + female + + +503 7012-3456 + 00123458-7 + + + + Rubén Contreras + + P-R23M50 + Carga Inicial + 1937-11-14 + male + +503 7123-4567 + 01234560-8 + + + + Alejandra Fuentes + + P-A56F51 + Carga Inicial + + female + +503 7234-5678 + + + + Nicolás Ramos + + P-N90M52 + Carga Inicial + 1986-01-19 + male + +503 7345-6789 + 02345671-9 + + + + Fernanda Acosta + + P-F34F53 + Carga Inicial + 2000-05-12 + female + +503 7456-7890 + 03456782-0 + + \ No newline at end of file diff --git a/pr_body_10.txt b/pr_body_10.txt deleted file mode 100644 index d8673a2..0000000 --- a/pr_body_10.txt +++ /dev/null @@ -1,32 +0,0 @@ -## Descripción -Implementación del sistema de etiquetas con código de barras para las muestras de laboratorio. - -## Cambios realizados - -### Funcionalidad principal -- Creado reporte QWeb para imprimir etiquetas de muestras (100x50mm) -- Implementado botón 'Imprimir Etiquetas' en órdenes de laboratorio -- Las etiquetas incluyen: - - Información del paciente - - Código de muestra y orden - - Tipo de contenedor - - Fecha de recolección - - Código de barras Code128 - - Lista de análisis a realizar - -### Correcciones técnicas -- **Código de barras**: Corregido problema de visualización usando widget nativo de Odoo 18 -- **Caracteres especiales**: Solucionado problema de codificación UTF-8 con referencias numéricas -- **Layout**: Ajustado diseño para mostrar múltiples etiquetas por página sin solapamiento -- **Espaciado**: Optimizado el tamaño y posición del código de barras - -## Testing -- Probado con órdenes que tienen múltiples muestras -- Verificado que los códigos de barras se generen y visualicen correctamente -- Confirmado que los caracteres en español (tildes, ñ) se muestren bien -- Validado que no hay solapamiento entre etiquetas - -## Capturas -- Los códigos de barras ahora se visualizan correctamente -- Las etiquetas respetan el formato 100x50mm -- Múltiples etiquetas por página sin problemas de diseño diff --git a/pr_body_54.txt b/pr_body_54.txt deleted file mode 100644 index f942676..0000000 --- a/pr_body_54.txt +++ /dev/null @@ -1,74 +0,0 @@ -## Descripción - -Implementación de la funcionalidad para cancelar automáticamente muestras y pruebas cuando se cancela una orden de laboratorio, evitando que queden elementos "huérfanos" en el sistema. - -## 🎯 Objetivo - -Resolver el issue #54: Las muestras y pruebas asociadas a una orden de laboratorio deben cancelarse automáticamente cuando se cancela la orden. - -## 🔧 Cambios implementados - -### 1. Modelo `stock.lot` (Muestras) -- Agregado nuevo estado `'cancelled'` a la selección de estados -- Implementado método `action_cancel()` para cambiar el estado a cancelado - -### 2. Modelo `sale.order` (Órdenes) -- Override del método `action_cancel()` que: - - Llama primero al método padre para mantener el comportamiento estándar - - Si es una orden de laboratorio (`is_lab_request = True`): - - Cancela muestras en estados: `pending_collection`, `collected`, `received`, `in_process` - - Cancela pruebas asociadas que no estén en estado `validated` o `cancelled` - - Registra mensajes en el chatter de cada elemento cancelado - - Muestra un resumen en la orden con la cantidad de elementos cancelados - -### 3. Tests unitarios -- Creado `test_order_cancel_cascade.py` con 6 tests que verifican: - - ✅ Cancelación correcta de muestras - - ✅ Cancelación correcta de pruebas - - ✅ No cancelación de muestras en estados finales (analyzed, stored, disposed) - - ✅ No cancelación de pruebas validadas - - ✅ Generación de mensajes en chatter - - ✅ Órdenes normales (no laboratorio) no afectadas - -## 🧪 Pruebas realizadas - -### Test manual exitoso: -``` -📦 Muestras generadas: - - 0000012: Contenedor de Heces (Estado: pending_collection) - -🔬 Pruebas generadas: - - LAB-2025-00014: Coprocultivo (Estado: draft) - -❌ Cancelando la orden de laboratorio... - -📦 Estado final de las muestras: - - 0000012: cancelled ✓ - -🔬 Estado final de las pruebas: - - LAB-2025-00014: cancelled ✓ - -✅ Mensajes de cancelación registrados en todos los elementos -``` - -## 📋 Checklist - -- [x] Código implementado y probado -- [x] Tests unitarios creados -- [x] Pruebas manuales exitosas -- [x] Mensajes en chatter funcionando -- [x] Sin errores o warnings -- [x] Documentación en código - -## 🔍 Cómo probar - -1. Crear una orden de laboratorio con análisis -2. Confirmar la orden (se generan muestras y pruebas) -3. Opcionalmente iniciar proceso en alguna prueba -4. Cancelar la orden -5. Verificar que: - - Las muestras cambiaron a estado "Cancelada" - - Las pruebas cambiaron a estado "Cancelado" - - Hay mensajes en el chatter explicando la cancelación - -Resuelve #54 \ No newline at end of file diff --git a/pr_body_9.txt b/pr_body_9.txt deleted file mode 100644 index fa45958..0000000 --- a/pr_body_9.txt +++ /dev/null @@ -1,48 +0,0 @@ -## Implementación del flujo de validación y seguridad - -### Cambios realizados - -#### 1. Ajuste de permisos base (ir.model.access.csv) -- Recepcionista: Solo lectura en lims.test y lims.result -- Técnico: Lectura/escritura pero sin crear/eliminar -- Administrador: Permisos completos - -#### 2. Reglas de registro implementadas (lims_security.xml) -- Recepcionistas no pueden editar pruebas -- Técnicos solo pueden editar pruebas no validadas -- Administradores tienen acceso completo - -#### 3. Validación de permisos en transiciones (lims_test.py) -- `action_start_process()`: Solo técnicos y administradores -- `action_enter_results()`: Solo técnicos y administradores -- `action_validate()`: Solo administradores -- `action_cancel()`: Técnicos (excepto validadas) y administradores -- `action_draft()`: Solo administradores - -#### 4. Trazabilidad mejorada -- stock.lot ahora hereda de mail.thread -- Todos los cambios de estado se registran en el chatter -- Mensajes más descriptivos con contexto - -#### 5. Validaciones adicionales -- Control de transiciones de estado válidas -- Verificación del estado de la muestra -- Validación de resultados críticos fuera de rango -- No se puede crear pruebas en estado != draft sin ser admin - -#### 6. Vistas actualizadas -- Botones visibles solo para roles apropiados -- Campos de resultados editables solo por técnicos/admin - -#### 7. Usuarios demo para pruebas -- Usuario: `recepcionista` / Contraseña: `demo` -- Usuario: `tecnico` / Contraseña: `demo` -- Usuario: `administrador` / Contraseña: `demo` - -### Pruebas realizadas -- Verificación de permisos por rol -- Validación de transiciones de estado -- Trazabilidad en chatter -- Restricciones visuales en formularios - -Closes #9 \ No newline at end of file diff --git a/test/create_lab_requests.py b/test/create_lab_requests.py index 226bc25..741e650 100644 --- a/test/create_lab_requests.py +++ b/test/create_lab_requests.py @@ -1,5 +1,198 @@ import odoo import json +import random +from datetime import datetime + +# Diccionario de notas médicas para parámetros críticos +CRITICAL_NOTES = { + 'glucosa': { + 'high': 'Valor elevado de glucosa. Posible prediabetes o diabetes. Se recomienda repetir la prueba en ayunas y consultar con endocrinología.', + 'low': 'Hipoglucemia detectada. Riesgo de síntomas neuroglucogénicos. Evaluar causas: medicamentos, insuficiencia hepática o endocrinopatías.' + }, + 'hemoglobina': { + 'high': 'Policitemia. Evaluar posibles causas: deshidratación, tabaquismo, cardiopatía o policitemia vera.', + 'low': 'Anemia severa. Investigar origen: deficiencia de hierro, pérdida sanguínea, hemólisis o enfermedad crónica.' + }, + 'hematocrito': { + 'high': 'Hemoconcentración. Correlacionar con hemoglobina. Descartar deshidratación o policitemia.', + 'low': 'Valor compatible con anemia. Evaluar junto con hemoglobina e índices eritrocitarios.' + }, + 'leucocitos': { + 'high': 'Leucocitosis marcada. Descartar proceso infeccioso, inflamatorio o hematológico.', + 'low': 'Leucopenia severa. Riesgo de infecciones. Evaluar causas: viral, medicamentosa o hematológica.' + }, + 'plaquetas': { + 'high': 'Trombocitosis. Riesgo trombótico. Descartar causa primaria vs reactiva.', + 'low': 'Trombocitopenia severa. Riesgo de sangrado. Evaluar PTI, hiperesplenismo o supresión medular.' + }, + 'neutrofilos': { + 'high': 'Neutrofilia. Sugiere infección bacteriana o proceso inflamatorio agudo.', + 'low': 'Neutropenia. Alto riesgo de infección bacteriana. Evaluar urgentemente.' + }, + 'linfocitos': { + 'high': 'Linfocitosis. Considerar infección viral o proceso linfoproliferativo.', + 'low': 'Linfopenia. Evaluar inmunodeficiencia o efecto de corticoides.' + }, + 'colesterol total': { + 'high': 'Hipercolesterolemia. Riesgo cardiovascular elevado. Iniciar medidas dietéticas y evaluar tratamiento con estatinas.', + 'low': 'Hipocolesterolemia. Evaluar malnutrición, hipertiroidismo o enfermedad hepática.' + }, + 'trigliceridos': { + 'high': 'Hipertrigliceridemia severa. Riesgo de pancreatitis aguda. Considerar tratamiento farmacológico urgente.', + 'low': 'Valor bajo, generalmente sin significado patológico.' + }, + 'hdl': { + 'high': 'HDL elevado, factor protector cardiovascular.', + 'low': 'HDL bajo. Factor de riesgo cardiovascular. Recomendar ejercicio y cambios en estilo de vida.' + }, + 'ldl': { + 'high': 'LDL elevado. Alto riesgo aterogénico. Evaluar inicio de estatinas según riesgo global.', + 'low': 'LDL bajo, generalmente favorable.' + }, + 'glucosa en sangre': { + 'high': 'Hiperglucemia. Si en ayunas >126 mg/dL sugiere diabetes. Confirmar con segunda muestra.', + 'low': 'Hipoglucemia. Evaluar síntomas y causas. Riesgo neurológico si <50 mg/dL.' + } +} + +def get_critical_note(param_name, value, normal_min=None, normal_max=None): + """Obtiene la nota apropiada para un resultado crítico""" + param_lower = param_name.lower() + + # Buscar el parámetro en el diccionario + for key in CRITICAL_NOTES: + if key in param_lower: + if normal_max and value > normal_max: + return CRITICAL_NOTES[key].get('high', f'Valor crítico alto para {param_name}. Requiere evaluación médica inmediata.') + elif normal_min and value < normal_min: + return CRITICAL_NOTES[key].get('low', f'Valor crítico bajo para {param_name}. Requiere evaluación médica inmediata.') + + # Nota genérica si no se encuentra el parámetro + if normal_max and value > normal_max: + return f'Valor significativamente elevado. Rango normal: {normal_min}-{normal_max}. Se recomienda evaluación médica.' + elif normal_min and value < normal_min: + return f'Valor significativamente bajo. Rango normal: {normal_min}-{normal_max}. Se recomienda evaluación médica.' + + return 'Valor fuera de rango normal. Requiere interpretación clínica.' + +def process_order_tests(env, order): + """Process all tests for a given order: regenerate results, fill values, and validate""" + print(f"\nProcessing tests for order {order.name}...") + + # First, update sample states to allow processing + samples = order.generated_sample_ids.sudo() + for sample in samples: + if sample.state == 'pending_collection': + sample.action_collect() + print(f" - Sample {sample.name} collected") + if sample.state == 'collected': + sample.action_receive() + print(f" - Sample {sample.name} received") + if sample.state == 'received': + sample.action_start_analysis() + print(f" - Sample {sample.name} analysis started") + + # Find all tests associated with this order + tests = env['lims.test'].search([('sale_order_id', '=', order.id)]) + print(f"Found {len(tests)} tests for order {order.name}") + + # Ensure we have the right permissions by using sudo() + tests = tests.sudo() + + for test in tests: + try: + print(f"\nProcessing test {test.name} - {test.product_id.name}") + + # First, mark the test as in_process if it's in draft state + if test.state == 'draft': + test.write({'state': 'in_process'}) + + # Manually create results if they don't exist + if not test.result_ids: + # Get analysis parameters from product template + product_tmpl = test.product_id.product_tmpl_id + for param_link in product_tmpl.parameter_ids: + param = param_link.parameter_id + result = env['lims.result'].create({ + 'test_id': test.id, + 'parameter_id': param.id, + }) + # Immediately set a value to avoid validation errors + if param.value_type == 'numeric': + # Generar valor que a veces esté fuera de rango + if random.random() < 0.3: # 30% de valores críticos + # Obtener rangos normales del parámetro + normal_min = param_link.normal_min if hasattr(param_link, 'normal_min') and param_link.normal_min else 10 + normal_max = param_link.normal_max if hasattr(param_link, 'normal_max') and param_link.normal_max else 100 + + # Decidir si será alto o bajo + if random.random() < 0.5: + # Valor alto + value = round(random.uniform(normal_max * 1.2, normal_max * 1.5), 2) + else: + # Valor bajo + value = round(random.uniform(normal_min * 0.5, normal_min * 0.8), 2) + result.value_numeric = value + else: + result.value_numeric = 50.0 + elif param.value_type == 'text': + result.value_text = "Normal" + elif param.value_type == 'boolean': + result.value_boolean = False + elif param.value_type == 'selection' and param.selection_options: + options = param.selection_options.split(',') + result.value_selection = options[0].strip() + print(f" - Created {len(product_tmpl.parameter_ids)} result fields") + + # Evaluar resultados críticos y agregar notas + for result in test.result_ids: + # Leer el registro para actualizar campos computados + result.read(['is_critical']) + + # Si el resultado es crítico, agregar nota + if result.is_critical and result.parameter_id.value_type == 'numeric': + value = result.value_numeric + param_name = result.parameter_id.name + + # Obtener rangos del rango aplicable si existe + normal_min = normal_max = None + if result.applicable_range_id: + normal_min = result.applicable_range_id.normal_min + normal_max = result.applicable_range_id.normal_max + + # Obtener la nota apropiada + note = get_critical_note(param_name, value, normal_min, normal_max) + result.write({'notes': note}) + print(f" - Agregada nota crítica para {param_name}: valor {value}") + + print(f" - Results ready with values and critical notes") + + # Update test state directly to bypass permission checks + if test.state == 'in_process': + # Mark as results entered + test.write({ + 'state': 'result_entered' + }) + print(f" - Results entered") + + # Then validate the test + if test.state == 'result_entered': + test.write({ + 'state': 'validated', + 'validator_id': env.user.id, + 'validation_date': datetime.now() + }) + print(f" - Test validated successfully") + + except Exception as e: + print(f" - Error processing test {test.name}: {str(e)}") + import traceback + traceback.print_exc() + print(f" - Test state: {test.state}") + print(f" - Product template: {test.product_id.product_tmpl_id.name}") + print(f" - Parameters: {len(test.product_id.product_tmpl_id.parameter_ids)}") + + print(f"\nCompleted processing tests for order {order.name}") def create_lab_requests(cr): env = odoo.api.Environment(cr, odoo.SUPERUSER_ID, {}) @@ -48,6 +241,9 @@ def create_lab_requests(cr): # Confirm the order to test automatic sample generation order1.action_confirm() print(f"Confirmed Lab Order 1. Generated samples: {len(order1.generated_sample_ids)}") + + # Process tests for order1 + process_order_tests(env, order1) # Create Lab Request 2 - Different sample types if patient2 and glucosa and urocultivo: @@ -65,6 +261,9 @@ def create_lab_requests(cr): order2.action_confirm() print(f"Confirmed Lab Order 2. Generated samples: {len(order2.generated_sample_ids)}") + # Process tests for order2 + process_order_tests(env, order2) + except Exception as e: print(f"Error creating lab requests: {str(e)}") import traceback