Grabar valor calculado en metodo onchange para un campo con attr readonly (odoo8)

1,011 views
Skip to first unread message

Davor

unread,
Dec 29, 2017, 10:11:11 PM12/29/17
to Usuarios Odoo / OpenERP en España

Hola,

He creado un campo que se encuentra dentro de las lineas de ventas heredando la clase sale.order.line. A este campo le he asignado una condición de sólo lectura mediante atributo readonly en el xml, y a su vez es calculado segun otra un metodo onchange en el py.

El problema está en que al modificar la linea de venta el campo calculado no se guarda en la base de datos.

Por lo que he podido leer al respecto, odoo usa los campos readonly con fines meramente informativos, por lo que no los almacena en la base de datos, y he leido varias alternativas para solucionar mi problema:

Sobrescribir los metodos create o write de la clase padre y, como alternativa, usar "web_readonly_bypass".

He intentado esas soluciones pero no he sido capaz de solucionarlo.

¿Sabriais que hago mal,o si hay alguna otra solucion?

Os adjunto el código para explicarlo mejor:

Cod Python
class SaleOrderLineExt(models.Model):
    _inherit
='sale.order.line'

    tipo_coste
= fields.Selection([
       
('a','A'),
       
('b','B'),
       
('c','C'),
       
('d','D'),
       
('e','E'),
       
('f','F'),
       
('g','G')])
    coste_bruto
= fields.Float(
       
string = "Coste bruto")
    prueba_log_tipo_coste
= fields.Boolean()

   
@api.one
   
@api.onchange('tipo_coste')
   
def _calcular_coste_bruto(self):
       
if self.tipo_coste == 'c' or self.tipo_coste == 'd' or self.tipo_coste == 'e':
           
self.prueba_log_tipo_coste = True
       
else:
           
self.prueba_log_tipo_coste = False
       
if self.tipo_coste == 'a' or self.tipo_coste == 'b':
           
self.coste_bruto = self.product_id.standard_price
       
elif self.tipo_coste == 'c':
           
self.coste_bruto = 10
       
elif self.tipo_coste == 'd':
           
self.coste_bruto = 20
       
elif self.tipo_coste == 'e':
           
self.coste_bruto = 30
       
else:
           
self.coste_bruto = 0

   
@api.model
   
def create(self, vals):
       
if self.tipo_coste == 'c':
             vals
['coste_bruto'] = 10
       
if self.tipo_coste == 'd':
            vals
['coste_bruto'] = 20
       
if self.tipo_coste == 'e':
            vals
['coste_bruto'] = 30
       
return super(sale_order_line, self).create(vals)

   
@api.multi
   
def write(self, vals):
       
if self.tipo_coste == 'c':
             vals
['coste_bruto'] = 10
       
if self.tipo_coste == 'd':
            vals
['coste_bruto'] = 20
       
if self.tipo_coste == 'e':
            vals
['coste_bruto'] = 30
       
return super(sale_order_line, self).write(vals)




Vistas xml
<record model="ir.ui.view" id="sale_order_ext_form">
     
<field name="name">sale.order.ext.form</field>
     
<field name="model">sale.order</field>
     
<field name="inherit_id" ref="sale.view_order_form"/>
     
<field name="arch" type="xml">
       
<data>
           
<xpath expr="//notebook/page/field[@name='order_line']/tree[@string='Sales Order Lines']" position="replace">
             
<tree string="Sales Order Lines" editable="bottom">
                 
<field name="coste_bruto" attrs="{'readonly':[('prueba_log_tipo_coste','=',True)]}"/>
                  ...
                  ...

Saludos

Darío Lodeiros

unread,
Jan 1, 2018, 4:28:16 AM1/1/18
to Usuarios Odoo / OpenERP en España
El unico problema que tienes es que el campo tipo coste no lo has incluido en la vista... Por lo que la funcion onchange no puede interpretarlo... Te esta devolviendo False y no te entra en ningun condicional. Debes de definirlo en la vista aunque sea con visible = False.
Los campos de solo lectura puedes modificarlos sin problema por codigo... Eso seguro ;)

Darío Lodeiros

unread,
Jan 1, 2018, 4:33:21 AM1/1/18
to Usuarios Odoo / OpenERP en España
Bueno, digo q no lo tienes por q no lo veo xD... Igual lo has metido en la parte q falta del codigo??
De todos modos juraria q el problema lo debes de tener por ahi... Probaste q realmente se esta ejecutando la asignacion?

Davor

unread,
Jan 1, 2018, 7:20:09 AM1/1/18
to Usuarios Odoo / OpenERP en España

Gracias Dario, el campo "tipo_coste" si que lo tengo en el código (se me pasó incluirlo en el ejemplo). La función "_calcular_coste_bruto" se ejecuta correctamente al cambiar el campo "tipo_coste", pero, a la hora de guardar los cambios, cuando la condición readonly del campo "coste_bruto" es True, éstos no se almacenan en la base de datos...

Darío Lodeiros

unread,
Jan 1, 2018, 12:02:51 PM1/1/18
to Usuarios Odoo / OpenERP en España
Vale... Sips... me estaba refiriendo a q los campos readonly so q se almacenan, aunque si viene de un metodo onchange no te lo permitirá. Pero me acabo de dar cuenta que en el codigo estas llamando mal al padre, debes usar el nombre de la clase interno (SaleOrderLineExt en ti caso): super(SaleOrderLineExt,self)....

Tambien deberias iterar por el self en el caso de write (@api.multi), y el vals... Mejor utiliza vals.update({....

A ver si ahora hai mas suerte ;)

david fernandez

unread,
Jan 3, 2018, 8:32:36 AM1/3/18
to openerp-s...@googlegroups.com
Gracias de nuevo, he intentado hacer lo que me comentas y parece que siguo sin dar en el clavo. Por tema de prisas, he optado por usar dos campos para cubrir esa funcionalidad y ocultarlos en la vista según la necesidad. No es como me hubiese gustado..., pero de momento sirve.
Seguiré probando y si doy con ello os comento.
Un saludo

 


--
Has recibido este mensaje porque estás suscrito a un tema del grupo "Usuarios Odoo / OpenERP en España" de Grupos de Google.
Para cancelar la suscripción a este tema, visita https://groups.google.com/d/topic/openerp-spain-users/-1PO_OFYlCs/unsubscribe.
Para cancelar la suscripción a este grupo y a todos sus temas, envía un correo electrónico a openerp-spain-users+unsub...@googlegroups.com.
Para obtener más opciones, visita https://groups.google.com/d/optout.

victor...@kayuulab.com

unread,
Jan 4, 2018, 10:35:44 AM1/4/18
to Usuarios Odoo / OpenERP en España
Sí, yo creo que es por usar el campo readonly, sus cambios no se guardan, es como si se quedaran en el cliente y no llegan de vuelta al servidor.

En casos similares yo prefiero no usar el onchange, sino un campo definido como calculado con una función que tenga un depends en el campo o campos que hay que ver si cambian, me parece más fácil y limpio.

Sería algo así como:

coste_bruto = fields.Float("Coste bruto", compute='_calcular_coste_bruto',
                               store=True, compute_sudo=False)

    @api.one
   
@api.depends('tipo_coste')
   
def _calcular_coste_bruto(self):
(... código...)

Lo del store=True es lo que hace que el valor se guarde en la BBDD una vez calculado.

Otra posibilidad más complicada es mandar el valor de vuelta al servidor a través del contexto, pero me parece una solución más complicada y menos limpia que la anterior.

Saludos,

Victor

Davor

unread,
Jan 5, 2018, 7:24:10 AM1/5/18
to Usuarios Odoo / OpenERP en España
Perfecto Victor, he probado como dices y me sirve perfectamente.

Un saludo y muchas gracias


Muchas gracias!

Iniciado

unread,
Jan 5, 2018, 3:20:32 PM1/5/18
to Usuarios Odoo / OpenERP en España
Estupendo, me he estado pegando con esto unos días para una modificación, y que facil era!!!

Un saludo y gracias también de mi parte.


El jueves, 4 de enero de 2018, 16:35:44 (UTC+1), victor...@kayuulab.com escribió:

victor...@kayuulab.com

unread,
Jan 6, 2018, 11:24:25 AM1/6/18
to Usuarios Odoo / OpenERP en España
Me alegro por los dos, gracias por la respuesta.

Por cierto, creo que el problema viene realmente del onchange y no del readonly, en la documentación de la V8 dice:

onchange methods work on virtual records assignment on these records is not written to the database, just used to know which value to send back to the client

Por eso el cambio se queda en el cliente y no se refleja en la BBDD.

(fuente: https://www.odoo.com/documentation/8.0/reference/orm.html)

Saludos,

Victor
----
Victor Garcia
www.kayuulab.com

Iniciado

unread,
Jan 6, 2018, 1:43:37 PM1/6/18
to Usuarios Odoo / OpenERP en España
Es un problema del onchage con el readonly, bueno, realmente no es un problema, porque lo han hecho así a posta, o eso he leido por ahí.

Hay un módulo que dice solucionarlo, web_readonly_bypass, pero yo no lo he conseguido hacer funcionar.

Un saludo.

victor...@kayuulab.com

unread,
Jan 7, 2018, 10:16:11 AM1/7/18
to Usuarios Odoo / OpenERP en España
Pues sí, totalmente de acuerdo, el hecho de que esté documentado convierte ese comportamiento en un "feature" que es resultado de una "decisión de diseño". :-)


Saludos,

Victor
----
Victor Garcia
www.kayuulab.com

Reply all
Reply to author
Forward
0 new messages