[REF] core: add method get_currency_field() on Monetary to retrieve it
This replaces the setup of the attribute 'currency_field', which depends on the presence of other fields on the model, and may therefore vary from one registry to another. This is necessary to make monetary fields shareable across registries.
This commit is contained in:
@@ -355,8 +355,8 @@ class AccountMove(models.Model):
|
||||
return current_ids != after_write_ids
|
||||
if field.type == 'one2many':
|
||||
return True
|
||||
if field.type == 'monetary' and record[field.currency_field]:
|
||||
return not record[field.currency_field].is_zero(record[field_name] - vals[field_name])
|
||||
if field.type == 'monetary' and record[field.get_currency_field(record)]:
|
||||
return not record[field.get_currency_field(record)].is_zero(record[field_name] - vals[field_name])
|
||||
if field.type == 'float':
|
||||
record_value = field.convert_to_cache(record[field_name], record)
|
||||
to_write_value = field.convert_to_cache(vals[field_name], record)
|
||||
|
||||
@@ -241,7 +241,7 @@ class WebsiteSnippetFilter(models.Model):
|
||||
elif field_widget == 'monetary':
|
||||
model_currency = None
|
||||
if field and field.type == 'monetary':
|
||||
model_currency = record[record[field_name].currency_field]
|
||||
model_currency = record[field.get_currency_field(record)]
|
||||
elif 'currency_id' in model._fields:
|
||||
model_currency = record['currency_id']
|
||||
if model_currency:
|
||||
|
||||
@@ -460,8 +460,8 @@ class MonetaryConverter(models.AbstractModel):
|
||||
#currency should be specified by monetary field
|
||||
field = record._fields[field_name]
|
||||
|
||||
if not options.get('display_currency') and field.type == 'monetary' and field.currency_field:
|
||||
options['display_currency'] = record[field.currency_field]
|
||||
if not options.get('display_currency') and field.type == 'monetary' and field.get_currency_field(record):
|
||||
options['display_currency'] = record[field.get_currency_field(record)]
|
||||
if not options.get('display_currency'):
|
||||
# search on the model if they are a res.currency field to set as default
|
||||
fields = record._fields.items()
|
||||
|
||||
@@ -2042,22 +2042,26 @@ class TestFields(TransactionCaseWithUserDemo):
|
||||
def test_93_monetary_related(self):
|
||||
""" Check the currency field on related monetary fields. """
|
||||
# check base field
|
||||
field = self.env['test_new_api.monetary_base']._fields['amount']
|
||||
self.assertEqual(field.currency_field, 'base_currency_id')
|
||||
model = self.env['test_new_api.monetary_base']
|
||||
field = model._fields['amount']
|
||||
self.assertEqual(field.get_currency_field(model), 'base_currency_id')
|
||||
|
||||
# related fields must use the field 'currency_id' or 'x_currency_id'
|
||||
field = self.env['test_new_api.monetary_related']._fields['amount']
|
||||
model = self.env['test_new_api.monetary_related']
|
||||
field = model._fields['amount']
|
||||
self.assertEqual(field.related, ('monetary_id', 'amount'))
|
||||
self.assertEqual(field.currency_field, 'currency_id')
|
||||
self.assertEqual(field.get_currency_field(model), 'currency_id')
|
||||
|
||||
field = self.env['test_new_api.monetary_custom']._fields['x_amount']
|
||||
model = self.env['test_new_api.monetary_custom']
|
||||
field = model._fields['x_amount']
|
||||
self.assertEqual(field.related, ('monetary_id', 'amount'))
|
||||
self.assertEqual(field.currency_field, 'x_currency_id')
|
||||
self.assertEqual(field.get_currency_field(model), 'x_currency_id')
|
||||
|
||||
# inherited field must use the same field as its parent field
|
||||
field = self.env['test_new_api.monetary_inherits']._fields['amount']
|
||||
model = self.env['test_new_api.monetary_inherits']
|
||||
field = model._fields['amount']
|
||||
self.assertEqual(field.related, ('monetary_id', 'amount'))
|
||||
self.assertEqual(field.currency_field, 'base_currency_id')
|
||||
self.assertEqual(field.get_currency_field(model), 'base_currency_id')
|
||||
|
||||
def test_94_image(self):
|
||||
f = io.BytesIO()
|
||||
|
||||
+21
-18
@@ -1422,40 +1422,42 @@ class Monetary(Field):
|
||||
def __init__(self, string=Default, currency_field=Default, **kwargs):
|
||||
super(Monetary, self).__init__(string=string, currency_field=currency_field, **kwargs)
|
||||
|
||||
_description_currency_field = property(attrgetter('currency_field'))
|
||||
def _description_currency_field(self, env):
|
||||
return self.get_currency_field(env[self.model_name])
|
||||
|
||||
def _setup_currency_field(self, model):
|
||||
if not self.currency_field:
|
||||
# pick a default, trying in order: 'currency_id', 'x_currency_id'
|
||||
if 'currency_id' in model._fields:
|
||||
self.currency_field = 'currency_id'
|
||||
elif 'x_currency_id' in model._fields:
|
||||
self.currency_field = 'x_currency_id'
|
||||
assert self.currency_field in model._fields, \
|
||||
"Field %s with unknown currency_field %r" % (self, self.currency_field)
|
||||
def get_currency_field(self, model):
|
||||
""" Return the name of the currency field. """
|
||||
return self.currency_field or (
|
||||
'currency_id' if 'currency_id' in model._fields else
|
||||
'x_currency_id' if 'x_currency_id' in model._fields else
|
||||
None
|
||||
)
|
||||
|
||||
def setup_nonrelated(self, model):
|
||||
super().setup_nonrelated(model)
|
||||
self._setup_currency_field(model)
|
||||
assert self.get_currency_field(model) in model._fields, \
|
||||
"Field %s with unknown currency_field %r" % (self, self.get_currency_field(model))
|
||||
|
||||
def setup_related(self, model):
|
||||
super().setup_related(model)
|
||||
if self.inherited:
|
||||
self.currency_field = self.related_field.currency_field
|
||||
self._setup_currency_field(model)
|
||||
self.currency_field = self.related_field.get_currency_field(model.env[self.related_field.model_name])
|
||||
assert self.get_currency_field(model) in model._fields, \
|
||||
"Field %s with unknown currency_field %r" % (self, self.get_currency_field(model))
|
||||
|
||||
def convert_to_column(self, value, record, values=None, validate=True):
|
||||
# retrieve currency from values or record
|
||||
if values and self.currency_field in values:
|
||||
field = record._fields[self.currency_field]
|
||||
currency = field.convert_to_cache(values[self.currency_field], record, validate)
|
||||
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)
|
||||
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)[self.currency_field]
|
||||
currency = record[:1].with_context(prefetch_fields=False)[currency_field]
|
||||
|
||||
value = float(value or 0.0)
|
||||
if currency:
|
||||
@@ -1470,7 +1472,8 @@ class Monetary(Field):
|
||||
# a function or related field!
|
||||
# BEWARE: do not prefetch other fields, because 'value' may be in
|
||||
# cache, and would be overridden by the value read from database!
|
||||
currency = record.sudo().with_context(prefetch_fields=False)[self.currency_field]
|
||||
currency_field = self.get_currency_field(record)
|
||||
currency = record.sudo().with_context(prefetch_fields=False)[currency_field]
|
||||
if len(currency) > 1:
|
||||
raise ValueError("Got multiple currencies while assigning values of monetary field %s" % str(self))
|
||||
elif currency:
|
||||
|
||||
@@ -540,7 +540,7 @@ class BaseCase(unittest.TestCase, metaclass=MetaCase):
|
||||
field_type = field.type
|
||||
if field_type == 'monetary':
|
||||
# Compare monetary field.
|
||||
currency_field_name = record._fields[field_name].currency_field
|
||||
currency_field_name = record._fields[field_name].get_currency_field(record)
|
||||
record_currency = record[currency_field_name]
|
||||
if field_name not in candidate:
|
||||
diff[field_name] = (record_value, None)
|
||||
|
||||
Reference in New Issue
Block a user