For CSV files, the issue could be an incorrect encoding.
+
For CSV files, you may need to select the correct separator.
Here is the start of the file we could not import:
diff --git a/addons/base_import/tests/test_base_import.py b/addons/base_import/tests/test_base_import.py
index df2d18a3feb..3f5830a8db2 100644
--- a/addons/base_import/tests/test_base_import.py
+++ b/addons/base_import/tests/test_base_import.py
@@ -189,6 +189,31 @@ class TestMatchHeadersMultiple(TransactionCase):
)
+class TestColumnMapping(TransactionCase):
+
+ def test_column_mapping(self):
+ import_record = self.env['base_import.import'].create({
+ 'res_model': 'base_import.tests.models.preview',
+ 'file': u"Name,Some Value,value\n"
+ u"chhagan,10,1\n"
+ u"magan,20,2\n".encode('utf-8'),
+ 'file_type': 'text/csv',
+ 'file_name': 'data.csv',
+ })
+ import_record.do(
+ ['name', 'somevalue', 'othervalue'],
+ ['Name', 'Some Value', 'value'],
+ {'quoting': '"', 'separator': ',', 'headers': True},
+ True
+ )
+ fields = self.env['base_import.mapping'].search_read(
+ [('res_model', '=', 'base_import.tests.models.preview')],
+ ['column_name', 'field_name']
+ )
+ self.assertItemsEqual([f['column_name'] for f in fields], ['Name', 'Some Value', 'value'])
+ self.assertItemsEqual([f['field_name'] for f in fields], ['somevalue', 'name', 'othervalue'])
+
+
class TestPreview(TransactionCase):
def make_import(self):
@@ -207,7 +232,7 @@ class TestPreview(TransactionCase):
'quoting': '"',
'separator': ',',
})
- self.assertTrue('error' in result)
+ self.assertFalse('error' in result)
@mute_logger('odoo.addons.base_import.models.base_import')
def test_csv_errors(self):
@@ -216,14 +241,12 @@ class TestPreview(TransactionCase):
result = import_wizard.parse_preview({
'quoting': 'foo',
'separator': ',',
- 'encoding': 'euc_kr',
})
self.assertTrue('error' in result)
result = import_wizard.parse_preview({
'quoting': '"',
'separator': 'bob',
- 'encoding': 'euc_kr',
})
self.assertTrue('error' in result)
@@ -258,7 +281,7 @@ class TestPreview(TransactionCase):
['qux', '5', '6'],
])
# Ensure we only have the response fields we expect
- self.assertItemsEqual(list(result), ['matches', 'headers', 'fields', 'preview', 'headers_type', 'options', 'debug'])
+ self.assertItemsEqual(list(result), ['matches', 'headers', 'fields', 'preview', 'headers_type', 'options', 'advanced_mode', 'debug'])
@unittest.skipUnless(can_import('xlrd'), "XLRD module not available")
def test_xls_success(self):
@@ -288,7 +311,7 @@ class TestPreview(TransactionCase):
['qux', '5', '6'],
])
# Ensure we only have the response fields we expect
- self.assertItemsEqual(list(result), ['matches', 'headers', 'fields', 'preview', 'headers_type', 'options', 'debug'])
+ self.assertItemsEqual(list(result), ['matches', 'headers', 'fields', 'preview', 'headers_type', 'options', 'advanced_mode', 'debug'])
@unittest.skipUnless(can_import('xlrd.xlsx'), "XLRD/XLSX not available")
def test_xlsx_success(self):
@@ -318,7 +341,7 @@ class TestPreview(TransactionCase):
['qux', '5', '6'],
])
# Ensure we only have the response fields we expect
- self.assertItemsEqual(list(result), ['matches', 'headers', 'fields', 'preview', 'headers_type', 'options', 'debug'])
+ self.assertItemsEqual(list(result), ['matches', 'headers', 'fields', 'preview', 'headers_type', 'options', 'advanced_mode', 'debug'])
@unittest.skipUnless(can_import('odf'), "ODFPY not available")
def test_ods_success(self):
@@ -348,7 +371,7 @@ class TestPreview(TransactionCase):
['aux', '5', '6'],
])
# Ensure we only have the response fields we expect
- self.assertItemsEqual(list(result), ['matches', 'headers', 'fields', 'preview', 'headers_type', 'options', 'debug'])
+ self.assertItemsEqual(list(result), ['matches', 'headers', 'fields', 'preview', 'headers_type', 'options', 'advanced_mode', 'debug'])
class test_convert_import_data(TransactionCase):
@@ -388,6 +411,7 @@ class test_convert_import_data(TransactionCase):
results = import_wizard.do(
['name', 'date', 'create_date'],
+ [],
{
'date_format': '%Y年%m月%d日',
'datetime_format': '%Y-%m-%d %H:%M',
@@ -398,7 +422,7 @@ class test_convert_import_data(TransactionCase):
)
# if results empty, no errors
- self.assertItemsEqual(results, [])
+ self.assertItemsEqual(results['messages'], [])
def test_parse_relational_fields(self):
""" Ensure that relational fields float and date are correctly
@@ -570,5 +594,6 @@ class test_failures(TransactionCase):
})
results = import_wizard.do(
['name', 'db_datas'],
+ [],
{'headers': True, 'separator': ',', 'quoting': '"'})
- self.assertFalse(results, "results should be empty on successful import")
+ self.assertFalse(results['messages'], "results should be empty on successful import")
diff --git a/addons/crm/models/crm_lead.py b/addons/crm/models/crm_lead.py
index 9e6c4a83416..756a9f272a4 100644
--- a/addons/crm/models/crm_lead.py
+++ b/addons/crm/models/crm_lead.py
@@ -1212,6 +1212,13 @@ class Lead(models.Model):
break
return result
+ @api.model
+ def get_import_templates(self):
+ return [{
+ 'label': _('Import Template for Leads & Opportunities'),
+ 'template': '/crm/static/xls/crm_lead.xls'
+ }]
+
class Tag(models.Model):
diff --git a/addons/crm/static/xls/crm_lead.xls b/addons/crm/static/xls/crm_lead.xls
new file mode 100644
index 00000000000..8801d92cb82
Binary files /dev/null and b/addons/crm/static/xls/crm_lead.xls differ
diff --git a/addons/hr/models/hr.py b/addons/hr/models/hr.py
index cb84b0eaca6..e36e6246ff3 100644
--- a/addons/hr/models/hr.py
+++ b/addons/hr/models/hr.py
@@ -273,6 +273,13 @@ class Employee(models.Model):
except AccessError:
employee.is_address_home_a_company = False
+ @api.model
+ def get_import_templates(self):
+ return [{
+ 'label': _('Import Template for Employees'),
+ 'template': '/hr/static/xls/hr_employee.xls'
+ }]
+
class Department(models.Model):
_name = "hr.department"
diff --git a/addons/hr/static/xls/hr_employee.xls b/addons/hr/static/xls/hr_employee.xls
new file mode 100644
index 00000000000..f6a552bcc7b
Binary files /dev/null and b/addons/hr/static/xls/hr_employee.xls differ
diff --git a/addons/mrp/models/mrp_bom.py b/addons/mrp/models/mrp_bom.py
index 922802f9659..4648a5a2a9b 100644
--- a/addons/mrp/models/mrp_bom.py
+++ b/addons/mrp/models/mrp_bom.py
@@ -175,6 +175,13 @@ class MrpBom(models.Model):
return boms_done, lines_done
+ @api.model
+ def get_import_templates(self):
+ return [{
+ 'label': _('Import Template for Bills of Materials'),
+ 'template': '/mrp/static/xls/mrp_bom.xls'
+ }]
+
class MrpBomLine(models.Model):
_name = 'mrp.bom.line'
diff --git a/addons/mrp/static/xls/mrp_bom.xls b/addons/mrp/static/xls/mrp_bom.xls
new file mode 100644
index 00000000000..5fd4ea3b2cf
Binary files /dev/null and b/addons/mrp/static/xls/mrp_bom.xls differ
diff --git a/addons/product/__manifest__.py b/addons/product/__manifest__.py
index dc3328591b3..51280c2d3a9 100644
--- a/addons/product/__manifest__.py
+++ b/addons/product/__manifest__.py
@@ -37,7 +37,6 @@ Print product labels with barcode.
'views/product_template_views.xml',
'views/product_pricelist_views.xml',
'views/res_partner_views.xml',
- 'views/product_template_import_templates.xml',
'views/res_users_views.xml',
'report/product_reports.xml',
'report/product_pricelist_templates.xml',
diff --git a/addons/product/models/product.py b/addons/product/models/product.py
index 51b450cba2b..17d6f29c9b1 100644
--- a/addons/product/models/product.py
+++ b/addons/product/models/product.py
@@ -630,3 +630,10 @@ class SupplierInfo(models.Model):
delay = fields.Integer(
'Delivery Lead Time', default=1, required=True,
help="Lead time in days between the confirmation of the purchase order and the receipt of the products in your warehouse. Used by the scheduler for automatic computation of the purchase order planning.")
+
+ @api.model
+ def get_import_templates(self):
+ return [{
+ 'label': _('Import Template for Vendor Pricelists'),
+ 'template': '/product/static/xls/product_supplierinfo.xls'
+ }]
diff --git a/addons/product/models/product_pricelist.py b/addons/product/models/product_pricelist.py
index 4f14d6394bb..42ceee46dfb 100644
--- a/addons/product/models/product_pricelist.py
+++ b/addons/product/models/product_pricelist.py
@@ -333,6 +333,13 @@ class Pricelist(models.Model):
return pl
+ @api.model
+ def get_import_templates(self):
+ return [{
+ 'label': _('Import Template for Pricelists'),
+ 'template': '/product/static/xls/product_pricelist.xls'
+ }]
+
class ResCountryGroup(models.Model):
_inherit = 'res.country.group'
@@ -470,4 +477,3 @@ class PricelistItem(models.Model):
'price_min_margin': 0.0,
'price_max_margin': 0.0,
})
-
diff --git a/addons/product/models/product_template.py b/addons/product/models/product_template.py
index 9629a1f111e..9d13d1ba228 100644
--- a/addons/product/models/product_template.py
+++ b/addons/product/models/product_template.py
@@ -483,3 +483,10 @@ class ProductTemplate(models.Model):
empty_list_help_document_name=_("product"),
)
return super(ProductTemplate, self).get_empty_list_help(help)
+
+ @api.model
+ def get_import_templates(self):
+ return [{
+ 'label': _('Import Template for Products'),
+ 'template': '/product/static/xls/product_template.xls'
+ }]
diff --git a/addons/product/static/csv/product.template.csv b/addons/product/static/csv/product.template.csv
deleted file mode 100644
index bb47b9c4fae..00000000000
--- a/addons/product/static/csv/product.template.csv
+++ /dev/null
@@ -1,4 +0,0 @@
-ID,Name,Product Type,Internal Reference,Barcode,Sales Price,Cost,Weight,Sale Description
-product_template_1,Pedal Bin,Consumable,AK789,,29.99,12,,
-product_template_2,Dell Inspiron Laptop without OS,Consumable,DELL15,,2499,1643,,2 years warranty
-product_template_3,Prepaid Consulting,Service,,,90,40,,
diff --git a/addons/product/static/src/js/product_template_import.js b/addons/product/static/src/js/product_template_import.js
deleted file mode 100644
index c00a6d983e1..00000000000
--- a/addons/product/static/src/js/product_template_import.js
+++ /dev/null
@@ -1,19 +0,0 @@
-odoo.define('product_template_import.import', function (require) {
-"use strict";
-
-var core = require('web.core');
-var BaseImport = require('base_import.import');
-
-var _t = core._t;
-
-BaseImport.DataImport.include({
- renderImportLink: function() {
- this._super();
- if (this.res_model == 'product.template') {
- this.$(".import-link").prop({"text": _t(" Import Template for Products"), "href": "/product/static/csv/product.template.csv"});
- this.$(".template-import").removeClass("hidden");
- }
- },
-});
-
-});
diff --git a/addons/product/static/xls/product_pricelist.xls b/addons/product/static/xls/product_pricelist.xls
new file mode 100644
index 00000000000..308534d88e7
Binary files /dev/null and b/addons/product/static/xls/product_pricelist.xls differ
diff --git a/addons/product/static/xls/product_supplierinfo.xls b/addons/product/static/xls/product_supplierinfo.xls
new file mode 100644
index 00000000000..75a07730980
Binary files /dev/null and b/addons/product/static/xls/product_supplierinfo.xls differ
diff --git a/addons/product/static/xls/product_template.xls b/addons/product/static/xls/product_template.xls
new file mode 100644
index 00000000000..f74e7064ba6
Binary files /dev/null and b/addons/product/static/xls/product_template.xls differ
diff --git a/addons/product/views/product_template_import_templates.xml b/addons/product/views/product_template_import_templates.xml
deleted file mode 100644
index eba0f8327ed..00000000000
--- a/addons/product/views/product_template_import_templates.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/addons/purchase/models/product.py b/addons/purchase/models/product.py
index 3cd911b3925..fbff07dca89 100644
--- a/addons/purchase/models/product.py
+++ b/addons/purchase/models/product.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from odoo import api, fields, models
+from odoo import api, fields, models, _
from odoo.addons.base.models.res_partner import WARNING_MESSAGE, WARNING_HELP
@@ -27,6 +27,16 @@ class ProductTemplate(models.Model):
purchase_line_warn = fields.Selection(WARNING_MESSAGE, 'Purchase Order Line', help=WARNING_HELP, required=True, default="no-message")
purchase_line_warn_msg = fields.Text('Message for Purchase Order Line')
+ @api.model
+ def get_import_templates(self):
+ res = super(ProductTemplate, self).get_import_templates()
+ if self.env.context.get('purchase_product_template'):
+ return [{
+ 'label': _('Import Template for Products'),
+ 'template': '/purchase/static/xls/product_purchase.xls'
+ }]
+ return res
+
class ProductProduct(models.Model):
_name = 'product.product'
diff --git a/addons/purchase/static/xls/product_purchase.xls b/addons/purchase/static/xls/product_purchase.xls
new file mode 100644
index 00000000000..77f2a20971d
Binary files /dev/null and b/addons/purchase/static/xls/product_purchase.xls differ
diff --git a/addons/purchase/views/purchase_views.xml b/addons/purchase/views/purchase_views.xml
index 9d19a329efd..fc2f910b06b 100644
--- a/addons/purchase/views/purchase_views.xml
+++ b/addons/purchase/views/purchase_views.xml
@@ -55,7 +55,7 @@
product.templateformkanban,tree,form
- {"search_default_filter_to_purchase":1}
+ {"search_default_filter_to_purchase":1, "purchase_product_template": 1}
diff --git a/addons/sale/models/product_template.py b/addons/sale/models/product_template.py
index 79dffdd719b..98edf5eb28c 100644
--- a/addons/sale/models/product_template.py
+++ b/addons/sale/models/product_template.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from odoo import api, fields, models
+from odoo import api, fields, models, _
from odoo.addons.base.models.res_partner import WARNING_MESSAGE, WARNING_HELP
@@ -59,3 +59,18 @@ class ProductTemplate(models.Model):
if self.type == 'consu':
self.invoice_policy = 'order'
self.service_type = 'manual'
+
+ @api.model
+ def get_import_templates(self):
+ res = super(ProductTemplate, self).get_import_templates()
+ if self.env.context.get('sale_multi_pricelist_product_template'):
+ sale_pricelist_setting = self.env['ir.config_parameter'].sudo().get_param('sale.sale_pricelist_setting')
+ if sale_pricelist_setting == 'percentage':
+ return [{
+ 'label': _('Import Template for Products'),
+ 'template': '/product/static/xls/product_template.xls'
+ }, {
+ 'label': _('Import Template for Products (with several prices)'),
+ 'template': '/sale/static/xls/product_pricelist_several.xls'
+ }]
+ return res
diff --git a/addons/sale/static/xls/product_pricelist_several.xls b/addons/sale/static/xls/product_pricelist_several.xls
new file mode 100644
index 00000000000..71a7ac03c65
Binary files /dev/null and b/addons/sale/static/xls/product_pricelist_several.xls differ
diff --git a/addons/sale/views/sale_views.xml b/addons/sale/views/sale_views.xml
index 8a081130f64..529a5a2db51 100644
--- a/addons/sale/views/sale_views.xml
+++ b/addons/sale/views/sale_views.xml
@@ -61,9 +61,27 @@
parent="menu_sale_report"
sequence="2"/>
-
+
+ Products
+ ir.actions.act_window
+ product.template
+ kanban,tree,form
+ form
+
+ {"search_default_filter_to_sell":1, "sale_multi_pricelist_product_template": 1}
+
+
+ Create a new product
+
+ You must define a product for everything you purchase,
+ whether it's a physical product, a consumable or services.
+
+
+
+
+
-
+
diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py
index cd0f2ff0873..bf27842d55e 100644
--- a/addons/web/controllers/main.py
+++ b/addons/web/controllers/main.py
@@ -1238,8 +1238,8 @@ class Export(http.Controller):
:rtype: [(str, str)]
"""
return [
- {'tag': 'csv', 'label': 'CSV'},
{'tag': 'xls', 'label': 'Excel', 'error': None if xlwt else "XLWT 1.3.0 required"},
+ {'tag': 'csv', 'label': 'CSV'},
]
def fields_get(self, model):
@@ -1250,24 +1250,29 @@ class Export(http.Controller):
@http.route('/web/export/get_fields', type='json', auth="user")
def get_fields(self, model, prefix='', parent_name= '',
import_compat=True, parent_field_type=None,
- exclude=None):
+ parent_field=None, exclude=None):
- if import_compat and parent_field_type == "many2one":
- fields = {}
+ if import_compat and parent_field_type in ['many2one', 'many2many']:
+ fields = self.fields_get(model)
+ fields = {k: v for k, v in fields.items() if k in ['id', 'name']}
else:
fields = self.fields_get(model)
- if import_compat:
- fields.pop('id', None)
- else:
+ if not import_compat:
fields['.id'] = fields.pop('id', {'string': 'ID'})
+ else:
+ fields['id']['string'] = _('External ID')
+
+ if parent_field:
+ parent_field['string'] = _('External ID')
+ fields['id'] = parent_field
fields_sequence = sorted(fields.items(),
- key=lambda field: odoo.tools.ustr(field[1].get('string', '')))
+ key=lambda field: (field[0] not in ['id', '.id', 'display_name', 'name'], odoo.tools.ustr(field[1].get('string', ''))))
records = []
for field_name, field in fields_sequence:
- if import_compat:
+ if import_compat and not field_name == 'id':
if exclude and field_name in exclude:
continue
if field.get('readonly'):
@@ -1279,6 +1284,9 @@ class Export(http.Controller):
continue
id = prefix + (prefix and '/'or '') + field_name
+ if field_name == 'name' and import_compat and parent_field_type in ['many2one', 'many2many']:
+ # Add name field when expand m2o and m2m fields in import-compatible mode
+ id = prefix
name = parent_name + (parent_name and '/' or '') + field['string']
record = {'id': id, 'string': name,
'value': id, 'children': False,
@@ -1290,11 +1298,8 @@ class Export(http.Controller):
if len(name.split('/')) < 3 and 'relation' in field:
ref = field.pop('relation')
record['value'] += '/id'
- record['params'] = {'model': ref, 'prefix': id, 'name': name}
-
- if not import_compat or field['type'] == 'one2many':
- # m2m field in import_compat is childless
- record['children'] = True
+ record['params'] = {'model': ref, 'prefix': id, 'name': name, 'parent_field': field}
+ record['children'] = True
return records
diff --git a/addons/web/static/src/js/views/list/list_controller.js b/addons/web/static/src/js/views/list/list_controller.js
index a210c07a885..ce0554a8fe6 100644
--- a/addons/web/static/src/js/views/list/list_controller.js
+++ b/addons/web/static/src/js/views/list/list_controller.js
@@ -446,7 +446,10 @@ var ListController = BasicController.extend({
*/
_onExportData: function () {
var record = this.model.get(this.handle);
- new DataExport(this, record).open();
+ var defaultExportFields = _.map(this.renderer.columns, function (field) {
+ return field.attrs.name;
+ });
+ new DataExport(this, record, defaultExportFields).open();
},
/**
* Called when the renderer displays an editable row and the user tries to
diff --git a/addons/web/static/src/js/widgets/data_export.js b/addons/web/static/src/js/widgets/data_export.js
index 8a09f7fa034..30e17604077 100644
--- a/addons/web/static/src/js/widgets/data_export.js
+++ b/addons/web/static/src/js/widgets/data_export.js
@@ -14,7 +14,7 @@ var _t = core._t;
var DataExport = Dialog.extend({
template: 'ExportDialog',
events: {
- 'click .o_expand_parent': function(e) {
+ 'click .o_expand': function(e) {
this.on_expand_action(this.records[$(e.target).closest('.o_export_tree_item').data('id')]);
},
'click .o_export_tree_item': function(e) {
@@ -56,10 +56,19 @@ var DataExport = Dialog.extend({
}
}
},
- 'dblclick .o_export_tree_item': function(e) {
- var $elem = $(e.currentTarget);
- $elem.removeClass('o_selected');
- this.add_field($elem.data('id'), $elem.find('.o_tree_column').first().text());
+ 'dblclick .o_export_tree_item:not(.haschild)': function(e) {
+ var self = this;
+ function addElement(el) {
+ self.add_field(el.getAttribute('data-id'), el.querySelector('.o_tree_column').textContent);
+ }
+ var target = e.currentTarget;
+ target.classList.remove('o_selected');
+ // Add parent fields to export
+ [].reverse.call($(target).parents('.o_export_tree_item')).each(function () {
+ addElement(this);
+ });
+ // add field itself
+ addElement(target);
},
'keydown .o_export_tree_item': function(e) {
e.stopPropagation();
@@ -195,7 +204,7 @@ var DataExport = Dialog.extend({
});
},
},
- init: function(parent, record) {
+ init: function(parent, record, defaultExportFields) {
var options = {
title: _t("Export Data"),
buttons: [
@@ -206,6 +215,7 @@ var DataExport = Dialog.extend({
this._super(parent, options);
this.records = {};
this.record = record;
+ this.defaultExportFields = defaultExportFields;
this.exports = new data.DataSetSearch(this, 'ir.exports', this.record.getContext());
this.row_index = 0;
@@ -228,13 +238,14 @@ var DataExport = Dialog.extend({
var got_fields = new $.Deferred();
this.$import_compat_radios.change(function(e) {
+ self.isCompatibleMode = !!$(e.target).val();
self.$('.o_field_tree_structure').remove();
self._rpc({
route: '/web/export/get_fields',
params: {
model: self.record.model,
- import_compat: !!$(e.target).val(),
+ import_compat: self.isCompatibleMode,
},
})
.done(function (records) {
@@ -250,6 +261,15 @@ var DataExport = Dialog.extend({
.remove();
got_fields.resolve();
self.on_show_data(records);
+ // In compatible mode add ID field as first field to export
+ if (self.isCompatibleMode) {
+ self.$('.o_fields_list').prepend(new Option(_('External ID'), 'id'));
+ }
+ _.each(records, function (record) {
+ if (_.contains(self.defaultExportFields, record.id)) {
+ self.add_field(record.id, record.string);
+ }
+ });
});
}).eq(0).change();
waitFor.push(got_fields);
@@ -262,10 +282,15 @@ var DataExport = Dialog.extend({
self.ids_to_export = false;
self.domain = domain;
}
- self.on_show_domain();
}));
- waitFor.push(this.show_exports_list());
+ waitFor.push(this.show_exports_list().then(function () {
+ _.each(self.records, function (record, key) {
+ if (_.contains(self.defaultExportFields, key)) {
+ self.add_field(key, record.string);
+ }
+ });
+ }));
return $.when.apply($, waitFor);
@@ -274,14 +299,15 @@ var DataExport = Dialog.extend({
_.each(formats, function(format, i) {
var $radio = $('', {type: 'radio', value: format.tag, name: 'o_export_format_name'});
- var $label = $('', {html: format.label});
+ var $label = $('', {html: format.label});
if (format.error) {
$radio.prop('disabled', true);
$label.html(_.str.sprintf("%s — %s", format.label, format.error));
}
- $fmts.append($("").append($radio, $label));
+ var $radioButton = $('').append($radio, $label);
+ $fmts.append($("").append($radioButton));
});
self.$export_format_inputs = $fmts.find('input');
@@ -366,7 +392,8 @@ var DataExport = Dialog.extend({
parent_name: name,
import_compat: !!this.$import_compat_radios.filter(':checked').val(),
parent_field_type : record['field_type'],
- exclude: exclude_fields
+ parent_field: record['params']['parent_field'],
+ exclude: exclude_fields,
},
})
.done(function(results) {
@@ -377,17 +404,13 @@ var DataExport = Dialog.extend({
this.show_content(record.id);
}
},
- on_show_domain: function() {
- this.$('p').first()
- .after(QWeb.render('Export.DomainMessage', {record: this}));
- },
on_show_data: function(records, expansion) {
var self = this;
if(expansion) {
this.$('.o_export_tree_item[data-id="' + expansion + '"]')
.addClass('open')
.find('.o_expand_parent')
- .toggleClass('fa-plus fa-minus')
+ .toggleClass('fa-chevron-right fa-chevron-down')
.next()
.after(QWeb.render('Export.TreeItems', {'fields': records, 'debug': this.getSession().debug}));
} else {
@@ -409,7 +432,7 @@ var DataExport = Dialog.extend({
$this.toggleClass('open');
var is_open = $this.hasClass('open');
- $this.children('.o_expand_parent').toggleClass('fa-minus', !!is_open).toggleClass('fa-plus', !is_open);
+ $this.children('.o_expand_parent').toggleClass('fa-chevron-down', !!is_open).toggleClass('fa-chevron-right', !is_open);
var $child_field = $this.find('.o_export_tree_item');
var child_len = (id.split("/")).length + 1;
@@ -420,7 +443,7 @@ var DataExport = Dialog.extend({
} else if(child_len === $child_field.eq(i).data('id').split("/").length) {
if ($child.hasClass('open')) {
$child.removeClass('open');
- $child.children('.o_expand_parent').removeClass('fa-minus').addClass('fa-plus');
+ $child.children('.o_expand_parent').removeClass('fa-chevron-down').addClass('fa-chevron-right');
}
$child.show();
}
@@ -455,7 +478,9 @@ var DataExport = Dialog.extend({
Dialog.alert(this, _t("Please select fields to export..."));
return;
}
- exported_fields.unshift({name: 'id', label: _t('External ID')});
+ if (!this.isCompatibleMode) {
+ exported_fields.unshift({name: 'id', label: _t('External ID')});
+ }
var export_format = this.$export_format_inputs.filter(':checked').val();
diff --git a/addons/web/static/src/scss/data_export.scss b/addons/web/static/src/scss/data_export.scss
index aa690cfdb74..17cec27d3a5 100644
--- a/addons/web/static/src/scss/data_export.scss
+++ b/addons/web/static/src/scss/data_export.scss
@@ -8,25 +8,6 @@
@include o-flex(0, 0, auto);
}
- label {
- vertical-align: top;
- font-weight: normal;
- }
-
- .o_import_compat, .o_export_format {
- display: inline-block;
-
- > div {
- margin-left: 5px;
- @include o-inline-flex-display;
- @include o-align-items(center);
-
- > label, > input {
- margin: 0 0 0 5px;
- }
- }
- }
-
.o_export_panel {
@include o-flex(1, 1, auto);
position: relative;
@@ -77,6 +58,7 @@
.o_expand_parent {
@include o-position-absolute($top: 4px, $left: 5px);
+ font-size: 10px;
}
.o_tree_column {
display: block;
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index 758f5bcd416..4c081b679dd 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -1281,21 +1281,26 @@
-
- This wizard will export all data that matches the current search criteria to a CSV file.
- You can export all data or only the fields that can be reimported after modification.
-
-
-
+ What do you want to do?
-
-
+
+
+
+
+
+
-
+ Export Format:
@@ -1323,19 +1328,20 @@
-
- Please pay attention that all records matching your search filter will be exported. Not only the selected ids.
- Please note that only the selected ids will be exported.
-