[FIX] breakage of m2m (tag) fields in editable (o2m) listviews

e.g. quotation form view, "Order Lines" table, add a tax (or more) to
a line, save, then try to edit the line.

Issue: the listview mostly uses a single-level structure for its
display, each record is a trivial map of {name: value}. For the M2O
the expected value can be complex-ish (a name_get which holds all the
interesting stuff) but not so for the m2m.

An m2m value is just a list of ids (Array<Integer>), the list view
would overwrite that with the concatenated name_get strings to get
something kind-of displayable. Except editable serializes the record
it has and passes that as-is to the embedded formview. The
corresponding widget (FieldMany2ManyTags) most definitely does not
expect a big string to be shoved up its fat ass.

So use a different but just as disgusting hack: instead of *replacing*
the ids array with the string, add the string to the record after very
slightly munging the original name, that way the form is happy because
it gets the value it expects, and the Many2Many column can override
_format to use the value of the munged/fake column as "stuff it passes
to whatever is in charge of formatting fields for display" when the
original field is asked for.

NOTE: redundant work is done as every line will do its own name_get,
      potentially on the same ids over and over again. Having a
      short-lived backend cache may allow not name_get-ing ids we've
      already fetched during the same table display...

bzr revid: xmo@openerp.com-20121108145705-uphw76z4q4krcpnl
This commit is contained in:
Xavier Morel 2012-11-08 15:57:05 +01:00
parent c6d4dcd2ab
commit 3a5421309b
1 changed files with 19 additions and 3 deletions

View File

@ -1000,7 +1000,8 @@ instance.web.ListView.List = instance.web.Class.extend( /** @lends instance.web.
} else if (column.type === 'many2many') {
value = record.get(column.id);
// non-resolved (string) m2m values are arrays
if (value instanceof Array && !_.isEmpty(value)) {
if (value instanceof Array && !_.isEmpty(value)
&& !record.get(column.id + '__display')) {
var ids;
// they come in two shapes:
if (value[0] instanceof Array) {
@ -1016,8 +1017,13 @@ instance.web.ListView.List = instance.web.Class.extend( /** @lends instance.web.
}
new instance.web.Model(column.relation)
.call('name_get', [ids]).done(function (names) {
record.set(column.id, _(names).pluck(1).join(', '));
})
// FIXME: nth horrible hack in this poor listview
record.set(column.id + '__display',
_(names).pluck(1).join(', '));
record.set(column.id, ids);
});
// temp empty value
record.set(column.id, false);
}
}
return column.format(record.toForm().data, {
@ -2015,6 +2021,7 @@ instance.web.list.columns = new instance.web.Registry({
'field.handle': 'instance.web.list.Handle',
'button': 'instance.web.list.Button',
'field.many2onebutton': 'instance.web.list.Many2OneButton',
'field.many2many': 'instance.web.list.Many2Many'
});
instance.web.list.columns.for_ = function (id, field, node) {
var description = _.extend({tag: node.tag}, field, node.attrs);
@ -2208,5 +2215,14 @@ instance.web.list.Many2OneButton = instance.web.list.Column.extend({
return QWeb.render('Many2OneButton.cell', {'widget': this});
},
});
instance.web.list.Many2Many = instance.web.list.Column.extend({
_format: function (row_data, options) {
if (row_data[this.id].value) {
// If value, use __display version for printing
row_data[this.id] = row_data[this.id + '__display'];
}
return this._super(row_data, options);
}
});
};
// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax: