Hi Yves,
The @api.one function is indeed being phased out in Odoo V12/V13. The reason behind this is that it was confusing and causing issues for multiple developers. You should now go with @api.multi. With @api.multi you can have multiple records though (for example when opening multiple records somewhere) so you should deal with this. Usually what you do is loop over all the records in the onchange function (so all records within self) and then do your computations on every record in the record set. An example:
@api.multi
def _compute_total_cost(self):
for record in self:
# Find all tasks for this record (which can be one record in a recordset)
task_records = self.env["project.task"].search([("model", "in", record.ids)])
tcost = 0.0
# Loop over your tasks results
for task in task_records:
tcost += task.cost
# Write the result for this record on this record
record.total_cost = tcost
If you're sure that your function is always one record (and want to enforce it) you can also use the self.ensure_one(). The Odoo framework will make sure there is always just one record then. In this case your example would be:
@api.multi
def _compute_total_cost(self):
self.ensure_one()
for rec in records:
task_records = self.env["project.task"].search([("model", "in", self.ids)])
tcost = 0.0
for task in task_records:
tcost += task.cost
record.total_cost = tcost
You can even remove the loop in a self.ensure_one and just work with self, as it should always be one record. I've coded it the same for transparancy about the difference in both functions.
For more information about @api.one and @api.multi see https://www.odoo.com/nl_NL/forum/help-1/question/difference-between-api-one-and-api-multi-in-api-odoo-openerp-68209 and https://www.odoo.com/documentation/12.0/reference/orm.html#recordsets
Regards,
Yenthe