From 0f878e4839c36cd73fe8096ec1364f71af6bd8be Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Wed, 7 Aug 2019 07:28:57 +0000 Subject: [PATCH 01/10] [FIX] tools: epsilon magnitude MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The following rounding is incorrect: ``` >>> float_round(6.6 * 0.175, precision_digits=2) 1.15 ``` Indeed, 6.6 * 0.175 = 1.155 ≈ 1.16. In this specific case, the `epsilon` computed is not sufficient. A precision of 53 gives: normalized_value = 115.49999999999997 epsilon = 1.2823075934420547e-14 => new normalized_value = 115.49999999999999 Bad luck, this is just not enough to tip the value in the right direction. However, a precision of 52 is sufficient: normalized_value = 115.49999999999997 epsilon = 2.5646151868841094e-14 => new normalized_value = 115.5 The value of 53 was chosen from the `binary64` number format precision. In case of Python, the corresponding machine epsilon is 2^-52 [1]. Therefore, using 52 instead of 53 does make sense. It is worth noting that the value of the machine epsilon 2^-52 = 2.2204460492503131e-16, which is still 2 orders of magnitude below our dynamic estimation. [1] https://en.wikipedia.org/wiki/Machine_epsilon [2] `numpy.finfo(float).eps = 2.2204460492503131e-16` opw-2047368 closes odoo/odoo#35565 Signed-off-by: Nicolas Martinelli (nim) --- addons/web/static/src/js/core/utils.js | 2 +- odoo/addons/base/tests/test_float.py | 2 ++ odoo/tools/float_utils.py | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/addons/web/static/src/js/core/utils.js b/addons/web/static/src/js/core/utils.js index 99240870c18..1857c9f3be5 100644 --- a/addons/web/static/src/js/core/utils.js +++ b/addons/web/static/src/js/core/utils.js @@ -324,7 +324,7 @@ var utils = { } var normalized_value = value / precision; var epsilon_magnitude = Math.log(Math.abs(normalized_value))/Math.log(2); - var epsilon = Math.pow(2, epsilon_magnitude - 53); + var epsilon = Math.pow(2, epsilon_magnitude - 52); normalized_value += normalized_value >= 0 ? epsilon : -epsilon; /** diff --git a/odoo/addons/base/tests/test_float.py b/odoo/addons/base/tests/test_float.py index c55ba2588f3..8263de76a70 100644 --- a/odoo/addons/base/tests/test_float.py +++ b/odoo/addons/base/tests/test_float.py @@ -27,6 +27,8 @@ class TestFloatPrecision(TransactionCase): try_round(0.0049,'0.00') # 0.0049 is closer to 0 than to 0.01, so should round down try_round(0.005,'0.01') # the rule is to round half away from zero try_round(-0.005,'-0.01') # the rule is to round half away from zero + try_round(6.6 * 0.175, '1.16') # 6.6 * 0.175 is rounded to 1.15 with epsilon = 53 + try_round(-6.6 * 0.175, '-1.16') def try_zero(amount, expected): self.assertEqual(currency.is_zero(amount), expected, diff --git a/odoo/tools/float_utils.py b/odoo/tools/float_utils.py index 3e13f9ee0bc..3b6e78a8f3b 100644 --- a/odoo/tools/float_utils.py +++ b/odoo/tools/float_utils.py @@ -73,7 +73,7 @@ def float_round(value, precision_digits=None, precision_rounding=None, rounding_ normalized_value = value / rounding_factor # normalize sign = math.copysign(1.0, normalized_value) epsilon_magnitude = math.log(abs(normalized_value), 2) - epsilon = 2**(epsilon_magnitude-53) + epsilon = 2**(epsilon_magnitude-52) # TIE-BREAKING: UP/DOWN (for ceiling[resp. flooring] operations) # When rounding the value up[resp. down], we instead subtract[resp. add] the epsilon value From 5e3d49bc474271dfb7807fe4c21bbfb737e7c853 Mon Sep 17 00:00:00 2001 From: "Lucas Perais (lpe)" Date: Tue, 20 Aug 2019 08:12:32 +0000 Subject: [PATCH 02/10] [FIX] im_livechat: livechat rating computes well Open a livechat session between a visitor and a user That is, open the / controller as public user, and click, on the bottom right corner, on "Have a question ? Chat with us." Exchange at least one message to open the session From the visitor side, close the window. There is a proposal to rate the discussion Assign either the green face or the yellow one (The red one is a bit trickier) Now, on the user side, check the list view of LiveChat sessions Before this commit, the rating of those sessions were 0 This is because: The rating.rating < Many2One > mail.channel link is not a foreign key (rather, it is composed by char::res_model; Integer::res_id) and doesn't make the reciprocal field recompute, which in turn doesn't make our relevant field compute After this commit, the last_rating field field is recomputed and appear in the list view OPW 2052964 closes odoo/odoo#35830 Signed-off-by: Lucas Perais (lpe) --- addons/im_livechat/controllers/main.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/addons/im_livechat/controllers/main.py b/addons/im_livechat/controllers/main.py index 14df16fb6c3..4e6b9e77b23 100644 --- a/addons/im_livechat/controllers/main.py +++ b/addons/im_livechat/controllers/main.py @@ -80,7 +80,6 @@ class LivechatController(http.Controller): @http.route('/im_livechat/feedback', type='json', auth='public') def feedback(self, uuid, rate, reason=None, **kwargs): Channel = request.env['mail.channel'] - Rating = request.env['rating.rating'] channel = Channel.sudo().search([('uuid', '=', uuid)], limit=1) if channel: # limit the creation : only ONE rating per session @@ -101,7 +100,11 @@ class LivechatController(http.Controller): # if logged in user, set its partner on rating values['partner_id'] = request.env.user.partner_id.id if request.session.uid else False # create the rating - rating = Rating.sudo().create(values) + + channel.write({ + 'rating_ids': [(0, False, values)] + }) + rating = channel.rating_ids[0] else: rating = channel.rating_ids[0] rating.write(values) From 7cbc088d8408d647ec6111fc052a73f16365e991 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Thu, 28 Mar 2019 10:10:43 +0000 Subject: [PATCH 03/10] [FIX] purchase: return dropship Backport of 4da82776ffb. Because of e38ed7c7 the code moved between versions, but is otherwise identical. - Set an internal location as a return location - Create a SO with a dropship product, validate and deliver - Return the product, and choose the internal location as the return location. The received quantity on the PO is counted twice. Since the return is an 'in' move linked to a PO, it is automatically counted as incoming quantity. This case is quite specific, so we explicitly add an exception in case the origin move was a dropship, but the return is not a returned dropship. opw-1958228 opw 2045685 closes odoo/odoo#35831 Signed-off-by: Nans Lefebvre (len) --- addons/purchase/models/purchase.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/addons/purchase/models/purchase.py b/addons/purchase/models/purchase.py index 423b794771c..83b1bb30a7b 100644 --- a/addons/purchase/models/purchase.py +++ b/addons/purchase/models/purchase.py @@ -592,6 +592,12 @@ class PurchaseOrderLine(models.Model): if move.location_dest_id.usage == "supplier": if move.to_refund: total -= move.product_uom._compute_quantity(move.product_uom_qty, line.product_uom) + elif move.origin_returned_move_id._is_dropshipped() and not move._is_dropshipped_returned(): + # Edge case: the dropship is returned to the stock, no to the supplier. + # In this case, the received quantity on the PO is set although we didn't + # receive the product physically in our stock. To avoid counting the + # quantity twice, we do nothing. + pass else: total += move.product_uom._compute_quantity(move.product_uom_qty, line.product_uom) line.qty_received = total From e34de5c565327d56d5202c02a1e0b9c98ff55318 Mon Sep 17 00:00:00 2001 From: Nans Lefebvre Date: Mon, 19 Aug 2019 14:05:42 +0000 Subject: [PATCH 04/10] [FIX] mail: preview of almost empty mail templates The lxml.html.fromstring method does not accept an encoding parameter, so the preview crash if the going through this branch, i.e. if the root is an empty tag. opw 2054368 closes odoo/odoo#35817 Signed-off-by: Nans Lefebvre (len) --- addons/mail/models/mail_template.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/mail/models/mail_template.py b/addons/mail/models/mail_template.py index 4aaada0ba56..9b35323f096 100644 --- a/addons/mail/models/mail_template.py +++ b/addons/mail/models/mail_template.py @@ -292,8 +292,8 @@ class MailTemplate(models.Model): # form a tree root = lxml.html.fromstring(html) if not len(root) and root.text is None and root.tail is None: - html = u'
%s
' % html - root = lxml.html.fromstring(html, encoding='unicode') + html = u'
%s
' % tools.ustr(html) + root = lxml.html.fromstring(html) base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') base = urls.url_parse(base_url) From 3bc4d91e9b87286a2c0a43b775e80afbbb7c8122 Mon Sep 17 00:00:00 2001 From: "Andrea Grazioso (agr-odoo)" Date: Tue, 20 Aug 2019 09:53:29 +0000 Subject: [PATCH 05/10] [FIX] website_sale_comparison: translate product attribute categories Install the module "Product Comparison". Go to Website>Configuration>Attribute Categories, then create or edit a category. No translate button is present when editing the field, there should be one on the right edge to enter the translation menu. Adding the missing option in the model. opw-2052331 closes odoo/odoo#35838 Signed-off-by: Nicolas Martinelli (nim) --- .../i18n/website_sale_comparison.pot | 53 ++++++++++++++++++- .../models/website_sale_comparison.py | 2 +- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/addons/website_sale_comparison/i18n/website_sale_comparison.pot b/addons/website_sale_comparison/i18n/website_sale_comparison.pot index f4716c9b308..342673a74ad 100644 --- a/addons/website_sale_comparison/i18n/website_sale_comparison.pot +++ b/addons/website_sale_comparison/i18n/website_sale_comparison.pot @@ -111,6 +111,11 @@ msgstr "" msgid "Audio Formats Supported" msgstr "" +#. module: website_sale_comparison +#: model:product.attribute.category,name:website_sale_comparison.product_attribute_category_5 +msgid "Battery" +msgstr "" + #. module: website_sale_comparison #: model:product.attribute,name:website_sale_comparison.product_attribute_14 msgid "Battery Type" @@ -127,7 +132,12 @@ msgid "Brand" msgstr "" #. module: website_sale_comparison -#: model:ir.model.fields,field_description:website_sale_comparison.field_product_attribute_category_id_11272 +#: model:product.attribute.category,name:website_sale_comparison.product_attribute_category_1 +msgid "Camera" +msgstr "" + +#. module: website_sale_comparison +#: model:ir.model.fields,field_description:website_sale_comparison.field_product_attribute_category_id_4633 msgid "Category" msgstr "" @@ -166,9 +176,15 @@ msgstr "" #. module: website_sale_comparison #: model:product.attribute,name:website_sale_comparison.product_attribute_8 +#: model:product.attribute.category,name:website_sale_comparison.product_attribute_category_2 msgid "Dimensions" msgstr "" +#. module: website_sale_comparison +#: model:product.attribute.category,name:website_sale_comparison.product_attribute_category_3 +msgid "Display" +msgstr "" + #. module: website_sale_comparison #: model:ir.model.fields,field_description:website_sale_comparison.field_product_attribute_category_display_name msgid "Display Name" @@ -184,11 +200,21 @@ msgstr "" msgid "Dual Core A5" msgstr "" +#. module: website_sale_comparison +#: model:product.attribute.category,name:website_sale_comparison.product_attribute_category_general_features +msgid "General Features" +msgstr "" + #. module: website_sale_comparison #: model:ir.model.fields,field_description:website_sale_comparison.field_product_attribute_category_id msgid "ID" msgstr "" +#. module: website_sale_comparison +#: model:product.attribute.category,name:website_sale_comparison.product_attribute_category_8 +msgid "Internet And Connectivity" +msgstr "" + #. module: website_sale_comparison #: model:product.attribute.value,name:website_sale_comparison.product_attribute_value_12 msgid "LED Backlit Multi-touch Display with IPS Technology, Fingerprint-resistant Oleophobic Coating" @@ -214,6 +240,16 @@ msgstr "" msgid "Lithium - Polymer" msgstr "" +#. module: website_sale_comparison +#: model:product.attribute.category,name:website_sale_comparison.product_attribute_category_6 +msgid "Memory And Storage" +msgstr "" + +#. module: website_sale_comparison +#: model:product.attribute.category,name:website_sale_comparison.product_attribute_category_9 +msgid "Multimedia" +msgstr "" + #. module: website_sale_comparison #: model:product.attribute.value,name:website_sale_comparison.product_attribute_value_9 msgid "No" @@ -229,6 +265,16 @@ msgstr "" msgid "Other Display Features" msgstr "" +#. module: website_sale_comparison +#: model:product.attribute.category,name:website_sale_comparison.product_attribute_category_10 +msgid "Other Features" +msgstr "" + +#. module: website_sale_comparison +#: model:product.attribute.category,name:website_sale_comparison.product_attribute_category_4 +msgid "Platform" +msgstr "" + #. module: website_sale_comparison #: model:product.attribute,name:website_sale_comparison.product_attribute_15 msgid "Play Time" @@ -307,6 +353,11 @@ msgstr "" msgid "Video Formats Supported" msgstr "" +#. module: website_sale_comparison +#: model:product.attribute.category,name:website_sale_comparison.product_attribute_category_11 +msgid "Warranty" +msgstr "" + #. module: website_sale_comparison #: model:product.attribute,name:website_sale_comparison.product_attribute_13 msgid "Warranty Summary" diff --git a/addons/website_sale_comparison/models/website_sale_comparison.py b/addons/website_sale_comparison/models/website_sale_comparison.py index 88be2499c0a..a03da2638f0 100644 --- a/addons/website_sale_comparison/models/website_sale_comparison.py +++ b/addons/website_sale_comparison/models/website_sale_comparison.py @@ -9,7 +9,7 @@ class ProductAttributeCategory(models.Model): _description = "Product Attribute Category" _order = 'sequence' - name = fields.Char("Category Name", required=True) + name = fields.Char("Category Name", required=True, translate=True) sequence = fields.Integer("Sequence", default=10) From 9e579173762f281487a8ae988511355ce8b1a5cc Mon Sep 17 00:00:00 2001 From: Pieter Paulussen Date: Wed, 20 Jun 2018 15:37:09 +0000 Subject: [PATCH 06/10] [FIX] account: fix account_move_line's default_get() Backport of 50ee1c964b5994c5e08eaf7f9ef800e0437f1672. Previous version was buggy, as it was already patched by 54c2c0874 and 862c2455. When creating a journal entry manually, the computed value for the next line was not taking into consideration all existing lines. Was PR #25298. Courtesy of Pieter Paulussen (Dynapps) --- addons/account/models/account_move.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index b3471525b7d..da616cc63b7 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -486,12 +486,9 @@ class AccountMoveLine(models.Model): #compute the default credit/debit of the next line in case of a manual entry balance = 0 - for line in self._context['line_ids']: - if line[2]: # in case of command 0: add a record with values - balance += line[2].get('debit', 0) - line[2].get('credit', 0) - elif line[0] == 2: # line has been deleted - line_obj = self.browse(line[1]) - balance -= line_obj.debit - line_obj.credit + for line in self.move_id.resolve_2many_commands( + 'line_ids', self._context['line_ids'], fields=['credit', 'debit']): + balance += line.get('debit', 0) - line.get('credit', 0) if balance < 0: rec.update({'debit': -balance}) if balance > 0: From 67d82b875cddba7bf28c3f4eba295df31dce3d48 Mon Sep 17 00:00:00 2001 From: Nans Lefebvre Date: Mon, 19 Aug 2019 13:09:24 +0000 Subject: [PATCH 07/10] [FIX] account: round balance in the default_get of account move lines Edit journal entries (account.move). Create a new line. Credit and debit values are filled in with the default get. Conveniently, if lines_ids is given in context this computes the right value to balance existing move lines. However, this is done by float operations. Let e be the resulting epsilon in balance. As a result a new line may contain e, 0 for credit, debit (or respectively). If the user fills in the 0 value with v, then the new line contains e, v. This violates the constraint that exactly one of the two values should be nonzero. We get the currency from the journal to round adequately the balance. opw 2046137 closes odoo/odoo#35815 Signed-off-by: Nans Lefebvre (len) --- addons/account/models/account_move.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index da616cc63b7..522ea243542 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -489,6 +489,10 @@ class AccountMoveLine(models.Model): for line in self.move_id.resolve_2many_commands( 'line_ids', self._context['line_ids'], fields=['credit', 'debit']): balance += line.get('debit', 0) - line.get('credit', 0) + # if we are here, line_ids is in context, so journal_id should also be. + currency = self._context.get('journal_id') and self.browse(self._context['journal_id']).company_id.currency_id + if currency: + balance = currency.round(balance) if balance < 0: rec.update({'debit': -balance}) if balance > 0: From e6a1ac6e6462c973f55d12ef4b5543aad7790179 Mon Sep 17 00:00:00 2001 From: Richard Mathot Date: Tue, 20 Aug 2019 13:16:07 +0000 Subject: [PATCH 08/10] [FIX] models: avoid Unicode error when translating that error message Same cause, error, rationale and fix than 0ec0a4a32e98f2288e419dcb0627cfd972f32034 #OneCharacterPatch, reloaded opw-2056251 closes odoo/odoo#35857 Signed-off-by: Richard Mathot (rim) --- odoo/addons/base/ir/ir_model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/odoo/addons/base/ir/ir_model.py b/odoo/addons/base/ir/ir_model.py index 3a12f2d7c82..c75e028534c 100644 --- a/odoo/addons/base/ir/ir_model.py +++ b/odoo/addons/base/ir/ir_model.py @@ -958,7 +958,7 @@ class IrModelAccess(models.Model): else: msg_tail = _("Please contact your system administrator if you think this is an error.") + "\n\n(" + _("Document model") + ": %s)" msg_params = (model_name,) - msg_tail += ' - ({} {}, {} {})'.format(_('Operation:'), mode, _('User:'), self._uid) + msg_tail += u' - ({} {}, {} {})'.format(_('Operation:'), mode, _('User:'), self._uid) _logger.info('Access Denied by ACLs for operation: %s, uid: %s, model: %s', mode, self._uid, model_name) msg = '%s %s' % (msg_heads[mode], msg_tail) raise AccessError(msg % msg_params) From b058f7094191364083fbd50b18cafabf5fa82b4a Mon Sep 17 00:00:00 2001 From: Nicolas Lempereur Date: Tue, 20 Aug 2019 13:39:39 +0000 Subject: [PATCH 09/10] [FIX] web_editor: font>a colorize a change font color If you change the color of a link with the editor without using the link edition menu, this do not work (which might be expected), but if the text outside the font had been colorized, the font will be applied outside of the link only. This is unexpected since if we have: "hello cruel world!", if we select only "cruel" and change color, the change only happen to "hello" and "world!". With this changeset, an anchor in the ancestor prevent to use an ancestor font tag to change color (which prevent the issue). opw-2044551 closes #35862 Signed-off-by: Nicolas Lempereur (nle) --- addons/web_editor/static/src/js/summernote.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/addons/web_editor/static/src/js/summernote.js b/addons/web_editor/static/src/js/summernote.js index e52ea66614d..0f6c7cddd03 100644 --- a/addons/web_editor/static/src/js/summernote.js +++ b/addons/web_editor/static/src/js/summernote.js @@ -2121,13 +2121,15 @@ $.summernote.pluginEvents.applyFont = function (event, editor, layoutInfo, color } // apply font: foreColor, backColor, size (the color can be use a class text-... or bg-...) - var node, font, $font, fonts = [], className; + var node, ancestors, font, $font, fonts = [], className; if (color || bgcolor || size) { for (var i=0; i Date: Wed, 7 Aug 2019 04:59:08 +0000 Subject: [PATCH 10/10] [IMP] l10n_uk: updated website link -website link now redirects to accounting page of odoo.com portal task-2040072 Closes #35513 Signed-off-by: Nicolas Martinelli (nim) --- addons/l10n_uk/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/l10n_uk/__manifest__.py b/addons/l10n_uk/__manifest__.py index 6a5607878a5..3e8a31550dc 100644 --- a/addons/l10n_uk/__manifest__.py +++ b/addons/l10n_uk/__manifest__.py @@ -15,7 +15,7 @@ This is the latest UK Odoo localisation necessary to run Odoo accounting for UK - InfoLogic UK counties listing - a few other adaptations""", 'author': 'SmartMode LTD', - 'website': 'http://www.smartmode.co.uk', + 'website': 'https://www.odoo.com/page/accounting', 'depends': [ 'account', 'base_iban',