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'
|
string='Valor de Texto'
|
||||||
)
|
)
|
||||||
|
|
||||||
value_selection = fields.Selection(
|
# Keep as Char but add domain validation
|
||||||
string='Valor de Selección',
|
value_selection = fields.Char(
|
||||||
selection='_get_selection_options'
|
string='Valor de Selección'
|
||||||
)
|
)
|
||||||
|
|
||||||
# Campo para mostrar las opciones disponibles
|
# Campo para mostrar las opciones disponibles
|
||||||
|
@ -283,6 +283,14 @@ class LimsResult(models.Model):
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
_('Para parámetros de selección solo se debe elegir una opción.')
|
_('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':
|
elif value_type == 'boolean':
|
||||||
has_value = True # Boolean siempre tiene valor (True o False)
|
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:
|
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"/>
|
class="oe_edit_only"/>
|
||||||
<field name="value_selection"
|
<field name="value_selection"
|
||||||
invisible="parameter_value_type != '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"
|
<field name="value_boolean"
|
||||||
invisible="parameter_value_type != 'boolean'"
|
invisible="parameter_value_type != 'boolean'"
|
||||||
widget="boolean_toggle"
|
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