Reputation: 10189
Is there any way in Odoo 8 to create a field which is computed only if some condition is fulfilled, otherwise the user will be able to set its value?
Example
I have a model named box
, which has a float field named value
.
Imagine a box can have several boxes inside, each one which its own value.
So we have a one2many field named child_ids
pointing to box
and a many2one named parent_id
pointig to box too.
Now I want the following behaviour: an user can set the value
field of a box which has not any box inside (it means, childs_ids
is False), but, if the box has at least one box inside (it means, childs_ids
is NOT False), the value
field must be computed and it will be the sum of its childs value
.
Does anyone have an idea of how to achieve this behaviour?
I put my code, which is not working (the value of value
is always being reset to 0):
class box(models.Model):
_name='box'
@api.one
@api.depends('child_ids', 'child_ids.value')
def _compute_value(self):
if self.child_ids:
self.value = sum(
[child.value for child in self.child_ids])
def _set_value(self):
pass
parent_id = fields.Many2one(comodel_name='box',
string='Parent Box')
child_ids = fields.One2many(comodel_name='box',
inverse_name='parent_id',
string='Boxes inside')
value = fields.Float(
string='Value',
compute='_compute_value',
inverse='_set_value',
store=False,
required=True,
readonly=True,
states={'draft':[('readonly',False)]},
)
Upvotes: 0
Views: 4128
Reputation: 1575
in the model
computed_field = fields.Char(compute='comp', inverse='inv', store=True)
boolean_field = fields.Boolean()
@api.one
def comp(self):
...
@api.one
def inv(self):
...
in the view
<field name="boolean_field" />
<field name="computed_field" attrs="{'readonly': [('boolean_field','=',True)]}" />
edit:
now that your example is more clear, i'd say you should change the following:
set value's store parameter to True instead of False and just remove the inverse which, in your case, you don't need.
then you need another 2 fields
value_manual = fields.Float()
manual = fields.Boolean(compute='_is_manual', default=True)
@api.one
@api.depends('child_ids')
def _is_manual(self):
self.manual = len(self.child_ids) == 0
plus
@api.one
@api.depends('child_ids', 'child_ids.value')
def _compute_value(self):
if self.child_ids:
self.value = sum(
[child.value for child in self.child_ids])
else:
self.value = self.value_manual
in the view:
<field name="manual" invisible="1" />
<field name="value" attrs="{'invisible': [('manual','=',True)]}" />
<field name="value_manual" attrs="{'invisible': [('manual','=',False)]}" />
There could be another solution that avoid this double field, maybe using the inverse, but I am not sure.
Upvotes: 2