feat(#32): Create verification script - Task 7 completed
- Comprehensive verification script for automatic sample generation - Tests existing orders with generated samples - Creates and tests new order with sample generation - Verifies barcode uniqueness across all samples - Checks for analyses without sample types - Provides detailed summary and issue reporting - Successful test with ephemeral instance restart
This commit is contained in:
parent
f3443619ce
commit
97cdc368d0
|
@ -70,12 +70,12 @@ Automatizar la generación de muestras cuando se confirman órdenes de laborator
|
|||
- [x] Agregar validación de duplicados
|
||||
- [x] Considerar prefijos por tipo de muestra
|
||||
|
||||
### 4. Actualizar vistas de sale.order
|
||||
### 4. Actualizar vistas de sale.order ✅
|
||||
**Archivo:** `lims_management/views/sale_order_views.xml`
|
||||
- [ ] Agregar pestaña "Muestras Generadas" en formulario de orden
|
||||
- [ ] Mostrar campo `generated_sample_ids` con vista de lista embebida
|
||||
- [ ] Agregar botón para regenerar muestras (si es necesario)
|
||||
- [ ] Incluir indicadores visuales del estado de generación
|
||||
- [x] Agregar pestaña "Muestras Generadas" en formulario de orden
|
||||
- [x] Mostrar campo `generated_sample_ids` con vista de lista embebida
|
||||
- [x] Agregar botón para regenerar muestras (si es necesario)
|
||||
- [x] Incluir indicadores visuales del estado de generación
|
||||
|
||||
### 5. Crear wizard de configuración (opcional)
|
||||
**Archivos:**
|
||||
|
@ -85,13 +85,13 @@ Automatizar la generación de muestras cuando se confirman órdenes de laborator
|
|||
- [ ] Permitir ajustes manuales de agrupación si es necesario
|
||||
- [ ] Opción para excluir ciertos análisis de la generación automática
|
||||
|
||||
### 6. Notificaciones y alertas
|
||||
### 6. Notificaciones y alertas ✅
|
||||
**Archivo:** `lims_management/models/sale_order.py`
|
||||
- [ ] Implementar sistema de notificaciones:
|
||||
- [x] Implementar sistema de notificaciones:
|
||||
- Análisis sin tipo de muestra definido
|
||||
- Muestras generadas exitosamente
|
||||
- Errores en la generación
|
||||
- [ ] Usar el sistema de mensajería de Odoo (`mail.thread`)
|
||||
- [x] Usar el sistema de mensajería de Odoo (`mail.thread`)
|
||||
|
||||
### 7. Pruebas y validación
|
||||
**Archivo:** `verify_automatic_sample_generation.py`
|
||||
|
|
Binary file not shown.
206
verify_automatic_sample_generation.py
Normal file
206
verify_automatic_sample_generation.py
Normal file
|
@ -0,0 +1,206 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Verification script for automatic sample generation in LIMS
|
||||
This script tests the automatic generation of samples when lab orders are confirmed.
|
||||
"""
|
||||
|
||||
import odoo
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
def verify_automatic_sample_generation(cr):
|
||||
"""Verify automatic sample generation functionality"""
|
||||
env = odoo.api.Environment(cr, odoo.SUPERUSER_ID, {})
|
||||
|
||||
print("\n" + "="*60)
|
||||
print("AUTOMATIC SAMPLE GENERATION VERIFICATION")
|
||||
print("="*60)
|
||||
print(f"Execution time: {datetime.now()}")
|
||||
print("="*60 + "\n")
|
||||
|
||||
# 1. Check existing lab orders with generated samples
|
||||
print("1. EXISTING LAB ORDERS WITH GENERATED SAMPLES:")
|
||||
print("-" * 60)
|
||||
|
||||
lab_orders = env['sale.order'].search([
|
||||
('is_lab_request', '=', True),
|
||||
('state', '=', 'sale')
|
||||
])
|
||||
|
||||
if not lab_orders:
|
||||
print("No confirmed lab orders found.")
|
||||
else:
|
||||
for order in lab_orders:
|
||||
print(f"\nOrder: {order.name}")
|
||||
print(f" Patient: {order.partner_id.name}")
|
||||
print(f" Doctor: {order.doctor_id.name if order.doctor_id else 'None'}")
|
||||
print(f" Generated Samples: {len(order.generated_sample_ids)}")
|
||||
|
||||
if order.generated_sample_ids:
|
||||
for sample in order.generated_sample_ids:
|
||||
print(f" - {sample.name} | Barcode: {sample.barcode}")
|
||||
print(f" Type: {sample.sample_type_product_id.name if sample.sample_type_product_id else 'None'}")
|
||||
print(f" Volume: {sample.volume_ml} ml")
|
||||
print(f" Analyses: {sample.analysis_names}")
|
||||
print(f" State: {sample.state}")
|
||||
|
||||
# 2. Test sample generation with a new order
|
||||
print("\n2. TESTING NEW SAMPLE GENERATION:")
|
||||
print("-" * 60)
|
||||
|
||||
try:
|
||||
# Get test data
|
||||
patient = env.ref('lims_management.demo_patient_1', raise_if_not_found=False)
|
||||
doctor = env.ref('lims_management.demo_doctor_1', raise_if_not_found=False)
|
||||
|
||||
if not patient:
|
||||
print("ERROR: Demo patient not found. Cannot proceed with test.")
|
||||
return
|
||||
|
||||
# Get some analyses with different sample types
|
||||
analyses = env['product.template'].search([
|
||||
('is_analysis', '=', True),
|
||||
('required_sample_type_id', '!=', False)
|
||||
], limit=5)
|
||||
|
||||
if not analyses:
|
||||
print("ERROR: No analyses with sample types found. Cannot proceed with test.")
|
||||
return
|
||||
|
||||
print(f"Creating test order with {len(analyses)} analyses...")
|
||||
|
||||
# Create order lines
|
||||
order_lines = []
|
||||
for analysis in analyses:
|
||||
order_lines.append((0, 0, {
|
||||
'product_id': analysis.product_variant_id.id,
|
||||
'product_uom_qty': 1
|
||||
}))
|
||||
|
||||
# Create test order
|
||||
test_order = env['sale.order'].create({
|
||||
'partner_id': patient.id,
|
||||
'doctor_id': doctor.id if doctor else False,
|
||||
'is_lab_request': True,
|
||||
'order_line': order_lines
|
||||
})
|
||||
|
||||
print(f"Created order: {test_order.name}")
|
||||
print("Confirming order...")
|
||||
|
||||
# Confirm order (this should trigger sample generation)
|
||||
test_order.action_confirm()
|
||||
|
||||
print(f"\nOrder confirmed. Generated samples: {len(test_order.generated_sample_ids)}")
|
||||
|
||||
# Check generated samples
|
||||
if test_order.generated_sample_ids:
|
||||
print("\nGenerated samples details:")
|
||||
|
||||
# Group by sample type to verify grouping logic
|
||||
sample_types = {}
|
||||
for sample in test_order.generated_sample_ids:
|
||||
sample_type_name = sample.sample_type_product_id.name if sample.sample_type_product_id else 'Unknown'
|
||||
if sample_type_name not in sample_types:
|
||||
sample_types[sample_type_name] = []
|
||||
sample_types[sample_type_name].append(sample)
|
||||
|
||||
for sample_type, samples in sample_types.items():
|
||||
print(f"\n Sample Type: {sample_type}")
|
||||
for sample in samples:
|
||||
print(f" - {sample.name}")
|
||||
print(f" Barcode: {sample.barcode}")
|
||||
print(f" Volume: {sample.volume_ml} ml")
|
||||
print(f" Analyses: {sample.analysis_names}")
|
||||
print(f" State: {sample.state}")
|
||||
else:
|
||||
print("WARNING: No samples were generated!")
|
||||
|
||||
# Check for messages/notifications
|
||||
print("\nChecking notifications...")
|
||||
messages = test_order.message_ids.filtered(lambda m: m.body)
|
||||
for msg in messages[:5]: # Show last 5 messages
|
||||
print(f" - {msg.body[:100]}...")
|
||||
|
||||
except Exception as e:
|
||||
print(f"ERROR during test: {str(e)}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
# 3. Verify barcode uniqueness
|
||||
print("\n3. BARCODE UNIQUENESS CHECK:")
|
||||
print("-" * 60)
|
||||
|
||||
all_samples = env['stock.lot'].search([
|
||||
('is_lab_sample', '=', True),
|
||||
('barcode', '!=', False)
|
||||
])
|
||||
|
||||
barcodes = {}
|
||||
duplicates = []
|
||||
|
||||
for sample in all_samples:
|
||||
if sample.barcode in barcodes:
|
||||
duplicates.append((sample.barcode, sample.name, barcodes[sample.barcode]))
|
||||
else:
|
||||
barcodes[sample.barcode] = sample.name
|
||||
|
||||
print(f"Total samples with barcodes: {len(all_samples)}")
|
||||
print(f"Unique barcodes: {len(barcodes)}")
|
||||
print(f"Duplicates found: {len(duplicates)}")
|
||||
|
||||
if duplicates:
|
||||
print("\nDUPLICATE BARCODES FOUND:")
|
||||
for barcode, name1, name2 in duplicates:
|
||||
print(f" Barcode {barcode}: {name1} and {name2}")
|
||||
|
||||
# 4. Check analyses without sample types
|
||||
print("\n4. ANALYSES WITHOUT SAMPLE TYPES:")
|
||||
print("-" * 60)
|
||||
|
||||
analyses_without_type = env['product.template'].search([
|
||||
('is_analysis', '=', True),
|
||||
('required_sample_type_id', '=', False)
|
||||
])
|
||||
|
||||
print(f"Found {len(analyses_without_type)} analyses without sample types:")
|
||||
for analysis in analyses_without_type[:10]: # Show first 10
|
||||
print(f" - {analysis.name}")
|
||||
|
||||
if len(analyses_without_type) > 10:
|
||||
print(f" ... and {len(analyses_without_type) - 10} more")
|
||||
|
||||
# 5. Summary
|
||||
print("\n" + "="*60)
|
||||
print("SUMMARY:")
|
||||
print("="*60)
|
||||
|
||||
issues = []
|
||||
|
||||
if duplicates:
|
||||
issues.append(f"{len(duplicates)} duplicate barcodes found")
|
||||
|
||||
if analyses_without_type:
|
||||
issues.append(f"{len(analyses_without_type)} analyses without sample types")
|
||||
|
||||
if issues:
|
||||
print("\n⚠️ ISSUES FOUND:")
|
||||
for issue in issues:
|
||||
print(f" - {issue}")
|
||||
else:
|
||||
print("\n✅ All checks passed successfully!")
|
||||
|
||||
print("\n" + "="*60)
|
||||
|
||||
if __name__ == '__main__':
|
||||
db_name = 'lims_demo'
|
||||
try:
|
||||
registry = odoo.registry(db_name)
|
||||
with registry.cursor() as cr:
|
||||
verify_automatic_sample_generation(cr)
|
||||
except Exception as e:
|
||||
print(f"ERROR: {str(e)}")
|
||||
print("\nMake sure:")
|
||||
print("1. The Odoo instance is running")
|
||||
print("2. The database 'lims_demo' exists")
|
||||
print("3. The LIMS module is installed")
|
Loading…
Reference in New Issue
Block a user