[FIX] web: fix float value representation in export
- Create a product with: Cost: 60.80 Quantity On Hand: 999.0 - Go to Inventory / Reporting / Inventory Valuation - Click on export all (little button next to "Inventory at date") The field "Total value" have too many decimals: 60739.2000000004 This occur because of the multiplication: it yield the correct value (60739.2), but every rounding attempt done, even in the ORM, will mess up the representation https://github.com/odoo/odoo/blob/042298f8c949fba470eda6ad90f94c95ca291030/odoo/fields.py#L1333 opw-2438384 closes odoo/odoo#67558 X-original-commit: 67cf82962688360cfe25c6b2118a7dbd17a6ee95 Signed-off-by: agr-odoo <agr-odoo@users.noreply.github.com>
This commit is contained in:
@@ -20,6 +20,8 @@ class GroupOperator(models.Model):
|
||||
int_max = fields.Integer(group_operator='max')
|
||||
float_min = fields.Float(group_operator='min')
|
||||
float_avg = fields.Float(group_operator='avg')
|
||||
float_monetary = fields.Monetary(currency_field='currency_id', group_operator='sum')
|
||||
currency_id = fields.Many2one('res.currency')
|
||||
date_max = fields.Date(group_operator='max')
|
||||
bool_and = fields.Boolean(group_operator='bool_and')
|
||||
bool_or = fields.Boolean(group_operator='bool_or')
|
||||
|
||||
@@ -50,6 +50,7 @@ class XlsxCreatorCase(common.HttpCase):
|
||||
params['fields'] = [{
|
||||
'name': self.model._fields[f].name,
|
||||
'label': self.model._fields[f].string,
|
||||
'type': self.model._fields[f].type,
|
||||
} for f in fields]
|
||||
|
||||
with patch.object(ExportXlsxWriter, 'write', self._mock_write):
|
||||
@@ -340,3 +341,31 @@ class TestGroupedExport(XlsxCreatorCase):
|
||||
[' Undefined (1)' ,''],
|
||||
['10' ,''],
|
||||
])
|
||||
|
||||
def test_float_representation(self):
|
||||
currency = self.env['res.currency'].create({
|
||||
'name': "bottlecap",
|
||||
'symbol': "b",
|
||||
'rounding': 0.001,
|
||||
'decimal_places': 3,
|
||||
})
|
||||
|
||||
values = [
|
||||
{'int_sum': 1, 'currency_id': currency.id, 'float_monetary': 60739.2000000004},
|
||||
{'int_sum': 2, 'currency_id': currency.id, 'float_monetary': 2.0},
|
||||
{'int_sum': 3, 'currency_id': currency.id, 'float_monetary': 999.9995999},
|
||||
]
|
||||
export = self.export(values, fields=['int_sum', 'float_monetary'], params={'groupby': ['int_sum', 'float_monetary']})
|
||||
|
||||
self.assertExportEqual(export, [
|
||||
['Int Sum', 'Float Monetary'],
|
||||
['1 (1)', '60739.200'],
|
||||
[' 60739.2 (1)', '60739.200'],
|
||||
['1', '60739.2'],
|
||||
['2 (1)', '2.000'],
|
||||
[' 2.0 (1)', '2.000'],
|
||||
['2', '2.0'],
|
||||
['3 (1)', '1000.000'],
|
||||
[' 1000.0 (1)', '1000.000'],
|
||||
['3', '1000.0'],
|
||||
])
|
||||
|
||||
@@ -854,13 +854,25 @@ class GroupExportXlsxWriter(ExportXlsxWriter):
|
||||
|
||||
label = '%s%s (%s)' % (' ' * group_depth, label, group.count)
|
||||
self.write(row, column, label, self.header_bold_style)
|
||||
if any(f.get('type') == 'monetary' for f in self.fields[1:]):
|
||||
|
||||
decimal_places = [res['decimal_places'] for res in group._model.env['res.currency'].search_read([], ['decimal_places'])]
|
||||
decimal_places = max(decimal_places) if decimal_places else 2
|
||||
for field in self.fields[1:]: # No aggregates allowed in the first column because of the group title
|
||||
column += 1
|
||||
aggregated_value = aggregates.get(field['name'])
|
||||
# Non-stored float fields may not be displayed properly because of float representation
|
||||
# => we force 2 digits
|
||||
if not field.get('store') and isinstance(aggregated_value, float):
|
||||
aggregated_value = float_repr(aggregated_value, 2)
|
||||
# Float fields may not be displayed properly because of float
|
||||
# representation issue with non stored fields or with values
|
||||
# that, even stored, cannot be rounded properly and it is not
|
||||
# acceptable to display useless digits (i.e. monetary)
|
||||
#
|
||||
# non stored field -> we force 2 digits
|
||||
# stored monetary -> we force max digits of installed currencies
|
||||
if isinstance(aggregated_value, float):
|
||||
if field.get('type') == 'monetary':
|
||||
aggregated_value = float_repr(aggregated_value, decimal_places)
|
||||
elif not field.get('store'):
|
||||
aggregated_value = float_repr(aggregated_value, 2)
|
||||
self.write(row, column, str(aggregated_value if aggregated_value is not None else ''), self.header_bold_style)
|
||||
return row + 1, 0
|
||||
|
||||
|
||||
@@ -121,6 +121,7 @@ var DataExport = Dialog.extend({
|
||||
name: field,
|
||||
label: this.record.fields[field].string,
|
||||
store: this.record.fields[field].store,
|
||||
type: this.record.fields[field].type,
|
||||
}));
|
||||
this._exportData(exportedFields, 'xlsx', false);
|
||||
},
|
||||
|
||||
@@ -323,9 +323,11 @@ QUnit.module('widgets', {
|
||||
fields: [{
|
||||
name: 'foo',
|
||||
label: 'Foo',
|
||||
type: 'char',
|
||||
}, {
|
||||
name: 'bar',
|
||||
label: 'Bar',
|
||||
type: 'char',
|
||||
}]
|
||||
}, "should be called with correct params");
|
||||
args.complete();
|
||||
@@ -368,9 +370,11 @@ QUnit.module('widgets', {
|
||||
fields: [{
|
||||
name: 'foo',
|
||||
label: 'Foo',
|
||||
type: 'char',
|
||||
}, {
|
||||
name: 'bar',
|
||||
label: 'Bar',
|
||||
type: 'char',
|
||||
}]
|
||||
}, "should be called with correct params");
|
||||
args.complete();
|
||||
|
||||
Reference in New Issue
Block a user