From 2014fabfbaf2e24a047881deb404844a81c7bbc1 Mon Sep 17 00:00:00 2001 From: Nicolas Lempereur Date: Tue, 30 Jan 2018 15:01:39 +0100 Subject: [PATCH 01/27] [FIX] web_editor: firefox editor hidden mass mail When saving a modified mass mailing, the editor will do a number of things to improve the mail readability accross mail client. One of those is replacing font awesome icons by image, but firefox acts differently than other browser. On a display:none iframe, doing .css('color') or .height() on an element returns respectively `undefined` and 0. This caused an error when getting the color that we could solve by doing a fallback for firefox like this: window.parent.getComputedStyle($font[0]).color But to get the height() of an element, it seems we always need the iframe displayed. With this change, when the iframe is hidden and the browser is firefox, the code try to display the iframe (with "visibility:hidden;height:1px") when this part of the code happen. note: backport of 10.0 13c326caaa opw-807180 closes #22701 --- addons/web_editor/static/src/js/backend.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/addons/web_editor/static/src/js/backend.js b/addons/web_editor/static/src/js/backend.js index 2b3c0e0790c..8677b683da5 100644 --- a/addons/web_editor/static/src/js/backend.js +++ b/addons/web_editor/static/src/js/backend.js @@ -407,7 +407,19 @@ var FieldTextHtml = widget.extend({ var layoutInfo = this.editor.rte.editable().data('layoutInfo'); $.summernote.pluginEvents.codeview(undefined, undefined, layoutInfo, false); } + var $ancestors = this.$iframe.filter(':not(:visible)').parentsUntil(':visible').addBack(); + var ancestorsStyle = []; + // temporarily force displaying iframe (needed for firefox) + _.each($ancestors, function (el) { + var $el = $(el); + ancestorsStyle.unshift($el.attr('style') || null); + $el.css({display: 'initial', visibility: 'hidden', height: 1}); + }); this.editor.buildingBlock.clean_for_save(); + _.each($ancestors, function (el) { + var $el = $(el); + $el.attr('style', ancestorsStyle.pop()); + }); this.internal_set_value( this.$content.html() ); } }, From bf9024abcb3e64dd299e7107c43e6800733c05f5 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Thu, 1 Feb 2018 17:05:28 +0100 Subject: [PATCH 02/27] [FIX] web: correctly forward-port 695bd75a1383e88099a79de89db9ee1042c83d5e Match implementation of original backport --- addons/web/static/src/js/widgets/domain_selector.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/addons/web/static/src/js/widgets/domain_selector.js b/addons/web/static/src/js/widgets/domain_selector.js index 298f4f064e5..6688a5785e7 100644 --- a/addons/web/static/src/js/widgets/domain_selector.js +++ b/addons/web/static/src/js/widgets/domain_selector.js @@ -185,11 +185,10 @@ var DomainTree = DomainNode.extend({ } catch (err) { // TODO: domain could contain `parent` for example, which is // currently not handled by the DomainSelector - this._isValid = false; + this.invalidDomain = false; this.children = []; return; } - this._initialize(domain); }, /** @@ -579,7 +578,7 @@ var DomainSelector = DomainTree.extend({ start: function () { var self = this; return this._super.apply(this, arguments).then(function () { - if (!self._isValid) { + if (self.invalidDomain) { var msg = _t("This domain is not supported."); self.$el.html(msg); } From ecfcaea080d4813a99f66ae11ff6fecd57c8c278 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Thu, 1 Feb 2018 14:30:34 +0100 Subject: [PATCH 03/27] [FIX] payment_stripe: correctly handle error If there is an error, we should handle it first. Otherwise, some keys might not be found in the results (e.g. 'object' or type') and cause a crash. --- addons/payment_stripe/models/payment.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/payment_stripe/models/payment.py b/addons/payment_stripe/models/payment.py index 76b8e3aebf7..c4e2760f228 100644 --- a/addons/payment_stripe/models/payment.py +++ b/addons/payment_stripe/models/payment.py @@ -263,6 +263,10 @@ class PaymentTokenStripe(models.Model): def _stripe_create_customer(self, token, description=None, acquirer_id=None): + if token.get('error'): + _logger.error('payment.token.stripe_create_customer: Token error:\n%s', pprint.pformat(token['error'])) + raise Exception(token['error']['message']) + if token['object'] != 'token': _logger.error('payment.token.stripe_create_customer: Cannot create a customer for object type "%s"', token.get('object')) raise Exception('We are unable to process your credit card information.') @@ -271,10 +275,6 @@ class PaymentTokenStripe(models.Model): _logger.error('payment.token.stripe_create_customer: Cannot create a customer for token type "%s"', token.get('type')) raise Exception('We are unable to process your credit card information.') - if token.get('error'): - _logger.error('payment.token.stripe_create_customer: Token error:\n%s', pprint.pformat(token['error'])) - raise Exception(token['error']['message']) - payment_acquirer = self.env['payment.acquirer'].browse(acquirer_id or self.acquirer_id.id) url_customer = 'https://%s/customers' % payment_acquirer._get_stripe_api_url() From 4df087b24d651b6763fcc50544194cbd48b5008a Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Thu, 1 Feb 2018 14:31:26 +0100 Subject: [PATCH 04/27] [FIX] payment_stripe: incorrect route The route should contain the SO id, not the acquier id. --- addons/payment_stripe/static/src/js/stripe.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/payment_stripe/static/src/js/stripe.js b/addons/payment_stripe/static/src/js/stripe.js index 13f8f91bfcd..ee8f0ff4ca6 100644 --- a/addons/payment_stripe/static/src/js/stripe.js +++ b/addons/payment_stripe/static/src/js/stripe.js @@ -121,8 +121,7 @@ odoo.define('payment_stripe.stripe', function(require) { try { provider_form[0].innerHTML = data; } catch (e) {}; }); } else if (window.location.href.includes("/my/orders/")) { - var create_tx = ajax.jsonRpc('/pay/sale/' + acquirer_id + '/form_tx/', 'call', { - so_id: so_id, + var create_tx = ajax.jsonRpc('/pay/sale/' + so_id + '/form_tx/', 'call', { access_token: access_token, acquirer_id: acquirer_id }).then(function (data) { From ad9edfc2dd2a041932bc89df55c7c3e42507efbb Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Thu, 1 Feb 2018 14:35:43 +0100 Subject: [PATCH 05/27] [FIX] payment_stripe: missing route In case an invoice is required to be paid thanks to the route '/my/invoices/', the user is redirected to '/shop/payment/transaction/'. If website_sale is not installed, this causes a crash. Complement of 2bd17285ea3bcde5c86d8cd925070b048ce39082 opw-813481 --- addons/payment_stripe/static/src/js/stripe.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/addons/payment_stripe/static/src/js/stripe.js b/addons/payment_stripe/static/src/js/stripe.js index ee8f0ff4ca6..2c22dcfa0f4 100644 --- a/addons/payment_stripe/static/src/js/stripe.js +++ b/addons/payment_stripe/static/src/js/stripe.js @@ -97,7 +97,10 @@ odoo.define('payment_stripe.stripe', function(require) { if (so_id) { so_id = parseInt(so_id[1]); } - + var invoice_id = $("input[name='return_url']").val().match(/invoices\/([0-9]+)/) || undefined; + if (invoice_id) { + invoice_id = parseInt(invoice_id[1]); + } var currency = $("input[name='currency']").val(); var currency_id = $("input[name='currency_id']").val(); @@ -127,6 +130,13 @@ odoo.define('payment_stripe.stripe', function(require) { }).then(function (data) { try { provider_form.innerHTML = data; } catch (e) {}; }); + } else if (window.location.href.includes("/my/invoices/")) { + var create_tx = ajax.jsonRpc('/invoice/pay/' + invoice_id + '/form_tx/', 'call', { + access_token: access_token, + acquirer_id: acquirer_id + }).then(function (data) { + try { provider_form.innerHTML = data; } catch (e) {}; + }); } else { var create_tx = ajax.jsonRpc('/shop/payment/transaction/' + acquirer_id, 'call', { From 1b1978eec1e80e6f20eceb42ee06a3df26e94c3c Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Wed, 31 Jan 2018 15:37:13 +0100 Subject: [PATCH 06/27] [FIX] account: default taxes Use `ir.values` for default taxes. Stop using `ir.config_parameter`. The logic is made in order to be as error-proof as possible. Backport of a9ede7fdfa0cec06d8bdc31b26e7549959c256d4 opw-807226 --- addons/account/models/res_config.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/addons/account/models/res_config.py b/addons/account/models/res_config.py index e6b705c86cd..ef3168c555f 100644 --- a/addons/account/models/res_config.py +++ b/addons/account/models/res_config.py @@ -61,14 +61,23 @@ class AccountConfigSettings(models.TransientModel): @api.model def get_default_tax_fields(self, fields): - default_purchase_tax_id = self.env['ir.config_parameter'].sudo().get_param('account.default_purchase_tax_id', default=False) - default_sale_tax_id = self.env['ir.config_parameter'].sudo().get_param('account.default_sale_tax_id', default=False) - return dict(default_purchase_tax_id=int(default_purchase_tax_id), default_sale_tax_id=int(default_sale_tax_id)) + # DO NOT FORWARDPORT, ONLY FOR SAAS-15 + default_purchase_tax_id = ( + self.env['ir.values'].sudo().get_default('product.template', 'supplier_taxes_id', company_id=self.env.user.company_id.id) or + self.env['ir.config_parameter'].sudo().get_param('account.default_purchase_tax_id', default=False) + ) + default_sale_tax_id = ( + self.env['ir.values'].sudo().get_default('product.template', 'taxes_id', company_id=self.env.user.company_id.id) or + self.env['ir.config_parameter'].sudo().get_param('account.default_sale_tax_id', default=False) + ) + return { + 'default_purchase_tax_id': int(default_purchase_tax_id[0]) if isinstance(default_purchase_tax_id, list) and default_purchase_tax_id else default_purchase_tax_id, + 'default_sale_tax_id': int(default_sale_tax_id[0]) if isinstance(default_sale_tax_id, list) and default_sale_tax_id else default_sale_tax_id, + } @api.multi def set_default_tax_fields(self): - self.env['ir.config_parameter'].sudo().set_param("account.default_purchase_tax_id", self.default_purchase_tax_id.id) - self.env['ir.config_parameter'].sudo().set_param("account.default_sale_tax_id", self.default_sale_tax_id.id) + pass @api.depends('company_id') def _compute_has_chart_of_accounts(self): From 56a25e5f0c2fa83cc622e0ed010ea24a62fbc8d9 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Fri, 2 Feb 2018 10:06:55 +0100 Subject: [PATCH 07/27] [FIX] base_import: translate column name The labels of the imported columns were untranslated, displaying the name of the field in English opw-813996 Fixes #22703 Closes #22717 --- addons/base_import/static/src/js/import_action.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/addons/base_import/static/src/js/import_action.js b/addons/base_import/static/src/js/import_action.js index 9c6d5563400..1872dec6205 100644 --- a/addons/base_import/static/src/js/import_action.js +++ b/addons/base_import/static/src/js/import_action.js @@ -137,6 +137,7 @@ var DataImport = Widget.extend(ControlPanelMixin, { model: 'base_import.import', method: 'create', args: [{res_model: this.res_model}], + kwargs: {context: session.user_context}, }); }, renderButtons: function() { @@ -280,6 +281,7 @@ var DataImport = Widget.extend(ControlPanelMixin, { model: 'base_import.import', method: 'parse_preview', args: [this.id, this.import_options()], + kwargs: {context: session.user_context}, }).done(function (result) { var signal = result.error ? 'preview_failed' : 'preview_succeeded'; self[signal](result); From 76665df0cfc765483c8d2856ad9579e9d7b6b58d Mon Sep 17 00:00:00 2001 From: qsm-odoo Date: Wed, 31 Jan 2018 13:11:18 +0100 Subject: [PATCH 08/27] [FIX] website_forum: allow portal users to post replies to replies Before this commit, when connected as a portal user, the user was not able to post replies to existing replies. This is because the textarea section was marked to be displayed for connected internal users only. This commit removes the whole group restriction. Indeed, it makes sense (as a fix), to show the textarea section for public users too. Indeed, the "Reply" button is already shown to public users but does not do anything. With this commit, clicking the "Reply" button shows the textarea section for everybody and, if the user is not connected, redirects to the login page when posting the message. This of course needs usability improvements in master. Note: the problem had originally been fixed for regular answers with commit https://github.com/odoo/odoo/commit/b81b03c82d282dc94595a9beb94444041509ef25 Note 2: both mentioned problems were originally introduced by commit https://github.com/odoo/odoo/commit/9069d0127c176317436b67b23ae5677dd9d53de7 Closes https://github.com/odoo/odoo/issues/22648 --- addons/website_forum/views/website_forum.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website_forum/views/website_forum.xml b/addons/website_forum/views/website_forum.xml index d6bef90930a..e06f78e4108 100644 --- a/addons/website_forum/views/website_forum.xml +++ b/addons/website_forum/views/website_forum.xml @@ -667,7 +667,7 @@