[FIX] core: find currency when writing monetary field

When creating a record, if a value is related to a monetary field and if
the currency field is a non-stored related one, the value will not be
rounding: when writing the monetary value in the database, we first call
`convert_to_column`. In the parameter, `record` is empty (it is not yet
created) and `values` only contains the stored values (so the currency
value is not present). As a result, `currency` will not be defined and
the value will not be rounded.

OPW-2955202

closes odoo/odoo#106283

X-original-commit: 28196693b50b9d424887391ad13db69c5f5dfe4f
Related: odoo/enterprise#34265
Signed-off-by: Raphael Collet <rco@odoo.com>
Signed-off-by: Adrien Widart <awt@odoo.com>
This commit is contained in:
Adrien Widart (awt)
2022-11-23 11:26:28 +01:00
parent 51b5ee8d5f
commit e762362ef0
3 changed files with 28 additions and 6 deletions
@@ -868,6 +868,7 @@ class MonetaryRelated(models.Model):
monetary_id = fields.Many2one('test_new_api.monetary_base')
currency_id = fields.Many2one('res.currency', related='monetary_id.base_currency_id')
amount = fields.Monetary(related='monetary_id.amount')
total = fields.Monetary()
class MonetaryCustom(models.Model):
@@ -933,6 +933,23 @@ class TestFields(TransactionCaseWithUserDemo):
})
check(1.0)
def test_20_monetary_related(self):
""" test value rounding with related currency """
currency = self.env.ref('base.USD')
monetary_base = self.env['test_new_api.monetary_base'].create({
'base_currency_id': currency.id
})
monetary_related = self.env['test_new_api.monetary_related'].create({
'monetary_id': monetary_base.id,
'total': 1/3,
})
self.env.cr.execute(
"SELECT total FROM test_new_api_monetary_related WHERE id=%s",
monetary_related.ids,
)
[total] = self.env.cr.fetchone()
self.assertEqual(total, .33)
def test_20_like(self):
""" test filtered_domain() on char fields. """
record = self.env['test_new_api.multi.tag'].create({'name': 'Foo'})
+10 -6
View File
@@ -1569,17 +1569,21 @@ class Monetary(Field):
def convert_to_column(self, value, record, values=None, validate=True):
# retrieve currency from values or record
currency_field = self.get_currency_field(record)
if values and currency_field in values:
field = record._fields[currency_field]
currency = field.convert_to_cache(values[currency_field], record, validate)
currency = field.convert_to_record(currency, record)
currency_field_name = self.get_currency_field(record)
currency_field = record._fields[currency_field_name]
if values and currency_field_name in values:
dummy = record.new({currency_field_name: values[currency_field_name]})
currency = dummy[currency_field_name]
elif values and currency_field.related and currency_field.related.split('.')[0] in values:
related_field_name = currency_field.related.split('.')[0]
dummy = record.new({related_field_name: values[related_field_name]})
currency = dummy[currency_field_name]
else:
# Note: this is wrong if 'record' is several records with different
# currencies, which is functional nonsense and should not happen
# BEWARE: do not prefetch other fields, because 'value' may be in
# cache, and would be overridden by the value read from database!
currency = record[:1].with_context(prefetch_fields=False)[currency_field]
currency = record[:1].with_context(prefetch_fields=False)[currency_field_name]
currency = currency.with_env(record.env)
value = float(value or 0.0)