Dominio dinámico para campo many2one (odoo8)

894 views
Skip to first unread message

Davor

unread,
Jan 9, 2018, 7:22:14 PM1/9/18
to Usuarios Odoo / OpenERP en España

Hola,

Quiero aplicar un filtro al campo m2o "product_id" del modelo "sale.order.line", para que los resultados a mostrar varíen en función de los valores de 2 campos: "tipo_coste", que es un campo tipo selection del modelo 'sale.order.line', y "mo_ok", que es un booleano del modelo 'product.template'.

la idea sería tener dos tipos de resultados, unos en el que

tipo_coste = 'a'

 y otros para:

mo_ok = True


Lo he intentado usando el atributo domain en python, pero no se como hacer la llamada a los campos de diferentes clases ni la manera de conseguir dos tipos de resultados en el mismo dominio

product_id=fields.Many2one('product.product', domain = [('')])

Luego he estado intentándolo a traves de un metodo onchange, pero creo que el ejemplo del que me estoy fijando no lo estoy adaptando del todo bién:

    @api.one
   
@api.onchange('tipo_coste')
   
def _condicionar_tipo_producto(self):
        domain
= {}
        product_list
= []
       
if self.prueba_log_tipo_coste == True:###filtrar si tipo_coste es mo_ok
            product_obj
= self.env['product.product'].search([('product_tmpl_id.mo_ok','=',True)])
           
for product_ids in product_obj:
                product_list
.append(product_ids.id)
            domain
= {'product_id':[('id','=','product_list')]}
           
return {'domain' : domain}
       
else:
            product_obj
= self.env['product.product'].search([('product_tmpl_id.mo_ok','=',False)])
           
for product_ids in product_obj:
                product_list
.append(product_ids.id)
            domain
= {'product_id':[('id','=','product_list')]}
           
return {'domain' : domain}


Saludos

Gabriel Davini

unread,
Jan 9, 2018, 11:32:39 PM1/9/18
to openerp-s...@googlegroups.com
Hola

Quitá el decorador @api.one, que mete todos los return dentro de una lista. Además, está deprecado y en los on change no es necesario. 

Saludos 

--
Gabriel

...

Davor

unread,
Jan 10, 2018, 2:51:47 PM1/10/18
to Usuarios Odoo / OpenERP en España
Gracias Gabriel,

Quité el decorador y por lo menos ahora reconoce el codigo, pero me da un error de sintaxis:

"""DataError: invalid input syntax for integer: "product_list"
LINE 1: ...ct"."active" = true)  AND  "product_product".id = 'product_l..."""

Gabriel Davini

unread,
Jan 10, 2018, 3:19:53 PM1/10/18
to openerp-s...@googlegroups.com
Estas comparando un entero con un string, por eso. 

--
Gabriel

...

Davor

unread,
Jan 14, 2018, 3:11:21 PM1/14/18
to Usuarios Odoo / OpenERP en España
Pues sí que lo estaba enfocando mal, aplicaba un ejemplo tal cual, sin llegar a comprenderlo del todo y así me iba...

Para lo que quería hacer me ha servido con lo siguiente:

   
@api.onchange('tipo_coste')
   
def _condicionar_tipo_producto(self):
        domain
= {}

       
if self.tipo_coste == 'c' or self.tipo_coste == 'd' or self.tipo_coste == 'e':
            domain
= {'product_id':[('product_tmpl_id.mo_ok','=',True)]}
           
return {'domain' : domain}
       
else:
            domain
= {'product_id':[('product_tmpl_id.mo_ok','=',False)]}
           
return {'domain' : domain}

Muchas gracias!

Davor

unread,
Jan 14, 2018, 4:29:24 PM1/14/18
to Usuarios Odoo / OpenERP en España
Ahora me surge la duda de cómo hacer para que ese dominio permanezca tras guardar la linea de venta. Me explico, al cambiar el campo "tipo_coste", se aplica el dominio en el campo "product_id" segun el método onchange, pero si guardo la línea y vuelvo a editarla, no se refleja el dominio del campo "product_id" hasta que no se vuelva a cambiar el campo "tipo_coste" de nuevo... No domino nada el tema de asignar funciones en los eventos, podríais aconsejarme?

Saludos,

Nacho

unread,
Jan 17, 2018, 7:49:24 AM1/17/18
to Usuarios Odoo / OpenERP en España
Hola Davor.

Tuve el mismo problema que tienes tú y lo solucioné de esta forma. (Te aviso de que es un poco enrevesado, pero funciona):

En la vista XML, define el campo así:
<field name="product_id" domain="[('product_id_computed', '=', tipo_coste)]"/>


En el fichero .py, elimina la función que has puesto de "onchange" (la de tu último mensaje), y añade lo siguiente:
class product_template(models.Model):
  _inherit
= ['product.template']

  product_id_computed
= fields.Boolean(compute='compute_auxiliar', search='search_mo_ok')

 
def compute_auxiliar(self):
   
return True

 
def search_mo_ok(self, operator, value):
    tipo_coste
= value
   
if tipo_coste == 'c' or tipo_coste == 'd' or tipo_coste == 'e':
      product_id_domain
= [('product_tmpl_id.mo_ok', '=', True)]
    else:
      product_id_domain
= [('product_tmpl_id.mo_ok', '=', False)]
   
return product_id_domain



Nota: Asegúrate de que el campo "tipo_coste" esté en la vista XML. Si no está, y no quieres que se vea, añádelo así:
<field name="tipo_coste" invisible="1"/>

La función "search" sirve para indicar el dominio del campo actual. 
En la vista, le indicas el campo que tiene la función search y le pasas el valor del operador (operator) y del operando (value)
Con el operador no hacemos nada. Con el operando, le pasamos el valor del campo que vamos a usar (tipo_coste)
Lo de compute_auxiliar no sirve para nada, pero no he encontrado la forma de hacer funcionar la función search sin combinarlo con un campo calculado.

Prueba y me dices.

Saludos

Davor

unread,
Jan 21, 2018, 12:50:23 PM1/21/18
to Usuarios Odoo / OpenERP en España
Gracias Nacho, funcionó perfectamente.

Me viene de lujo, y lo de la propiedad "search" de los campos es un descubrimiento (para mí, claro).

Saludos,
Reply all
Reply to author
Forward
0 new messages