2
votes

I've set my order_line to be editable and want to remove the delete button if it's not in draft mode. I attempted the following but the delete button remains:

<xpath expr="//field[@name='order_line']//tree" position="attributes">
  <attribute name="delete" domain="[(parent.state,'!=','draft')]"/>
</xpath>

Is it possible to dynamically set delete=false based on the draft state of the parent?

I tried this:

<record id="delete_drafts_only" model="ir.rule">
  <field name="name">You can only delete items with draft parents</field>
  <field name="model_id" ref="sale.model_sale_order_line"/>
  <field name="global" eval="True"/>
  <field name="domain_force">[('parent.state', '=', 'draft')]</field>
  <field name="perm_unlink" eval="True"/>
</record>

and

<record id="delete_drafts_only" model="ir.rule">
  <field name="name">You can only delete items with draft parents</field>
  <field name="model_id" ref="sale.model_sale_order_line"/>
  <field name="global" eval="True"/>
  <field name="domain_force">[('parent.state', '!=', 'draft')]</field>
  <field name="perm_read" eval="True"/>
  <field name="perm_write" eval="True"/>
  <field name="perm_create" eval="False"/>
  <field name="perm_unlink" eval="False"/>
</record>

But it doesn't seem to actually apply. The only thing that seem to be working is manipulating the ir_model_access, but that toggles it globally which isn't what I want.

enter image description here

3
why not make it readonly? do you need to edit it? - StackUP
@StackUP I need to edit 1 field that I've added, yes. - Kit Sunde

3 Answers

2
votes

I have made something similar work, also using Record Rules.

The lines should have the delete access, so that the delete button can be available in the form, and the record Rule should deny delete access if certain conditions are met.

So your second Record Rule should work. The catch is that the delete button will still be visible, but an Access error will be raised by the rule, effectively enforcing it.

You could try removing the global option and assigning the Rule to a group:

<record id="delete_drafts_only" model="ir.rule">
  <field name="name">You can only delete items with draft parents</field>
  <field name="model_id" ref="sale.model_sale_order_line"/>
  <field name="domain_force">[('parent.state', '!=', 'draft')]</field>
  <field name="groups" eval="[(4,ref('base.group_user'))]"/>
  <field name="perm_read" eval="True"/>
  <field name="perm_write" eval="True"/>
  <field name="perm_create" eval="False"/>
  <field name="perm_unlink" eval="False"/>
</record>
1
votes

The "ir.rule" solution you wrote almost works: the delete button still stay visible, but when you try to save, it gives you an exception for invalid access.

Besides, the logic behind is different: In order to "disable" delete of a line you should use a negative logic. This worked for me:

<record id="delete_drafts_only" model="ir.rule">
  <field name="name">You can only delete items with draft parents</field>
  <field name="model_id" ref="sale.model_sale_order_line"/>
  <field name="domain_force">[('state', '=', 'draft')]</field>
  <field name="groups" eval="[(4,ref('base.group_user'))]"/>
  <field name="perm_read" eval="False"/>
  <field name="perm_write" eval="False"/>
  <field name="perm_create" eval="False"/>
  <field name="perm_unlink" eval="True"/>
</record>

I suppose the semantic is:

  • domain_force field point out which records of the model have to be considered
  • perm_* fields indicate which operations cannot be executed (thus a "False" value means the operation can be executed and vice-versa)
0
votes

Instead of deleting you can just make it invisible with given criteria

<xpath expr="//field[@name='order_line']//tree" position='attributes'>
<attribute name='invisible' attrs="{'invisible':[('parent.state','!=','draft')]}">1</attribute>
</xpath>

This is just a brief idea.. Just try it.