Mariano DAngelo
Mariano DAngelo

Reputation: 940

How to save value on Readonly / editable false fields in odoo Models?

I've a field which I want to compute it's value on change, but I don't want the user can modify it.

If I set the field as readonly=1 or editable=0 the value isn't store.

I'm trying to set a global discount on the invoice

class account_invoice(models.Model):
    _inherit = "account.invoice"

    global_discount_p = fields.Float('Descuento porcentaje')
    global_discount = fields.Float('Descuento')
    neto = fields.Float('Neto')

    @api.one
    @api.depends('invoice_line.price_subtotal', 'tax_line.amount','global_discount_p')
    def _compute_amount(self):
        ret = super(account_invoice,self)._compute_amount()
        if self.type == 'in_invoice':
            self.neto = self.amount_untaxed
            discount = self.global_discount_p/100
            self.global_discount = self.neto * discount
            self.amount_untaxed = self.neto - self.global_discount

            for line in self.tax_line:
                line.base = self.amount_untaxed
                line.amount = line.amount - (line.amount * discount)

            self.amount_tax = sum(line.amount for line in self.tax_line)
            self.amount_total = self.amount_untaxed + self.amount_tax

        return ret

And in the layout:

<xpath expr="//field[@name='amount_untaxed']" position="before">
                <field name="neto" readonly="1"/>
                <field name="global_discount_p" onchange="_compute_amount"/>
                <field name="global_discount" readonly="1"/>
            </xpath>

It work well, if I remove readonly="1" attrs from the fields

Upvotes: 4

Views: 13102

Answers (3)

Abhay Singh Rathore
Abhay Singh Rathore

Reputation: 179

In odoo11 you can use force_save="1" in the xml file

Hope it will help you!!

Upvotes: 14

Parmar Bharat
Parmar Bharat

Reputation: 11

Override this two methods in your account_invoice class and declare field like,

global_discount = fields.Float('Descuento', readonly=True)



@api.model
def create(self, vals):
    if vals['global_discount']:
        if vals['type'] == 'in_invoice':
        vals['neto'] = vals['amount_untaxed']
        discount = vals['global_discount_p']/100
        vals['global_discount'] = vals['neto'] * discount
        vals['amount_untaxed'] = vals['neto'] - vals['global_discount']

        for line in vals['tax_line']:
            line.base = vals['amount_untaxed']
            line.amount = line.amount - (line.amount * discount)

        vals['amount_tax'] = sum(line.amount for line in vals['tax_line'])
        vals['amount_total'] = vals['amount_untaxed'] + vals['amount_tax']
    res = super(PersonInformation, self).create(vals)
    return res

@api.multi
def write(self, vals):
    if vals['global_discount']:
        if vals['type'] == 'in_invoice':
        vals['neto'] = vals['amount_untaxed']
        discount = vals['global_discount_p']/100
        vals['global_discount'] = vals['neto'] * discount
        vals['amount_untaxed'] = vals['neto'] - vals['global_discount']

        for line in vals['tax_line']:
            line.base = vals['amount_untaxed']
            line.amount = line.amount - (line.amount * discount)

        vals['amount_tax'] = sum(line.amount for line in vals['tax_line'])
        vals['amount_total'] = vals['amount_untaxed'] + vals['amount_tax']
    res = super(PersonInformation, self).create(vals)
    return res

And in the layout:

<field name="global_discount" readonly="1"/>

I hope this will help you.

Upvotes: 1

Alessandro Ruffolo
Alessandro Ruffolo

Reputation: 1575

Try defining the fields as

neto = fields.Float('Neto', compute='_compute_amount', store=True)
global_discount = fields.Float('Descuento', compute='_compute_amount', store=True)

Upvotes: 3

Related Questions