Se adicionan diseño ToBe manejo de reactivos y muestras
This commit is contained in:
parent
f460ebee75
commit
fc558bcd0f
|
@ -138,6 +138,136 @@ En el diseño de este módulo se enfatiza la **reutilización de modelos y funci
|
|||
|
||||
- **Seguridad:** Se reutilizará el sistema de **Grupos y Accesos** de Odoo para asignar permisos a los roles (por ejemplo, grupo Lab Recepcionista, Lab Técnico, Lab Administrador), definiendo **reglas de registro** (Record Rules) para restringir qué datos ve o edita cada quien. Esto garantiza que los principios de seguridad y privacidad se mantengan consistentes con el resto de la plataforma.
|
||||
|
||||
# Extensión de modelos de inventario para muestras de pacientes y reactivos en Odoo
|
||||
|
||||
## Separar las **muestras** de pacientes de los **reactivos** en inventario
|
||||
|
||||
Para evitar que las **muestras clínicas** (de pacientes) se mezclen con los **reactivos e insumos** en los catálogos y reportes estándar de Odoo, conviene diferenciarlos a nivel de modelo de datos. La recomendación es **extender o personalizar los modelos de inventario** de forma que los reactivos se manejen como productos de inventario convencionales, mientras que las muestras de pacientes se gestionen aparte. Por ejemplo, todos los reactivos y materiales del laboratorio pueden darse de alta como **productos almacenables** en Odoo, organizados en **categorías** específicas (p. ej. _Reactivos Químicos_, _Material de Muestreo_, _Equipos de Protección_). De este modo se aprovechan las funcionalidades nativas de stock (control de lotes, fechas de caducidad, alertas de mínimos, etc.) para los reactivos, integrando completamente el módulo **Inventario** estándar.
|
||||
|
||||
En cambio, las **muestras de pacientes** no deberían ser productos normales en Odoo. Lo ideal es manejar las muestras con un modelo específico (por ejemplo, un modelo personalizado `lab.sample`) enlazado al inventario, en lugar de crearlas como productos almacenables. Esto garantiza que las muestras **no aparezcan en los listados de productos ni en las valoraciones de inventario** de la empresa. La documentación sugiere que integrar la solución con los módulos estándar (como Inventario) evita _“islas de información”_ y aprovecha una experiencia unificada. Siguiendo este principio, reutilizaremos componentes de Odoo (ubicaciones, movimientos, etc.) para las muestras, **pero marcándolas de forma que no contaminen los informes generales**. Por ejemplo, se puede añadir un campo o categoría que identifique un producto o registro como “Muestra” y ajustar las vistas/filtrados para excluirlos de los catálogos principales. Así mantenemos separados los dos ámbitos: reactivos (inventario corporativo) vs. muestras (trazabilidad de laboratorio).
|
||||
|
||||
## **Reportes** separados para reactivos vs. muestras
|
||||
|
||||
Para mantener informes y vistas separados, se pueden aplicar varias estrategias de configuración y desarrollo:
|
||||
|
||||
- **Categorías de producto o tipo personalizado:** Como se mencionó, los reactivos estarán categorizados (químicos, insumos, etc.), y podríamos tener una categoría especial para “Muestras” (o un flag booleano en el modelo) que permita filtrar. Los reportes estándar de inventario (existencias, valoraciones) pueden ser **filtrados por categoría** para excluir las muestras de pacientes. Por ejemplo, asegurarse de que los informes de stock valorado solo consideren categorías de reactivos y excluyan la categoría de muestras. De igual forma, en el catálogo de productos se puede aplicar un filtro por defecto para no mostrar los productos marcados como muestras, si es que se hubiesen modelado como productos.
|
||||
|
||||
- **Modelo separado con informes propios:** Si las muestras se gestionan en un modelo `lab.sample`, se pueden crear **vistas y reportes personalizados** para ellas. Por ejemplo, un listado de muestras con su estado, paciente y ubicación, o un informe PDF de trazabilidad de muestras. Esto mantiene la información de muestras aislada de los informes financieros de inventario de Odoo. Al mismo tiempo, los reactivos seguirán usando los informes estándar (ej. existencias por ubicación, movimientos de stock) sin interferencia de las muestras.
|
||||
|
||||
- **Uso de propiedad (consignación) para muestras:** Una técnica útil es aprovechar la funcionalidad de **stock en consignación** de Odoo. Consiste en asignar un **propietario (partner)** a las existencias que no son de la compañía. En este caso, las muestras podrían ingresar al inventario con el paciente como dueño. De ese modo, Odoo registrará que el producto está en una ubicación interna pero **no pertenece a la empresa**, por lo que _“no impactan la valoración de inventario”_. Esta configuración haría que las muestras no se incluyan en los reportes estándar de valor de inventario de la compañía, manteniéndolos separados. Odoo permite, por ejemplo, recibir stock indicando un propietario externo, de forma que queda en almacén solo para trazabilidad pero fuera de las existencias de la empresa. Con este enfoque avanzado, incluso si modelamos las muestras como productos (p. ej. un producto genérico “Muestra de laboratorio” con lotes para cada muestra individual), al tener dueño (el paciente) quedarían efectivamente fuera de los cómputos habituales de inventario. Los informes podrían segregarse agrupando por propietario (Odoo permite agrupar movimientos o existencias por el campo _Owner_). En resumen, las muestras serían **stock en depósito** del paciente, no parte del stock propio.
|
||||
|
||||
En cualquiera de los casos anteriores, es importante diseñar **reportes específicos** para el módulo de laboratorio. Por ejemplo, un informe interno que liste cuántas muestras están actualmente almacenadas (y en qué estado), separado del informe de existencias de reactivos. Esto cumple el requerimiento de mantener reportes separados: la gerencia de inventario verá solo reactivos en los informes estándar, mientras que el personal de laboratorio accederá a reportes de muestras a través de las vistas del módulo LIMS personalizado.
|
||||
|
||||
## Manejo de **ubicaciones físicas** de las muestras (almacenamiento)
|
||||
|
||||
Para gestionar dónde se ubican físicamente las muestras (congeladores, estantes, etc.) sin que esas ubicaciones interfieran con los almacenes de reactivos, se recomienda separar la jerarquía de **ubicaciones**. En Odoo, una _ubicación_ es un lugar específico dentro de un almacén (por ejemplo, “WH/Existencias/Zona A/Refrigerador 1”). Usando esta lógica, podemos crear ubicaciones dedicadas para muestras que no se usen para reactivos. Algunas sugerencias:
|
||||
|
||||
- **Almacén o rama de ubicaciones separada:** Una opción es definir un **almacén independiente** (o al menos una ubicación padre distinta) para las muestras. Por ejemplo, dentro de la compañía podría haber un almacén llamado “LAB Muestras” con ubicaciones internas como _Refrigerador 2/Estante 3_, etc. Alternativamente, si se mantiene un solo almacén, crear bajo éste una ubicación padre llamada “Muestras” y, dentro de ella, subdividir por cada refrigerador/estante necesario. De esta forma, todas las ubicaciones de muestras están agrupadas en una sección separada del almacén principal de reactivos. En los informes estándar de inventario, normalmente se puede filtrar por almacén o por ubicación parent; así se excluirían esas ubicaciones de muestras al generar reportes de stock de los almacenes de reactivos. Por ejemplo, _“Refrigerador 2 - Estante 3”_ podría configurarse bajo la rama de **Muestras** en vez de bajo **Existencias** de almacén general, evitando que aparezca como ubicación regular en informes de inventario de mercancías.
|
||||
|
||||
- **Marcar ubicaciones como especiales:** Al crear las ubicaciones físicas para muestras, podríamos activar ciertos indicadores para control interno. No existe un tipo de ubicación “de muestra” por defecto, pero podríamos aprovechar campos como _¿Es una ubicación de desecho?_ o crear un campo personalizado. No se recomienda marcar los congeladores de muestras directamente como “ubicación de desecho” en Odoo (ya que este tipo está pensado para pérdidas de inventario); en su lugar, un campo custom (ej. `is_sample_location=True`) ayudaría a identificarlas. Con ese flag, se puede ajustar vía código que dichas ubicaciones no aparezcan en menús o que se filtren fuera de los informes estándar. Otra alternativa es utilizar reglas de registro (record rules) para que solo ciertos grupos (p. ej. usuarios del laboratorio) vean esas ubicaciones.
|
||||
|
||||
- **Trazabilidad de movimientos y disposiciones:** Aunque las muestras no formen parte del inventario vendible, sí queremos saber dónde están y quién las movió. Se puede implementar un registro de movimientos de muestras parecido a los movimientos de stock. Por ejemplo, cada vez que una muestra cambia de ubicación (p. ej. de recepción a Refrigerador 2), registrar un movimiento interno (ya sea en un modelo propio o reutilizando `stock.move` con las adaptaciones mencionadas de propietario o producto genérico). El **historial de ubicaciones** de la muestra debe incluir fechas, responsable que realizó el traslado, y motivo si corresponde. Esto cumple con la trazabilidad requerida. Cuando una muestra se **desecha** al terminar su vida útil o análisis, podemos utilizar una ubicación especial de descarte. Odoo soporta mover productos a una ubicación marcada como _Pérdida de inventario_ (scrap) para indicar su eliminación. En el contexto de muestras, esto equivaldría a marcar la muestra como _desechada_ – ya sea moviéndola a una ubicación de desecho del laboratorio mediante un movimiento de stock (si fue modelada como producto) o simplemente actualizando un estado en el modelo de muestra. Lo importante es registrar la fecha de eliminación y el usuario que la realizó, para mantener la trazabilidad completa de la muestra desde su toma hasta su disposición final.
|
||||
|
||||
La estrategia propuesta es **mixta**:
|
||||
|
||||
| Capa | Objeto Odoo | Por qué | Cómo se usa |
|
||||
| --------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **Tipo de muestra** (sangre, orina, hisopo, etc.) | **`product.product` / `product.template`** (1 por tipo) | • Aprovecha UoM, impuestos = 0, coste = 0.<br>• Permite usar el flujo estándar de movimientos/ubicaciones.<br>• Se comporta como un “contenedor genérico” para todas las muestras de ese tipo. | • Categoría “LIMS / Muestras”.<br>• `can_be_sold=False`, `can_be_purchased=False`, `detailed_type='sample'` (campo custom).<br>• Invisible en catálogos generales mediante reglas de registro / propiedades `active=False` en vistas públicas. |
|
||||
| **Muestra física individual** (el tubo real del paciente) | **`stock.lot`** o modelo propio **`lab.sample`** ligado a ese producto | • Cada tubo necesita nº único, fechas (toma, análisis, descarte) y dueño (paciente).<br>• `stock.lot` ya trae código único, fecha de caducidad, owner y rastreo por ubicación. | • Al registrar la toma se crea un `stock.lot` (o `lab.sample`) y se mueve a la ubicación “LAB / Muestras / Recepción”.<br>• Se asigna `owner_id = paciente`. Así NO afecta valoraciones ni stock de la compañía.<br>• Estados y eventos adicionales (recogida, en análisis, desechada) se guardan en campos extra del lote o en el modelo `lab.sample`. |
|
||||
| **Reactivos e insumos** | `product.product` estándar | • Se compran, almacenan y valorizan. | Flujo normal de compras, lotes, caducidad, consumo automático al validar la prueba. |
|
||||
|
||||
### Ventajas del enfoque “tipo de muestra → producto genérico / muestra → lote”
|
||||
|
||||
1. **Trazabilidad completa**: `stock.lot` ya tiene campos de número de serie, fechas y propietario → basta añadir unos cuantos campos extras (`state`, `analysis_start`, `disposed_by`, etc.).
|
||||
2. **Zero impacto contable**: como el `owner` es el paciente, los lotes **no se incluyen** en valoraciones de inventario ni en reportes de existencias de la empresa.
|
||||
3. **Ubicaciones clínicas separadas**: todas bajo la rama “LAB / Muestras”, que puedes filtrar fuera de vistas y reportes financieros.
|
||||
4. **Reuso de reporting de trazabilidad**: el wizard “Rastrear lote/serial” funciona tal cual para ver dónde estuvo cada muestra.
|
||||
|
||||
### Ejemplo técnico rápido
|
||||
|
||||
```python
|
||||
# producto genérico "Muestra de sangre"
|
||||
<record id="product_sample_blood" model="product.template">
|
||||
<field name="name">Muestra - Sangre</field>
|
||||
<field name="detailed_type">sample</field> <!-- campo nuevo -->
|
||||
<field name="categ_id" ref="product_category_samples"/>
|
||||
<field name="sale_ok" eval="False"/>
|
||||
<field name="purchase_ok" eval="False"/>
|
||||
<field name="list_price" eval="0"/>
|
||||
</record>
|
||||
|
||||
# hook al confirmar orden de laboratorio
|
||||
def create_sample_lot(self):
|
||||
for test in self:
|
||||
product = test.sample_product_id # ej. producto "Muestra - Sangre"
|
||||
lot = self.env['stock.lot'].create({
|
||||
'name' : test.generate_barcode(),
|
||||
'product_id': product.id,
|
||||
'owner_id' : test.patient_id.id,
|
||||
'sample_state': 'collected', # campo personalizado
|
||||
'collection_datetime': fields.Datetime.now(),
|
||||
})
|
||||
# movimiento a ubicación recepción de muestras
|
||||
self.env['stock.move'].create({
|
||||
'product_id' : product.id,
|
||||
'lot_id' : lot.id,
|
||||
'quantity' : 1,
|
||||
'location_id' : lab_reception_loc.id,
|
||||
'location_dest_id': lab_analysis_loc.id,
|
||||
'owner_id' : test.patient_id.id,
|
||||
})._action_confirm()._action_done()
|
||||
```
|
||||
|
||||
### Qué ve cada área
|
||||
|
||||
| Área | Listado de productos | Reportes de stock | Vistas de muestras |
|
||||
| ---------------- | --------------------------------------------------------------------- | ------------------------------------------------ | ---------------------------------------------------------------------------- |
|
||||
| Compras / Bodega | Solo reactivos e insumos (filtrado por categoría ≠ “LIMS / Muestras”) | Existencias, valorización, rotación de reactivos | — |
|
||||
| Laboratorio | Opcionalmente ve tipo de muestra para referencia | Puede ignorar reportes de stock estándar | Vista kanban/list de `stock.lot` o `lab.sample`: estado, paciente, ubicación |
|
||||
|
||||
### Resumen
|
||||
|
||||
- **Reactivos** → producto almacenable normal.
|
||||
- **Tipos de muestra** → producto “especial” marcado como `detailed_type='sample'` (o categoría “Muestras”) para poder moverlos/ubicarlos.
|
||||
- **Muestra individual** → lote/serial (o modelo propio) con propietario = paciente, campos extra de estado y fechas.
|
||||
Así obtienes la **potencia del módulo de inventario** (códigos de barras, ubicaciones, historiales) sin contaminar catálogos ni reportes financieros, y mantienes trazabilidad por paciente y por ubicación tal como necesitas.
|
||||
|
||||
### Cómo manejar reactivos con **fecha de caducidad** en Odoo 18 (Community)
|
||||
|
||||
| Paso | Configuración / Buenas prácticas | Detalle técnico |
|
||||
| ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **1. Activar seguimiento por lote** | En cada reactivo, marca:<br>`Tipo de seguimiento ► Lotes` (Menú ⚙︎ Inventario → Productos → Reactivo → Pestaña Inventario). | Odoo creará un `stock.lot` por cada lote que compras; allí podrás almacenar la **fecha de caducidad**. |
|
||||
| **2. Registrar lote y caducidad al recibir** | Al validar la recepción del pedido al proveedor (PO) ‑ la pantalla pedirá _Lote_ y _Fecha de caducidad_. | Campos estándar `expiration_date`, `use_date` y `removal_date` del lote. |
|
||||
| **3. Aplicar regla **FEFO** (First‑Expire‑First‑Out)** | En **Almacén ⇒ Configuración ⇒ Ajustes ⇒ Ubicaciones & Inventario**, activa “Usar FEFO”. | Odoo propondrá para cada orden de consumo el lote con la fecha de **caducidad más próxima**, evitando usar reactivos viejos. |
|
||||
| **4. Alertas automáticas** | _Programar_ el «Scheduler de caducidad» (`stock.cron_products_expiration_alert`) para que corra diariamente.<br>Configura en Ajustes de Inventario los días de antelación para aviso (p. ej. 30 días). | Odoo enviará al grupo de inventario correos/notificaciones con lista de lotes que vencerán o ya vencieron. |
|
||||
| **5. Bloqueo o cuarentena de reactivos vencidos** | Dos alternativas: <br>• Mover el lote vencido a una ubicación “Reactivos Obsoletos” mediante picking interno.<br>• Marcar el lote con **“Bloqueado”** (campo `state`). | Puedes crear una _ubicación de desecho_ para scrap o una regla en el módulo **Quality** para mover/restar. |
|
||||
| **6. Consumo automático al validar una prueba** | En la **lista de materiales (BoM) del análisis** define qué reactivos consume (1 u de Reactivo X, 0.2 ml Reactivo Y, etc.). | Al confirmar la “orden de trabajo” (laboratory work order) el sistema:<br>• Reserva el lote con FEFO.<br>• Ejecuta el movimiento de salida y descuenta stock. |
|
||||
| **7. Reabastecimiento** | Configura **Punto de reorden** en cada reactivo (Cantidad mínima, máxima y múltiplo de compra). | Cuando el stock neto (sin vencidos) baja del mínimo, Odoo crea automáticamente **RFQ** al proveedor. |
|
||||
| **8. Auditoría y reportes** | • Informe “Inventario de lotes” para ver cantidad y expiración.<br>• Filtro “Caducado” en la vista de lotes.<br>• Histórico de movimientos para rastrear qué análisis usó cada lote. | Si integras el módulo **Quality**, puedes generar reportes de pruebas de control (p. ej. calibraciones) por lote. |
|
||||
| **9. UX para el laboratorio** | • Escáner de código de barras en el momento de consumo: el técnico escanea el lote, Odoo verifica que **no esté bloqueado** y lo asigna.<br>• Mensaje de validación: si el lote está vencido, el sistema bloquea el picking y muestra alerta. | Añade un `onchange` o `constraint` en el modelo de consumo para impedir validar movimientos con lotes expirados (`raise ValidationError`). |
|
||||
|
||||
#### Ejemplo de flujo de recepción
|
||||
|
||||
1. **Compra** 3 cajas de _Reactivo Hematología_ (lote “HEM‑2507” | caducidad 25‑Jul‑2026).
|
||||
2. En la validación del albarán de entrada:
|
||||
|
||||
- Ingresas cantidad 30 u, lote `HEM‑2507`, fecha caducidad `2026‑07‑25`.
|
||||
|
||||
3. El lote queda en **WH/Reactivos/Estantería A** con 30 u y caducidad registrada.
|
||||
4. Cada vez que una orden de laboratorio requiera 1 u de ese reactivo, el picking interno
|
||||
|
||||
- Filtra lotes por FEFO,
|
||||
- Reserva `HEM‑2507` hasta agotar existencias o hasta que otro lote caduque antes.
|
||||
|
||||
5. Cuando falten 5 días para la caducidad (o el rango configurado) el scheduler envía un correo “Lotes por caducar”.
|
||||
6. Si algún lote caduca antes de consumirse, se ejecuta un movimiento a **LAB/Reactivos Obsoletos** y se descarta (scrap).
|
||||
|
||||
> **Otros escenarios:** si usan varios reactivos con la misma referencia pero diferentes concentraciones, crearemos un **atributo de variante** (p. ej. “Concentración”) y se mantendran separados los lotes; FEFO seguirá funcionando por lote.
|
||||
|
||||
Con esta configuración los reactivos **participan plenamente del flujo de inventario**, mientras las muestras continúan aisladas gracias al esquema de “lote con propietario = paciente”. Así la trazabilidad, la gestión de caducidad y los reportes se mantienen limpios y separados.
|
||||
|
||||
# Conclusiones Diseño ToBe
|
||||
|
||||
En resumen, la filosofía de diseño es **no duplicar** lo que Odoo ya ofrece. Funciones como la gestión de usuarios, contactos, productos, ventas, stock, reportes PDF y portal ya existen y son sólidas, por lo que el módulo se enfocará en la lógica específica de laboratorio (órdenes, muestras, resultados y su trazabilidad), integrándose de forma nativa con las piezas estándar. Esto reduce el esfuerzo de desarrollo, aprovecha las actualizaciones futuras de Odoo y brinda una experiencia unificada al usuario final.
|
||||
|
||||
# Criterios de Aceptación, UX de Pruebas Dinámicas y Trazabilidad de Muestras
|
||||
|
@ -255,5 +385,3 @@ En resumen, una buena UX en este contexto implica: para la **entrada de datos**,
|
|||
## Conclusiones
|
||||
|
||||
Con las funcionalidades descritas, el módulo de gestión de laboratorios clínicos para Odoo 18 permitirá al laboratorio operar de manera eficiente, precisa y con alta calidad en sus procesos. Desde la **planificación de muestreos y gestión de todo el ciclo de vida de la muestra**, hasta la entrega final de resultados con trazabilidad completa, el sistema cubrirá las necesidades típicas de un laboratorio clínico moderno. La integración con módulos corporativos (ventas, inventario, etc.) asegurará que la solución sea **integral** y evite islas de información, mientras que la posibilidad de incorporar características adicionales (portal web, citas, calidad) brinda **escalabilidad y flexibilidad** para adaptarse a diferentes entornos de laboratorio. En definitiva, este documento de requerimientos servirá como base para el desarrollo de un módulo robusto que automatice tareas, minimice errores humanos y mejore la calidad y rapidez en la entrega de resultados a los pacientes y médicos.
|
||||
|
||||
**Referencias:** Las especificaciones anteriores se han alineado con funcionalidades comúnmente encontradas en sistemas LIMS comerciales y recomendaciones de la industria para la gestión de laboratorios clínicos, como la gestión de muestras, stock de reactivos, control de calidad y generación de informes personalizados, adaptándolas al contexto de Odoo 18 Community. Estas referencias respaldan la viabilidad y relevancia de los requerimientos propuestos.
|
||||
|
|
Loading…
Reference in New Issue
Block a user