From 78fdd8580c7676980a81a4bc190274055702eddc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20D=2E=20D=C3=ADaz?= Date: Fri, 19 Feb 2021 23:56:00 +0100 Subject: [PATCH] [IMP] web_widget_one2many_product_picker: Add option to ignore onchange warnings --- web_widget_one2many_product_picker/README.rst | 2 + .../__manifest__.py | 2 +- web_widget_one2many_product_picker/i18n/ca.po | 4 +- web_widget_one2many_product_picker/i18n/es.po | 4 +- .../i18n/pt_BR.po | 14 +- .../web_widget_one2many_product_picker.pot | 4 +- .../readme/CONFIGURE.rst | 2 + .../static/description/index.html | 2 + .../js/views/One2ManyProductPicker/record.js | 12 +- .../views/One2ManyProductPicker/renderer.js | 27 +++ .../static/src/js/views/basic_model.js | 174 ++---------------- .../widgets/field_one2many_product_picker.js | 7 +- 12 files changed, 81 insertions(+), 173 deletions(-) diff --git a/web_widget_one2many_product_picker/README.rst b/web_widget_one2many_product_picker/README.rst index 0587024f2..bd6dc7ef0 100644 --- a/web_widget_one2many_product_picker/README.rst +++ b/web_widget_one2many_product_picker/README.rst @@ -86,6 +86,8 @@ Widget options: will lose part of its functionality as the document will be saved every time you modify/create a record with the widget. +* ignore_warning > Enable/Disable display onchange warnings (False by default) + All widget options are optional. Notice that you can call '_' method to use translations. This only can be used with this widget. diff --git a/web_widget_one2many_product_picker/__manifest__.py b/web_widget_one2many_product_picker/__manifest__.py index b9d0b122e..5842edae2 100644 --- a/web_widget_one2many_product_picker/__manifest__.py +++ b/web_widget_one2many_product_picker/__manifest__.py @@ -4,7 +4,7 @@ { 'name': 'Web Widget One2Many Product Picker', 'summary': 'Widget to select products on one2many fields', - 'version': '12.0.2.2.0', + 'version': '12.0.2.3.0', 'category': 'Website', 'author': "Tecnativa, " "Odoo Community Association (OCA)", diff --git a/web_widget_one2many_product_picker/i18n/ca.po b/web_widget_one2many_product_picker/i18n/ca.po index 38fd2e7a0..fc6ba21ff 100644 --- a/web_widget_one2many_product_picker/i18n/ca.po +++ b/web_widget_one2many_product_picker/i18n/ca.po @@ -25,7 +25,7 @@ msgstr "Afegir" #. module: web_widget_one2many_product_picker #. openerp-web -#: code:addons/web_widget_one2many_product_picker/static/src/js/widgets/field_one2many_product_picker.js:192 +#: code:addons/web_widget_one2many_product_picker/static/src/js/widgets/field_one2many_product_picker.js:193 #, python-format msgid "All" msgstr "Tot" @@ -114,7 +114,7 @@ msgstr "Imatge variant mitjana ( calculada)" #. module: web_widget_one2many_product_picker #. openerp-web -#: code:addons/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/record.js:340 +#: code:addons/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/record.js:341 #, python-format msgid "[No widget %s]" msgstr "[Sense widget %s]" diff --git a/web_widget_one2many_product_picker/i18n/es.po b/web_widget_one2many_product_picker/i18n/es.po index e428bfd3a..8caba4d46 100644 --- a/web_widget_one2many_product_picker/i18n/es.po +++ b/web_widget_one2many_product_picker/i18n/es.po @@ -25,7 +25,7 @@ msgstr "Añadir" #. module: web_widget_one2many_product_picker #. openerp-web -#: code:addons/web_widget_one2many_product_picker/static/src/js/widgets/field_one2many_product_picker.js:192 +#: code:addons/web_widget_one2many_product_picker/static/src/js/widgets/field_one2many_product_picker.js:193 #, python-format msgid "All" msgstr "Todo" @@ -114,7 +114,7 @@ msgstr "Imagen variante media (calculada)" #. module: web_widget_one2many_product_picker #. openerp-web -#: code:addons/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/record.js:340 +#: code:addons/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/record.js:341 #, python-format msgid "[No widget %s]" msgstr "[Sin widget %s]" diff --git a/web_widget_one2many_product_picker/i18n/pt_BR.po b/web_widget_one2many_product_picker/i18n/pt_BR.po index a03a52c02..d977eaa14 100644 --- a/web_widget_one2many_product_picker/i18n/pt_BR.po +++ b/web_widget_one2many_product_picker/i18n/pt_BR.po @@ -1,6 +1,6 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * web_widget_one2many_product_picker +# * web_widget_one2many_product_picker # msgid "" msgstr "" @@ -23,7 +23,7 @@ msgstr "" #. module: web_widget_one2many_product_picker #. openerp-web -#: code:addons/web_widget_one2many_product_picker/static/src/js/widgets/field_one2many_product_picker.js:192 +#: code:addons/web_widget_one2many_product_picker/static/src/js/widgets/field_one2many_product_picker.js:193 #, python-format msgid "All" msgstr "" @@ -84,12 +84,16 @@ msgstr "" #. module: web_widget_one2many_product_picker #: model:ir.model.fields,help:web_widget_one2many_product_picker.field_product_product__image_variant_medium -msgid "This field holds the image used as image for the product variantor product image medium, limited to 512x512px." +msgid "" +"This field holds the image used as image for the product variantor product " +"image medium, limited to 512x512px." msgstr "" #. module: web_widget_one2many_product_picker #: model:ir.model.fields,help:web_widget_one2many_product_picker.field_product_product__image_variant_big -msgid "This field holds the image used as image for the product variantor product image, limited to 1024x1024px." +msgid "" +"This field holds the image used as image for the product variantor product " +"image, limited to 1024x1024px." msgstr "" #. module: web_widget_one2many_product_picker @@ -104,7 +108,7 @@ msgstr "" #. module: web_widget_one2many_product_picker #. openerp-web -#: code:addons/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/record.js:340 +#: code:addons/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/record.js:341 #, python-format msgid "[No widget %s]" msgstr "" diff --git a/web_widget_one2many_product_picker/i18n/web_widget_one2many_product_picker.pot b/web_widget_one2many_product_picker/i18n/web_widget_one2many_product_picker.pot index d75ace2eb..8e01a53b5 100644 --- a/web_widget_one2many_product_picker/i18n/web_widget_one2many_product_picker.pot +++ b/web_widget_one2many_product_picker/i18n/web_widget_one2many_product_picker.pot @@ -22,7 +22,7 @@ msgstr "" #. module: web_widget_one2many_product_picker #. openerp-web -#: code:addons/web_widget_one2many_product_picker/static/src/js/widgets/field_one2many_product_picker.js:192 +#: code:addons/web_widget_one2many_product_picker/static/src/js/widgets/field_one2many_product_picker.js:193 #, python-format msgid "All" msgstr "" @@ -103,7 +103,7 @@ msgstr "" #. module: web_widget_one2many_product_picker #. openerp-web -#: code:addons/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/record.js:340 +#: code:addons/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/record.js:341 #, python-format msgid "[No widget %s]" msgstr "" diff --git a/web_widget_one2many_product_picker/readme/CONFIGURE.rst b/web_widget_one2many_product_picker/readme/CONFIGURE.rst index 1e5f8698b..29d8e9813 100644 --- a/web_widget_one2many_product_picker/readme/CONFIGURE.rst +++ b/web_widget_one2many_product_picker/readme/CONFIGURE.rst @@ -44,6 +44,8 @@ Widget options: will lose part of its functionality as the document will be saved every time you modify/create a record with the widget. +* ignore_warning > Enable/Disable display onchange warnings (False by default) + All widget options are optional. Notice that you can call '_' method to use translations. This only can be used with this widget. diff --git a/web_widget_one2many_product_picker/static/description/index.html b/web_widget_one2many_product_picker/static/description/index.html index 18ba5686e..de595921c 100644 --- a/web_widget_one2many_product_picker/static/description/index.html +++ b/web_widget_one2many_product_picker/static/description/index.html @@ -471,6 +471,8 @@ You need to define the view fields. The view must be of ignore_warning > Enable/Disable display onchange warnings (False by default)

+

All widget options are optional. Notice that you can call ‘_’ method to use translations. This only can be used with this widget.

diff --git a/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/record.js b/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/record.js index a91c9db8d..f65ecc85b 100644 --- a/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/record.js +++ b/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/record.js @@ -557,6 +557,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu _addProduct: function () { var self = this; var model = this.options.basicFieldParams.model; + model.updateRecordContext(this.state.id, {ignore_warning: this.options.ignoreWarning}); var record = model.get(this.state.id); var changes = _.pick(record.data, this.options.fieldMap.product_uom_qty); if (changes[this.options.fieldMap.product_uom_qty] === 0) { @@ -564,7 +565,10 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu } var model = this.options.basicFieldParams.model; this.$card.addClass("blocked"); - return model.notifyChanges(record.id, changes).then(function () { + return model.notifyChanges( + record.id, + changes + ).then(function () { self._saveRecord(); }); }, @@ -577,11 +581,15 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRecord", fu _incProductQty: function (amount) { var self = this; var model = this.options.basicFieldParams.model; + model.updateRecordContext(this.state.id, {ignore_warning: this.options.ignoreWarning}); var record = model.get(this.state.id); var changes = _.pick(record.data, this.options.fieldMap.product_uom_qty); changes[this.options.fieldMap.product_uom_qty] += amount; - return model.notifyChanges(record.id, changes).then(function () { + return model.notifyChanges( + record.id, + changes + ).then(function () { self._processDynamicFields(); self._lazyUpdateRecord(); }); diff --git a/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/renderer.js b/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/renderer.js index e5225d0a0..71750434d 100644 --- a/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/renderer.js +++ b/web_widget_one2many_product_picker/static/src/js/views/One2ManyProductPicker/renderer.js @@ -300,6 +300,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer", }); this.$extraButtonsContainer = $(qweb.render("One2ManyProductPicker.ExtraButtons")); this.$btnLoadMore = this.$extraButtonsContainer.find("#productPickerLoadMore"); + this.search_data = this._sort_search_data(this.search_data); return $.Deferred(function (d) { var defs = self.appendSearchRecords(self.search_data, true); defs[0].then(function () { @@ -316,6 +317,31 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer", }); }, + /** + * @param {Array} datas + * @returns {Array} + */ + _sort_search_data: function (datas) { + if (this.search_group.name === "main_lines") { + var field_name = this.options.field_map.product; + for (var index_datas in datas) { + var data = datas[index_datas]; + + for (var index_state in this.state.data) { + var state_data = this.state.data[index_state]; + if (state_data.data[field_name].res_id === data.id) { + data._order_value = state_data.res_id; + } + } + } + var sorted_datas = _.chain(datas).sortBy('_order_value').map(function(item) { + return _.omit(item, '_order_value'); + }).value().reverse(); + return sorted_datas; + } + return datas; + }, + /** * Compare search results with current lines. * Link a current state with the 'search record'. @@ -385,6 +411,7 @@ odoo.define("web_widget_one2many_product_picker.One2ManyProductPickerRenderer", editDiscount: this.options.edit_discount, editPrice: this.options.edit_price, autoSave: this.options.auto_save, + ignoreWarning: this.options.ignore_warning, }); }, diff --git a/web_widget_one2many_product_picker/static/src/js/views/basic_model.js b/web_widget_one2many_product_picker/static/src/js/views/basic_model.js index 9a69b6ccd..9d8fd3f52 100644 --- a/web_widget_one2many_product_picker/static/src/js/views/basic_model.js +++ b/web_widget_one2many_product_picker/static/src/js/views/basic_model.js @@ -79,8 +79,9 @@ odoo.define("web_widget_one2many_product_picker.BasicModel", function (require) self._makeDefaultRecord(list.model, params) .then(function (recordID) { self.setPureVirtual(recordID, true); + self.updateRecordContext(recordID, {ignore_warning: true}); if (options.data) { - self._applyChangeNoWarnings( + self._applyChange( recordID, options.data, params @@ -95,165 +96,26 @@ odoo.define("web_widget_one2many_product_picker.BasicModel", function (require) }, /** - * Cloned '_applyChange' but without warning messages + * Adds support to avoid show onchange warnings. + * The implementation is a pure hack that clone + * the context and do a monkey path the + * 'trigger_up' method. * - * @private - * @param {Number} recordID - * @param {Object} changes - * @param {Object} options - * @returns {Deferred} + * @override */ - _applyChangeNoWarnings: function (recordID, changes, options) { - var self = this; - var record = this.localData[recordID]; - var field; - var defs = []; - options = options || {}; - record._changes = record._changes || {}; - 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) { - field = record.fields[fieldName]; - if (field && (field.type === 'one2many' || field.type === 'many2many')) { - defs.push(this._applyX2ManyChange( - record, - fieldName, - changes[fieldName], - options.viewType, - options.allowWarning)); - } else if (field && (field.type === 'many2one' || field.type === 'reference')) { - defs.push(this._applyX2OneChange(record, fieldName, changes[fieldName])); - } else { - record._changes[fieldName] = changes[fieldName]; - } - } - - if (options.notifyChange === false) { - return $.Deferred().resolve(_.keys(changes)); - } - - return $.when.apply($, defs).then(function () { - - // The fields that have changed and that have an on_change - var onChangeFields = []; - for (var fieldName in changes) { - field = record.fields[fieldName]; - if (field && field.onChange) { - var isX2Many = ( - field.type === 'one2many' || - field.type === 'many2many' - ); - if ( - !isX2Many || - ( - self._isX2ManyValid( - record._changes[fieldName] || - record.data[fieldName] - ) - ) - ) { - onChangeFields.push(fieldName); - } + _performOnChange: function (record, fields, viewType) { + if (record.context && record.context.ignore_warning) { + var this_mp = _.clone(this); + var super_call = this.trigger_up; + this_mp.trigger_up = function (event_name, data) { + if (event_name === 'warning' && data.type === "dialog") { + return; // Do nothing } - } - var onchangeDef = $.Deferred(); - if (onChangeFields.length) { - self._performOnChangeNoWarnings(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]); - }); - - // Safe fix for stable version, for opw-2267444 - if (!options.force_fail) { - onchangeDef.resolve({}); - } else { - onchangeDef.reject({}); - } - }); - } else { - onchangeDef = $.Deferred().resolve(_.keys(changes)); - } - return onchangeDef.then(function (fieldNames) { - _.each(fieldNames, function (name) { - if ( - record._changes && - record._changes[name] === record.data[name] - ) { - delete record._changes[name]; - record._isDirty = !_.isEmpty(record._changes); - } - }); - return self._fetchSpecialData(record).then(function (fieldNames2) { - - // Return the names of the fields that changed (onchange or - // associated special data change) - return _.union(fieldNames, fieldNames2); - }); - }); - }); - }, - - /** - * Cloned '_performOnChange' but without warning messages - * - * @private - * @param {Object} record - * @param {Object} fields - * @param {String} viewType - * @returns {Deferred} - */ - _performOnChangeNoWarnings: function (record, fields, viewType) { - var self = this; - var onchangeSpec = this._buildOnchangeSpecs(record, viewType); - if (!onchangeSpec) { - return $.when(); + return super_call.apply(this, arguments); + }.bind(this); + return this._super.apply(this_mp, arguments); } - var idList = record.data.id ? [record.data.id] : []; - var options = { - full: true, - }; - if (fields.length === 1) { - fields = fields[0]; - - // If only one field changed, add its context to the RPC context - options.fieldName = fields; - } - var context = this._getContext(record, options); - var currentData = this._generateOnChangeData(record, {changesOnly: false}); - - return self._rpc({ - model: record.model, - method: 'onchange', - args: [idList, currentData, fields, onchangeSpec, context], - }).then(function (result) { - if (!record._changes) { - - // If the _changes key does not exist anymore, it means that - // it was removed by discarding the changes after the rpc - // to onchange. So, in that case, the proper response is to - // ignore the onchange. - return; - } - if (result.domain) { - record._domains = _.extend(record._domains, result.domain); - } - return self._applyOnChange(result.value, record).then(function () { - return result; - }); - }); + return this._super.apply(this, arguments); }, }); diff --git a/web_widget_one2many_product_picker/static/src/js/widgets/field_one2many_product_picker.js b/web_widget_one2many_product_picker/static/src/js/widgets/field_one2many_product_picker.js index 3f2593c8e..d642a7aea 100644 --- a/web_widget_one2many_product_picker/static/src/js/widgets/field_one2many_product_picker.js +++ b/web_widget_one2many_product_picker/static/src/js/widgets/field_one2many_product_picker.js @@ -439,7 +439,7 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun discount: "discount", }, auto_save: false, - allow_warning: true, + ignore_warning: false, }; }, @@ -662,7 +662,7 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun }); // This will trigger an "state" update this._setValue( - {operation: "UPDATE", id: evt.data.id, data: evt.data.data} + {operation: "UPDATE", id: evt.data.id, data: evt.data.data}, ).then(function () { if (evt.data.callback) { evt.data.callback(); @@ -746,7 +746,8 @@ odoo.define("web_widget_one2many_product_picker.FieldOne2ManyProductPicker", fun * * @override */ - _setValue: function () { + + _setValue: function (value, options) { var self = this; return this._super.apply(this, arguments).then(function () { self.updateBadgeLines();