From 0eaaaef98dc496fba1ea86904a76d16adb44fd6c Mon Sep 17 00:00:00 2001 From: Luis Ernesto Portillo Zaldivar Date: Sun, 13 Jul 2025 23:45:32 -0600 Subject: [PATCH] =?UTF-8?q?feat(#5):=20Implementar=20cat=C3=A1logo=20de=20?= =?UTF-8?q?an=C3=A1lisis=20cl=C3=ADnicos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Se extiende el modelo product.template para incluir análisis. - Se crea el modelo para rangos de referencia (lims.analysis.range). - Se definen permisos de seguridad para el nuevo modelo. - Se crean las vistas de formulario y lista necesarias. - Se añade el menú 'Catálogo de Análisis' en Configuración. - Se actualiza la guía de desarrollo en GEMINI.md con las nuevas convenciones de Odoo 18. --- GEMINI.md | 73 ++++++++++++++++++ documents/plans/ISSUE5_PLAN.md | 61 ++++++++------- lims_management/__manifest__.py | 3 +- .../__pycache__/__init__.cpython-312.pyc | Bin 178 -> 178 bytes lims_management/models/__init__.py | 4 +- .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 253 bytes .../analysis_range.cpython-312.pyc | Bin 0 -> 1357 bytes .../__pycache__/partner.cpython-312.pyc | Bin 0 -> 2194 bytes .../__pycache__/product.cpython-312.pyc | Bin 0 -> 1230 bytes lims_management/models/analysis_range.py | 26 +++++++ lims_management/models/product.py | 28 +++++++ lims_management/security/ir.model.access.csv | 1 + lims_management/views/analysis_views.xml | 49 ++++++++++++ lims_management/views/menus.xml | 29 +++++++ 14 files changed, 242 insertions(+), 32 deletions(-) create mode 100644 lims_management/models/__pycache__/__init__.cpython-312.pyc create mode 100644 lims_management/models/__pycache__/analysis_range.cpython-312.pyc create mode 100644 lims_management/models/__pycache__/partner.cpython-312.pyc create mode 100644 lims_management/models/__pycache__/product.cpython-312.pyc create mode 100644 lims_management/models/analysis_range.py create mode 100644 lims_management/models/product.py create mode 100644 lims_management/views/analysis_views.xml 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 52b6a3e2af34465b7b5ec203af1f61b7abb0dacc..98b96b49daac6600d49f031f5b440a5b864d10c3 100644 GIT binary patch delta 19 ZcmdnQxQUVbG%qg~0}zPWmrUed4gf5!1Z@BS delta 19 ZcmdnQxQUVbG%qg~0}wpETQre-IRG?@1=aun 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 0000000000000000000000000000000000000000..ddb34cfc64fec65d95a91bc32b17e30edeeb4674 GIT binary patch literal 253 zcmXw!JB|V|42JE=Aka$C(QyE#Sf-&|?cRU`OcNp!u_GlJ?8FF+xH$t&01ffAMS%is>cRy9+FjgEak>R|_wF9Mw19ygI2q_rWHV}a$<#;P$>#*f8y-J?{P_4tKJxc+ zc>;lb@?*00VF97PRVO!d1WpzK>>z@O7NSV=v`F`K4e4kF5&bD51*$!=@=4=%58^5F zj19vzUn%J7(uz2tVJxjqKtmF@6`fli{JPk&}zZEh!L# zn8eyI?ioYYD`wi-Sd*hJBK9vDDUpf&$+HAYnfgMm8MnkCWzgwE#+!Vnu0pEkbWWz5 z9mmNLsqNSIU~kI2$~#q4=Ty~9)ySs2;mGtkRej@vdr{W!22s4kaJUf%@qNs?baOfc zY5|Y91)<3FIs{U~JZ=!$xKBG&P}UA`qlX1tx59&8S!3Ik0C3)!9M);-EfzS~91t{+GuNs=W8?!C&RMKg)Cf zBIAm6Y@_O>-I>#pQE~grFkYQ|*7<>b&vsXTTRN;P_E!d#%V*5Z!^#)^m806_Eo;Zw zc6RR_);{jv8NAg$nwj6~>^$Cn{D=G5;mnQi?un~;#;dL=4Nf>0>RTFKh1pVn(QsGq vD>hSK1N7RyF}&DC;X+qE+4vH;5#LZ*) literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..8282316dccbbeefd1d2127a7041286533e11e48a GIT binary patch literal 2194 zcmZ`)TWAzl7(R2^$!?Op#AIXATpZgJonkf=DQdA&G$u`J;;o2mka3)IvO8fe>zP?e zmI(VGG=fC~EwN9PJ{cm|=RTF%heBUAHR5ufgg%tMg(d~@ssEY1bZzQ^J#+qZzW;vN zU*qw11nYnw!Q^L^iT0Ymq-Wp-D_}JWOn#DRUOFvCkxPoSrFLqNLmLxUs)wYC2Cabj%6Hqq^ygzyKMB0xHcTcu}AGq4`Ly*r&U(%j5}KN zc7&+D-KZSGo!<#K4%mk7c!>Q!PZBK>6K}LI`I;w5oWfl>F`FV?^CP?UFQYjD@3|FS zuRmqGm(hZd?YW4wZq|N*_~#57xP+EEDDg9e265U~&l#pg+<<5TQ~ZEhZm!fnh2h4U zvrGefRK=tTn$Seb>ww9oS6F1qS!(5o%am!uEgE*|!f8Jss%ba{PqkbO{3@|kF9d-Y zTcsptff6qy3U$ruK{B6FYa$M*rwp1i)G608EyLC_np9KRhRK{!v;!vRiCrjlPY^S2 zaMNZ$io-qdG)WVg>=-s-v1!9Mi?-!@aHY(V@G?3<9OBmQB3_Uul*wnom|`1vH2Gu= z!s8Wrz91^oPu9SEub2YzjAarRtf^lbP~!asBj7r9s~#yr^`dKCFOt$*weP{*2(6gm z!fmy|)CjMwHba5QHKO{2s!x7^2zcN=OJmOrJgVE=44*Xg^w#yf{;Cyuahx&K5Y3Ht zLQi<8S|uA9vtFkFM@WVr@8#{EVEbBFMN7gsx-yB-O>s$_uXi0hH5V2dz32;f(r>_s z4Gb0T99Tm0ts3i+u+$Hy`Nl+O%7=cJ8{A7G7LUWrohcawN&^x!=g|`SaxVgl8+fSs z$P8<@e7&9nwr6)TN*xx>_yjWMnxr(`(iPAh|IMwYFeyg@CK2}r>vYLNpkG_mO&D`5 z;ui~qQeHw#F)1;ilVm3Q#GYfZ8;0#e-h8N9eq=FSH*LfBb=~I?S5>wA>hPH324f(S z8lwirp6id6mzY5#SGJ4T7^cNCi zfv`MYO?Ka1xV><{^I7uUhxl=REnhkE*|W@<>gfBAFRxwx-q{!(e?EGCWAuFG0)0B_ z-;*n8?YGo>TM^E`qo7p!tL%fGjpXP<>uK_6C3Y=R z8;e~eHZcRsgJ}aJ2SfA5Aj7rlXNlLlfTeW*x(x|(Vb~a!8~Bu07~2y@Qm+L|cVL`Y zVJKO=o*0wZwytXe-4Ae|*Zs%zZP>&7h8y?6{~5NIw@@`XSpMWi*S>qbtHUe94{mOD zeNg_i+COr?_uGMQ1}cXpe<7RwpI7AGYP@gx(%sqHv(@C@YO1dqH+I_Ogi@Z^YDc~M z?_FA*U74*M{Ae?MqC8WL4=rDM9v|9>L;mD_%2pI5`*vb-q95R$2(&4yiIv0ydoy*o zJXKAr4fYRzOmC(q%QIUFiro;ZQFALI^(hs(2b3tW=aGSp$iTKJM~-bvNEzJWC;Cpq zw;3pL*~6Yk`4|W@RSQ{Un*W)HuCJjQo(JSr^mr}ZC+HC%d8GUS*tR4=5dJ_T8)#%l S9u|&4Xa-jX|3+{Ong0O+ghhq` literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..6e5e283b4c089f4d4b136918a863dc43d4e98ec8 GIT binary patch literal 1230 zcmZuxJ8#rL5MKLyKId|WAtVqX9_AJ4gt!Q3Bg8|zghF_vy2e_(o4ZBp-NS1mE;K>n z2P8Cs3PFb;9sl4;8mKtALZU!)5gZK_v-UXw!4~$+H{Z;BJKpvCdcBHZ%{`4fb0vhn zXs1}^k@4d!80&~2VsI21Eh98rrh!a!1rhTJA|-0vvx}td_Zz6ESIg>Ijq*2bHq6ux zC81oU_7bC#AWf1#qWsB=%+=+j=!~vF(4h~^=gfJ>fVebNrHHhhFy+h zy1cWS1I>7ZB-2prlJXMaofrL=oGGTfi@d)fSRj*A5S+(RfFn;akE)n@qXH5Baa&sD_{6YbRMP~L6WfK)p)#IfYE-Aigv^=jevH!y_90*Eun>Lt4%dMoK~ge<^? z5>2TA5XrkNuc4vEAgF7`b`4P6d$x2+J8Rl(_Tjmh?y)I3yMfxyKr(+s)v|R3QZA7zG>MRI)I>e%v zx(_f36W@Zm9 zT5)(hK?C>j%GJ*k-s;SHbFDdW8-x0}VY#&1Ub(*MpsC}lmp@G&`#5>*JF3jsn>&zu zWaw6=j;_paP9X2Zvj;C8J%2QCPYg?@XMeEvL(blr)una0CI`-efipF5j}I%>Ui-)p4UHvT;c(ZX6!>?{c`5=uW&Xx0 + + + + + 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 +

+
+
+ + +