Odoo 11: How to correctly implement @api.onchange?

982 Views Asked by At

I want to compute a telephone number, if the number in the 8 position is either "0" or "1" I want to print just the last 4 numbers with a "(3)" before them, otherwise just print the 4 numbers, but what is happening is that my code is printing "0.0" and I don't know why, I'll appreciate your help...

This is my python code:

class Employee(models.Model):
    _inherit = "hr.employee"

    marcado_rapido = fields.Float("MarcadoRapido",compute='_compute_marcado_rapido')
    @api.onchange("emp.marcado_rapido")
    def onchange_compute_marcado_rapido(self):
        for num in self:
            num = "809-257-1457"
            if num[8] in ('0','1'):
                "(3)"+num[8:]

This is my xml code:

<td>
    <t t-foreach="env['hr.employee'].search([('department_id', '=', dep.id)])" t-as="emp">
        <div class="contact_form">
            <img t-if="emp.image" t-att-src="'data:image/png;base64,%s' % to_text(emp.image)"/>
            <div class="bloqueP">
                <div class="bloque" t-field="emp.marcado_rapido"/>
            </div>
        </div>
    </t>
</td>
2

There are 2 best solutions below

1
Kenly On

@onchange only supports simple field names, dotted names (fields of relational fields e.g. partner_id.tz) are not supported and will be ignored

You can check the official documentation on how the onchange decorator works and what are the limitations.

0.0 is the default value for float fields and the value of marcado_rapido is computed using _compute_marcado_rapido function. If the field updated in onchange method depends on marcado_rapido field value, you can compute its value using the same method

0
Juan Salcedo On

You should use compute decoration instead of onchange, but compute method aproach always depend in someone else field. My sugestion is use a another computed field, something like this:

class Employee(models.Model):
    _inherit = 'hr.employee'
    
    # If your number contains special characters(like '-') you should use `Char` insted of `float`
    num_telefono = fields.Char('Num. Telefono')
    marcado_rapido = fields.Char('MarcadoRapido', compute='_compute_marcado_rapido')

    @api.depends('num_telefono')
    def _compute_marcado_rapido(self):
        for rec in self:
            num = rec.num_telefono[-4:]
            rec.marcado_rapido = '(3){}'.format(num) if num[:1] in ('0','1') else num

Now you can call marcado_rapido from your XML.

I hope this answer can be helful for you.