From fa5ee6ed2634b1a5b4388efb2c6ab6ae80356f28 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Sat, 11 Nov 2017 01:01:48 +0100 Subject: [PATCH 01/19] [FIX] ir_sequence: add support for PG 10 PostgreSQL 10 move sequences' metadata fields into a new `pg_sequence` system catalog. As a result, selecting from a sequence relation now only return three fields, and does not include the `increment_by` metadata field anymore. This patch obtains the `increment_by` value from the new system catalog for PostgreSQL server versions >= 10. Fixes #20269 --- openerp/addons/base/ir/ir_sequence.py | 40 +++++++++++++++------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/openerp/addons/base/ir/ir_sequence.py b/openerp/addons/base/ir/ir_sequence.py index 2a0f3ab47b7..25728399b19 100644 --- a/openerp/addons/base/ir/ir_sequence.py +++ b/openerp/addons/base/ir/ir_sequence.py @@ -63,6 +63,24 @@ def _update_nogap(self, number_increment): self.invalidate_cache(['number_next'], [self.id]) return number_next +def _predict_nextval(self, seq_id): + """Predict next value for PostgreSQL sequence without consuming it""" + # Cannot use currval() as it requires prior call to nextval() + query = """SELECT last_value, + (SELECT increment_by + FROM pg_sequences + WHERE sequencename = 'ir_sequence_%(seq_id)s'), + is_called + FROM ir_sequence_%(seq_id)s""" + if self.env.cr._cnx.server_version < 100000: + query = "SELECT last_value, increment_by, is_called FROM ir_sequence_%(seq_id)s" + self.env.cr.execute(query % {'seq_id': seq_id}) + (last_value, increment_by, is_called) = self.env.cr.fetchone() + if is_called: + return last_value + increment_by + # sequence has just been RESTARTed to return last_value next time + return last_value + class ir_sequence(models.Model): """ Sequence model. @@ -82,15 +100,8 @@ class ir_sequence(models.Model): if element.implementation != 'standard': element.number_next_actual = element.number_next else: - # get number from postgres sequence. Cannot use currval, because that might give an error when - # not having used nextval before. - query = "SELECT last_value, increment_by, is_called FROM ir_sequence_%03d" % element.id - self.env.cr.execute(query) - (last_value, increment_by, is_called) = self.env.cr.fetchone() - if is_called: - element.number_next_actual = last_value + increment_by - else: - element.number_next_actual = last_value + seq_id = "%03d" % element.id + element.number_next_actual = _predict_nextval(self, seq_id) def _set_number_next_actual(self): for record in self: @@ -319,15 +330,8 @@ class ir_sequence_date_range(models.Model): if element.sequence_id.implementation != 'standard': element.number_next_actual = element.number_next else: - # get number from postgres sequence. Cannot use currval, because that might give an error when - # not having used nextval before. - query = "SELECT last_value, increment_by, is_called FROM ir_sequence_%03d_%03d" % (element.sequence_id.id, element.id) - self.env.cr.execute(query) - (last_value, increment_by, is_called) = self.env.cr.fetchone() - if is_called: - element.number_next_actual = last_value + increment_by - else: - element.number_next_actual = last_value + seq_id = "%03d_%03d" % (element.sequence_id.id, element.id) + element.number_next_actual = _predict_nextval(self, seq_id) def _set_number_next_actual(self): for record in self: From 9bea73514554a92dff65ca90a600a7be6ee7b009 Mon Sep 17 00:00:00 2001 From: Aaron Bohy Date: Mon, 13 Nov 2017 14:05:09 +0100 Subject: [PATCH 02/19] [FIX] web: search view: autocomplete on datetime fields ... gives wrong values due to the timezone. For instance, let's assume that the browser timezone of the user is UTC+2, and the user types 10/09/2017 10:00:00 in a searchview with a datetime field in its arch (i.e. which autocompletes on a datatime field). Before this rev., the suggested value was 10/09/2017 08:00:00, i.e. the timezone offset was substracted from the value. --- addons/web/static/src/js/views/search_inputs.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/web/static/src/js/views/search_inputs.js b/addons/web/static/src/js/views/search_inputs.js index edeffd874b0..e8b2c87baae 100644 --- a/addons/web/static/src/js/views/search_inputs.js +++ b/addons/web/static/src/js/views/search_inputs.js @@ -351,7 +351,8 @@ var DateField = Field.extend(/** @lends instance.web.search.DateField# */{ return $.when(null); } - var m = moment(v, t === 'datetime' ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD'); + // THIS SHOULD BE FORWARDPORTED UP TO SAAS-15, NOT LATER + var m = moment.utc(v, t === 'datetime' ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD'); if (!m.isValid()) { return $.when(null); } var d = m.toDate(); var date_string = formats.format_value(d, this.attrs); From e419f395a123040896dbe942ad7f0ce10983d197 Mon Sep 17 00:00:00 2001 From: Grzegorz Krukar Date: Sat, 16 Sep 2017 18:44:34 +0200 Subject: [PATCH 03/19] [FIX] requirements: update psycopg2 version 2.7.1 is broken with glibc 2.66 upgrading to latest working version: 2.7.3 cf psycopg/psycopg2-wheels#2 Add CLA Fixes #19511 Closes #19512 --- doc/cla/individual/grzekru.md | 11 +++++++++++ requirements.txt | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 doc/cla/individual/grzekru.md diff --git a/doc/cla/individual/grzekru.md b/doc/cla/individual/grzekru.md new file mode 100644 index 00000000000..6dbd42dbaf6 --- /dev/null +++ b/doc/cla/individual/grzekru.md @@ -0,0 +1,11 @@ +Poland, 2017-09-17 + +I hereby agree to the terms of the Odoo Individual Contributor License +Agreement v1.0. + +I declare that I am authorized and able to make this agreement and sign this +declaration. + +Signed, + +Grzegorz Krukar grzegorzgk1@gmail.com https://github.com/grzekru \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 2b41c3f9dd0..da721057f19 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,7 +16,7 @@ passlib==1.6.5 Pillow==3.4.1 psutil==4.3.1 psycogreen==1.0 -psycopg2==2.7.1 +psycopg2==2.7.3 pydot==1.2.3 pyparsing==2.1.10 pyPdf==1.13 From 13d2b29f0151a9f607df96246104f30bb49cae86 Mon Sep 17 00:00:00 2001 From: Victor Oliveira da Silva Date: Mon, 13 Nov 2017 13:36:48 -0200 Subject: [PATCH 04/19] [FIX] doc: fix typo Closes #20726 --- doc/reference/javascript.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/reference/javascript.rst b/doc/reference/javascript.rst index 2a1e2b3a018..a639d305f57 100644 --- a/doc/reference/javascript.rst +++ b/doc/reference/javascript.rst @@ -594,7 +594,7 @@ API. Odoo Web eschews direct calls to :py:meth:`~odoo.models.Model.read_group` in favor of calling a method of :class:`~odoo.web.Query`, :py:meth:`much -in the way it is one in SQLAlchemy ` +in the way it is done in SQLAlchemy ` [#terminal]_:: some_query.group_by(['field1', 'field2']).then(function (groups) { From d6c2906d447b18ff7949e064045c1aaed047d909 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20V=C3=A1zquez=20Acosta?= Date: Mon, 13 Nov 2017 10:41:03 -0500 Subject: [PATCH 05/19] [FIX] mail: access the super of TestMailGroup Instead of the parent of TestMail class Closes #20728 --- addons/mail/tests/test_mail_channel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/mail/tests/test_mail_channel.py b/addons/mail/tests/test_mail_channel.py index 1c43f79edaf..e50f493426e 100644 --- a/addons/mail/tests/test_mail_channel.py +++ b/addons/mail/tests/test_mail_channel.py @@ -31,7 +31,7 @@ class TestMailGroup(TestMail): def mail_group_message_get_recipient_values(self, cr, uid, ids, notif_message=None, recipient_ids=None, context=None): return self.pool['mail.thread'].message_get_recipient_values(cr, uid, ids, notif_message=notif_message, recipient_ids=recipient_ids, context=context) cls.env['mail.channel']._patch_method('message_get_recipient_values', mail_group_message_get_recipient_values) - super(TestMail, cls).tearDownClass() + super(TestMailGroup, cls).tearDownClass() @mute_logger('openerp.addons.base.ir.ir_model', 'openerp.models') def test_access_rights_public(self): From d07f9c5ef534732288352f6e6559956a15907b1e Mon Sep 17 00:00:00 2001 From: mehdi-ghezal Date: Fri, 10 Nov 2017 11:24:54 +0100 Subject: [PATCH 06/19] [CLA] signature for mehdi-ghezal Backported to 9.0 cf comment Closes #20850 --- doc/cla/individual/mehdi-ghezal.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 doc/cla/individual/mehdi-ghezal.md diff --git a/doc/cla/individual/mehdi-ghezal.md b/doc/cla/individual/mehdi-ghezal.md new file mode 100644 index 00000000000..a5083336bfd --- /dev/null +++ b/doc/cla/individual/mehdi-ghezal.md @@ -0,0 +1,9 @@ +France, 2017-11-10 + +I hereby agree to the terms of the Odoo Individual Contributor License Agreement v1.0. + +I declare that I am authorized and able to make this agreement and sign this declaration. + +Signed, + +Mehdi GHEZAL mehdi.ghezal@gmail.com https://github.com/mehdi-ghezal From 466ca1e07e6373d3683ad6b2b9245ffd52195e1c Mon Sep 17 00:00:00 2001 From: fwi-odoo Date: Tue, 14 Nov 2017 11:28:07 +0100 Subject: [PATCH 07/19] [FIX] web: handle SessionExpiredException in the crash_manager --- addons/web/static/src/js/framework/crash_manager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/web/static/src/js/framework/crash_manager.js b/addons/web/static/src/js/framework/crash_manager.js index bc9046f5719..831f762b78c 100644 --- a/addons/web/static/src/js/framework/crash_manager.js +++ b/addons/web/static/src/js/framework/crash_manager.js @@ -54,7 +54,7 @@ var CrashManager = core.Class.extend({ new (handler)(this, error).display(); return; } - if (error.data.name === "openerp.http.SessionExpiredException" || error.data.name === "werkzeug.exceptions.Forbidden") { + if (error.data.name === "odoo.http.SessionExpiredException" || error.data.name === "werkzeug.exceptions.Forbidden") { this.show_warning({type: "Session Expired", data: { message: _t("Your Odoo session expired. Please refresh the current web page.") }}); return; } From 73f0c6da6d60c308006f34e81573179bc1efda71 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Wed, 8 Nov 2017 15:20:18 +0100 Subject: [PATCH 08/19] [FIX] l10n_fr_fec: Receivable/Payable In the FEC report, opening entries on receivable and payable accounts should be split by partner. opw-781321 --- addons/l10n_fr_fec/wizard/fec.py | 61 +++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/addons/l10n_fr_fec/wizard/fec.py b/addons/l10n_fr_fec/wizard/fec.py index d56762b537c..00440affe2e 100644 --- a/addons/l10n_fr_fec/wizard/fec.py +++ b/addons/l10n_fr_fec/wizard/fec.py @@ -169,8 +169,9 @@ class AccountFrFec(models.TransientModel): ''' sql_query += ''' - GROUP BY aml.account_id + GROUP BY aml.account_id, aat.type HAVING sum(aml.balance) != 0 + AND aat.type not in ('receivable', 'payable') ''' formatted_date_from = self.date_from.replace('-', '') date_from = datetime.strptime(self.date_from, DEFAULT_SERVER_DATE_FORMAT) @@ -208,6 +209,64 @@ class AccountFrFec(models.TransientModel): unaffected_earnings_results[5] = unaffected_earnings_account.name w.writerow([s.encode("utf-8") for s in unaffected_earnings_results]) + # INITIAL BALANCE - receivable/payable + sql_query = ''' + SELECT + 'OUV' AS JournalCode, + 'Balance initiale' AS JournalLib, + 'OUVERTURE/' || %s AS EcritureNum, + %s AS EcritureDate, + MIN(aa.code) AS CompteNum, + replace(MIN(aa.name), '|', '/') AS CompteLib, + CASE WHEN rp.ref IS null OR rp.ref = '' + THEN COALESCE('ID ' || rp.id, '') + ELSE rp.ref + END + AS CompAuxNum, + COALESCE(replace(rp.name, '|', '/'), '') AS CompAuxLib, + '-' AS PieceRef, + %s AS PieceDate, + '/' AS EcritureLib, + replace(CASE WHEN sum(aml.balance) <= 0 THEN '0,00' ELSE to_char(SUM(aml.balance), '999999999999999D99') END, '.', ',') AS Debit, + replace(CASE WHEN sum(aml.balance) >= 0 THEN '0,00' ELSE to_char(-SUM(aml.balance), '999999999999999D99') END, '.', ',') AS Credit, + '' AS EcritureLet, + '' AS DateLet, + %s AS ValidDate, + '' AS Montantdevise, + '' AS Idevise, + MIN(aa.id) AS CompteID + FROM + account_move_line aml + LEFT JOIN account_move am ON am.id=aml.move_id + LEFT JOIN res_partner rp ON rp.id=aml.partner_id + JOIN account_account aa ON aa.id = aml.account_id + LEFT JOIN account_account_type aat ON aa.user_type_id = aat.id + WHERE + am.date < %s + AND am.company_id = %s + AND aat.include_initial_balance = 't' + AND (aml.debit != 0 OR aml.credit != 0) + ''' + + # For official report: only use posted entries + if self.export_type == "official": + sql_query += ''' + AND am.state = 'posted' + ''' + + sql_query += ''' + GROUP BY aml.account_id, aat.type, rp.ref, rp.id + HAVING sum(aml.balance) != 0 + AND aat.type in ('receivable', 'payable') + ''' + self._cr.execute( + sql_query, (formatted_date_year, formatted_date_from, formatted_date_from, formatted_date_from, self.date_from, company.id)) + + for row in self._cr.fetchall(): + listrow = list(row) + account_id = listrow.pop() + w.writerow([s.encode("utf-8") for s in listrow]) + # LINES sql_query = ''' SELECT From 97eb4a36b0a0b1004e8c49d5a457360ea3d4cdcb Mon Sep 17 00:00:00 2001 From: "Jonathan Nemry (METRUM)" Date: Tue, 14 Nov 2017 15:03:27 +0100 Subject: [PATCH 09/19] [CLA] METRUM signature of Corporate CLA 1.0 Done at #20926 --- doc/cla/corporate/metrum.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 doc/cla/corporate/metrum.md diff --git a/doc/cla/corporate/metrum.md b/doc/cla/corporate/metrum.md new file mode 100644 index 00000000000..b64bf351a8b --- /dev/null +++ b/doc/cla/corporate/metrum.md @@ -0,0 +1,16 @@ +Belgium, 2017-11-14 + +METRUM SA agrees to the terms of the Odoo Corporate Contributor License +Agreement v1.0. + +I declare that I am authorized and able to make this agreement and sign this +declaration. + +Signed, + +Jonathan Nemry jonathan.nemry@metrum.lu https://github.com/JonathanNEMRY + +List of contributors: + +Pascal Pelzer pascal.pelzer@metrum.lu https://github.com/PascalPelzer +Jonathan Nemry jonathan.nemry@metrum.lu https://github.com/JonathanNEMRY From b152c5be4faaca651e1fe0173e66d330291cef98 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Tue, 14 Nov 2017 15:36:58 +0100 Subject: [PATCH 10/19] [FIX] im_livechat: Creation date (hour) Go to Report -> Operator Analysis -> Apply group_by 'Creation date (hour)' => traceback. `start_date_hour` is implemented for Livechat Support Report on Channels, but not on Operators. opw-782255 --- addons/im_livechat/report/im_livechat_report_operator_views.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/im_livechat/report/im_livechat_report_operator_views.xml b/addons/im_livechat/report/im_livechat_report_operator_views.xml index 902a16ab1ac..773229b2577 100644 --- a/addons/im_livechat/report/im_livechat_report_operator_views.xml +++ b/addons/im_livechat/report/im_livechat_report_operator_views.xml @@ -36,7 +36,6 @@ - From 1662088ed649ba33645797457cba06d83f30d089 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Tue, 14 Nov 2017 15:55:28 +0100 Subject: [PATCH 11/19] [FIX] mrp: product name Complement of commit ea96aa167634281511dfe2 to raw materials. opw-781039 --- addons/mrp/report/mrp_production_templates.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/mrp/report/mrp_production_templates.xml b/addons/mrp/report/mrp_production_templates.xml index d8a90b371ac..13fd06a4477 100644 --- a/addons/mrp/report/mrp_production_templates.xml +++ b/addons/mrp/report/mrp_production_templates.xml @@ -93,8 +93,7 @@ - - + From 7f989b94b02bb7daf9cce964bdde078aac794033 Mon Sep 17 00:00:00 2001 From: Goffin Simon Date: Tue, 14 Nov 2017 14:25:36 +0100 Subject: [PATCH 12/19] [FIX] product: Impossible to get the right pricelist in multi company The logic was not the same in function _compute_product_pricelist and in function _inverse_product_pricelist. The function _get_partner_pricelist must check the default pricelist for the company when no pricelist is given for the specific partner(res_id) because the function set_multi doesn't set a specific pricelist to the partner if the pricelist set and the default one are the same. opw:779808 --- addons/product/models/product_pricelist.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/product/models/product_pricelist.py b/addons/product/models/product_pricelist.py index fd2bfdb9dec..a1bf5527b99 100644 --- a/addons/product/models/product_pricelist.py +++ b/addons/product/models/product_pricelist.py @@ -299,7 +299,7 @@ class Pricelist(models.Model): Property = self.env['ir.property'].with_context(force_company=company_id or self.env.user.company_id.id) p = Partner.browse(partner_id) - pl = Property.get('property_product_pricelist', Partner._name, '%s,%s' % (Partner._name, p.id)) + pl = Property.get('property_product_pricelist', Partner._name, '%s,%s' % (Partner._name, p.id)) or Property.get('property_product_pricelist', 'res.partner') if pl: pl = pl[0].id From 661dab1ed681ef408e7e7d78b7122157dae249ce Mon Sep 17 00:00:00 2001 From: Goffin Simon Date: Tue, 14 Nov 2017 22:34:45 +0100 Subject: [PATCH 13/19] [FIX] product: Keep the stable behavior Revert of this commit: 7f989b94b02bb7daf9cce964bdde078aac794033 because it changes the behavior in stable version. opw:779808 --- addons/product/models/product_pricelist.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/product/models/product_pricelist.py b/addons/product/models/product_pricelist.py index a1bf5527b99..fd2bfdb9dec 100644 --- a/addons/product/models/product_pricelist.py +++ b/addons/product/models/product_pricelist.py @@ -299,7 +299,7 @@ class Pricelist(models.Model): Property = self.env['ir.property'].with_context(force_company=company_id or self.env.user.company_id.id) p = Partner.browse(partner_id) - pl = Property.get('property_product_pricelist', Partner._name, '%s,%s' % (Partner._name, p.id)) or Property.get('property_product_pricelist', 'res.partner') + pl = Property.get('property_product_pricelist', Partner._name, '%s,%s' % (Partner._name, p.id)) if pl: pl = pl[0].id From 5297321207c2d45f8bb1c3e6f692fbde93148f0f Mon Sep 17 00:00:00 2001 From: Romain Derie Date: Mon, 13 Nov 2017 13:27:02 +0100 Subject: [PATCH 14/19] [FIX] website_sale: 0.00 total is showing in empty cart if logged in Before this commit, if you go on /shop/cart and your cart is empty, it will show the total (Subtotal, Taxes, Total) as $ 0.00. Indeed, the code is retrieving a 'sale.order' if you are connected and you already have a draft sale order on DB (eg: you just add something to cart and emptied it afterward). - Add product to your cart and proceed to checkout - On checkout cart, remove the product, your cart is now empty - Reload the page (you should still be on /shop/cart) or go to /shop/cart - You now see the zero prices (Subtotal, Taxes, Total) Now, we will hide this if you have an order but no line on that order. This closes #20896 --- addons/website_sale/views/templates.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website_sale/views/templates.xml b/addons/website_sale/views/templates.xml index 663f57f8b5e..b260d26af7e 100644 --- a/addons/website_sale/views/templates.xml +++ b/addons/website_sale/views/templates.xml @@ -1396,7 +1396,7 @@