[ADD] actual importing, no fields matching yet

also no error pinpointing because API does not allow for it currently

bzr revid: xmo@openerp.com-20120814141456-zh9kdbjy8wj1sxys
This commit is contained in:
Xavier Morel 2012-08-14 16:14:56 +02:00
parent 323b979146
commit 8fa23a9518
3 changed files with 89 additions and 15 deletions

View File

@ -11,6 +11,8 @@ try:
except ImportError:
from StringIO import StringIO
import psycopg2
from openerp.osv import orm, fields
from openerp.tools.translate import _
@ -300,24 +302,39 @@ class ir_import(orm.TransientModel):
record, fields, options, context=context)
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 invalid input.
# behavior of import_data on some (most) invalid
# input.
code, record, message = -1, None, str(e)
if dryrun:
cr.execute('ROLLBACK TO SAVEPOINT import')
else:
cr.execute('RELEASE SAVEPOINT import')
# If transaction aborted, RELEASE SAVEPOINT is going to raise
# an InternalError (ROLLBACK should work, maybe). Ignore that.
# TODO: to handle multiple errors, create savepoint around
# write and release it in case of write error (after
# adding error to errors array) => can keep on trying to
# import stuff, and rollback at the end if there is any
# error in the results.
try:
if dryrun:
cr.execute('ROLLBACK TO SAVEPOINT import')
else:
cr.execute('RELEASE SAVEPOINT import')
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?
# with higher ``count``?
return [{
'type': 'error',
'message': message,

View File

@ -1,5 +1,6 @@
openerp.base_import = function (instance) {
var QWeb = instance.web.qweb;
var _t = instance.web._t;
var _lt = instance.web._lt;
/**
@ -41,7 +42,14 @@ openerp.base_import = function (instance) {
'change input.oe_import_file': 'file_update'
},
init: function (parent, dataset) {
this._super(parent, {});
var self = this;
this._super(parent, {
buttons: [
{text: _t("Import File"), click: function () {
self.do_import();
}, 'class': 'oe_import_dialog_button'}
]
});
this.res_model = parent.model;
// import object id
this.id = null;
@ -57,6 +65,15 @@ openerp.base_import = function (instance) {
});
},
import_options: function () {
return {
// TODO: customizable gangnam style
quote: '"',
separator: ',',
headers: true,
};
},
//- File change section
file_update: function (e) {
if (!this.$('input.oe_import_file').val()) { return; }
@ -69,22 +86,49 @@ openerp.base_import = function (instance) {
file_updated: function () {
// immediately trigger preview...
// TODO: test that write // succeeded?
this.Import.call('parse_preview', [this.id, {
quote: '"',
separator: ',',
headers: true,
}]).then(this.proxy('preview'));
this.Import.call(
'parse_preview', [this.id, this.import_options()])
.then(this.proxy('preview'));
},
preview: function (result) {
if (result.error) {
this.$element.addClass('oe_import_error');
this.$('.oe_import_error_report').html(
QWeb.render('ImportView.error', result));
QWeb.render('ImportView.preview.error', result));
} else {
this.$element.addClass('oe_import_preview');
this.$('table').html(
QWeb.render('ImportView.preview', result));
}
},
//- import itself
do_import: function () {
var fields = this.$('.oe_import_fields input').map(function (index, el) {
return el.value || false;
}).get();
this.Import.call(
'do', [this.id, fields, this.import_options()], {
// maybe could do a dryrun after successful
// preview or something (note: don't go to
// this.result if dryrun=true)
dryrun: false
})
.then(this.proxy('result'));
},
result: function (errors) {
if (!errors.length) {
if (this.getParent().reload_content) {
this.getParent().reload_content();
}
this.close();
return;
}
// import failed (or maybe just warnings, if we ever get
// warnings?)
this.$element.addClass('oe_import_error');
this.$('.oe_import_error_report').html(
QWeb.render('ImportView.error', {errors: errors}));
},
});
};

View File

@ -7,9 +7,9 @@
<label for="csvfile">CSV File:</label>
<input type="file" id="csvfile" name="file" class="oe_import_file"/>
<div class="oe_import_error_report"></div>
<table class="oe_import_grid" width="100%">
</table>
<div class="oe_import_error_report"></div>
</form>
</t>
<!-- TODO: column matcher? -->
@ -18,14 +18,27 @@
<td t-foreach="headers" t-as="header" class="oe_import_grid-cell"
><t t-esc="header"/></td>
</tr>
<tr class="oe_import_fields">
<!-- Iterate on first row to ensure we have all columns -->
<td t-foreach="preview[0]" t-as="column">
<input placeholder="Don't Import"/>
</td>
</tr>
<tr t-foreach="preview" t-as="row" class="oe_import_grid-row">
<td t-foreach="row" t-as="cell" class="oe_import_grid-cell"
><t t-esc="cell"/></td>
</tr>
</t>
<t t-name="ImportView.error">
<t t-name="ImportView.preview.error">
<p>Import preview failed due to: <t t-esc="error"/></p>
<p>Here is the start of the file we could not import:</p>
<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>
</ul>
</templates>