#!/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")