summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/views/basic/basic_model.js
diff options
context:
space:
mode:
Diffstat (limited to 'addons/web/static/src/js/views/basic/basic_model.js')
-rw-r--r--addons/web/static/src/js/views/basic/basic_model.js140
1 files changed, 110 insertions, 30 deletions
diff --git a/addons/web/static/src/js/views/basic/basic_model.js b/addons/web/static/src/js/views/basic/basic_model.js
index 7952b75d7f0..d3a60ac3044 100644
--- a/addons/web/static/src/js/views/basic/basic_model.js
+++ b/addons/web/static/src/js/views/basic/basic_model.js
@@ -781,6 +781,55 @@ var BasicModel = AbstractModel.extend({
}
},
/**
+ * Resequences records.
+ *
+ * @param {string} modelName the resIDs model
+ * @param {Array[integer]} resIDs the new sequence of ids
+ * @param {string} parentID the localID of the parent
+ * @param {object} [options]
+ * @param {integer} [options.offset]
+ * @param {string} [options.field] the field name used as sequence
+ * @returns {Deferred<string>} resolves to the local id of the parent
+ */
+ resequence: function (modelName, resIDs, parentID, options) {
+ options = options || {};
+ if ((resIDs.length <= 1)) {
+ return $.when(parentID); // there is nothing to sort
+ }
+ var self = this;
+ var data = this.localData[parentID];
+ var params = {
+ model: modelName,
+ ids: resIDs,
+ };
+ if (options.offset) {
+ params.offset = options.offset;
+ }
+ if (options.field) {
+ params.field = options.field;
+ }
+ return this._rpc({
+ route: '/web/dataset/resequence',
+ params: params,
+ })
+ .then(function () {
+ data.data = _.sortBy(data.data, function (d) {
+ return _.indexOf(resIDs, self.localData[d].res_id);
+ });
+ data.res_ids = [];
+ _.each(data.data, function (d) {
+ var dataPoint = self.localData[d];
+ if (dataPoint.type === 'record') {
+ data.res_ids.push(dataPoint.res_id);
+ } else {
+ data.res_ids = data.res_ids.concat(dataPoint.res_ids);
+ }
+ });
+ self._updateParentResIDs(data);
+ return parentID;
+ });
+ },
+ /**
* Save a local resource, if needed. This is a complicated operation,
* - it needs to check all changes,
* - generate commands for x2many fields,
@@ -1186,6 +1235,7 @@ var BasicModel = AbstractModel.extend({
record._rawChanges[name] = val;
return;
}
+ var oldValue = record._changes[name] || record.data[name];
var id;
if (field.type === 'many2one') {
id = false;
@@ -1198,29 +1248,42 @@ var BasicModel = AbstractModel.extend({
var data = _.isArray(val) ?
{id: val[0], display_name: val[1]} :
{id: val};
- rec = self._makeDataPoint({
- context: record.context,
- data: data,
- modelName: field.relation,
- parentID: record.id,
- });
- id = rec.id;
+ if (!oldValue || (self.localData[oldValue].res_id !== data.id)) {
+ // only register a change if the value has changed
+ rec = self._makeDataPoint({
+ context: record.context,
+ data: data,
+ modelName: field.relation,
+ parentID: record.id,
+ });
+ id = rec.id;
+ record._changes[name] = id;
+ }
+ } else {
+ record._changes[name] = false;
}
- record._changes[name] = id;
} else if (field.type === 'reference') {
id = false;
if (val) {
var ref = val.split(',');
- rec = self._makeDataPoint({
- context: record.context,
- data: {id: parseInt(ref[1])},
- modelName: ref[0],
- parentID: record.id,
- });
- defs.push(self._fetchNameGet(rec));
- id = rec.id;
+ var modelName = ref[0];
+ var resID = parseInt(ref[1]);
+ if (!oldValue || self.localData[oldValue].res_id !== resID ||
+ self.localData[oldValue].model !== modelName) {
+ // only register a change if the value has changed
+ rec = self._makeDataPoint({
+ context: record.context,
+ data: {id: parseInt(ref[1])},
+ modelName: modelName,
+ parentID: record.id,
+ });
+ defs.push(self._fetchNameGet(rec));
+ id = rec.id;
+ record._changes[name] = id;
+ }
+ } else {
+ record._changes[name] = id;
}
- record._changes[name] = id;
} else if (field.type === 'one2many' || field.type === 'many2many') {
var listId = record._changes[name] || record.data[name];
var list;
@@ -1240,26 +1303,40 @@ var BasicModel = AbstractModel.extend({
viewType: fieldInfo.viewType,
});
}
+ // TODO: before registering the changes, verify that the x2many
+ // value has changed
record._changes[name] = list.id;
var shouldLoad = false;
list._changes = list._changes || [];
_.each(val, function (command) {
+ var rec;
if (command[0] === 0 || command[0] === 1) {
// CREATE or UPDATE
- var params = {
- context: list.context,
- fields: list.fields,
- fieldsInfo: list.fieldsInfo,
- modelName: list.model,
- parentID: list.id,
- viewType: list.viewType,
+ if (command[0] === 1 && command[1]) {
+ // updating an existing record
+ var recID = _.find(list.data, function (childID) {
+ var child = self.localData[childID];
+ return child.res_id === command[1];
+ });
+ rec = self.localData[recID];
+ }
+ if (!rec) {
+ var params = {
+ context: list.context,
+ fields: list.fields,
+ fieldsInfo: list.fieldsInfo,
+ modelName: list.model,
+ parentID: list.id,
+ viewType: list.viewType,
ref: command[1],
- };
- if (command[0] === 1) {
- params.res_id = command[1];
+ };
+ if (command[0] === 1) {
+ params.res_id = command[1];
+ }
+ rec = self._makeDataPoint(params);
+ list._cache[rec.res_id] = rec.id;
}
- rec = self._makeDataPoint(params);
- list._cache[rec.res_id] = rec.id;
+
list._changes.push({operation: 'ADD', id: rec.id});
if (command[0] === 1) {
list._changes.push({operation: 'UPDATE', id: rec.id});
@@ -1280,7 +1357,10 @@ var BasicModel = AbstractModel.extend({
defs.push(self._readUngroupedList(list));
}
} else {
- record._changes[name] = self._parseServerValue(field, val);
+ var newValue = self._parseServerValue(field, val);
+ if (newValue !== oldValue) {
+ record._changes[name] = newValue;
+ }
}
});
return $.when.apply($, defs);