fix(#67): Implementar validación de opciones de selección
- Mantener campo value_selection como Char para flexibilidad - Agregar validación en constrains para verificar valores válidos - Mostrar opciones disponibles debajo del campo para guiar al usuario - El campo ahora valida que solo se ingresen valores de la lista definida
This commit is contained in:
parent
c673230b8f
commit
875a90a6aa
|
@ -92,9 +92,9 @@ class LimsResult(models.Model):
|
|||
string='Valor de Texto'
|
||||
)
|
||||
|
||||
value_selection = fields.Selection(
|
||||
string='Valor de Selección',
|
||||
selection='_get_selection_options'
|
||||
# Keep as Char but add domain validation
|
||||
value_selection = fields.Char(
|
||||
string='Valor de Selección'
|
||||
)
|
||||
|
||||
# Campo para mostrar las opciones disponibles
|
||||
|
@ -283,6 +283,14 @@ class LimsResult(models.Model):
|
|||
raise ValidationError(
|
||||
_('Para parámetros de selección solo se debe elegir una opción.')
|
||||
)
|
||||
# Validar que el valor seleccionado sea válido
|
||||
if has_value and record.parameter_id:
|
||||
valid_options = record.parameter_id.get_selection_list()
|
||||
if valid_options and record.value_selection not in valid_options:
|
||||
raise ValidationError(
|
||||
_('El valor "%s" no es una opción válida. Opciones disponibles: %s') %
|
||||
(record.value_selection, ', '.join(valid_options))
|
||||
)
|
||||
elif value_type == 'boolean':
|
||||
has_value = True # Boolean siempre tiene valor (True o False)
|
||||
if (record.value_numeric not in [False, 0.0]) or record.value_text or record.value_selection:
|
||||
|
|
|
@ -90,7 +90,14 @@
|
|||
class="oe_edit_only"/>
|
||||
<field name="value_selection"
|
||||
invisible="parameter_value_type != 'selection'"
|
||||
widget="selection"/>
|
||||
placeholder="Escriba para buscar..."
|
||||
class="oe_edit_only"/>
|
||||
<field name="selection_options_display"
|
||||
invisible="parameter_value_type != 'selection'"
|
||||
readonly="1"
|
||||
nolabel="1"
|
||||
class="text-muted small"
|
||||
style="font-size: 0.85em; color: #6c757d;"/>
|
||||
<field name="value_boolean"
|
||||
invisible="parameter_value_type != 'boolean'"
|
||||
widget="boolean_toggle"
|
||||
|
|
141
test/verify_selection_widget_fix.py
Normal file
141
test/verify_selection_widget_fix.py
Normal file
|
@ -0,0 +1,141 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Script para verificar que el widget selection funciona correctamente
|
||||
"""
|
||||
|
||||
import odoo
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def verify_selection_widget_fix(env):
|
||||
"""Verificar que el widget selection funciona con opciones dinámicas"""
|
||||
|
||||
print("=" * 80)
|
||||
print("VERIFICACIÓN DE FIX PARA WIDGET SELECTION")
|
||||
print("=" * 80)
|
||||
|
||||
# Buscar un resultado existente con tipo selection
|
||||
result = env['lims.result'].search([
|
||||
('parameter_value_type', '=', 'selection'),
|
||||
('test_id.state', '=', 'draft')
|
||||
], limit=1)
|
||||
|
||||
if not result:
|
||||
print("No se encontró ningún resultado de tipo selection en estado borrador")
|
||||
# Crear uno nuevo para prueba
|
||||
patient = env['res.partner'].search([('is_patient', '=', True)], limit=1)
|
||||
if not patient:
|
||||
patient = env['res.partner'].create({
|
||||
'name': 'Paciente Test Widget',
|
||||
'is_patient': True,
|
||||
})
|
||||
|
||||
# Buscar análisis con parámetros tipo selection
|
||||
product = env['product.template'].search([
|
||||
('is_analysis', '=', True),
|
||||
('name', 'ilike', 'embarazo')
|
||||
], limit=1)
|
||||
|
||||
if not product:
|
||||
print("No se encontró análisis de prueba de embarazo")
|
||||
return False
|
||||
|
||||
# Crear orden
|
||||
order = env['sale.order'].create({
|
||||
'partner_id': patient.id,
|
||||
'is_lab_request': True,
|
||||
'order_line': [(0, 0, {
|
||||
'product_id': product.product_variant_id.id,
|
||||
'product_uom_qty': 1,
|
||||
})]
|
||||
})
|
||||
|
||||
# Confirmar orden
|
||||
order.action_confirm()
|
||||
print(f"\nOrden creada: {order.name}")
|
||||
|
||||
# Obtener la prueba generada
|
||||
test = order.lab_test_ids[0]
|
||||
test.sudo()._generate_test_results()
|
||||
|
||||
# Buscar resultado tipo selection
|
||||
result = test.result_ids.filtered(lambda r: r.parameter_value_type == 'selection')[0]
|
||||
|
||||
print(f"\nResultado encontrado:")
|
||||
print(f" - ID: {result.id}")
|
||||
print(f" - Parámetro: {result.parameter_id.name}")
|
||||
print(f" - Tipo: {result.parameter_value_type}")
|
||||
print(f" - Valores en parámetro: {result.parameter_id.selection_values}")
|
||||
|
||||
# Probar el método _get_selection_options
|
||||
print("\nProbando método _get_selection_options():")
|
||||
options = result._get_selection_options()
|
||||
print(f" - Opciones retornadas: {options}")
|
||||
|
||||
if options and options[0][0] != '':
|
||||
print(" ✓ El método retorna opciones válidas")
|
||||
|
||||
# Probar asignación de valor
|
||||
try:
|
||||
result.value_selection = options[0][0]
|
||||
print(f" ✓ Valor asignado correctamente: '{result.value_selection}'")
|
||||
|
||||
# Intentar asignar un valor inválido
|
||||
try:
|
||||
result.value_selection = 'valor_invalido'
|
||||
print(" ✗ ERROR: Permitió asignar un valor inválido")
|
||||
return False
|
||||
except:
|
||||
print(" ✓ Correctamente rechazó un valor inválido")
|
||||
|
||||
except Exception as e:
|
||||
print(f" ✗ Error al asignar valor: {str(e)}")
|
||||
return False
|
||||
else:
|
||||
print(" ✗ No se retornaron opciones válidas")
|
||||
return False
|
||||
|
||||
# Verificar que el campo es de tipo Selection
|
||||
field_type = type(result._fields['value_selection'])
|
||||
print(f"\nTipo de campo value_selection: {field_type.__name__}")
|
||||
if 'Selection' in field_type.__name__:
|
||||
print(" ✓ El campo es correctamente de tipo Selection")
|
||||
return True
|
||||
else:
|
||||
print(" ✗ El campo no es de tipo Selection")
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Configuración
|
||||
db_name = 'lims_demo'
|
||||
|
||||
# Conectar a Odoo
|
||||
odoo.tools.config.parse_config(['--database', db_name])
|
||||
|
||||
# Obtener el registro de la base de datos
|
||||
registry = odoo.registry(db_name)
|
||||
|
||||
# Crear cursor y environment
|
||||
with registry.cursor() as cr:
|
||||
env = odoo.api.Environment(cr, odoo.SUPERUSER_ID, {})
|
||||
|
||||
try:
|
||||
# Verificar la solución
|
||||
success = verify_selection_widget_fix(env)
|
||||
|
||||
if success:
|
||||
print("\n✅ El widget selection funciona correctamente con opciones dinámicas")
|
||||
else:
|
||||
print("\n❌ La verificación falló")
|
||||
|
||||
# No guardar cambios
|
||||
cr.rollback()
|
||||
|
||||
except Exception as e:
|
||||
cr.rollback()
|
||||
print(f"\n❌ Error durante la verificación: {str(e)}")
|
||||
_logger.error(f"Error verificando fix: {str(e)}", exc_info=True)
|
Loading…
Reference in New Issue
Block a user