Xavier (Open ERP) has proposed merging
lp:~openerp-dev/openobject-addons/trunk-newimport-phase2-xmo into
lp:openobject-addons.
Requested reviews:
OpenERP Core Team (openerp)
For more details, see:
https://code.launchpad.net/~openerp-dev/openobject-addons/trunk-newimport-phase2-xmo/+merge/126659
Adaptation of new client import to new import method
(https://code.launchpad.net/~openerp-dev/openobject-server/trunk-newimport-phase2-xmo/+merge/126658)
* Use new method
* Don't adapt returned values (output is identical on the python side)
* UI fixes (import error wouldn't hide after triggering new import)
* Improvements to error reporting to use improved error messages returned from
import
--
https://code.launchpad.net/~openerp-dev/openobject-addons/trunk-newimport-phase2-xmo/+merge/126659
Your team OpenERP R&D Team is subscribed to branch
lp:~openerp-dev/openobject-addons/trunk-newimport-phase2-xmo.
=== modified file 'base_import/models.py'
--- base_import/models.py 2012-09-03 14:00:22 +0000
+++ base_import/models.py 2012-09-27 10:46:27 +0000
@@ -83,6 +83,10 @@
}]
fields_got = self.pool[model].fields_get(cr, uid, context=context)
for name, field in fields_got.iteritems():
+ # an empty string means the field is deprecated, @deprecated must
+ # be absent or False to mean not-deprecated
+ if field.get('deprecated', False) is not False:
+ continue
if field.get('readonly'):
states = field.get('states')
if not states:
@@ -97,7 +101,7 @@
'id': name,
'name': name,
'string': field['string'],
- # Y U NO ALWAYS HAVE REQUIRED
+ # Y U NO ALWAYS HAS REQUIRED
'required': bool(field.get('required')),
'fields': [],
}
@@ -307,22 +311,14 @@
except ValueError, e:
return [{
'type': 'error',
- 'message': str(e),
+ 'message': unicode(e),
'record': False,
}]
- try:
- _logger.info('importing %d rows...', len(data))
- (code, record, message, _wat) = self.pool[record.res_model].import_data(
- cr, uid, import_fields, data, context=context)
- _logger.info('done')
-
- except Exception, e:
- _logger.exception("Import failed")
- # TODO: remove when exceptions stop being an "expected"
- # behavior of import_data on some (most) invalid
- # input.
- code, record, message = -1, None, str(e)
+ _logger.info('importing %d rows...', len(data))
+ import_result = self.pool[record.res_model].load(
+ cr, uid, import_fields, data, context=context)
+ _logger.info('done')
# If transaction aborted, RELEASE SAVEPOINT is going to raise
# an InternalError (ROLLBACK should work, maybe). Ignore that.
@@ -339,14 +335,4 @@
except psycopg2.InternalError:
pass
- if code != -1:
- return []
-
- # TODO: add key for error location?
- # TODO: error not within normal preview, how to display? Re-preview
- # with higher ``count``?
- return [{
- 'type': 'error',
- 'message': message,
- 'record': record or False
- }]
+ return import_result['messages']
=== modified file 'base_import/static/src/css/import.css'
--- base_import/static/src/css/import.css 2012-09-11 06:38:49 +0000
+++ base_import/static/src/css/import.css 2012-09-27 10:46:27 +0000
@@ -10,7 +10,8 @@
.oe_import .oe_import_grid,
.oe_import .oe_import_error_report,
.oe_import .oe_import_with_file,
-.oe_import .oe_import_noheaders {
+.oe_import .oe_import_noheaders,
+.oe_import .oe_import_report_more {
display: none;
}
@@ -19,7 +20,8 @@
}
.oe_import.oe_import_error .oe_import_error_report,
.oe_import.oe_import_with_file .oe_import_with_file,
-.oe_import.oe_import_noheaders .oe_import_noheaders {
+.oe_import.oe_import_noheaders .oe_import_noheaders,
+.oe_import .oe_import_report_showmore .oe_import_report_more {
display: block;
}
=== modified file 'base_import/static/src/js/import.js'
--- base_import/static/src/js/import.js 2012-09-11 06:38:49 +0000
+++ base_import/static/src/js/import.js 2012-09-27 10:46:27 +0000
@@ -63,7 +63,7 @@
{name: 'quoting', label: _lt("Quoting:"), value: '"'}
],
events: {
- 'change .oe_import_grid input': 'import_dryrun',
+ // 'change .oe_import_grid input': 'import_dryrun',
'change input.oe_import_file': 'file_update',
'change input.oe_import_has_header, .oe_import_options input': 'settings_updated',
'click a.oe_import_csv': function (e) {
@@ -79,15 +79,37 @@
? $el.next()
: $el.parent().next())
.toggle();
+ },
+ 'click .oe_import_report a.oe_import_report_count': function (e) {
+ e.preventDefault();
+ $(e.target).parent().toggleClass('oe_import_report_showmore');
+ },
+ 'click .oe_import_moreinfo_action a': function (e) {
+ e.preventDefault();
+ // #data will parse the attribute on its own, we don't like
+ // that sort of things
+ var action = JSON.parse($(e.target).attr('data-action'));
+ // FIXME: when JS-side clean_action
+ action.views = _(action.views).map(function (view) {
+ var id = view[0], type = view[1];
+ return [
+ id,
+ type !== 'tree' ? type
+ : action.view_type === 'form' ? 'list'
+ : 'tree'
+ ];
+ });
+ this.do_action(_.extend(action, {target: 'new'}));
}
},
init: function (parent, dataset) {
var self = this;
this._super(parent, {
buttons: [
- {text: _t("Import File"), click: function () {
- self.do_import();
- }, 'class': 'oe_import_dialog_button'}
+ {text: _t("Import"), click: self.proxy('do_import'),
+ 'class': 'oe_import_dialog_button'},
+ {text: _t("Validate"), click: self.proxy('import_dryrun'),
+ 'class': 'oe_import_dialog_button'}
]
});
this.res_model = parent.model;
@@ -134,11 +156,12 @@
.then(this.proxy('preview'));
},
preview: function (result) {
+ this.$el.removeClass('oe_import_preview_error oe_import_error');
this.$el.toggleClass(
'oe_import_noheaders',
!this.$('input.oe_import_has_header').prop('checked'));
if (result.error) {
- this.$el.addClass('oe_import_error');
+ this.$el.addClass('oe_import_preview_error oe_import_error');
this.$('.oe_import_error_report').html(
QWeb.render('ImportView.preview.error', result));
return;
@@ -180,7 +203,7 @@
width: 'resolve',
dropdownCssClass: 'oe_import_selector'
});
- this.import_dryrun();
+ //this.import_dryrun();
},
generate_fields_completion: function (root) {
var basic = [];
@@ -252,7 +275,6 @@
//- import itself
call_import: function (options) {
- var self = this;
var fields = this.$('.oe_import_fields input.oe_import_match_field').map(function (index, el) {
return $(el).select2('val') || false;
}).get();
@@ -260,32 +282,78 @@
'do', [this.id, fields, this.import_options()], options);
},
import_dryrun: function () {
-// this.call_import({ dryrun: true })
-// .then(this.proxy('render_import_errors'));
+ return this.call_import({ dryrun: true })
+ .then(this.proxy('render_import_result'));
},
do_import: function () {
var self = this;
- this.call_import({ dryrun: false }).then(function (errors) {
- if (_.isEmpty(errors)) {
+ return this.call_import({ dryrun: false }).then(function (message) {
+ if (!_.any(message, function (message) {
+ return message.type === 'error' })) {
if (self.getParent().reload_content) {
self.getParent().reload_content();
}
self.close();
return;
}
- self.render_import_errors(errors);
+ self.render_import_result(message);
});
},
- render_import_errors: function (errors) {
- if (_.isEmpty(errors)) {
+ render_import_result: function (message) {
+ if (_.isEmpty(message)) {
this.$el.removeClass('oe_import_error');
return;
}
- // import failed (or maybe just warnings, if we ever get
- // warnings?)
+ // row indexes come back 0-indexed, spreadsheets
+ // display 1-indexed.
+ var offset = 1;
+ // offset more if header
+ if (this.import_options().header) { offset += 1; }
+
this.$el.addClass('oe_import_error');
this.$('.oe_import_error_report').html(
- QWeb.render('ImportView.error', {errors: errors}));
+ QWeb.render('ImportView.error', {
+ errors: _(message).groupBy('message'),
+ at: function (rows) {
+ var from = rows.from + offset;
+ var to = rows.to + offset;
+ if (from === to) {
+ return _.str.sprintf(_t("at row %d"), from);
+ }
+ return _.str.sprintf(_t("between rows %d and %d"),
+ from, to);
+ },
+ more: function (n) {
+ return _.str.sprintf(_t("(%d more)"), n);
+ },
+ info: function (msg) {
+ if (typeof msg === 'string') {
+ return _.str.sprintf(
+ '<div class="oe_import_moreinfo oe_import_moreinfo_message">%s</div>',
+ _.str.escapeHTML(msg));
+ }
+ if (msg instanceof Array) {
+ return _.str.sprintf(
+ '<div class="oe_import_moreinfo oe_import_moreinfo_choices">%s <ul>%s</ul></div>',
+ _.str.escapeHTML(_t("Here are the possible values:")),
+ _(msg).map(function (msg) {
+ return '<li>'
+ + _.str.escapeHTML(msg)
+ + '</li>';
+ }).join(''));
+ }
+ // Final should be object, action descriptor
+ return [
+ '<div class="oe_import_moreinfo oe_import_moreinfo_action">',
+ _.str.sprintf('<a href="#" data-action="%s">',
+ _.str.escapeHTML(JSON.stringify(msg))),
+ _.str.escapeHTML(
+ _t("Get all possible values")),
+ '</a>',
+ '</div>'
+ ].join('')
+ },
+ }));
},
});
};
=== modified file 'base_import/static/src/xml/import.xml'
--- base_import/static/src/xml/import.xml 2012-09-11 06:38:49 +0000
+++ base_import/static/src/xml/import.xml 2012-09-27 10:46:27 +0000
@@ -86,12 +86,31 @@
<pre><t t-esc="preview"/></pre>
</t>
<ul t-name="ImportView.error">
- <li t-foreach="errors" t-as="error" t-attf-class="oe_import_report_#{error.type}">
- <!-- can also have error.record, but may be *huge* if
- e.g. has image fields -->
- <t t-esc="error.message"/>
+ <li t-foreach="errors" t-as="error"
+ t-attf-class="oe_import_report oe_import_report_#{error_value[0].type}">
+ <t t-call="ImportView.error.each">
+ <t t-set="error" t-value="error_value[0]"/>
+ </t>
+
+ <a href="#" class="oe_import_report_count" t-if="error_value.length gt 1">
+ <t t-esc="more(error_value.length - 1)"/>
+ </a>
+ <ul class="oe_import_report_more" t-if="error_value.length gt 1">
+ <li t-foreach="error_value.length - 1" t-as="index">
+ <t t-call="ImportView.error.each">
+ <t t-set="error" t-value="error_value[index + 1]"/>
+ </t>
+ </li>
+ </ul>
</li>
</ul>
+ <t t-name="ImportView.error.each">
+ <span class="oe_import_report_message">
+ <t t-esc="error.message"/>
+ </span>
+ <t t-if="error.rows" t-esc="at(error.rows)"/>
+ <t t-if="error.moreinfo" t-raw="info(error.moreinfo)"/>
+ </t>
<t t-extend="ListView.buttons">
<t t-jquery="span.oe_alternative">
this.attr('t-if', 'widget.options.import_enabled');
_______________________________________________
Mailing list: https://launchpad.net/~openerp-dev-gtk
Post to : [email protected]
Unsubscribe : https://launchpad.net/~openerp-dev-gtk
More help : https://help.launchpad.net/ListHelp