I'm trying to apply a global discount to invoices (v13). I don't want to modify the way Odoo calculates the invoice amount, so all I'm doing is change the discount field for every account.move.line of the invoice.
I create the global_discount field in account.move:
class AccountMove(models.Model):
_inherit = 'account.move'
global_discount = fields.Float(string='Global Discount (%)', digits='Discount', default=0.0)
Now, I want to change the discount field when global_discount is modified, but @api.onchange is not being called when doing so. It doesn't work adding either the parent reference or a related field to the decorator:
class AccountMoveLine(models.Model):
_inherit = 'account.move.line'
global_discount = fields.Float(related='move_id.global_discount')
# This method is not being called when changing global_discount
@api.onchange('move_id.global_discount', 'global_discount')
def _compute_discount(self):
for line in self:
# Simplified for easy reading, I'm not actually doing this
line.discount = line.global_discount
Even if I make discount a computed field and use @api.depends, its onchange methods won't be called.
If I modify the lines from an onchange method in the parent, the discount onchange methods won't be called and price_subtotal will not change:
class AccountMove(models.Model):
_inherit = 'account.move'
@api.onchange('global_discount')
def _compute_discount(self):
for invoice in self:
for line in invoice.invoice_line_ids:
line._compute_discount()
I have also tried calling the onchange methods manually, but I'm definitely doing something wrong because nothing new happens:
@api.onchange('global_discount')
def _compute_discount(self):
for invoice in self:
for line in invoice.invoice_line_ids:
line._compute_discount()
spec = line._onchange_spec()
values = dict(line._cache)
# onchange returns and empty dict {}
updates = line.onchange(values, 'discount', spec)
value = updates.get('value', {})
for name, val in value.items():
if isinstance(val, tuple):
value[name] = val[0]
values.update(value)
line.update(values)
I'm missing something on how Odoo calls onchange methods from python, but I can't figure it out.