diff --git a/GEMINI.md b/GEMINI.md index 1c15ed2..2fd3ea5 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -140,3 +140,76 @@ Busca errores en la salida. Si encuentras alguno, debes presentar un resumen del - **Errores de sintaxis:** Problemas en archivos Python (`.py`) o XML (`.views`, `.xml`). - **Permisos incorrectos:** Problemas de acceso a archivos o directorios. - **Datos incorrectos:** Errores en los archivos de datos de demostración o iniciales. + +--- + +## Convenciones de Desarrollo en Odoo 18 + +Para evitar errores recurrentes, es **mandatorio** seguir las siguientes convenciones específicas para Odoo 18, especialmente en lo que respecta a la definición de vistas. + +### Uso de Vistas de Lista (Tree Views) + +En Odoo 18, la etiqueta `` ha sido **reemplazada por ``**. El uso de `` provocará un error de validación (`ValueError: Wrong value for ir.ui.view.type: 'tree'`). + +**Forma Incorrecta (Odoo < 18):** +```xml + + + + + + + +``` + +**Forma Correcta (Odoo 18):** +```xml + + + + + + + +``` + +### Definición de Acciones de Ventana (`view_mode`) + +Consecuente con el cambio anterior, al definir una acción de ventana (`ir.actions.act_window`) que deba mostrar una vista de lista, el `view_mode` debe ser `'list,form'` en lugar de `'tree,form'`. + +**Forma Incorrecta:** +```xml + + Ejemplo + example.model + tree,form + +``` + +**Forma Correcta:** +```xml + + Ejemplo + example.model + list,form + + +### Atributos de Visibilidad (`attrs`) + +A partir de Odoo 17, el atributo `attrs` para controlar la visibilidad de los elementos ha sido **reemplazado por el uso directo de `invisible`**. + +**Forma Incorrecta (Odoo < 17):** +```xml + +``` + +**Forma Correcta (Odoo 18):** +Se utiliza el atributo `invisible` con una expresión de dominio simplificada. La expresión se evalúa como verdadera para ocultar el campo. +```xml + +``` +O, de forma equivalente: +```xml + +``` +``` diff --git a/documents/plans/ISSUE5_PLAN.md b/documents/plans/ISSUE5_PLAN.md index 9d0ffdb..010c608 100644 --- a/documents/plans/ISSUE5_PLAN.md +++ b/documents/plans/ISSUE5_PLAN.md @@ -2,39 +2,40 @@ ## TODO -- [ ] **Extender el Modelo de Productos (`product.template`):** - - [ ] Crear `lims_management/models/product.py`. - - [ ] Heredar de `product.template`. - - [ ] Añadir campo booleano `is_analysis`. - - [ ] Añadir campo de selección `analysis_type`. - - [ ] Añadir campo de texto `technical_specifications`. - - [ ] Crear campo `value_range` (One2many) que enlace al nuevo modelo `lims.analysis.range`. +- [x] **Extender el Modelo de Productos (`product.template`):** + - [x] Crear `lims_management/models/product.py`. + - [x] Heredar de `product.template`. + - [x] Añadir campo booleano `is_analysis`. + - [x] Añadir campo de selección `analysis_type`. + - [x] Añadir campo de texto `technical_specifications`. + - [x] Crear campo `value_range` (One2many) que enlace al nuevo modelo `lims.analysis.range`. -- [ ] **Crear el Modelo para Rangos de Referencia (`lims.analysis.range`):** - - [ ] Crear `lims_management/models/analysis_range.py`. - - [ ] Definir campos: `analysis_id` (Many2one), `gender`, `age_min`, `age_max`, `min_value`, `max_value`, `unit_of_measure`. +- [x] **Crear el Modelo para Rangos de Referencia (`lims.analysis.range`):** + - [x] Crear `lims_management/models/analysis_range.py`. + - [x] Definir campos: `analysis_id` (Many2one), `gender`, `age_min`, `age_max`, `min_value`, `max_value`, `unit_of_measure`. -- [ ] **Definir Permisos de Seguridad:** - - [ ] Modificar `lims_management/security/ir.model.access.csv`. - - [ ] Añadir permisos para el modelo `lims.analysis.range`. +- [x] **Definir Permisos de Seguridad:** + - [x] Modificar `lims_management/security/ir.model.access.csv`. + - [x] Añadir permisos para el modelo `lims.analysis.range`. -- [ ] **Crear las Vistas para el Catálogo de Análisis:** - - [ ] Crear `lims_management/views/analysis_views.xml`. - - [ ] Crear vista de lista/Kanban para análisis clínicos. - - [ ] Heredar de la vista de formulario de productos para añadir la pestaña "Configuración de Análisis". - - [ ] Mostrar campos condicionalmente (`is_analysis = True`). - - [ ] Añadir tabla editable para `value_range`. +- [x] **Crear las Vistas para el Catálogo de Análisis:** + - [x] Crear `lims_management/views/analysis_views.xml`. + - [x] Crear vista de lista/Kanban para análisis clínicos. + - [x] Heredar de la vista de formulario de productos para añadir la pestaña "Configuración de Análisis". + - [x] Mostrar campos condicionalmente (`is_analysis = True`). + - [x] Crear una vista de árbol independiente para los rangos de referencia (`lims.analysis.range`). + - [x] En la vista de formulario del producto, referenciar la nueva vista de árbol para el campo `value_range_ids`. -- [ ] **Crear el Menú "Catálogo de Análisis":** - - [ ] Modificar `lims_management/views/menus.xml`. - - [ ] Crear una nueva acción de ventana (`ir.actions.act_window`). - - [ ] Crear un `menuitem` para "Catálogo de Análisis". +- [x] **Crear el Menú "Catálogo de Análisis":** + - [x] Modificar `lims_management/views/menus.xml`. + - [x] Crear una nueva acción de ventana (`ir.actions.act_window`). + - [x] Crear un `menuitem` para "Catálogo de Análisis". -- [ ] **Actualizar el Manifiesto (`__manifest__.py`):** - - [ ] Añadir los nuevos modelos al `__init__.py` de la carpeta `models`. - - [ ] Añadir el nuevo archivo de vistas a la lista `data` en `__manifest__.py`. +- [x] **Actualizar el Manifiesto (`__manifest__.py`):** + - [x] Añadir los nuevos modelos al `__init__.py` de la carpeta `models`. + - [x] Añadir el nuevo archivo de vistas a la lista `data` en `__manifest__.py`. -- [ ] **Verificación Final:** - - [ ] Reiniciar la instancia de Odoo (`docker-compose down -v` y `docker-compose up -d`). - - [ ] Revisar logs de `odoo_init`. - - [ ] Verificar la funcionalidad en la interfaz de Odoo. +- [x] **Verificación Final:** + - [x] Reiniciar la instancia de Odoo (`docker-compose down -v` y `docker-compose up -d`). + - [x] Revisar logs de `odoo_init`. + - [x] Verificar la funcionalidad en la interfaz de Odoo. diff --git a/lims_management/__manifest__.py b/lims_management/__manifest__.py index a4a94ac..f02d487 100644 --- a/lims_management/__manifest__.py +++ b/lims_management/__manifest__.py @@ -16,12 +16,13 @@ 'website': "https://gitea.grupoconsiti.com/luis_portillo/clinical_laboratory", 'category': 'Industries', 'version': '18.0.1.0.0', - 'depends': ['base'], + 'depends': ['base', 'product'], 'data': [ 'security/lims_security.xml', 'security/ir.model.access.csv', 'data/ir_sequence.xml', 'views/partner_views.xml', + 'views/analysis_views.xml', 'views/menus.xml', ], 'demo': [ diff --git a/lims_management/__pycache__/__init__.cpython-312.pyc b/lims_management/__pycache__/__init__.cpython-312.pyc index 52b6a3e..98b96b4 100644 Binary files a/lims_management/__pycache__/__init__.cpython-312.pyc and b/lims_management/__pycache__/__init__.cpython-312.pyc differ diff --git a/lims_management/models/__init__.py b/lims_management/models/__init__.py index 1d3c2e9..cdf3ffc 100644 --- a/lims_management/models/__init__.py +++ b/lims_management/models/__init__.py @@ -1,2 +1,4 @@ # -*- coding: utf-8 -*- -from . import partner \ No newline at end of file +from . import partner +from . import product +from . import analysis_range \ No newline at end of file diff --git a/lims_management/models/__pycache__/__init__.cpython-312.pyc b/lims_management/models/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000..ddb34cf Binary files /dev/null and b/lims_management/models/__pycache__/__init__.cpython-312.pyc differ diff --git a/lims_management/models/__pycache__/analysis_range.cpython-312.pyc b/lims_management/models/__pycache__/analysis_range.cpython-312.pyc new file mode 100644 index 0000000..dc8ed33 Binary files /dev/null and b/lims_management/models/__pycache__/analysis_range.cpython-312.pyc differ diff --git a/lims_management/models/__pycache__/partner.cpython-312.pyc b/lims_management/models/__pycache__/partner.cpython-312.pyc new file mode 100644 index 0000000..8282316 Binary files /dev/null and b/lims_management/models/__pycache__/partner.cpython-312.pyc differ diff --git a/lims_management/models/__pycache__/product.cpython-312.pyc b/lims_management/models/__pycache__/product.cpython-312.pyc new file mode 100644 index 0000000..6e5e283 Binary files /dev/null and b/lims_management/models/__pycache__/product.cpython-312.pyc differ diff --git a/lims_management/models/analysis_range.py b/lims_management/models/analysis_range.py new file mode 100644 index 0000000..c527226 --- /dev/null +++ b/lims_management/models/analysis_range.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +from odoo import models, fields + +class LimsAnalysisRange(models.Model): + _name = 'lims.analysis.range' + _description = 'Rangos de Referencia para Análisis Clínicos' + + analysis_id = fields.Many2one( + 'product.template', + string="Análisis", + required=True, + ondelete='cascade' + ) + gender = fields.Selection([ + ('male', 'Masculino'), + ('female', 'Femenino'), + ('both', 'Ambos') + ], string="Género", default='both') + + age_min = fields.Integer(string="Edad Mínima", default=0) + age_max = fields.Integer(string="Edad Máxima", default=99) + + min_value = fields.Float(string="Valor Mínimo") + max_value = fields.Float(string="Valor Máximo") + + unit_of_measure = fields.Char(string="Unidad de Medida") diff --git a/lims_management/models/product.py b/lims_management/models/product.py new file mode 100644 index 0000000..248a0d4 --- /dev/null +++ b/lims_management/models/product.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +from odoo import models, fields + +class ProductTemplate(models.Model): + _inherit = 'product.template' + + is_analysis = fields.Boolean( + string="Es un Análisis Clínico", + help="Marcar si este producto es un análisis clínico." + ) + analysis_type = fields.Selection([ + ('hematology', 'Hematología'), + ('chemistry', 'Química Clínica'), + ('microbiology', 'Microbiología'), + ('immunology', 'Inmunología'), + ('endocrinology', 'Endocrinología'), + ('other', 'Otro') + ], string="Tipo de Análisis") + + technical_specifications = fields.Text( + string="Especificaciones Técnicas" + ) + + value_range_ids = fields.One2many( + 'lims.analysis.range', + 'analysis_id', + string="Rangos de Referencia" + ) diff --git a/lims_management/security/ir.model.access.csv b/lims_management/security/ir.model.access.csv index 97dd8b9..c12dc28 100644 --- a/lims_management/security/ir.model.access.csv +++ b/lims_management/security/ir.model.access.csv @@ -1 +1,2 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_lims_analysis_range_user,lims.analysis.range.user,model_lims_analysis_range,base.group_user,1,1,1,1 diff --git a/lims_management/views/analysis_views.xml b/lims_management/views/analysis_views.xml new file mode 100644 index 0000000..93584a6 --- /dev/null +++ b/lims_management/views/analysis_views.xml @@ -0,0 +1,49 @@ + + + + + + lims.analysis.range.tree + lims.analysis.range + + + + + + + + + + + + + + + product.template.form.lims + product.template + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lims_management/views/menus.xml b/lims_management/views/menus.xml index f6229ec..6d89bba 100644 --- a/lims_management/views/menus.xml +++ b/lims_management/views/menus.xml @@ -52,5 +52,34 @@ parent="lims_menu_root" action="action_lims_doctor" sequence="30"/> + + + + + + + Catálogo de Análisis + product.template + list,form + [('is_analysis', '=', True)] + {'default_is_analysis': True} + +

+ Crea un nuevo análisis clínico +

+
+
+ + +