How to make onchange field editable only for draft state?

Question:

I have onchange field, and i need to make it readonly for all state except the draft state.
My .py file:

class SaleOrderInherited(models.Model):
_inherit = 'sale.order' 

custom_field = fields.Char(string='Test', store=True, default=randint(1, 1000)
)

@api.onchange('tax_totals_json', 'date_order')
def _onchage_test(self):
    for record in self:
        if int(json.loads(record.tax_totals_json)['amount_total']) == 0:
            record.custom_field = randint(1, 1000)
        else:
            record.custom_field = f"{json.loads(record.tax_totals_json)['amount_total']} - {record.date_order}"

My .xml file:

<odoo>
  <data>
    <!--Inherit the sale order form view--> 
    <record id="view_sale_order_custom" model="ir.ui.view"> 
        <field name="name">sale.order.custom.form.inherited</field>
        <field name="model">sale.order</field> 
        <field name="inherit_id" ref="sale.view_order_form"/> 
        <field name="arch" type="xml"> 
            <xpath expr="//field[@name='partner_id']" position="after"> 
                <field name="custom_field"/>
            </xpath> 
        </field> 
    </record>
  </data>
</odoo>

I tried to use attrs="{'readonly':[('state','!=','draft')]}" in xml, and tried use
states={'draft': [('readonly', False)], 'sent': [('readonly', True)]} in py. Both variations works on Char field, but didnt give any result there.

Asked By: FMaslina

||

Answers:

Set the readonly attribute to True then use states to make the field editable in draft state. You can find an example in sale_management module:

sale_order_template_id = fields.Many2one(
    readonly=True, check_company=True,
    states={'draft': [('readonly', False)], 'sent': [('readonly', False)]})

Using only attrs in XML arch should be enough to make the field read-only using a domain, the attrs you used should work (tested)

Answered By: Kenly
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.