diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index 69eaa567490..6ad1b0c0fe0 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -227,6 +227,7 @@ class AccountMove(models.Model): @api.multi def _reverse_move(self, date=None, journal_id=None): self.ensure_one() + date = date or fields.Date.today() reversed_move = self.copy(default={ 'date': date, 'journal_id': journal_id.id if journal_id else self.journal_id.id, @@ -437,8 +438,8 @@ class AccountMoveLine(models.Model): help="Technical field used to mark a tax line as exigible in the vat report or not (only exigible journal items are displayed). By default all new journal items are directly exigible, but with the feature cash_basis on taxes, some will become exigible only when the payment is recorded.") _sql_constraints = [ - ('credit_debit1', 'CHECK (credit*debit=0)', 'Wrong credit or debit value in accounting entry !'), - ('credit_debit2', 'CHECK (credit+debit>=0)', 'Wrong credit or debit value in accounting entry !'), + ('credit_debit1', 'CHECK (credit*debit=0)', 'Wrong credit or debit value in accounting entry! Credit or debit should be zero.'), + ('credit_debit2', 'CHECK (credit+debit>=0)', 'Wrong credit or debit value in accounting entry! Credit and debit should be positive.'), ] @api.model diff --git a/addons/account_asset/models/account_asset.py b/addons/account_asset/models/account_asset.py index 2dd11c42fa6..b58122cddc0 100644 --- a/addons/account_asset/models/account_asset.py +++ b/addons/account_asset/models/account_asset.py @@ -481,9 +481,9 @@ class AccountAssetDepreciationLine(models.Model): def create_move(self, post_move=True): created_moves = self.env['account.move'] prec = self.env['decimal.precision'].precision_get('Account') + if self.mapped('move_id'): + raise UserError(_('This depreciation is already linked to a journal entry! Please post or delete it.')) for line in self: - if line.move_id: - raise UserError(_('This depreciation is already linked to a journal entry! Please post or delete it.')) category_id = line.asset_id.category_id depreciation_date = self.env.context.get('depreciation_date') or line.depreciation_date or fields.Date.context_today(self) company_currency = line.asset_id.company_id.currency_id diff --git a/addons/l10n_be_intrastat_2019/__manifest__.py b/addons/l10n_be_intrastat_2019/__manifest__.py index b3de01cd46b..48554dc064b 100644 --- a/addons/l10n_be_intrastat_2019/__manifest__.py +++ b/addons/l10n_be_intrastat_2019/__manifest__.py @@ -10,6 +10,7 @@ Adds the possibility to specify the origin country of goods and the partner VAT 'depends': ['l10n_be_intrastat'], 'data': [ 'views/account_invoice_line_view.xml', + 'views/report_invoice.xml', ], 'auto_install': True, } diff --git a/addons/l10n_be_intrastat_2019/views/report_invoice.xml b/addons/l10n_be_intrastat_2019/views/report_invoice.xml new file mode 100644 index 00000000000..c693021d0dc --- /dev/null +++ b/addons/l10n_be_intrastat_2019/views/report_invoice.xml @@ -0,0 +1,33 @@ + + + + + + diff --git a/addons/payment_adyen/models/payment.py b/addons/payment_adyen/models/payment.py index b54adc58a9c..216ac86e575 100644 --- a/addons/payment_adyen/models/payment.py +++ b/addons/payment_adyen/models/payment.py @@ -128,7 +128,7 @@ class AcquirerAdyen(models.Model): 'sessionValidity': tmp_date.isoformat('T')[:19] + "Z", 'resURL': '%s' % urlparse.urljoin(base_url, AdyenController._return_url), 'merchantReturnData': json.dumps({'return_url': '%s' % values.pop('return_url')}) if values.get('return_url', '') else False, - 'shopperEmail': values.get('partner_email', ''), + 'shopperEmail': values.get('partner_email') or values.get('billing_partner_email') or '', }) values['merchantSig'] = self._adyen_generate_merchant_sig_sha256('in', values) diff --git a/addons/web_editor/static/src/js/widgets.js b/addons/web_editor/static/src/js/widgets.js index a9f7538a036..8244dcdfb25 100644 --- a/addons/web_editor/static/src/js/widgets.js +++ b/addons/web_editor/static/src/js/widgets.js @@ -1006,6 +1006,7 @@ var LinkDialog = Dialog.extend({ } this.data.range = range.create(sc, so, ec, eo); + $(editable).data("range", this.data.range); this.data.range.select(); } else { nodes = dom.ancestor(sc, dom.isAnchor).childNodes; diff --git a/doc/cla/individual/luisiniguezh.md b/doc/cla/individual/luisiniguezh.md new file mode 100644 index 00000000000..11a1613066b --- /dev/null +++ b/doc/cla/individual/luisiniguezh.md @@ -0,0 +1,11 @@ +Mexico, 2018-12-05 + +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, + +Luis Arturo Íñiguez Hernández luis.iniguezh@gmail.com https://github.com/luisiniguezh diff --git a/doc/cla/individual/michelezak.md b/doc/cla/individual/michelezak.md new file mode 100644 index 00000000000..d3bf2ff1b6f --- /dev/null +++ b/doc/cla/individual/michelezak.md @@ -0,0 +1,11 @@ +Italy, 2019-06-04 + +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, + +Michele Zaccheddu michelezak93@gmail.com https://github.com/MicheleZak diff --git a/odoo/addons/base/ir/ir_actions.py b/odoo/addons/base/ir/ir_actions.py index 5690577b597..ab32ff95538 100644 --- a/odoo/addons/base/ir/ir_actions.py +++ b/odoo/addons/base/ir/ir_actions.py @@ -874,3 +874,11 @@ class IrActionsActClient(models.Model): for record in self: params = record.params record.params_store = repr(params) if isinstance(params, dict) else params + + def _get_default_form_view(self): + doc = super(IrActionsActClient, self)._get_default_form_view() + params = doc.find(".//field[@name='params']") + params.getparent().remove(params) + params_store = doc.find(".//field[@name='params_store']") + params_store.getparent().remove(params_store) + return doc diff --git a/odoo/addons/base/ir/ir_model.py b/odoo/addons/base/ir/ir_model.py index 308d64d32b7..fa0e3bab342 100644 --- a/odoo/addons/base/ir/ir_model.py +++ b/odoo/addons/base/ir/ir_model.py @@ -674,7 +674,7 @@ class IrModelFields(models.Model): item._prepare_update() if column_rename: raise UserError(_('Can only rename one field at a time!')) - column_rename = (obj._table, item.name, vals['name'], item.index) + column_rename = (obj._table, item.name, vals['name'], item.index, item.store) # We don't check the 'state', because it might come from the context # (thus be set for multiple fields) and will be ignored anyway. @@ -693,10 +693,11 @@ class IrModelFields(models.Model): if column_rename: # rename column in database, and its corresponding index if present - table, oldname, newname, index = column_rename - self._cr.execute('ALTER TABLE "%s" RENAME COLUMN "%s" TO "%s"' % (table, oldname, newname)) - if index: - self._cr.execute('ALTER INDEX "%s_%s_index" RENAME TO "%s_%s_index"' % (table, oldname, table, newname)) + table, oldname, newname, index, stored = column_rename + if stored: + self._cr.execute('ALTER TABLE "%s" RENAME COLUMN "%s" TO "%s"' % (table, oldname, newname)) + if index: + self._cr.execute('ALTER INDEX "%s_%s_index" RENAME TO "%s_%s_index"' % (table, oldname, table, newname)) if column_rename or patched_models: # setup models, this will reload all manual fields in registry diff --git a/odoo/addons/test_lint/__init__.py b/odoo/addons/test_lint/__init__.py new file mode 100644 index 00000000000..0e68430dabe --- /dev/null +++ b/odoo/addons/test_lint/__init__.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, SUPERUSER_ID + + +# TO REMOVE in master +def uninstall_test_pylint(cr): + env = api.Environment(cr, SUPERUSER_ID, {}) + env['ir.module.module'].search([ + ('name', '=', 'test_pylint'), + ('state', '=', 'installed') + ]).write({'state': 'uninstalled'}) diff --git a/odoo/addons/test_lint/__manifest__.py b/odoo/addons/test_lint/__manifest__.py new file mode 100644 index 00000000000..554e20ba3b2 --- /dev/null +++ b/odoo/addons/test_lint/__manifest__.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +{ + 'name': 'test-lint', + 'version': '0.1', + 'category': 'Tests', + 'description': """A module to test Odoo code with various linters.""", + 'maintainer': 'Odoo SA', + 'depends': ['base'], + 'installable': True, + 'auto_install': False, + 'pre_init_hook': 'uninstall_test_pylint' +} diff --git a/odoo/addons/test_lint/tests/__init__.py b/odoo/addons/test_lint/tests/__init__.py new file mode 100644 index 00000000000..03f1bd714d1 --- /dev/null +++ b/odoo/addons/test_lint/tests/__init__.py @@ -0,0 +1,2 @@ +import test_pylint +import test_ecmascript diff --git a/odoo/addons/test_lint/tests/test_ecmascript.py b/odoo/addons/test_lint/tests/test_ecmascript.py new file mode 100644 index 00000000000..46008b0587d --- /dev/null +++ b/odoo/addons/test_lint/tests/test_ecmascript.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +import logging +import os +import re +import subprocess +from unittest import skipIf +from odoo.tests.common import TransactionCase +from odoo import tools +from odoo.modules import get_modules, get_module_path + +MAX_ES_VERSION = 'es5' + +_logger = logging.getLogger(__name__) + +try: + es_check = tools.misc.find_in_path('es-check') +except IOError: + es_check = None + + +@skipIf(es_check is None, "es-check tool not found on this system") +class TestECMAScriptVersion(TransactionCase): + + longMessage = True + + def test_ecmascript_version(self): + """ Test that there is no unsupported ecmascript in javascript files """ + + black_re = re.compile(r'summernote.+(intro\.js|outro.js)$') + + mod_paths = [get_module_path(m) for m in get_modules()] + files_to_check = [] + for p in mod_paths: + for dp, _, file_names in os.walk(p): + if 'static/test' in dp: + continue + for fn in file_names: + fullpath_name = os.path.join(dp, fn) + if fullpath_name.endswith('.js') and not black_re.search(fullpath_name): + files_to_check.append(fullpath_name) + + _logger.info('Testing %s js files', len(files_to_check)) + cmd = [es_check, MAX_ES_VERSION] + files_to_check + process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = process.communicate() + self.assertEqual(process.returncode, 0, msg=out) diff --git a/odoo/addons/test_pylint/tests/test_pylint.py b/odoo/addons/test_lint/tests/test_pylint.py similarity index 100% rename from odoo/addons/test_pylint/tests/test_pylint.py rename to odoo/addons/test_lint/tests/test_pylint.py diff --git a/odoo/addons/test_pylint/__manifest__.py b/odoo/addons/test_pylint/__manifest__.py index 66f801454a5..42e9d621f71 100644 --- a/odoo/addons/test_pylint/__manifest__.py +++ b/odoo/addons/test_pylint/__manifest__.py @@ -3,7 +3,7 @@ 'name': 'test-eval', 'version': '0.1', 'category': 'Tests', - 'description': """A module to test Odoo with pylint.""", + 'description': """Deprecated empty module in favor of test-lint.""", 'maintainer': 'Odoo SA', 'depends': ['base'], 'installable': True, diff --git a/odoo/addons/test_pylint/tests/__init__.py b/odoo/addons/test_pylint/tests/__init__.py deleted file mode 100644 index c102da5600e..00000000000 --- a/odoo/addons/test_pylint/tests/__init__.py +++ /dev/null @@ -1 +0,0 @@ -import test_pylint