
- Agregar QWeb template para generar PDF profesional con: - Encabezado con datos del laboratorio y logo - Información completa del paciente y orden - Tabla de resultados con indicadores visuales para valores fuera de rango - Sección de observaciones y notas - Información del validador y fecha de validación - Agregar campo computado reference_text en parameter_range para mostrar rangos formateados - Agregar botón "Imprimir Informe de Resultados" en vista de órdenes (solo visible cuando hay pruebas validadas) - Agregar campo lab_notes en sale.order para observaciones generales - Reorganizar vista de lims.test con pestañas para mejor UX - Corregir manejo de employee_ids en el reporte para casos donde no existe el módulo HR - Incluir scripts de prueba para generar datos de demostración El informe resalta valores críticos y fuera de rango con colores distintivos, facilitando la interpretación rápida de los resultados por parte del médico. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
226 lines
8.9 KiB
Python
226 lines
8.9 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
Script para crear órdenes de laboratorio con resultados validados para probar el reporte PDF
|
|
"""
|
|
|
|
import odoo
|
|
import logging
|
|
from datetime import datetime, timedelta
|
|
import random
|
|
from odoo import fields
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
def create_validated_lab_order(env):
|
|
"""Crear una orden de laboratorio con resultados completos y validados"""
|
|
|
|
# Obtener o crear paciente y doctor demo
|
|
patient = env['res.partner'].search([('is_patient', '=', True)], limit=1)
|
|
if not patient:
|
|
patient = env['res.partner'].create({
|
|
'name': 'Juan Pérez (Demo)',
|
|
'is_patient': True,
|
|
'birthdate_date': '1980-05-15',
|
|
'gender': 'male',
|
|
'vat': '12345678',
|
|
})
|
|
|
|
doctor = env['res.partner'].search([('is_doctor', '=', True)], limit=1)
|
|
if not doctor:
|
|
doctor = env['res.partner'].create({
|
|
'name': 'Dr. María García (Demo)',
|
|
'is_doctor': True,
|
|
})
|
|
|
|
# Usar usuario admin como técnico y validador
|
|
admin_user = env.ref('base.user_admin')
|
|
technician = admin_user
|
|
validator = admin_user
|
|
|
|
# Obtener análisis disponibles
|
|
hemograma = env.ref('lims_management.analysis_hemograma')
|
|
glucosa = env.ref('lims_management.analysis_glucosa')
|
|
perfil_lipidico = env.ref('lims_management.analysis_perfil_lipidico')
|
|
|
|
# Crear orden de laboratorio
|
|
order = env['sale.order'].create({
|
|
'partner_id': patient.id,
|
|
'doctor_id': doctor.id,
|
|
'is_lab_request': True,
|
|
'lab_notes': 'Paciente en ayunas de 12 horas. Control de rutina anual.',
|
|
'order_line': [
|
|
(0, 0, {
|
|
'product_id': hemograma.product_variant_id.id,
|
|
'product_uom_qty': 1,
|
|
'price_unit': hemograma.list_price,
|
|
}),
|
|
(0, 0, {
|
|
'product_id': glucosa.product_variant_id.id,
|
|
'product_uom_qty': 1,
|
|
'price_unit': glucosa.list_price,
|
|
}),
|
|
(0, 0, {
|
|
'product_id': perfil_lipidico.product_variant_id.id,
|
|
'product_uom_qty': 1,
|
|
'price_unit': perfil_lipidico.list_price,
|
|
}),
|
|
]
|
|
})
|
|
|
|
# Confirmar orden (genera muestras y pruebas automáticamente)
|
|
order.action_confirm()
|
|
|
|
_logger.info(f"Orden creada: {order.name}")
|
|
|
|
# Primero, marcar todas las muestras como recolectadas
|
|
for sample in order.generated_sample_ids:
|
|
sample.write({'state': 'collected'})
|
|
|
|
# Procesar cada prueba
|
|
for test in order.lab_test_ids:
|
|
# Asignar técnico
|
|
test.write({
|
|
'technician_id': technician.id
|
|
})
|
|
|
|
# Generar resultados si no existen
|
|
if not test.result_ids:
|
|
# Usar sudo para evitar restricciones de permisos y llamar método interno
|
|
test.sudo()._generate_test_results()
|
|
_logger.info(f"Generados {len(test.result_ids)} resultados para prueba {test.name}")
|
|
|
|
# Cambiar estado a in_process
|
|
test.write({'state': 'in_process'})
|
|
|
|
# Ingresar resultados según el tipo de análisis
|
|
for result in test.result_ids:
|
|
parameter = result.parameter_id
|
|
vals = {}
|
|
|
|
# Solo procesar parámetros numéricos
|
|
if parameter.value_type == 'numeric':
|
|
# Generar valores basados en el parámetro
|
|
if parameter.code == 'HGB': # Hemoglobina
|
|
vals['value_numeric'] = random.uniform(11.0, 16.5) # Algunos fuera de rango
|
|
elif parameter.code == 'HCT': # Hematocrito
|
|
vals['value_numeric'] = random.uniform(35.0, 48.0)
|
|
elif parameter.code == 'WBC': # Leucocitos
|
|
vals['value_numeric'] = random.uniform(3.5, 11.0) # Algunos fuera de rango
|
|
elif parameter.code == 'PLT': # Plaquetas
|
|
vals['value_numeric'] = random.uniform(140, 450)
|
|
elif parameter.code == 'RBC': # Eritrocitos
|
|
vals['value_numeric'] = random.uniform(3.8, 5.8)
|
|
elif parameter.code == 'GLU': # Glucosa
|
|
vals['value_numeric'] = random.uniform(65, 125) # Algunos elevados
|
|
elif parameter.code == 'CHOL': # Colesterol
|
|
vals['value_numeric'] = random.uniform(150, 240) # Algunos elevados
|
|
elif parameter.code == 'TRIG': # Triglicéridos
|
|
vals['value_numeric'] = random.uniform(40, 200) # Algunos elevados
|
|
elif parameter.code == 'HDL': # HDL
|
|
vals['value_numeric'] = random.uniform(35, 65)
|
|
elif parameter.code == 'LDL': # LDL
|
|
vals['value_numeric'] = random.uniform(70, 160)
|
|
else:
|
|
# Valor genérico para otros parámetros numéricos
|
|
if result.applicable_range_id:
|
|
# Generar valor cercano al rango normal
|
|
min_val = result.applicable_range_id.normal_min or 0
|
|
max_val = result.applicable_range_id.normal_max or 100
|
|
vals['value_numeric'] = random.uniform(min_val * 0.8, max_val * 1.2)
|
|
else:
|
|
# Valor por defecto si no hay rango
|
|
vals['value_numeric'] = random.uniform(1, 100)
|
|
|
|
_logger.info(f"Asignando valor numérico {vals.get('value_numeric', 0):.2f} a {parameter.name} ({parameter.code})")
|
|
elif parameter.value_type == 'text':
|
|
vals['value_text'] = "Normal"
|
|
elif parameter.value_type == 'selection':
|
|
vals['value_selection'] = "normal"
|
|
elif parameter.value_type == 'boolean':
|
|
vals['value_boolean'] = False
|
|
|
|
# Escribir valores
|
|
if vals:
|
|
result.write(vals)
|
|
|
|
# Agregar notas si está fuera de rango
|
|
if result.is_out_of_range:
|
|
if result.is_critical:
|
|
result.notes = "Valor crítico. Se recomienda repetir el análisis y consultar con el médico de inmediato."
|
|
else:
|
|
result.notes = "Valor ligeramente alterado. Se sugiere control en 3 meses."
|
|
|
|
# Marcar resultados como ingresados
|
|
test.write({'state': 'result_entered'})
|
|
|
|
# Agregar comentarios a algunas pruebas
|
|
if test.product_id == hemograma:
|
|
test.notes = "Serie roja dentro de parámetros normales. Serie blanca con ligera leucocitosis."
|
|
elif test.product_id == perfil_lipidico:
|
|
test.notes = "Se recomienda dieta baja en grasas y control en 3 meses."
|
|
|
|
# Validar todas las pruebas
|
|
for test in order.lab_test_ids:
|
|
test.write({
|
|
'state': 'validated',
|
|
'validator_id': validator.id,
|
|
'validation_date': fields.Datetime.now()
|
|
})
|
|
|
|
_logger.info(f"Todas las pruebas validadas para orden {order.name}")
|
|
|
|
return order
|
|
|
|
|
|
def create_multiple_test_orders(env, count=3):
|
|
"""Crear múltiples órdenes con diferentes escenarios"""
|
|
orders = env['sale.order']
|
|
|
|
for i in range(count):
|
|
_logger.info(f"Creando orden {i+1} de {count}")
|
|
order = create_validated_lab_order(env)
|
|
orders |= order
|
|
|
|
# Variar las observaciones
|
|
if i == 1:
|
|
order.lab_notes = "Paciente diabético tipo 2. Control mensual de glucemia."
|
|
elif i == 2:
|
|
order.lab_notes = "Control post-operatorio. Paciente con antecedentes de anemia."
|
|
|
|
return orders
|
|
|
|
|
|
if __name__ == '__main__':
|
|
# Configuración
|
|
db_name = 'lims_demo'
|
|
|
|
# Conectar a Odoo
|
|
odoo.tools.config.parse_config(['--database', db_name])
|
|
|
|
# Obtener el registro de la base de datos
|
|
registry = odoo.registry(db_name)
|
|
|
|
# Crear cursor y environment
|
|
with registry.cursor() as cr:
|
|
env = odoo.api.Environment(cr, odoo.SUPERUSER_ID, {})
|
|
|
|
try:
|
|
# Crear órdenes con resultados validados
|
|
orders = create_multiple_test_orders(env, count=2)
|
|
|
|
# Confirmar cambios
|
|
cr.commit()
|
|
|
|
print(f"\n✅ Se crearon {len(orders)} órdenes de laboratorio con resultados validados:")
|
|
for order in orders:
|
|
print(f" - {order.name}: {order.partner_id.name}")
|
|
print(f" Pruebas: {', '.join(test.product_id.name for test in order.lab_test_ids)}")
|
|
|
|
print("\n📋 Ahora puedes probar el botón 'Imprimir Informe de Resultados' en estas órdenes.")
|
|
|
|
except Exception as e:
|
|
cr.rollback()
|
|
print(f"\n❌ Error: {str(e)}")
|
|
_logger.error(f"Error creando datos demo: {str(e)}", exc_info=True) |