[REF] web: remove raw_mode flag on export
The export is now always in raw_mode Adapt the tests Fixes odoo/odoo#18798 closes odoo/odoo#26724 Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
This commit is contained in:
@@ -1604,10 +1604,10 @@ class Meeting(models.Model):
|
||||
self.env['calendar.alarm_manager']._notify_next_alarm(meeting.partner_ids.ids)
|
||||
return meeting
|
||||
|
||||
def export_data(self, fields_to_export, raw_data=False):
|
||||
def export_data(self, fields_to_export):
|
||||
""" Override to convert virtual ids to ids """
|
||||
records = self.browse(set(get_real_ids(self.ids)))
|
||||
return super(Meeting, records).export_data(fields_to_export, raw_data)
|
||||
return super(Meeting, records).export_data(fields_to_export)
|
||||
|
||||
@api.model
|
||||
def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True):
|
||||
|
||||
@@ -1576,7 +1576,6 @@ class Export(http.Controller):
|
||||
for k, v in self.fields_info(model, export_fields).items())
|
||||
|
||||
class ExportFormat(object):
|
||||
raw_data = False
|
||||
|
||||
@property
|
||||
def content_type(self):
|
||||
@@ -1612,7 +1611,7 @@ class ExportFormat(object):
|
||||
fields = [field for field in fields if field['name'] != 'id']
|
||||
|
||||
field_names = [f['name'] for f in fields]
|
||||
import_data = records.export_data(field_names, self.raw_data).get('datas',[])
|
||||
import_data = records.export_data(field_names).get('datas',[])
|
||||
|
||||
if import_compat:
|
||||
columns_headers = field_names
|
||||
@@ -1658,8 +1657,6 @@ class CSVExport(ExportFormat, http.Controller):
|
||||
return fp.getvalue()
|
||||
|
||||
class ExcelExport(ExportFormat, http.Controller):
|
||||
# Excel needs raw data to correctly handle numbers and date values
|
||||
raw_data = True
|
||||
|
||||
@http.route('/web/export/xls', type='http', auth="user")
|
||||
@serialize_exception
|
||||
|
||||
@@ -5,6 +5,7 @@ import itertools
|
||||
import pstats
|
||||
from cProfile import Profile
|
||||
|
||||
from odoo import fields
|
||||
from odoo.tests import common
|
||||
|
||||
|
||||
@@ -42,7 +43,7 @@ class test_xids(CreatorCase):
|
||||
record.invalidate_cache()
|
||||
self.assertEqual(
|
||||
record._export_rows([['id'], ['value']]),
|
||||
[[u'x', u'True']]
|
||||
[[u'x', True]]
|
||||
)
|
||||
|
||||
class test_boolean_field(CreatorCase):
|
||||
@@ -51,7 +52,7 @@ class test_boolean_field(CreatorCase):
|
||||
def test_true(self):
|
||||
self.assertEqual(
|
||||
self.export(True),
|
||||
[[u'True']])
|
||||
[[True]])
|
||||
|
||||
def test_false(self):
|
||||
""" ``False`` value to boolean fields is unique in being exported as a
|
||||
@@ -59,7 +60,7 @@ class test_boolean_field(CreatorCase):
|
||||
"""
|
||||
self.assertEqual(
|
||||
self.export(False),
|
||||
[[u'False']])
|
||||
[[False]])
|
||||
|
||||
|
||||
class test_integer_field(CreatorCase):
|
||||
@@ -72,22 +73,22 @@ class test_integer_field(CreatorCase):
|
||||
def test_0(self):
|
||||
self.assertEqual(
|
||||
self.export(0),
|
||||
[[u'0']])
|
||||
[[0]])
|
||||
|
||||
def test_basic_value(self):
|
||||
self.assertEqual(
|
||||
self.export(42),
|
||||
[[u'42']])
|
||||
[[42]])
|
||||
|
||||
def test_negative(self):
|
||||
self.assertEqual(
|
||||
self.export(-32),
|
||||
[[u'-32']])
|
||||
[[-32]])
|
||||
|
||||
def test_huge(self):
|
||||
self.assertEqual(
|
||||
self.export(2**31-1),
|
||||
[[str(2**31-1)]])
|
||||
[[2147483647]])
|
||||
|
||||
|
||||
class test_float_field(CreatorCase):
|
||||
@@ -96,27 +97,27 @@ class test_float_field(CreatorCase):
|
||||
def test_0(self):
|
||||
self.assertEqual(
|
||||
self.export(0.0),
|
||||
[[u'0.0']])
|
||||
[[0.0]])
|
||||
|
||||
def test_epsilon(self):
|
||||
self.assertEqual(
|
||||
self.export(0.000000000027),
|
||||
[[u'2.7e-11']])
|
||||
[[0.000000000027]])
|
||||
|
||||
def test_negative(self):
|
||||
self.assertEqual(
|
||||
self.export(-2.42),
|
||||
[[u'-2.42']])
|
||||
[[-2.42]])
|
||||
|
||||
def test_positive(self):
|
||||
self.assertEqual(
|
||||
self.export(47.36),
|
||||
[[u'47.36']])
|
||||
[[47.36]])
|
||||
|
||||
def test_big(self):
|
||||
self.assertEqual(
|
||||
self.export(87654321.4678),
|
||||
[[u'87654321.4678']])
|
||||
[[87654321.4678]])
|
||||
|
||||
|
||||
class test_decimal_field(CreatorCase):
|
||||
@@ -125,28 +126,28 @@ class test_decimal_field(CreatorCase):
|
||||
def test_0(self):
|
||||
self.assertEqual(
|
||||
self.export(0.0),
|
||||
[[u'0.0']])
|
||||
[[0.0]])
|
||||
|
||||
def test_epsilon(self):
|
||||
""" epsilon gets sliced to 0 due to precision
|
||||
"""
|
||||
self.assertEqual(
|
||||
self.export(0.000000000027),
|
||||
[[u'0.0']])
|
||||
[[0.0]])
|
||||
|
||||
def test_negative(self):
|
||||
self.assertEqual(
|
||||
self.export(-2.42),
|
||||
[[u'-2.42']])
|
||||
[[-2.42]])
|
||||
|
||||
def test_positive(self):
|
||||
self.assertEqual(
|
||||
self.export(47.36),
|
||||
[[u'47.36']])
|
||||
[[47.36]])
|
||||
|
||||
def test_big(self):
|
||||
self.assertEqual(
|
||||
self.export(87654321.4678), [[u'87654321.468']])
|
||||
self.export(87654321.4678), [[87654321.468]])
|
||||
|
||||
|
||||
class test_string_field(CreatorCase):
|
||||
@@ -218,6 +219,10 @@ class test_text(CreatorCase):
|
||||
u" programming in the A-normal form. That is indeed all there"
|
||||
u" is to monads"]])
|
||||
|
||||
def test_numeric(self):
|
||||
self.assertEqual(
|
||||
self.export(42),
|
||||
[["42"]])
|
||||
|
||||
class test_date(CreatorCase):
|
||||
model_name = 'export.date'
|
||||
@@ -230,7 +235,7 @@ class test_date(CreatorCase):
|
||||
def test_basic(self):
|
||||
self.assertEqual(
|
||||
self.export('2011-11-07'),
|
||||
[[u'2011-11-07']])
|
||||
[[fields.Date.from_string('2011-11-07')]])
|
||||
|
||||
|
||||
class test_datetime(CreatorCase):
|
||||
@@ -247,7 +252,7 @@ class test_datetime(CreatorCase):
|
||||
self.env.user.write({'tz': False})
|
||||
self.assertEqual(
|
||||
self.export('2011-11-07 21:05:48'),
|
||||
[[u'2011-11-07 21:05:48']])
|
||||
[[fields.Datetime.from_string('2011-11-07 21:05:48')]])
|
||||
|
||||
def test_tz(self):
|
||||
""" Export converts the value in the user's TZ
|
||||
@@ -256,7 +261,7 @@ class test_datetime(CreatorCase):
|
||||
"""
|
||||
self.assertEqual(
|
||||
self.export('2011-11-07 21:05:48', context={'tz': 'Pacific/Norfolk'}),
|
||||
[[u'2011-11-08 08:35:48']])
|
||||
[[fields.Datetime.from_string('2011-11-08 08:35:48')]])
|
||||
|
||||
|
||||
class test_selection(CreatorCase):
|
||||
@@ -270,7 +275,7 @@ class test_selection(CreatorCase):
|
||||
def test_empty(self):
|
||||
self.assertEqual(
|
||||
self.export(False),
|
||||
[[False]])
|
||||
[['']])
|
||||
|
||||
def test_value(self):
|
||||
""" selections export the *label* for their value
|
||||
@@ -339,7 +344,7 @@ class test_m2o(CreatorCase):
|
||||
record = self.env['export.integer'].create({'value': 42})
|
||||
self.assertEqual(
|
||||
self.export(record.id, fields=['value/.id', 'value/value']),
|
||||
[[str(record.id), '42']])
|
||||
[[str(record.id), 42]])
|
||||
|
||||
def test_external_id(self):
|
||||
record = self.env['export.integer'].create({'value': 42})
|
||||
@@ -395,30 +400,30 @@ class test_o2m(CreatorCase):
|
||||
self.assertEqual(
|
||||
self.export([(0, False, {'value': 42})],
|
||||
fields=['value', 'value/value']),
|
||||
[[u'export.one2many.child:42', u'42']])
|
||||
[[u'export.one2many.child:42', 42]])
|
||||
|
||||
def test_integrate_one_in_parent(self):
|
||||
self.assertEqual(
|
||||
self.export([(0, False, {'value': 42})],
|
||||
fields=['const', 'value/value']),
|
||||
[[u'4', u'42']])
|
||||
[[4, 42]])
|
||||
|
||||
def test_multiple_records(self):
|
||||
self.assertEqual(
|
||||
self.export(self.commands, fields=['const', 'value/value']),
|
||||
[
|
||||
[u'4', u'4'],
|
||||
[u'', u'42'],
|
||||
[u'', u'36'],
|
||||
[u'', u'4'],
|
||||
[u'', u'13'],
|
||||
[4, 4],
|
||||
[u'', 42],
|
||||
[u'', 36],
|
||||
[u'', 4],
|
||||
[u'', 13],
|
||||
])
|
||||
|
||||
def test_multiple_records_name(self):
|
||||
self.assertEqual(
|
||||
self.export(self.commands, fields=['const', 'value']),
|
||||
[
|
||||
[u'4', u'export.one2many.child:4'],
|
||||
[4, u'export.one2many.child:4'],
|
||||
[u'', u'export.one2many.child:42'],
|
||||
[u'', u'export.one2many.child:36'],
|
||||
[u'', u'export.one2many.child:4'],
|
||||
@@ -431,7 +436,7 @@ class test_o2m(CreatorCase):
|
||||
self.assertEqual(
|
||||
export,
|
||||
[
|
||||
['4', str(records[0].id)],
|
||||
[4, str(records[0].id)],
|
||||
['', str(records[1].id)],
|
||||
['', str(records[2].id)],
|
||||
['', str(records[3].id)],
|
||||
@@ -442,44 +447,44 @@ class test_o2m(CreatorCase):
|
||||
self.assertEqual(
|
||||
self.export(self.commands, fields=['const', 'value', 'value/value']),
|
||||
[
|
||||
[u'4', u'export.one2many.child:4', u'4'],
|
||||
['', u'export.one2many.child:42', u'42'],
|
||||
['', u'export.one2many.child:36', u'36'],
|
||||
['', u'export.one2many.child:4', u'4'],
|
||||
['', u'export.one2many.child:13', u'13'],
|
||||
[4, u'export.one2many.child:4', 4],
|
||||
['', u'export.one2many.child:42', 42],
|
||||
['', u'export.one2many.child:36', 36],
|
||||
['', u'export.one2many.child:4', 4],
|
||||
['', u'export.one2many.child:13', 13],
|
||||
])
|
||||
|
||||
def test_multiple_records_with_name_after(self):
|
||||
self.assertEqual(
|
||||
self.export(self.commands, fields=['const', 'value/value', 'value']),
|
||||
[
|
||||
[u'4', u'4', u'export.one2many.child:4'],
|
||||
['', u'42', u'export.one2many.child:42'],
|
||||
['', u'36', u'export.one2many.child:36'],
|
||||
['', u'4', u'export.one2many.child:4'],
|
||||
['', u'13', u'export.one2many.child:13'],
|
||||
[4, 4, u'export.one2many.child:4'],
|
||||
['', 42, u'export.one2many.child:42'],
|
||||
['', 36, u'export.one2many.child:36'],
|
||||
['', 4, u'export.one2many.child:4'],
|
||||
['', 13, u'export.one2many.child:13'],
|
||||
])
|
||||
|
||||
def test_multiple_subfields_neighbour(self):
|
||||
self.assertEqual(
|
||||
self.export(self.commands, fields=['const', 'value/str','value/value']),
|
||||
[
|
||||
[u'4', u'record1', u'4'],
|
||||
['', u'record2', u'42'],
|
||||
['', u'record3', u'36'],
|
||||
['', u'record4', u'4'],
|
||||
['', u'record5', u'13'],
|
||||
[4, u'record1', 4],
|
||||
['', u'record2', 42],
|
||||
['', u'record3', 36],
|
||||
['', u'record4', 4],
|
||||
['', u'record5', 13],
|
||||
])
|
||||
|
||||
def test_multiple_subfields_separated(self):
|
||||
self.assertEqual(
|
||||
self.export(self.commands, fields=['value/str', 'const', 'value/value']),
|
||||
[
|
||||
[u'record1', u'4', u'4'],
|
||||
[u'record2', '', u'42'],
|
||||
[u'record3', '', u'36'],
|
||||
[u'record4', '', u'4'],
|
||||
[u'record5', '', u'13'],
|
||||
[u'record1', 4, 4],
|
||||
[u'record2', '', 42],
|
||||
[u'record3', '', 36],
|
||||
[u'record4', '', 4],
|
||||
[u'record5', '', 13],
|
||||
])
|
||||
|
||||
|
||||
@@ -519,18 +524,18 @@ class test_o2m_multiple(CreatorCase):
|
||||
self.assertEqual(
|
||||
self.export(child1=False, child2=[(0, False, {'value': 42})],
|
||||
fields=fields),
|
||||
[[u'36', False, u'42']])
|
||||
[[36, False, 42]])
|
||||
|
||||
self.assertEqual(
|
||||
self.export(child1=[(0, False, {'value': 43})], child2=False,
|
||||
fields=fields),
|
||||
[[u'36', u'43', False]])
|
||||
[[36, 43, False]])
|
||||
|
||||
self.assertEqual(
|
||||
self.export(child1=[(0, False, {'value': 43})],
|
||||
child2=[(0, False, {'value': 42})],
|
||||
fields=fields),
|
||||
[[u'36', u'43', u'42']])
|
||||
[[36, 43, 42]])
|
||||
|
||||
def test_multiple(self):
|
||||
""" With two "concurrent" o2ms, exports the first line combined, then
|
||||
@@ -545,35 +550,35 @@ class test_o2m_multiple(CreatorCase):
|
||||
self.assertEqual(
|
||||
self.export(child1=child1, child2=False, fields=fields),
|
||||
[
|
||||
[u'36', u'4', False],
|
||||
['', u'42', ''],
|
||||
['', u'36', ''],
|
||||
['', u'4', ''],
|
||||
['', u'13', ''],
|
||||
[36, 4, False],
|
||||
['', 42, ''],
|
||||
['', 36, ''],
|
||||
['', 4, ''],
|
||||
['', 13, ''],
|
||||
])
|
||||
self.assertEqual(
|
||||
self.export(child1=False, child2=child2, fields=fields),
|
||||
[
|
||||
[u'36', False, u'8'],
|
||||
['', '', u'12'],
|
||||
['', '', u'8'],
|
||||
['', '', u'55'],
|
||||
['', '', u'33'],
|
||||
['', '', u'13'],
|
||||
[36, False, 8],
|
||||
['', '', 12],
|
||||
['', '', 8],
|
||||
['', '', 55],
|
||||
['', '', 33],
|
||||
['', '', 13],
|
||||
])
|
||||
self.assertEqual(
|
||||
self.export(child1=child1, child2=child2, fields=fields),
|
||||
[
|
||||
[u'36', u'4', u'8'],
|
||||
['', u'42', ''],
|
||||
['', u'36', ''],
|
||||
['', u'4', ''],
|
||||
['', u'13', ''],
|
||||
['', '', u'12'],
|
||||
['', '', u'8'],
|
||||
['', '', u'55'],
|
||||
['', '', u'33'],
|
||||
['', '', u'13'],
|
||||
[36, 4, 8],
|
||||
['', 42, ''],
|
||||
['', 36, ''],
|
||||
['', 4, ''],
|
||||
['', 13, ''],
|
||||
['', '', 12],
|
||||
['', '', 8],
|
||||
['', '', 55],
|
||||
['', '', 33],
|
||||
['', '', 13],
|
||||
])
|
||||
|
||||
|
||||
@@ -606,30 +611,30 @@ class test_m2m(CreatorCase):
|
||||
self.assertEqual(
|
||||
self.export([(0, False, {'value': 42})],
|
||||
fields=['value', 'value/value']),
|
||||
[[u'export.many2many.other:42', u'42']])
|
||||
[[u'export.many2many.other:42', 42]])
|
||||
|
||||
def test_integrate_one_in_parent(self):
|
||||
self.assertEqual(
|
||||
self.export([(0, False, {'value': 42})],
|
||||
fields=['const', 'value/value']),
|
||||
[[u'4', u'42']])
|
||||
[[4, 42]])
|
||||
|
||||
def test_multiple_records(self):
|
||||
self.assertEqual(
|
||||
self.export(self.commands, fields=['const', 'value/value']),
|
||||
[
|
||||
[u'4', u'4'],
|
||||
[u'', u'42'],
|
||||
[u'', u'36'],
|
||||
[u'', u'4'],
|
||||
[u'', u'13'],
|
||||
[4, 4],
|
||||
[u'', 42],
|
||||
[u'', 36],
|
||||
[u'', 4],
|
||||
[u'', 13],
|
||||
])
|
||||
|
||||
def test_multiple_records_name(self):
|
||||
self.assertEqual(
|
||||
self.export(self.commands, fields=['const', 'value']),
|
||||
[
|
||||
[u'4', u'export.many2many.other:4'],
|
||||
[4, u'export.many2many.other:4'],
|
||||
['', u'export.many2many.other:42'],
|
||||
['', u'export.many2many.other:36'],
|
||||
['', u'export.many2many.other:4'],
|
||||
@@ -667,21 +672,21 @@ class test_m2m(CreatorCase):
|
||||
self.assertEqual(
|
||||
r.with_context(import_compat=False)._export_rows([['id'], ['value', 'id'], ['value', 'value']]),
|
||||
[
|
||||
[xid, u'__t__.record000', u'4'],
|
||||
[u'', u'__t__.record001', u'42'],
|
||||
[u'', u'__t__.record010', u'36'],
|
||||
[u'', u'__t__.record011', u'4'],
|
||||
[u'', u'__t__.record100', u'13']
|
||||
[xid, u'__t__.record000', 4],
|
||||
[u'', u'__t__.record001', 42],
|
||||
[u'', u'__t__.record010', 36],
|
||||
[u'', u'__t__.record011', 4],
|
||||
[u'', u'__t__.record100', 13]
|
||||
]
|
||||
)
|
||||
self.assertEqual(
|
||||
r.with_context(import_compat=False)._export_rows([['id'], ['value', 'value'], ['value', 'id']]),
|
||||
[
|
||||
[xid, u'4', u'__t__.record000'],
|
||||
[u'', u'42', u'__t__.record001'],
|
||||
[u'', u'36', u'__t__.record010'],
|
||||
[u'', u'4', u'__t__.record011'],
|
||||
[u'', u'13', u'__t__.record100']
|
||||
[xid, 4, u'__t__.record000'],
|
||||
[u'', 42, u'__t__.record001'],
|
||||
[u'', 36, u'__t__.record010'],
|
||||
[u'', 4, u'__t__.record011'],
|
||||
[u'', 13, u'__t__.record100']
|
||||
]
|
||||
)
|
||||
|
||||
@@ -694,7 +699,7 @@ class test_function(CreatorCase):
|
||||
"""
|
||||
self.assertEqual(
|
||||
self.export(42),
|
||||
[[u'3']])
|
||||
[[3]])
|
||||
|
||||
|
||||
@common.tagged('-standard', 'bench')
|
||||
|
||||
+7
-9
@@ -858,7 +858,7 @@ class Field(MetaField('DummyField', (object,), {})):
|
||||
""" Convert ``value`` from the record format to the export format. """
|
||||
if not value:
|
||||
return ''
|
||||
return value if record._context.get('export_raw_data') else ustr(value)
|
||||
return value
|
||||
|
||||
def convert_to_display_name(self, value, record):
|
||||
""" Convert ``value`` from the record format to a suitable display name. """
|
||||
@@ -1214,9 +1214,7 @@ class Boolean(Field):
|
||||
return bool(value)
|
||||
|
||||
def convert_to_export(self, value, record):
|
||||
if record._context.get('export_raw_data'):
|
||||
return value
|
||||
return ustr(value)
|
||||
return value
|
||||
|
||||
|
||||
class Integer(Field):
|
||||
@@ -1250,7 +1248,7 @@ class Integer(Field):
|
||||
|
||||
def convert_to_export(self, value, record):
|
||||
if value or value == 0:
|
||||
return value if record._context.get('export_raw_data') else ustr(value)
|
||||
return value
|
||||
return ''
|
||||
|
||||
|
||||
@@ -1310,7 +1308,7 @@ class Float(Field):
|
||||
|
||||
def convert_to_export(self, value, record):
|
||||
if value or value == 0.0:
|
||||
return value if record._context.get('export_raw_data') else ustr(value)
|
||||
return value
|
||||
return ''
|
||||
|
||||
|
||||
@@ -1671,7 +1669,7 @@ class Date(Field):
|
||||
def convert_to_export(self, value, record):
|
||||
if not value:
|
||||
return ''
|
||||
return self.from_string(value) if record._context.get('export_raw_data') else ustr(value)
|
||||
return self.from_string(value)
|
||||
|
||||
|
||||
class Datetime(Field):
|
||||
@@ -1782,7 +1780,7 @@ class Datetime(Field):
|
||||
if not value:
|
||||
return ''
|
||||
value = self.convert_to_display_name(value, record)
|
||||
return self.from_string(value) if record._context.get('export_raw_data') else ustr(value)
|
||||
return self.from_string(value)
|
||||
|
||||
def convert_to_display_name(self, value, record):
|
||||
assert record, 'Record expected'
|
||||
@@ -2007,7 +2005,7 @@ class Selection(Field):
|
||||
for item in self._description_selection(record.env):
|
||||
if item[0] == value:
|
||||
return item[1]
|
||||
return False
|
||||
return ''
|
||||
|
||||
|
||||
class Reference(Selection):
|
||||
|
||||
+1
-3
@@ -825,7 +825,7 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
|
||||
# backward compatibility
|
||||
__export_rows = _export_rows
|
||||
|
||||
def export_data(self, fields_to_export, raw_data=False):
|
||||
def export_data(self, fields_to_export):
|
||||
""" Export fields for selected objects
|
||||
|
||||
:param fields_to_export: list of fields
|
||||
@@ -835,8 +835,6 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
|
||||
This method is used when exporting data via client menu
|
||||
"""
|
||||
fields_to_export = [fix_import_export_id_paths(f) for f in fields_to_export]
|
||||
if raw_data:
|
||||
self = self.with_context(export_raw_data=True)
|
||||
return {'datas': self._export_rows(fields_to_export)}
|
||||
|
||||
@api.model
|
||||
|
||||
Reference in New Issue
Block a user