diff --git a/sao/CHANGELOG b/sao/CHANGELOG index c1cc03076d..faeb4deabb 100644 --- a/sao/CHANGELOG +++ b/sao/CHANGELOG @@ -1,3 +1,4 @@ +* Support language suffix in CSV import Version 7.2.0 - 2024-04-29 -------------------------- diff --git a/sao/src/window.js b/sao/src/window.js index 0e721b649a..73c4e7b183 100644 --- a/sao/src/window.js +++ b/sao/src/window.js @@ -1396,6 +1396,14 @@ this.session = Sao.Session.current_session; this.fields_data = {}; // Ask before Removing this. this.fields_invert = {}; + this.languages = Sao.rpc({ + 'method': 'model.ir.lang.search_read', + 'params': [ + [['translatable', '=', true]], + 0, null, null, ['code', 'name'], + {}, + ], + }, this.session, false); Sao.Window.Import._super.init.call(this, Sao.i18n.gettext('CSV Import: %1', name)); @@ -1550,7 +1558,7 @@ }).prependTo(node); expander_icon.css( 'visibility', - parent_node[field].relation ? 'visible' : 'hidden'); + parent_node[field].children ? 'visible' : 'hidden'); }); }, model_populate: function (fields, parent_node, prefix_field, @@ -1559,28 +1567,47 @@ prefix_field = prefix_field || ''; prefix_name = prefix_name || ''; - for (const field of Object.keys(fields)) { - if(!fields[field].readonly || field == 'id') { - var name = fields[field].string || field; + for (const field_name of Object.keys(fields)) { + const field = fields[field_name]; + if(!field.readonly || field_name == 'id') { + var name = field.string || field_name; name = prefix_name + name; // Only One2Many can be nested for import var relation; - if (fields[field].type == 'one2many') { - relation = fields[field].relation; + if (field.type == 'one2many') { + relation = field.relation; } else { relation = null; } var node = { name: name, - field: prefix_field + field, + field: prefix_field + field_name, relation: relation, - string: fields[field].string + string: field.string }; - parent_node[field] = node; - this.fields[prefix_field + field] = node; - this.fields_invert[name] = prefix_field + field; + parent_node[field_name] = node; + this.fields[prefix_field + field_name] = node; + this.fields_invert[name] = prefix_field + field_name; if (relation) { node.children = {}; + } else if (field.translate) { + node.children = {}; + for (const language of this.languages) { + const l_field_name = ( + `${field_name}:lang=${language.code}`); + const l_name = ( + prefix_name + name + ` (${language.name})`); + const l_node = { + name: l_name, + field: prefix_field + l_field_name, + relation: null, + string: language.name, + }; + node.children[l_field_name] = l_node; + this.fields[prefix_field + l_field_name] = l_node; + this.fields_invert[l_name] = ( + prefix_field + l_field_name); + } } } } diff --git a/tryton/CHANGELOG b/tryton/CHANGELOG index d5d051b002..6248079a7d 100644 --- a/tryton/CHANGELOG +++ b/tryton/CHANGELOG @@ -1,3 +1,4 @@ +* Support language suffix in CSV import Version 7.2.0 - 2024-04-29 -------------------------- diff --git a/tryton/tryton/gui/window/win_import.py b/tryton/tryton/gui/window/win_import.py index 5ccbd79735..6f4145a1e3 100644 --- a/tryton/tryton/gui/window/win_import.py +++ b/tryton/tryton/gui/window/win_import.py @@ -26,6 +26,10 @@ class WinImport(WinCSV): self.fields_data = {} self.fields = {} self.fields_invert = {} + self.languages = RPCExecute( + 'model', 'ir.lang', 'search_read', [ + ('translatable', '=', True), + ], 0, None, None, ['code', 'name']) super(WinImport, self).__init__() self.dialog.set_title(_('CSV Import: %s') % name) @@ -67,22 +71,34 @@ class WinImport(WinCSV): fields_order = list(fields.keys()) fields_order.sort( key=lambda x: fields[x].get('string', ''), reverse=True) - for field in fields_order: - if not fields[field].get('readonly', False) or field == 'id': - self.fields_data[prefix_field + field] = fields[field] - name = fields[field]['string'] or field + for field_name in fields_order: + field = fields[field_name] + if not field.get('readonly', False) or field_name == 'id': + self.fields_data[prefix_field + field_name] = field + name = field['string'] or field_name node = self.model1.insert( - parent_node, 0, [name, prefix_field + field]) + parent_node, 0, [name, prefix_field + field_name]) name = prefix_name + name # Only One2Many can be nested for import - if fields[field]['type'] == 'one2many': - relation = fields[field].get('relation') + if field['type'] == 'one2many': + relation = field.get('relation') else: relation = None - self.fields[prefix_field + field] = (name, relation) - self.fields_invert[name] = prefix_field + field + self.fields[prefix_field + field_name] = (name, relation) + self.fields_invert[name] = prefix_field + field_name if relation: self.model1.insert(node, 0, [None, '']) + elif field.get('translate', False): + for language in self.languages: + l_field_name = f"{field_name}:lang={language['code']}" + self.model1.insert( + node, 0, [ + language['name'], prefix_field + l_field_name]) + l_name = prefix_name + name + f" ({language['name']})" + self.fields[prefix_field + l_field_name] = ( + l_name, relation) + self.fields_invert[l_name] = ( + prefix_field + l_field_name) def _get_fields(self, model): try: