clinical_laboratory/lims_management/models/analysis_parameter.py
Luis Ernesto Portillo Zaldivar 98aba1c747 feat(#51): Task 1 completada - Crear modelo lims.analysis.parameter
- Creado modelo lims.analysis.parameter con campos: name, code, value_type, unit, etc.
- Implementadas validaciones y constraints
- Creadas vistas form, list y search
- Agregado menú en Configuración
- Configurados permisos de seguridad

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-15 11:10:13 -06:00

125 lines
4.2 KiB
Python

# -*- coding: utf-8 -*-
from odoo import models, fields, api
from odoo.exceptions import ValidationError
class LimsAnalysisParameter(models.Model):
_name = 'lims.analysis.parameter'
_description = 'Catálogo de Parámetros de Laboratorio'
_order = 'name'
_rec_name = 'name'
name = fields.Char(
string='Nombre',
required=True,
help='Nombre descriptivo del parámetro (ej: Hemoglobina)'
)
code = fields.Char(
string='Código',
required=True,
help='Código único del parámetro (ej: HGB)'
)
value_type = fields.Selection([
('numeric', 'Numérico'),
('text', 'Texto'),
('boolean', 'Sí/No'),
('selection', 'Selección')
],
string='Tipo de Valor',
required=True,
default='numeric',
help='Tipo de dato que acepta este parámetro'
)
unit = fields.Char(
string='Unidad de Medida',
help='Unidad de medida del parámetro (ej: g/dL, mg/dL, %)'
)
selection_values = fields.Text(
string='Valores de Selección',
help='Para tipo "Selección", ingrese los valores posibles separados por comas'
)
description = fields.Text(
string='Descripción',
help='Descripción detallada del parámetro y su significado clínico'
)
active = fields.Boolean(
string='Activo',
default=True,
help='Si está desmarcado, el parámetro no estará disponible para nuevas configuraciones'
)
# Relaciones - Se agregarán cuando se creen los modelos relacionados
# template_parameter_ids = fields.One2many(
# 'product.template.parameter',
# 'parameter_id',
# string='Análisis que usan este parámetro'
# )
# range_ids = fields.One2many(
# 'lims.parameter.range',
# 'parameter_id',
# string='Rangos de Referencia'
# )
@api.constrains('code')
def _check_code_unique(self):
for record in self:
if self.search_count([
('code', '=', record.code),
('id', '!=', record.id)
]) > 0:
raise ValidationError(f'El código "{record.code}" ya existe. Los códigos deben ser únicos.')
@api.constrains('value_type', 'selection_values')
def _check_selection_values(self):
for record in self:
if record.value_type == 'selection' and not record.selection_values:
raise ValidationError('Debe especificar los valores de selección para parámetros de tipo "Selección".')
@api.constrains('value_type', 'unit')
def _check_numeric_unit(self):
for record in self:
if record.value_type == 'numeric' and not record.unit:
raise ValidationError('Los parámetros numéricos deben tener una unidad de medida.')
def get_selection_list(self):
"""Devuelve la lista de valores de selección como una lista de Python"""
self.ensure_one()
if self.value_type == 'selection' and self.selection_values:
return [val.strip() for val in self.selection_values.split(',') if val.strip()]
return []
@api.model
def create(self, vals):
# Convertir código a mayúsculas
if 'code' in vals:
vals['code'] = vals['code'].upper()
return super(LimsAnalysisParameter, self).create(vals)
def write(self, vals):
# Convertir código a mayúsculas
if 'code' in vals:
vals['code'] = vals['code'].upper()
return super(LimsAnalysisParameter, self).write(vals)
def name_get(self):
result = []
for record in self:
name = f"[{record.code}] {record.name}"
if record.unit:
name += f" ({record.unit})"
result.append((record.id, name))
return result
@api.model
def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None):
args = args or []
if name:
args = ['|', ('code', operator, name), ('name', operator, name)] + args
return self._search(args, limit=limit, access_rights_uid=name_get_uid)