diff --git a/addons/base_import/models/base_import.py b/addons/base_import/models/base_import.py index e970d1ca3ad..6a2f6b729bc 100644 --- a/addons/base_import/models/base_import.py +++ b/addons/base_import/models/base_import.py @@ -453,7 +453,7 @@ class Import(models.TransientModel): :rtype: (None, None) | (list(str), dict(int: list(str))) """ if not options.get('headers'): - return None, None + return [], {} headers = next(rows) return headers, { diff --git a/addons/base_import/tests/test_base_import.py b/addons/base_import/tests/test_base_import.py index 0502af6d0ab..a0031c192e9 100644 --- a/addons/base_import/tests/test_base_import.py +++ b/addons/base_import/tests/test_base_import.py @@ -152,7 +152,7 @@ class TestMatchHeadersMultiple(TransactionCase): def test_noheaders(self): self.assertEqual( - self.env['base_import.import']._match_headers([], [], {}), (None, None) + self.env['base_import.import']._match_headers([], [], {}), ([], {}) ) def test_nomatch(self): diff --git a/addons/mail/controllers/main.py b/addons/mail/controllers/main.py index c7b01e29fbd..8c3df12f12c 100644 --- a/addons/mail/controllers/main.py +++ b/addons/mail/controllers/main.py @@ -66,10 +66,15 @@ class MailController(http.Controller): # record does not seem to exist -> redirect to login return cls._redirect_to_messaging() record_action = record_sudo.get_access_action() + record_target_type = record_action.pop('target_type', 'dummy') - # the record has an URL redirection: use it directly + # the record has a public URL redirection: use it directly if record_action['type'] == 'ir.actions.act_url': - return werkzeug.utils.redirect(record_action['url']) + if record_target_type == 'public' and not uid: + return werkzeug.utils.redirect(record_action['url']) + else: + # user connected or non-public URL, handled below + pass # other choice: act_window (no support of anything else currently) elif not record_action['type'] == 'ir.actions.act_window': return cls._redirect_to_messaging() @@ -83,6 +88,9 @@ class MailController(http.Controller): except AccessError: return cls._redirect_to_messaging() + if record_action['type'] == 'ir.actions.act_url': + return werkzeug.utils.redirect(record_action['url']) + url_params = { 'view_type': record_action['view_type'], 'model': model, diff --git a/addons/point_of_sale/static/src/js/db.js b/addons/point_of_sale/static/src/js/db.js index c2b3fad52f0..ccdd0fb6616 100644 --- a/addons/point_of_sale/static/src/js/db.js +++ b/addons/point_of_sale/static/src/js/db.js @@ -477,6 +477,13 @@ var PosDB = core.Class.extend({ } return orders; }, + set_cashier: function(cashier) { + // Always update if the user is the same as before + this.save('cashier', cashier); + }, + get_cashier: function() { + return this.load('cashier'); + } }); return PosDB; diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index 9b222f12922..4edff2ce8ea 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -240,6 +240,7 @@ exports.PosModel = Backbone.Model.extend({ } self.db.set_uuid(self.config.uuid); + self.cashier = self.get_cashier(); var orders = self.db.get_orders(); for (var i = 0; i < orders.length; i++) { @@ -572,11 +573,12 @@ exports.PosModel = Backbone.Model.extend({ // returns the user who is currently the cashier for this point of sale get_cashier: function(){ - return this.cashier || this.user; + return this.db.get_cashier() || this.cashier || this.user; }, // changes the current cashier set_cashier: function(user){ this.cashier = user; + this.db.set_cashier(this.cashier); }, //creates a new empty order and sets it as the current order add_new_order: function(){ diff --git a/addons/website_blog/models/website_blog.py b/addons/website_blog/models/website_blog.py index b70b61b578f..d8daea8a6ff 100644 --- a/addons/website_blog/models/website_blog.py +++ b/addons/website_blog/models/website_blog.py @@ -226,6 +226,7 @@ class BlogPost(models.Model): 'type': 'ir.actions.act_url', 'url': self.url, 'target': 'self', + 'target_type': 'public', 'res_id': self.id, } diff --git a/addons/website_forum/models/forum.py b/addons/website_forum/models/forum.py index f4301209f17..f77d8dca4fd 100644 --- a/addons/website_forum/models/forum.py +++ b/addons/website_forum/models/forum.py @@ -786,6 +786,7 @@ class Post(models.Model): 'type': 'ir.actions.act_url', 'url': '/forum/%s/question/%s' % (self.forum_id.id, self.id), 'target': 'self', + 'target_type': 'public', 'res_id': self.id, } diff --git a/addons/website_slides/models/slides.py b/addons/website_slides/models/slides.py index ff4078a103e..830cf910e8a 100644 --- a/addons/website_slides/models/slides.py +++ b/addons/website_slides/models/slides.py @@ -450,6 +450,7 @@ class Slide(models.Model): 'type': 'ir.actions.act_url', 'url': '%s' % self.website_url, 'target': 'self', + 'target_type': 'public', 'res_id': self.id, } return super(Slide, self).get_access_action() diff --git a/doc/setup/deploy.rst b/doc/setup/deploy.rst index ec1a31e0a3c..eb5d4cec144 100644 --- a/doc/setup/deploy.rst +++ b/doc/setup/deploy.rst @@ -213,6 +213,10 @@ Instead you must have a proxy redirecting requests whose URL starts with ``/longpolling/`` to the longpolling port. Other request should be proxied to the :option:`normal HTTP port ` +.. warning:: The livechat worker requires the ``psycogreen`` Python module, + which is not always included with all installation packages. + It can be manually installed with ``pip install psycogreen``. + Configuration sample -------------------- diff --git a/odoo/addons/base/base.sql b/odoo/addons/base/base.sql index 9e3efde69a6..57d57a1389b 100644 --- a/odoo/addons/base/base.sql +++ b/odoo/addons/base/base.sql @@ -50,7 +50,7 @@ CREATE TABLE ir_module_module ( website character varying(256), summary character varying(256), name character varying(128) NOT NULL, - author character varying(128), + author character varying, icon varchar, state character varying(16), latest_version character varying(64),