diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 697b9cf..f9f6276 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -19,7 +19,9 @@ "Bash(move lab_logo.png lims_management/static/img/lab_logo.png)", "WebFetch(domain:github.com)", "WebFetch(domain:apps.odoo.com)", - "Bash(dir:*)" + "Bash(dir:*)", + "Bash(find:*)", + "Bash(true)" ], "deny": [] } diff --git a/lims_management/__manifest__.py b/lims_management/__manifest__.py index 3aecd8d..761494f 100644 --- a/lims_management/__manifest__.py +++ b/lims_management/__manifest__.py @@ -36,6 +36,7 @@ 'views/lims_test_views.xml', 'views/res_config_settings_views.xml', 'views/menus.xml', + 'views/analysis_parameter_views.xml', ], 'demo': [ 'demo/z_lims_demo.xml', diff --git a/lims_management/models/__init__.py b/lims_management/models/__init__.py index 78eb9f2..4e5f5d0 100644 --- a/lims_management/models/__init__.py +++ b/lims_management/models/__init__.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from . import analysis_parameter from . import analysis_range from . import product from . import partner diff --git a/lims_management/models/__pycache__/__init__.cpython-312.pyc b/lims_management/models/__pycache__/__init__.cpython-312.pyc index a1e9030..e5d6de6 100644 Binary files a/lims_management/models/__pycache__/__init__.cpython-312.pyc and b/lims_management/models/__pycache__/__init__.cpython-312.pyc differ diff --git a/lims_management/models/analysis_parameter.py b/lims_management/models/analysis_parameter.py new file mode 100644 index 0000000..e469789 --- /dev/null +++ b/lims_management/models/analysis_parameter.py @@ -0,0 +1,125 @@ +# -*- 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) \ No newline at end of file diff --git a/lims_management/security/ir.model.access.csv b/lims_management/security/ir.model.access.csv index b2d9cb9..41f33a9 100644 --- a/lims_management/security/ir.model.access.csv +++ b/lims_management/security/ir.model.access.csv @@ -1,4 +1,6 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_lims_analysis_parameter_user,lims.analysis.parameter.user,model_lims_analysis_parameter,base.group_user,1,0,0,0 +access_lims_analysis_parameter_manager,lims.analysis.parameter.manager,model_lims_analysis_parameter,group_lims_admin,1,1,1,1 access_lims_analysis_range_user,lims.analysis.range.user,model_lims_analysis_range,base.group_user,1,1,1,1 access_sale_order_receptionist,sale.order.receptionist,sale.model_sale_order,group_lims_receptionist,1,1,1,0 access_stock_lot_user,stock.lot.user,stock.model_stock_lot,base.group_user,1,1,1,1 diff --git a/lims_management/views/analysis_parameter_views.xml b/lims_management/views/analysis_parameter_views.xml new file mode 100644 index 0000000..3eb8f09 --- /dev/null +++ b/lims_management/views/analysis_parameter_views.xml @@ -0,0 +1,110 @@ + + + + + lims.analysis.parameter.form + lims.analysis.parameter + +
+ +
+ +
+ +
+

+ +

+

+ +

+
+ + + + + + + + + + + + +
+
+
+
+ + + + lims.analysis.parameter.list + lims.analysis.parameter + + + + + + + + + + + + + + lims.analysis.parameter.search + lims.analysis.parameter + + + + + + + + + + + + + + + + + + + + + + Parámetros de Análisis + lims.analysis.parameter + list,form + + {'search_default_active': 1} + +

+ Crear nuevo parámetro +

+

+ Los parámetros definen qué valores se pueden registrar en los análisis de laboratorio. + Cada parámetro tiene un tipo de dato, unidad de medida y rangos de referencia. +

+
+
+ + + +
\ No newline at end of file