fix: Implementar generación automática de pruebas y mejorar selección de muestras

- Agregar método _generate_lab_tests() en sale.order para crear pruebas automáticamente al confirmar orden
- Agregar método _find_sample_for_analysis() para asociar muestras con análisis según tipo
- Mejorar dominio de sample_id en lims.test para filtrar por paciente y estado (collected/in_analysis)
- Agregar método _onchange_sale_order_line() para actualizar dominio de muestra dinámicamente
- Las pruebas ahora se crean automáticamente con la muestra correcta asignada

Esto resuelve el problema reportado donde las órdenes aprobadas no generaban pruebas
y las muestras no estaban disponibles para selección manual.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Luis Ernesto Portillo Zaldivar 2025-07-15 01:17:37 -06:00
parent 80c70b67d9
commit 820c05ffa9
3 changed files with 106 additions and 7 deletions

View File

@ -47,7 +47,7 @@ class LimsTest(models.Model):
sample_id = fields.Many2one(
'stock.lot',
string='Muestra',
domain="[('is_lab_sample', '=', True)]",
domain="[('is_lab_sample', '=', True), ('patient_id', '=', patient_id), ('state', 'in', ['collected', 'in_analysis'])]",
tracking=True
)
@ -110,6 +110,36 @@ class LimsTest(models.Model):
for record in self:
record.require_validation = require_validation == 'True'
@api.onchange('sale_order_line_id')
def _onchange_sale_order_line(self):
"""Update sample domain when order line changes"""
if self.sale_order_line_id:
# Try to find a suitable sample from the order
order = self.sale_order_line_id.order_id
product = self.sale_order_line_id.product_id
if order.is_lab_request and product.required_sample_type_id:
# Find samples for this patient with the required sample type
suitable_samples = self.env['stock.lot'].search([
('is_lab_sample', '=', True),
('patient_id', '=', order.partner_id.id),
('sample_type_product_id', '=', product.required_sample_type_id.id),
('state', 'in', ['collected', 'in_analysis'])
])
if suitable_samples:
# If only one sample, select it automatically
if len(suitable_samples) == 1:
self.sample_id = suitable_samples[0]
# Update domain to show only suitable samples
return {
'domain': {
'sample_id': [
('id', 'in', suitable_samples.ids)
]
}
}
@api.model_create_multi
def create(self, vals_list):
"""Genera código único al crear."""

View File

@ -34,20 +34,21 @@ class SaleOrder(models.Model):
)
def action_confirm(self):
"""Override to generate laboratory samples automatically"""
"""Override to generate laboratory samples and tests automatically"""
res = super(SaleOrder, self).action_confirm()
# Generate samples only for laboratory requests
# Generate samples and tests only for laboratory requests
for order in self.filtered('is_lab_request'):
try:
order._generate_lab_samples()
order._generate_lab_tests()
except Exception as e:
_logger.error(f"Error generating samples for order {order.name}: {str(e)}")
# Continue with order confirmation even if sample generation fails
_logger.error(f"Error generating samples/tests for order {order.name}: {str(e)}")
# Continue with order confirmation even if generation fails
# But notify the user
order.message_post(
body=_("Error al generar muestras automáticamente: %s. "
"Por favor, genere las muestras manualmente.") % str(e),
body=_("Error al generar muestras/pruebas automáticamente: %s. "
"Por favor, genere las muestras y pruebas manualmente.") % str(e),
message_type='notification'
)
@ -163,3 +164,71 @@ class SaleOrder(models.Model):
raise UserError(
_("Error al crear muestra para %s: %s") % (sample_type.name, str(e))
)
def _generate_lab_tests(self):
"""Generate laboratory tests for analysis order lines"""
self.ensure_one()
_logger.info(f"Generating laboratory tests for order {self.name}")
# Get the test model
TestModel = self.env['lims.test']
created_tests = TestModel.browse()
# Create a test for each analysis line
for line in self.order_line:
if not line.product_id.is_analysis:
continue
# Find appropriate sample for this analysis
sample = self._find_sample_for_analysis(line.product_id)
if not sample:
_logger.warning(
f"No sample found for analysis {line.product_id.name} in order {self.name}"
)
self.message_post(
body=_("Advertencia: No se encontró muestra para el análisis '%s'") % line.product_id.name,
message_type='notification'
)
continue
# Create the test
try:
test = TestModel.create({
'sale_order_line_id': line.id,
'sample_id': sample.id,
})
created_tests |= test
_logger.info(f"Created test {test.name} for analysis {line.product_id.name}")
except Exception as e:
_logger.error(f"Error creating test for {line.product_id.name}: {str(e)}")
self.message_post(
body=_("Error al crear prueba para '%s': %s") % (line.product_id.name, str(e)),
message_type='notification'
)
# Post message with created tests
if created_tests:
test_list = "<ul>"
for test in created_tests:
test_list += f"<li>{test.name} - {test.product_id.name}</li>"
test_list += "</ul>"
self.message_post(
body=_("Pruebas generadas automáticamente: %s") % test_list,
message_type='notification'
)
_logger.info(f"Created {len(created_tests)} tests for order {self.name}")
def _find_sample_for_analysis(self, product):
"""Find the appropriate sample for an analysis product"""
# Check if the analysis has a required sample type
if not product.required_sample_type_id:
return False
# Find a generated sample with matching sample type
for sample in self.generated_sample_ids:
if sample.sample_type_product_id.id == product.required_sample_type_id.id:
return sample
return False