From 60d6c5402b3ecb705756a566b3e712b7bd8c0dcc Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Wed, 24 Apr 2019 08:51:34 +0000 Subject: [PATCH 01/51] [FIX] web: change bootstrap fonts only for reports Commit 42530b02fe14 was fixing a bug in reports that were using the standard bootstrap fonts instead of the changes we made in $font-family-sans-serif To solve this, 42530b02fe14 replicated the change in the file web_editor/static/src/scss/bootstrap_overridden.scss which is imported in report_assets_common **before** web._assets_bootstrap This was solving the issue for the report but had also the side-effect of changing body font-family in enterprise as the bootstrap_overridden.scss file is also used in web_editor._assets_backend_helpers and web_editor._assets_frontend_helpers 42530b02fe14 had effect only on enterprise where the desired font is Roboto/Noto Create a new bootstrap_overridden (6th of the name) file only for report closes odoo/odoo#32902 Signed-off-by: Martin Trigaux (mat) --- addons/web/static/src/scss/bootstrap_overridden_report.scss | 2 ++ addons/web/views/report_templates.xml | 1 + addons/web_editor/static/src/scss/bootstrap_overridden.scss | 2 -- 3 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 addons/web/static/src/scss/bootstrap_overridden_report.scss diff --git a/addons/web/static/src/scss/bootstrap_overridden_report.scss b/addons/web/static/src/scss/bootstrap_overridden_report.scss new file mode 100644 index 00000000000..a6e1cd23b32 --- /dev/null +++ b/addons/web/static/src/scss/bootstrap_overridden_report.scss @@ -0,0 +1,2 @@ +// remove Noto Color Emoji +$font-family-sans-serif: "Noto", "Lucida Grande", Helvetica, Verdana, Arial, sans-serif; diff --git a/addons/web/views/report_templates.xml b/addons/web/views/report_templates.xml index 15ed2ada200..330b97e389e 100644 --- a/addons/web/views/report_templates.xml +++ b/addons/web/views/report_templates.xml @@ -6,6 +6,7 @@ + diff --git a/addons/web_editor/static/src/scss/bootstrap_overridden.scss b/addons/web_editor/static/src/scss/bootstrap_overridden.scss index 849a891392b..5c64d275d56 100644 --- a/addons/web_editor/static/src/scss/bootstrap_overridden.scss +++ b/addons/web_editor/static/src/scss/bootstrap_overridden.scss @@ -83,5 +83,3 @@ $gray-700: gray('700') !default; $gray-800: gray('800') !default; $gray-900: gray('900') !default; $black: gray('black') !default; - -$font-family-sans-serif: "Noto", "Lucida Grande", Helvetica, Verdana, Arial, sans-serif; From 222ef11adbc048e9540e32b3276846f681258a3d Mon Sep 17 00:00:00 2001 From: Abdur-Rahmaan Janhangeer Date: Wed, 1 May 2019 08:43:13 +0000 Subject: [PATCH 02/51] [ADD] base: add address format for Mauritius Mauritius now uses zipcodes Source: http://www.mauritiuspost.mu/products-and-services/post-code-finder closes odoo/odoo#33074 Signed-off-by: Martin Trigaux (mat) --- odoo/addons/base/data/res_country_data.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/odoo/addons/base/data/res_country_data.xml b/odoo/addons/base/data/res_country_data.xml index 872b14c0775..c5abb5d0e08 100644 --- a/odoo/addons/base/data/res_country_data.xml +++ b/odoo/addons/base/data/res_country_data.xml @@ -1105,6 +1105,7 @@ mu + From 050ad8e189f197ed18670ac73efe0413dd0df751 Mon Sep 17 00:00:00 2001 From: Nans Lefebvre Date: Thu, 2 May 2019 12:39:02 +0000 Subject: [PATCH 03/51] [FIX] mail: clean context when running email action The action_subtask method adds 'default_parent_id' to the context. If the creation or edition of a subtasks triggers an email creation, (e.g. if there is an automated action 'send email') the default 'default_parent_id' is still in the context. Therefore, it tries to create the email with an arbitrary foreign key (since it is an existing record on the project.task model), or crashes. Similar to 816f3861. opw 1978498 closes odoo/odoo#33111 Signed-off-by: Nans Lefebvre (len) --- addons/mail/models/ir_actions.py | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/mail/models/ir_actions.py b/addons/mail/models/ir_actions.py index 40582b1d803..203304c7fb7 100644 --- a/addons/mail/models/ir_actions.py +++ b/addons/mail/models/ir_actions.py @@ -112,6 +112,7 @@ class ServerActions(models.Model): # with wrong values in subsequent operations cleaned_ctx = dict(self.env.context) cleaned_ctx.pop('default_type', None) + cleaned_ctx.pop('default_parent_id', None) action.template_id.with_context(cleaned_ctx).send_mail(self._context.get('active_id'), force_send=False, raise_exception=False) return False From a80f1ddcda416c76760acd920a7114382749a71e Mon Sep 17 00:00:00 2001 From: Jeremy Kersten Date: Thu, 2 May 2019 14:57:02 +0000 Subject: [PATCH 04/51] [FIX] doc: git guidelines, don't use # for task/opw MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use task-#xxx is wrong since it will refer to an unexising or wrong hash of github. closes odoo/odoo#33121 Signed-off-by: Jérémy Kersten (jke) --- doc/reference/guidelines.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/reference/guidelines.rst b/doc/reference/guidelines.rst index df8f0b5d4c2..d71f62971cd 100644 --- a/doc/reference/guidelines.rst +++ b/doc/reference/guidelines.rst @@ -1102,10 +1102,10 @@ description. Try to follow the preferred structure for your commit messages End the message with references, such as task or bug numbers, PR numbers, and OPW tickets, following the suggested format: - Related to task #taskId - Fixes #12345 (link and close issue on Github) - Closes #7865 (link and close PR on Github) - OPW-112233 + task-123 (related to task) + Fixes #123 (close related issue on Github) + Closes #123 (close related PR on Github) + opw-123 (related to ticket) Tag and module name ------------------- From 97b44806f5121e97b62ba25da910e77e26a9424d Mon Sep 17 00:00:00 2001 From: Jorge Pinna Puissant Date: Thu, 2 May 2019 11:42:52 +0000 Subject: [PATCH 05/51] [FIX] mrp: recursive bom with different quantities Having 4 products and 3 BoMs: BoM 1: product = Finished quantity = 100 units - Semi-Finished 10 units BoM 2: product = Semi-Finished quantity = 10 units - Assembly 10 units BoM 3: product = Assembly quantity = 10 units - Raw Material 10 units (product.product 5$/unit) Before this commit, the price for 100 units of Finished product was 500$, which is wrong. The price was calculated using 100 units of Semi-Finished product and not 10 units as it should be. Now, the price is 50$ opw-1973347 closes odoo/odoo#33115 Signed-off-by: Jorge Pinna Puissant (jpp) --- addons/mrp/report/mrp_report_bom_structure.py | 2 +- addons/mrp/tests/test_bom.py | 86 +++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/addons/mrp/report/mrp_report_bom_structure.py b/addons/mrp/report/mrp_report_bom_structure.py index 544c4aaa009..529b12e72a4 100644 --- a/addons/mrp/report/mrp_report_bom_structure.py +++ b/addons/mrp/report/mrp_report_bom_structure.py @@ -197,7 +197,7 @@ class ReportBomStructure(models.AbstractModel): if line._skip_bom_line(product): continue if line.child_bom_id: - qty = line.product_uom_id._compute_quantity(line.product_qty * factor, line.child_bom_id.product_uom_id) + qty = line.product_uom_id._compute_quantity(line.product_qty * factor, line.child_bom_id.product_uom_id) / line.child_bom_id.product_qty sub_price = self._get_price(line.child_bom_id, qty, line.product_id) price += sub_price else: diff --git a/addons/mrp/tests/test_bom.py b/addons/mrp/tests/test_bom.py index 90b1b6ff50f..c3e789cd4cc 100644 --- a/addons/mrp/tests/test_bom.py +++ b/addons/mrp/tests/test_bom.py @@ -628,3 +628,89 @@ class TestBoM(TestMrpCommon): report_values = self.env['report.mrp.report_bom_structure']._get_report_data(bom_id=bom_car.id, searchQty=1, searchVariant=red_car_without_gps.id) # Same math than before but without GPS self.assertEqual(report_values['lines']['total'], 210) + + def test_bom_report_recursive_bom(self): + """ Test report with recursive BoM and different quantities. + BoM 1: + product = Finished (units) + quantity = 100 units + - Semi-Finished 5 kg + + BoM 2: + product = Semi-Finished (kg) + quantity = 11 kg + - Assembly 2 dozens + + BoM 3: + product = Assembly (dozens) + quantity = 5 dozens + - Raw Material 4 litres (product.product 5$/litre) + + Check the Price for 80 units of Finished -> 2.92$: + """ + # Create a products templates + uom_unit = self.env.ref('uom.product_uom_unit') + uom_kg = self.env.ref('uom.product_uom_kgm') + uom_dozen = self.env.ref('uom.product_uom_dozen') + uom_litre = self.env.ref('uom.product_uom_litre') + + finished = self.env['product.product'].create({ + 'name': 'Finished', + 'type': 'product', + 'uom_id': uom_unit.id, + 'uom_po_id': uom_unit.id, + }) + + semi_finished = self.env['product.product'].create({ + 'name': 'Semi-Finished', + 'type': 'product', + 'uom_id': uom_kg.id, + 'uom_po_id': uom_kg.id, + }) + + assembly = self.env['product.product'].create({ + 'name': 'Assembly', + 'type': 'product', + 'uom_id': uom_dozen.id, + 'uom_po_id': uom_dozen.id, + }) + + raw_material = self.env['product.product'].create({ + 'name': 'Raw Material', + 'type': 'product', + 'uom_id': uom_litre.id, + 'uom_po_id': uom_litre.id, + 'standard_price': 5, + }) + + #Create bom + bom_finished = Form(self.env['mrp.bom']) + bom_finished.product_tmpl_id = finished.product_tmpl_id + bom_finished.product_qty = 100 + with bom_finished.bom_line_ids.new() as line: + line.product_id = semi_finished + line.product_uom_id = uom_kg + line.product_qty = 5 + bom_finished = bom_finished.save() + + bom_semi_finished = Form(self.env['mrp.bom']) + bom_semi_finished.product_tmpl_id = semi_finished.product_tmpl_id + bom_semi_finished.product_qty = 11 + with bom_semi_finished.bom_line_ids.new() as line: + line.product_id = assembly + line.product_uom_id = uom_dozen + line.product_qty = 2 + bom_semi_finished = bom_semi_finished.save() + + bom_assembly = Form(self.env['mrp.bom']) + bom_assembly.product_tmpl_id = assembly.product_tmpl_id + bom_assembly.product_qty = 5 + with bom_assembly.bom_line_ids.new() as line: + line.product_id = raw_material + line.product_uom_id = uom_litre + line.product_qty = 4 + bom_assembly = bom_assembly.save() + + report_values = self.env['report.mrp.report_bom_structure']._get_report_data(bom_id=bom_finished.id, searchQty=80) + + self.assertAlmostEqual(report_values['lines']['total'], 2.92) From 8df4bbf1ed759db18e55b63cd06c500971221a21 Mon Sep 17 00:00:00 2001 From: Meghna Jaswani Date: Wed, 24 Apr 2019 12:51:48 +0000 Subject: [PATCH 06/51] [FIX] website{,_sale_link_tracker}: ecommerce graph today The UTM graph data in Website > Dasboard > Analytics is not getting properly filtered on the basis of values of date_from and date_to on website_sale dashboard. The field confirmation date which is of type datetime while date_from and date_to are of date string in local browser timezone. Hence date_domain is not perfect as shown below on local date 29th april 2019, we would send: ('confirmation_date', '>=', '2019-04-22'), ('confirmation_date', '<=', '2019-04-29') But in reality we could want a from midnight of week before the current UTC day, and to current UTC now or 23:59:59 of current UTC day. This way, the data sent back matches more what is expected, instead of the preceding domain, we would then have the following: - if UTC now corresponding to local now is on '2019-04-29' ('confirmation_date', '>=', '2019-04-22 00:00:00'), ('confirmation_date', '<=', '2019-04-29 23:59:59') - if UTC now corresponding to local now is on '2019-04-28': ('confirmation_date', '>=', '2019-04-21 00:00:00'), ('confirmation_date', '<=', '2019-04-28 23:59:59') - if UTC now corresponding to local now is on '2019-04-30': ('confirmation_date', '>=', '2019-04-23 00:00:00'), ('confirmation_date', '<=', '2019-04-30 23:59:59') And each one will be displayed as days 22 up to 29 in line chart (with local today 29 being the last day of the chart and contening orders of the current UTC day). With these change in the UTM pie chart: - a local date that is before a UTC date => we see the sales from up to today UTC instead of from up to before yesterday UTC - a local date that is the same as an UTC date => we see the sale from up to today UTC instead of yesterday UTC And in the line chart (that already had half of the fix in f6fc7c23192): - a local date that is before a UTC date => we see the sales from up to today UTC instead of from up to yesterday UTC - a local date that is after a UTC date => we see the sales of current UTC day + range of days (eg. for a week 7) instead of current UTC day + range of days minus 1 (eg. for a week 6). opw-1971539 closes #33041 Signed-off-by: Nicolas Lempereur (nle) Co-authored-by: Nicolas Lempereur --- addons/website/static/src/js/backend/dashboard.js | 10 +++++----- .../website_sale_link_tracker/controllers/backend.py | 7 ++++++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/addons/website/static/src/js/backend/dashboard.js b/addons/website/static/src/js/backend/dashboard.js index f88dc249296..9dca1251f59 100644 --- a/addons/website/static/src/js/backend/dashboard.js +++ b/addons/website/static/src/js/backend/dashboard.js @@ -33,8 +33,8 @@ var Dashboard = AbstractAction.extend(ControlPanelMixin, { this._super(parent, context); this.date_range = 'week'; // possible values : 'week', 'month', year' - this.date_from = moment().subtract(1, 'week'); - this.date_to = moment(); + this.date_from = moment.utc().subtract(1, 'week'); + this.date_to = moment.utc(); this.dashboards_templates = ['website.dashboard_header', 'website.dashboard_content']; this.graphs = []; @@ -230,13 +230,13 @@ var Dashboard = AbstractAction.extend(ControlPanelMixin, { on_date_range_button: function(date_range) { if (date_range === 'week') { this.date_range = 'week'; - this.date_from = moment().subtract(1, 'weeks'); + this.date_from = moment.utc().subtract(1, 'weeks'); } else if (date_range === 'month') { this.date_range = 'month'; - this.date_from = moment().subtract(1, 'months'); + this.date_from = moment.utc().subtract(1, 'months'); } else if (date_range === 'year') { this.date_range = 'year'; - this.date_from = moment().subtract(1, 'years'); + this.date_from = moment.utc().subtract(1, 'years'); } else { console.log('Unknown date range. Choose between [week, month, year]'); return; diff --git a/addons/website_sale_link_tracker/controllers/backend.py b/addons/website_sale_link_tracker/controllers/backend.py index f301d1c4a2b..e1cfd6c6fa3 100644 --- a/addons/website_sale_link_tracker/controllers/backend.py +++ b/addons/website_sale_link_tracker/controllers/backend.py @@ -1,8 +1,11 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from datetime import datetime, time + from odoo import http from odoo.addons.website_sale.controllers.backend import WebsiteSaleBackend +from odoo.fields import Date from odoo.http import request @@ -10,8 +13,10 @@ class WebsiteSaleLinkTrackerBackend(WebsiteSaleBackend): @http.route() def fetch_dashboard_data(self, website_id, date_from, date_to): + datetime_from = datetime.combine(Date.from_string(date_from), time.min) + datetime_to = datetime.combine(Date.from_string(date_to), time.max) results = super(WebsiteSaleLinkTrackerBackend, self).fetch_dashboard_data(website_id, date_from, date_to) - results['dashboards']['sales']['utm_graph'] = self.fetch_utm_data(date_from, date_to) + results['dashboards']['sales']['utm_graph'] = self.fetch_utm_data(datetime_from, datetime_to) return results def fetch_utm_data(self, date_from, date_to): From ecae2fc9ca319774afc75ecbae5899eb617a971b Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Fri, 3 May 2019 11:48:01 +0000 Subject: [PATCH 07/51] [FIX] sale_stock: scope of warning The check on the ordered quantity should not apply to services. opw-1981332 closes odoo/odoo#33138 Signed-off-by: Nicolas Martinelli (nim) --- addons/sale_stock/models/sale_order.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/sale_stock/models/sale_order.py b/addons/sale_stock/models/sale_order.py index 41cd9b7ccc6..51c1d66a606 100644 --- a/addons/sale_stock/models/sale_order.py +++ b/addons/sale_stock/models/sale_order.py @@ -446,7 +446,8 @@ class SaleOrderLine(models.Model): def _update_line_quantity(self, values): precision = self.env['decimal.precision'].precision_get('Product Unit of Measure') - if self.mapped('qty_delivered') and float_compare(values['product_uom_qty'], max(self.mapped('qty_delivered')), precision_digits=precision) == -1: + line_products = self.filtered(lambda l: l.product_id.type in ['product', 'consu']) + if line_products.mapped('qty_delivered') and float_compare(values['product_uom_qty'], max(line_products.mapped('qty_delivered')), precision_digits=precision) == -1: raise UserError(_('You cannot decrease the ordered quantity below the delivered quantity.\n' 'Create a return first.')) super(SaleOrderLine, self)._update_line_quantity(values) From 94e35a19b3f7973c5ac3e2b0e6aca2facbb6eb07 Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Tue, 16 Apr 2019 11:53:47 +0000 Subject: [PATCH 08/51] [FIX] web: Trim spaces when selecting option by text It's quite common that the `$().text()` method returns lots of random whitespaces at the beginning and end of the string. They're pretty unpredictable (extension views can add or remove them) and invisible to the end user. This code chunk should allow to select an `