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:
parent
80c70b67d9
commit
820c05ffa9
Binary file not shown.
|
@ -47,7 +47,7 @@ class LimsTest(models.Model):
|
||||||
sample_id = fields.Many2one(
|
sample_id = fields.Many2one(
|
||||||
'stock.lot',
|
'stock.lot',
|
||||||
string='Muestra',
|
string='Muestra',
|
||||||
domain="[('is_lab_sample', '=', True)]",
|
domain="[('is_lab_sample', '=', True), ('patient_id', '=', patient_id), ('state', 'in', ['collected', 'in_analysis'])]",
|
||||||
tracking=True
|
tracking=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -110,6 +110,36 @@ class LimsTest(models.Model):
|
||||||
for record in self:
|
for record in self:
|
||||||
record.require_validation = require_validation == 'True'
|
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
|
@api.model_create_multi
|
||||||
def create(self, vals_list):
|
def create(self, vals_list):
|
||||||
"""Genera código único al crear."""
|
"""Genera código único al crear."""
|
||||||
|
|
|
@ -34,20 +34,21 @@ class SaleOrder(models.Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
def action_confirm(self):
|
def action_confirm(self):
|
||||||
"""Override to generate laboratory samples automatically"""
|
"""Override to generate laboratory samples and tests automatically"""
|
||||||
res = super(SaleOrder, self).action_confirm()
|
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'):
|
for order in self.filtered('is_lab_request'):
|
||||||
try:
|
try:
|
||||||
order._generate_lab_samples()
|
order._generate_lab_samples()
|
||||||
|
order._generate_lab_tests()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
_logger.error(f"Error generating samples for order {order.name}: {str(e)}")
|
_logger.error(f"Error generating samples/tests for order {order.name}: {str(e)}")
|
||||||
# Continue with order confirmation even if sample generation fails
|
# Continue with order confirmation even if generation fails
|
||||||
# But notify the user
|
# But notify the user
|
||||||
order.message_post(
|
order.message_post(
|
||||||
body=_("Error al generar muestras automáticamente: %s. "
|
body=_("Error al generar muestras/pruebas automáticamente: %s. "
|
||||||
"Por favor, genere las muestras manualmente.") % str(e),
|
"Por favor, genere las muestras y pruebas manualmente.") % str(e),
|
||||||
message_type='notification'
|
message_type='notification'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -163,3 +164,71 @@ class SaleOrder(models.Model):
|
||||||
raise UserError(
|
raise UserError(
|
||||||
_("Error al crear muestra para %s: %s") % (sample_type.name, str(e))
|
_("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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user