diff options
| author | Christophe Simonis <chs@odoo.com> | 2017-10-27 14:30:33 +0200 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2017-10-27 14:30:33 +0200 |
| commit | a54c60b45a1246a29ef8c5cef7681964f27e1435 (patch) | |
| tree | 0e9ce7f7be9d37b59db0d495db43cb265b7a3df5 /addons/web/static/src/js/views/basic/basic_model.js | |
| parent | 49b8eed40857a9e352c8c9b8c90715a065eccd5c (diff) | |
| parent | e918271f7600d9f77dc6631e48814f0daf951ad8 (diff) | |
[MERGE] forward port branch 11.0 up to e918271f760
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.js | 74 |
1 files changed, 49 insertions, 25 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 1df118ecfd9..4412d29c455 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -1092,9 +1092,12 @@ var BasicModel = AbstractModel.extend({ * @param {boolean} [options.doNotSetDirty=false] if this flag is set to * true, then we will not tag the record as dirty. This should be avoided * for most situations. + * @param {boolean} [options.notifyChange=true] if this flag is set to + * false, then we will not notify and not trigger the onchange, even though + * it was changed. * @param {string} [options.viewType] current viewType. If not set, we will assume * main viewType from the record - * @returns {Deferred} + * @returns {Deferred} list of changed fields */ _applyChange: function (recordID, changes, options) { var self = this; @@ -1106,6 +1109,10 @@ var BasicModel = AbstractModel.extend({ if (!options.doNotSetDirty) { record._isDirty = true; } + var initialData = {}; + this._visitChildren(record, function (elem) { + initialData[elem.id] = $.extend(true, {}, _.pick(elem, 'data', '_changes')); + }); // apply changes to local data for (var fieldName in changes) { @@ -1119,6 +1126,10 @@ var BasicModel = AbstractModel.extend({ } } + if (options.notifyChange === false) { + return $.Deferred().resolve(_.keys(changes)); + } + return $.when.apply($, defs).then(function () { var onChangeFields = []; // the fields that have changed and that have an on_change for (var fieldName in changes) { @@ -1130,12 +1141,18 @@ var BasicModel = AbstractModel.extend({ } } } - var onchangeDef; + var onchangeDef = $.Deferred(); if (onChangeFields.length) { - onchangeDef = self._performOnChange(record, onChangeFields, options.viewType).then(function (result) { - delete record._warning; - return _.keys(changes).concat(Object.keys(result && result.value || {})); - }); + self._performOnChange(record, onChangeFields, options.viewType) + .then(function (result) { + delete record._warning; + onchangeDef.resolve(_.keys(changes).concat(Object.keys(result && result.value || {}))); + }).fail(function () { + self._visitChildren(record, function (elem) { + _.extend(elem, initialData[elem.id]); + }); + onchangeDef.resolve({}); + }); } else { onchangeDef = $.Deferred().resolve(_.keys(changes)); } @@ -1306,15 +1323,17 @@ var BasicModel = AbstractModel.extend({ } else { var fieldInfo = record.fieldsInfo[viewType][name]; if (!fieldInfo) { - return; //ignore changes of x2many not in view + return; // ignore changes of x2many not in view } + var view = fieldInfo.views && fieldInfo.views[fieldInfo.mode]; list = self._makeDataPoint({ - fieldsInfo: fieldInfo.fieldsInfo, + fields: view ? view.fields : fieldInfo.relatedFields, + fieldsInfo: view ? view.fieldsInfo : fieldInfo.fieldsInfo, modelName: field.relation, parentID: record.id, static: true, type: 'list', - viewType: fieldInfo.viewType, + viewType: view ? view.type : fieldInfo.viewType, }); } // TODO: before registering the changes, verify that the x2many @@ -2305,6 +2324,7 @@ var BasicModel = AbstractModel.extend({ var ids = record.data[fieldName] || []; var list = self._makeDataPoint({ count: ids.length, + context: record.context, fieldsInfo: fieldsInfo, fields: view ? view.fields : fieldInfo.relatedFields, limit: fieldInfo.limit, @@ -2643,13 +2663,21 @@ var BasicModel = AbstractModel.extend({ } commands[fieldName].push(command); } else if (_.contains(addedIds, list.res_ids[i])) { - // this is a new id + // this is a new id (maybe existing in DB, but new in JS) relRecord = _.findWhere(relRecordAdded, {res_id: list.res_ids[i]}); changes = this._generateChanges(relRecord, options); if ('id' in changes) { + // the subrecord already exists in db delete changes.id; - commands[fieldName].push(x2ManyCommands.update(relRecord.res_id, changes)); + if (this.isNew(record.id)) { + // if the main record is new, link the subrecord to it + commands[fieldName].push(x2ManyCommands.link_to(relRecord.res_id)); + } + if (!_.isEmpty(changes)) { + commands[fieldName].push(x2ManyCommands.update(relRecord.res_id, changes)); + } } else { + // the subrecord is new, so create it commands[fieldName].push(x2ManyCommands.create(relRecord.ref, changes)); } } @@ -2882,7 +2910,8 @@ var BasicModel = AbstractModel.extend({ * @returns {boolean} */ _isFieldProtected: function (record, fieldName, viewType) { - var fieldInfo = record.fieldsInfo[viewType || record.viewType][fieldName]; + var fieldInfo = record.fieldsInfo && + (record.fieldsInfo[viewType || record.viewType][fieldName]); if (fieldInfo) { var rawModifiers = fieldInfo.modifiers || {}; var modifiers = this._evalModifiers(record, rawModifiers); @@ -3239,15 +3268,18 @@ var BasicModel = AbstractModel.extend({ }); return $.when.apply($, defs) .then(function () { - return self._performOnChange(record, fields_key).then(function () { + var def = $.Deferred(); + self._performOnChange(record, fields_key).always(function () { if (record._warning) { if (params.allowWarning) { delete record._warning; } else { - return $.Deferred().reject(); + def.reject(); } } + def.resolve(); }); + return def; }) .then(function () { return self._fetchRelationalData(record); @@ -3314,10 +3346,7 @@ var BasicModel = AbstractModel.extend({ * @param {string[]} fields changed fields * @param {string} [viewType] current viewType. If not set, we will assume * main viewType from the record - * @returns {Deferred} Note: this deferred cannot fail. It is either in the - * 'success' or 'pending' state. If the onchange rpc fails, it will be - * resolved with an empty dictionary. Note that the initial change was - * already applied. + * @returns {Deferred} */ _performOnChange: function (record, fields, viewType) { var self = this; @@ -3337,9 +3366,7 @@ var BasicModel = AbstractModel.extend({ var context = this._getContext(record, options); var currentData = this._generateOnChangeData(record, {changesOnly: false}); - var def = $.Deferred(); - - self._rpc({ + return self._rpc({ model: record.model, method: 'onchange', args: [idList, currentData, fields, onchangeSpec, context], @@ -3364,12 +3391,9 @@ var BasicModel = AbstractModel.extend({ record._domains = _.extend(record._domains, result.domain); } return self._applyOnChange(result.value, record).then(function () { - def.resolve(result); + return result; }); - }).fail(function () { - def.resolve({}); }); - return def; }, /** * Once a record is created and some data has been fetched, we need to do |
