0
votes

I've defined a new field on the product.product model using the UI in Odoo V10. The field is defined like this:

Name = x_sellable_inventory
Type = float
Readonly = true
Dependencies = qty_available,outgoing_qty

the Compute method is:

for record in self:
    record['x_sellable_inventory'] = record.qty_available - record.outgoing_qty

I added this field to a view and confirmed that it's changing correctly if the on-hand inventory is adjusted for the product. So far everything is working as expected.

Now, I want to be able to access this value from a sale.order.line, so I created a related field on the sale.order.line to access it. It's defined like this:

Name =  x_product_sellable_inventory_new
Type = float
Readonly = true
Stored = true
Related Field = product_id.x_sellable_inventory

I then added this field to the sale order view so I can see it in the list of order lines. It appears once for each order line in the tree.

Now, when I change the on-hand quantity for the product, it still updates correctly on the product view, but the value on the sale order line never changes. It never changes from that initial time it was set.

If I uncheck the Store option, the value gets updated correctly. What is happening here? Why does it matter if the related field is Stored or not? Shouldn't it get updated whenever the value of product_id.x_sellable_inventory changes?

2

2 Answers

3
votes

Computed fields are not stored by default. Which you know. This causes issues when you wish to be able to perform functions which require the data be available in the database.

To fix this Odoo provides the store=True flag on a computed field.

The gotcha is that it only fires once. In order to get around this you need to use the @api.depends decorator (as @danidee and @CZoellner had stated) in order to have your field updated every time your related field or fields is changed.

@api.depends can also receive a comma separated list of field names.

@api.depends('field_name')

OR

@api.depends('field_name','another_field_name')

@api.one
@api.depends('field2')
def _compute_field1(self):
    self.field1 = SOMETHING THAT OCCURS EVERY TIME `field2` CHANGES


field1 = fields.Char(compute=_compute_field1,store=True)
field2 = fields.Char()
1
votes

I think my issues here was that the fields I was trying to use as dependencies were not stored themselves. It seems that the fields need to be stored in order to function correctly as dependencies, which makes sense. The model has no way of knowing the dependent field has changed if it's not a field that is stored in the database. qty_available and outgoing_qty are not stored fields.