feat(#7): Implementar feedback de gestion de muestras

- Anadido catalogo de Tipos de Muestra.
- Mejorada la vista de Muestras para seleccionar el tipo.
- Creados datos de demostracion para tipos de muestra y muestras.
This commit is contained in:
Luis Ernesto Portillo Zaldivar 2025-07-14 09:09:24 -06:00
parent 25841b75f3
commit a047cd1a02
8 changed files with 123 additions and 56 deletions

View File

@ -6,45 +6,56 @@ Extender el modelo de Lotes/Números de Serie de Odoo (`stock.lot`) para represe
## TODO
- [ ] **Extender el Modelo de Lote/Número de Serie (`stock.lot`):**
- [ ] Crear el archivo `lims_management/models/stock_lot.py`.
- [ ] Heredar del modelo `stock.lot`.
- [ ] Añadir un campo booleano `is_lab_sample` para identificar los registros que son muestras de laboratorio.
- [ ] Añadir un campo `patient_id` (Many2one a `res.partner`) para vincular la muestra al paciente.
- [ ] Añadir un campo `request_id` (Many2one a `sale.order`) para vincular la muestra a la solicitud de laboratorio correspondiente.
- [ ] Añadir un campo `collection_date` (Datetime) para registrar la fecha y hora de la toma de la muestra.
- [ ] Añadir un campo `container_type` (Selection) para el tipo de recipiente (ej. 'Tubo de suero', 'Tubo EDTA', 'Hisopo', 'Orina').
- [x] **Extender el Modelo de Lote/Número de Serie (`stock.lot`):**
- [x] Crear el archivo `lims_management/models/stock_lot.py`.
- [x] Heredar del modelo `stock.lot`.
- [x] Añadir campos: `is_lab_sample`, `patient_id`, `request_id`, `collection_date`, `container_type`.
- [ ] **Adaptar las Vistas de Lote/Número de Serie:**
- [ ] Crear el archivo `lims_management/views/stock_lot_views.xml`.
- [ ] Crear una nueva vista de lista (`list`) para las muestras, mostrando campos clave como el número de muestra (`name`), paciente, fecha de recolección y tipo de recipiente.
- [ ] Crear una nueva vista de formulario (`form`) para el registro de muestras, incluyendo todos los campos nuevos.
- [ ] Asegurarse de que el campo `product_id` (requerido por `stock.lot`) se gestione adecuadamente. Se puede crear un producto de servicio genérico llamado "Muestra de Laboratorio" y asignarlo por defecto.
- [x] **Adaptar las Vistas de Lote/Número de Serie:**
- [x] Crear el archivo `lims_management/views/stock_lot_views.xml`.
- [x] Crear vistas de lista y formulario para las muestras.
- [x] Crear un producto de servicio por defecto para las muestras.
- [ ] **Crear el Menú "Gestión de Muestras":**
- [ ] Modificar `lims_management/views/menus.xml`.
- [ ] Crear una nueva acción de ventana (`ir.actions.act_window`) para el modelo `stock.lot`.
- [ ] Establecer un dominio en la acción para mostrar solo los registros que son muestras de laboratorio (`is_lab_sample = True`).
- [ ] En el `context` de la acción, establecer `default_is_lab_sample = True` y, si se decide, el `default_product_id`.
- [ ] Crear un `menuitem` para "Muestras" o "Gestión de Muestras" dentro del menú principal del LIMS.
- [x] **Crear el Menú "Gestión de Muestras":**
- [x] Modificar `lims_management/views/menus.xml`.
- [x] Crear acción de ventana y `menuitem` para `stock.lot` con el dominio y contexto adecuados.
- [ ] **Establecer Permisos y Reglas de Dominio:**
- [ ] Modificar `lims_management/security/ir.model.access.csv` para asegurar que los usuarios del LIMS tengan permisos para crear, leer, escribir y eliminar registros en `stock.lot`.
- [ ] Aplicar un dominio al campo `patient_id` en la vista de muestra para que solo muestre contactos que estén marcados como pacientes.
- [x] **Establecer Permisos y Reglas de Dominio:**
- [x] Modificar `lims_management/security/ir.model.access.csv` para dar permisos sobre `stock.lot`.
- [x] Añadir dominios en las vistas para los campos relacionales.
- [ ] **Actualizar el Manifiesto (`__manifest__.py`):**
- [ ] Añadir el nuevo archivo de modelo (`stock_lot.py`) al `__init__.py` correspondiente.
- [ ] Añadir el nuevo archivo de vistas (`stock_lot_views.xml`) a la clave `data` en `__manifest__.py`.
- [x] **Actualizar el Manifiesto (`__manifest__.py`):**
- [x] Añadir nuevos archivos de modelos, vistas y datos al manifiesto.
- [ ] **Verificación Final:**
- [ ] Reiniciar la instancia de Odoo (`docker-compose down -v` y `docker-compose up -d`).
- [ ] Revisar los logs de `odoo_init` en busca de errores de instalación o actualización.
- [ ] Verificar la funcionalidad en la interfaz de Odoo:
- Navegar al nuevo menú "Muestras".
- Crear una nueva muestra, asociarla a un paciente y (si la funcionalidad de solicitud ya existiera) a una solicitud.
- Confirmar que la lista de muestras solo muestra los registros correctos.
- [x] **Verificación Final:**
- [x] Reiniciar y verificar la instancia de Odoo.
- [ ] **(Opcional) Crear Datos de Demostración:**
- [ ] Crear un archivo `demo/z_sample_demo.xml`.
- [ ] Definir al menos dos muestras de ejemplo, vinculadas a los pacientes de demostración.
- [ ] Añadir el archivo a la clave `demo` en `__manifest__.py`.
---
## **Nuevas Tareas (Feedback)**
- [ ] **Mejorar Modelo de Productos para Tipos de Muestra:**
- [ ] Añadir un campo booleano `is_sample_type` al modelo `product.template` en `lims_management/models/product.py`.
- [ ] **Crear Menú para "Tipos de Muestra":**
- [ ] En `lims_management/views/menus.xml`, añadir una nueva acción de ventana y un `menuitem` en "Configuración".
- [ ] La acción debe mostrar los productos que tengan `is_sample_type = True`.
- [ ] El `context` de la acción debe preestablecer `default_is_sample_type = True` y `default_type = 'service'`.
- [ ] **Actualizar Vista de Muestras (`stock.lot`):**
- [ ] En `lims_management/views/stock_lot_views.xml`, hacer visible el campo `product_id` (Tipo de Muestra).
- [ ] Aplicar un dominio al campo `product_id` para que solo muestre productos con `is_sample_type = True`.
- [ ] Eliminar el `default_product_id` del contexto de la acción de la muestra.
- [ ] Eliminar el producto genérico "Lab Sample" del archivo de datos.
- [ ] **Crear Datos de Demostración:**
- [ ] Crear el archivo `lims_management/demo/z_sample_demo.xml`.
- [ ] Añadir registros de `product.template` para diferentes tipos de muestra (ej. "Tubo de Suero", "Tubo EDTA").
- [ ] Añadir registros de `stock.lot` que representen muestras reales, usando los pacientes y los nuevos tipos de muestra de demostración.
- [ ] Añadir el nuevo archivo de demostración al `__manifest__.py`.
- [ ] **Verificación Final (con Demo):**
- [ ] Reactivar temporalmente la carga de datos de demostración en `init_odoo.py`.
- [ ] Reiniciar la instancia (`docker-compose down -v` y `docker-compose up -d`).
- [ ] Revisar logs y verificar la funcionalidad completa en la interfaz de Odoo.
- [ ] Desactivar nuevamente la carga de datos de demostración al finalizar.

View File

@ -22,7 +22,6 @@
'security/ir.model.access.csv',
'data/ir_sequence.xml',
'data/product_category.xml',
'data/product_data.xml',
'views/partner_views.xml',
'views/analysis_views.xml',
'views/sale_order_views.xml',
@ -32,6 +31,7 @@
'demo': [
'demo/z_lims_demo.xml',
'demo/z_analysis_demo.xml',
'demo/z_sample_demo.xml',
],
'installable': True,
'application': True,

View File

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="product_lab_sample" model="product.product">
<field name="name">Lab Sample</field>
<field name="type">service</field>
<field name="invoice_policy">order</field>
<field name="purchase_ok" eval="False"/>
<field name="sale_ok" eval="False"/>
<field name="default_code">LAB-SAMPLE</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!-- Tipos de Muestra (Productos) -->
<record id="sample_type_serum" model="product.template">
<field name="name">Tubo de Suero (Tapa Roja)</field>
<field name="is_sample_type" eval="True"/>
<field name="type">service</field>
</record>
<record id="sample_type_edta" model="product.template">
<field name="name">Tubo EDTA (Tapa Morada)</field>
<field name="is_sample_type" eval="True"/>
<field name="type">service</field>
</record>
<record id="sample_type_urine" model="product.template">
<field name="name">Contenedor de Orina</field>
<field name="is_sample_type" eval="True"/>
<field name="type">service</field>
</record>
<!-- Muestras de Laboratorio (Lotes) -->
<record id="lab_sample_01" model="stock.lot">
<field name="name">SAM-2025-00001</field>
<field name="product_id" model="product.product" eval="obj().env.ref('lims_management.sample_type_serum').product_variant_id.id"/>
<field name="is_lab_sample" eval="True"/>
<field name="patient_id" ref="lims_management.demo_patient_1"/>
<field name="collection_date" eval="(DateTime.now() - timedelta(days=2)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="container_type">serum_tube</field>
</record>
<record id="lab_sample_02" model="stock.lot">
<field name="name">SAM-2025-00002</field>
<field name="product_id" model="product.product" eval="obj().env.ref('lims_management.sample_type_edta').product_variant_id.id"/>
<field name="is_lab_sample" eval="True"/>
<field name="patient_id" ref="lims_management.demo_patient_2"/>
<field name="collection_date" eval="(DateTime.now() - timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="container_type">edta_tube</field>
</record>
</data>
</odoo>

View File

@ -26,3 +26,8 @@ class ProductTemplate(models.Model):
'analysis_id',
string="Rangos de Referencia"
)
is_sample_type = fields.Boolean(
string="Is a Sample Type",
help="Check if this product represents a type of laboratory sample container."
)

View File

@ -85,8 +85,7 @@
(0, 0, {'view_mode': 'form', 'view_id': ref('view_lab_sample_form')})]"/>
<field name="domain">[('is_lab_sample', '=', True)]</field>
<field name="context" eval="{
'default_is_lab_sample': True,
'default_product_id': ref('lims_management.product_lab_sample')
'default_is_lab_sample': True
}"/>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
@ -136,5 +135,30 @@
parent="lims_menu_config"
action="action_lims_analysis_catalog"
sequence="10"/>
<!-- Acción de Ventana para Tipos de Muestra -->
<record id="action_lims_sample_type_catalog" model="ir.actions.act_window">
<field name="name">Tipos de Muestra</field>
<field name="res_model">product.template</field>
<field name="view_mode">kanban,form</field>
<field name="domain">[('is_sample_type', '=', True)]</field>
<field name="context" eval="{
'default_is_sample_type': True,
'default_type': 'service'
}"/>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Crea un nuevo tipo de muestra
</p>
</field>
</record>
<!-- Menú para Tipos de Muestra -->
<menuitem
id="lims_menu_sample_type_catalog"
name="Tipos de Muestra"
parent="lims_menu_config"
action="action_lims_sample_type_catalog"
sequence="20"/>
</data>
</odoo>

View File

@ -10,9 +10,9 @@
<list string="Lab Samples">
<field name="name"/>
<field name="patient_id"/>
<field name="product_id" string="Sample Type"/>
<field name="collection_date"/>
<field name="container_type"/>
<field name="product_id" invisible="1"/>
</list>
</field>
</record>
@ -33,7 +33,10 @@
<group>
<field name="patient_id"/>
<field name="request_id"/>
<field name="product_id" invisible="1"/>
<field name="product_id"
string="Sample Type"
domain="[('is_sample_type', '=', True)]"
options="{'no_create': True, 'no_create_edit': True}"/>
</group>
<group>
<field name="collection_date"/>