
- Modelo lims.test con todos los campos especificados - Modelo lims.result con soporte para múltiples tipos de valor - Secuencia automática para códigos de prueba - Flujo de estados: draft -> in_process -> result_entered -> validated - Validación de un solo tipo de valor por resultado - Permisos de seguridad configurados
124 lines
3.6 KiB
Python
124 lines
3.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
from odoo import models, fields, api, _
|
|
from odoo.exceptions import ValidationError
|
|
import logging
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class LimsResult(models.Model):
|
|
_name = 'lims.result'
|
|
_description = 'Resultado de Prueba de Laboratorio'
|
|
_rec_name = 'display_name'
|
|
_order = 'test_id, sequence'
|
|
|
|
display_name = fields.Char(
|
|
string='Nombre',
|
|
compute='_compute_display_name',
|
|
store=True
|
|
)
|
|
|
|
test_id = fields.Many2one(
|
|
'lims.test',
|
|
string='Prueba',
|
|
required=True,
|
|
ondelete='cascade'
|
|
)
|
|
|
|
# Por ahora, estos campos básicos
|
|
parameter_name = fields.Char(
|
|
string='Parámetro',
|
|
required=True
|
|
)
|
|
|
|
sequence = fields.Integer(
|
|
string='Secuencia',
|
|
default=10
|
|
)
|
|
|
|
# TODO: Implementar parameter_id cuando exista lims.test.parameter
|
|
# parameter_id = fields.Many2one(
|
|
# 'lims.test.parameter',
|
|
# string='Parámetro'
|
|
# )
|
|
|
|
value_numeric = fields.Float(
|
|
string='Valor Numérico'
|
|
)
|
|
|
|
value_text = fields.Char(
|
|
string='Valor de Texto'
|
|
)
|
|
|
|
value_selection = fields.Selection(
|
|
[], # Por ahora vacío
|
|
string='Valor de Selección'
|
|
)
|
|
|
|
is_out_of_range = fields.Boolean(
|
|
string='Fuera de Rango',
|
|
compute='_compute_is_out_of_range',
|
|
store=True
|
|
)
|
|
|
|
notes = fields.Text(
|
|
string='Notas del Técnico'
|
|
)
|
|
|
|
# Campos para rangos normales (temporal)
|
|
normal_min = fields.Float(
|
|
string='Valor Normal Mínimo'
|
|
)
|
|
|
|
normal_max = fields.Float(
|
|
string='Valor Normal Máximo'
|
|
)
|
|
|
|
unit = fields.Char(
|
|
string='Unidad'
|
|
)
|
|
|
|
@api.depends('test_id', 'parameter_name')
|
|
def _compute_display_name(self):
|
|
"""Calcula el nombre a mostrar."""
|
|
for record in self:
|
|
if record.test_id and record.parameter_name:
|
|
record.display_name = f"{record.test_id.name} - {record.parameter_name}"
|
|
else:
|
|
record.display_name = record.parameter_name or _('Nuevo')
|
|
|
|
@api.depends('value_numeric', 'normal_min', 'normal_max')
|
|
def _compute_is_out_of_range(self):
|
|
"""Determina si el valor está fuera del rango normal."""
|
|
for record in self:
|
|
if record.value_numeric and (record.normal_min or record.normal_max):
|
|
if record.normal_min and record.value_numeric < record.normal_min:
|
|
record.is_out_of_range = True
|
|
elif record.normal_max and record.value_numeric > record.normal_max:
|
|
record.is_out_of_range = True
|
|
else:
|
|
record.is_out_of_range = False
|
|
else:
|
|
record.is_out_of_range = False
|
|
|
|
@api.constrains('value_numeric', 'value_text', 'value_selection')
|
|
def _check_single_value_type(self):
|
|
"""Asegura que solo un tipo de valor esté lleno."""
|
|
for record in self:
|
|
filled_values = 0
|
|
if record.value_numeric:
|
|
filled_values += 1
|
|
if record.value_text:
|
|
filled_values += 1
|
|
if record.value_selection:
|
|
filled_values += 1
|
|
|
|
if filled_values > 1:
|
|
raise ValidationError(
|
|
_('Solo se puede ingresar un tipo de valor (numérico, texto o selección) por resultado.')
|
|
)
|
|
|
|
if filled_values == 0:
|
|
raise ValidationError(
|
|
_('Debe ingresar al menos un valor para el resultado.')
|
|
) |