From 07435b110440ba41e559373c4494e674e68e5724 Mon Sep 17 00:00:00 2001 From: "Lucas Perais (lpe)" Date: Tue, 27 Mar 2018 10:17:06 +0200 Subject: [FIX] web: correctly display reference field in subview Have a form view with a O2M. The model at the 'many' end has a reference field Have a record of the second model display in a modal (by clicking on a record in the o2m list) Before this commit: The field reference was not filled up This was because the fields to fetch on the modal creation weren't correctly set. Obvisouly, it also created problem when trying to change the record on the modal: spawning tracebacks because the reference field was not present in the local datas After this commit: The display of the reference field is as expected both in the original form and in the modal OPW 1829822 closes #22468 closes #23896 --- addons/web/static/src/js/views/basic/basic_model.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'addons/web/static/src/js/views/basic/basic_model.js') 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 e60e3f15a03..11e2347eba7 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -2011,7 +2011,7 @@ var BasicModel = AbstractModel.extend({ .then(function () { return $.when( self._fetchX2Manys(record, options), - self._fetchReferences(record) + self._fetchReferences(record, options) ).then(function () { return self._postprocess(record, options); }); @@ -2058,10 +2058,10 @@ var BasicModel = AbstractModel.extend({ * @param {Object} record * @returns {Deferred} */ - _fetchReferences: function (record) { + _fetchReferences: function (record, options) { var self = this; var defs = []; - var fieldNames = record.getFieldNames(); + var fieldNames = options && options.fieldNames || record.getFieldNames(); _.each(fieldNames, function (fieldName) { var field = record.fields[fieldName]; if (field.type === 'reference') { -- cgit v1.2.3 From 6397ce7eb0c4ad912259ab6d6ee3a9fbf16d0c64 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Wed, 4 Apr 2018 13:28:35 +0200 Subject: [FIX] web: loss of context when duplicating MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Create a vendor bill, save and validate - Duplicate the bill, save - Click on "Create" A customer invoice is created, while the user expects a vendor bill. After duplication, the new record is loaded but the context is lost. Since the default value for the invoice type is based on the context key `type`, a loss of context leads to an incorrect invoice type. opw-1826453 Co-authored-by: Géry Debongnie --- addons/web/static/src/js/views/basic/basic_model.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'addons/web/static/src/js/views/basic/basic_model.js') 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 11e2347eba7..d7d91a65405 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -375,11 +375,12 @@ var BasicModel = AbstractModel.extend({ duplicateRecord: function (recordID) { var self = this; var record = this.localData[recordID]; + var context = this._getContext(record); return this._rpc({ model: record.model, method: 'copy', args: [record.data.id], - context: this._getContext(record), + context: context, }) .then(function (res_id) { var index = record.res_ids.indexOf(record.res_id); @@ -391,6 +392,7 @@ var BasicModel = AbstractModel.extend({ res_id: res_id, res_ids: record.res_ids.slice(0), viewType: record.viewType, + context: context, }); }); }, -- cgit v1.2.3 From 9a9da5763b38a3bce54e9c4870af0032e38cacc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20K=C3=BChn?= Date: Wed, 4 Apr 2018 10:09:33 +0200 Subject: [FIX] web: no record abandon on discard from default_get/onchange Before this commit, when some records were created from an `onchange`, we have the following weird behaviour: Suppose that this record has some required fields that are empty. When we click on this record, then somewhere else, the record disappears from the list. This is because the records contains invalid fields, and it is wrongfully assuming that the record to be discarded comes from "Add an item". A previous commit [1] fixed a bit this issue with `default_get`, but since it relied on a fragile heuristic, we decide to apply the correct fix with this commit. [1] https://github.com/odoo/odoo/commit/b09f0c99be2b13d33986414485556d87da186d65 --- .../web/static/src/js/views/basic/basic_model.js | 29 +++++++++++----------- 1 file changed, 14 insertions(+), 15 deletions(-) (limited to 'addons/web/static/src/js/views/basic/basic_model.js') 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 d7d91a65405..979f8ae3fec 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -569,10 +569,15 @@ var BasicModel = AbstractModel.extend({ return _t("New"); }, /** - * Returns true if a record can be abandoned from a list datapoint. + * Returns true if a record can be abandoned. * - * A record cannot be abandonned if it has been registered as "added" - * in the parent's savepoint, otherwise it can be abandonned. + * A record can be abandonned if it is a new record, except if + * this datapoint has been specifically tagged as "do not abandon". + * + * Example: + * + * - Discard record from "Add an item" => "New" record => abandon + * - Discard record from `default_get`/`onchange` => do not abandon * * This is useful when discarding changes on this record, as it means that * we must keep the record even if some fields are invalids (e.g. required @@ -582,15 +587,7 @@ var BasicModel = AbstractModel.extend({ * @returns {boolean} */ canBeAbandoned: function (id) { - var data = this.localData[id]; - var parent = this.localData[data.parentID]; - var abandonable = true; - if (parent) { - abandonable = !_.some(parent._savePoint, function (entry) { - return entry.operation === 'ADD' && entry.id === id; - }); - } - return abandonable; + return !this.localData[id]._noAbandon && this.isNew(id); }, /** * Returns true if a record is dirty. A record is considered dirty if it has @@ -951,11 +948,11 @@ var BasicModel = AbstractModel.extend({ * @returns {Deferred} * Resolved with the list of field names (whose value has been modified) */ - save: function (record_id, options) { + save: function (recordID, options) { var self = this; return this.mutex.exec(function () { options = options || {}; - var record = self.localData[record_id]; + var record = self.localData[recordID]; if (options.savePoint) { self._visitChildren(record, function (rec) { var newValue = rec._changes || rec.data; @@ -973,7 +970,7 @@ var BasicModel = AbstractModel.extend({ }); } var shouldReload = 'reload' in options ? options.reload : true; - var method = self.isNew(record_id) ? 'create' : 'write'; + var method = self.isNew(recordID) ? 'create' : 'write'; if (record._changes) { // id never changes, and should not be written delete record._changes.id; @@ -1538,6 +1535,7 @@ var BasicModel = AbstractModel.extend({ list._cache[rec.res_id] = rec.id; } + rec._noAbandon = true; list._changes.push({operation: 'ADD', id: rec.id}); if (command[0] === 1) { list._changes.push({operation: 'UPDATE', id: rec.id}); @@ -3574,6 +3572,7 @@ var BasicModel = AbstractModel.extend({ parentID: x2manyList.id, viewType: viewType, }); + r._noAbandon = true; x2manyList._changes.push({operation: 'ADD', id: r.id}); x2manyList._cache[r.res_id] = r.id; -- cgit v1.2.3 From 729ff2d35eeac7db8cf5fa16009d5c918ee1dd5b Mon Sep 17 00:00:00 2001 From: Martin Geubelle Date: Wed, 11 Apr 2018 14:47:03 +0200 Subject: [FIX] web: update column in grouped kanban In a kanban grouped by many2one with a progressbar, after emptying a column by moving all records, the column wasn't correctly updated. This was causing, in the best case, a record duplication or, in the worst case, a traceback. This issue comes from the fact that, with a progressbar, a read_group is performed each time a record is moved. When the group (column) becomes empty, the read_group won't return this group even though the group still appears in the kankan. When moving back the record in this empty column, there is a desynchronization between the kanban controller data and the model. To fix this issue, an option `keepEmptyGroups` is passed when performing the mentioned read_group ; this mimics the kanban display that keeps empty groups displayed and there is no desync anymore. Fixes #23982 --- addons/web/static/src/js/views/basic/basic_model.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'addons/web/static/src/js/views/basic/basic_model.js') 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 979f8ae3fec..0b2d35cb89f 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -3166,6 +3166,9 @@ var BasicModel = AbstractModel.extend({ * @param {Object} [options] * @param {string[]} [options.fieldNames] the fields to fetch for a record * @param {boolean} [options.onlyGroups=false] + * @param {boolean} [options.keepEmptyGroups=false] if set, the groups not + * present in the read_group anymore (empty groups) will stay in the + * datapoint (used to mimic the kanban renderer behaviour for example) * @returns {Deferred} */ _load: function (dataPoint, options) { @@ -3796,6 +3799,16 @@ var BasicModel = AbstractModel.extend({ defs.push(self._load(newGroup, options)); } }); + if (options && options.keepEmptyGroups) { + // Find the groups that were available in a previous + // readGroup but are not there anymore. + // Note that these groups are put after existing groups so + // the order is not conserved. A sort *might* be useful. + var emptyGroupsIDs = _.difference(_.pluck(previousGroups, 'id'), list.data); + _.each(emptyGroupsIDs, function (groupID) { + list.data.push(groupID); + }); + } return $.when.apply($, defs).then(function () { // generate the res_ids of the main list, being the concatenation // of the fetched res_ids in each group -- cgit v1.2.3 From 8e5156938a9c87b80512bff9ecd025891406e624 Mon Sep 17 00:00:00 2001 From: "Lucas Perais (lpe)" Date: Fri, 6 Apr 2018 17:43:22 +0200 Subject: [FIX] web: o2m list with field datetime from server Have the create_date field displays on a one2many list Try to add a record onto the list Before this commit, when the virtual record is added onto the list it crashes because the datetime field is undefined and cannot be parsed After this commit, It doesn't crash though the value would have to wait the save on the main record to be updated (because it is the create_date) OPW 1834250 closes #24097 --- .../web/static/src/js/views/basic/basic_model.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'addons/web/static/src/js/views/basic/basic_model.js') 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 0b2d35cb89f..aa00df42e41 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -3321,9 +3321,29 @@ var BasicModel = AbstractModel.extend({ */ _makeDefaultRecord: function (modelName, params) { var self = this; + + var determineExtraFields = function() { + // Fields that are present in the originating view, that need to be initialized + // Hence preventing their value to crash when getting back to the originating view + var parentRecord = self.localData[params.parentID]; + + var originView = parentRecord && parentRecord.fieldsInfo; + if (!originView || !originView[parentRecord.viewType]) + return []; + + var fieldsFromOrigin = _.filter(Object.keys(originView[parentRecord.viewType]), + function(fieldname) { + return params.fields[fieldname] !== undefined; + }); + + return fieldsFromOrigin; + } + var fieldNames = Object.keys(params.fieldsInfo[params.viewType]); var fields_key = _.without(fieldNames, '__last_update'); + var extraFields = determineExtraFields(); + return this._rpc({ model: modelName, method: 'default_get', @@ -3341,7 +3361,7 @@ var BasicModel = AbstractModel.extend({ viewType: params.viewType, }); - return self.applyDefaultValues(record.id, result) + return self.applyDefaultValues(record.id, result, {fieldNames: _.union(fieldNames, extraFields)}) .then(function () { var def = $.Deferred(); self._performOnChange(record, fields_key).always(function () { -- cgit v1.2.3 From 52cd52e624d987916ea62e566cc777505c13e469 Mon Sep 17 00:00:00 2001 From: Aaron Bohy Date: Fri, 13 Apr 2018 12:20:55 +0200 Subject: [FIX] web: BasicModel: default_get on o2m with date field Before this rev., a crash occured when a default_get returned a command 0 (CREATE) for a one2many, with a value for a date(time) field (e.g. [0, false, {some_date_field: '2018-12-08'}]). This was because the related values (inside the commands) weren't parsed. This only impacted date and datetime fields, for which the parsing converts the string into a moment instance. Fixes #23672 --- addons/web/static/src/js/views/basic/basic_model.js | 2 ++ 1 file changed, 2 insertions(+) (limited to 'addons/web/static/src/js/views/basic/basic_model.js') 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 aa00df42e41..4180acae602 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -3625,6 +3625,8 @@ var BasicModel = AbstractModel.extend({ } else if (_.contains(['one2many', 'many2many'], fieldType)) { var x2mCommands = commands[0][2][fieldName]; defs.push(self._processX2ManyCommands(r, fieldName, x2mCommands)); + } else { + r._changes[fieldName] = self._parseServerValue(field, r._changes[fieldName]); } } } -- cgit v1.2.3