diff --git a/addons/account/models/account_invoice.py b/addons/account/models/account_invoice.py
index 565b81c5b53..6afbc6671bd 100644
--- a/addons/account/models/account_invoice.py
+++ b/addons/account/models/account_invoice.py
@@ -316,7 +316,7 @@ class AccountInvoice(models.Model):
payment_move_line_ids = fields.Many2many('account.move.line', string='Payment Move Lines', compute='_compute_payments', store=True)
user_id = fields.Many2one('res.users', string='Salesperson', track_visibility='onchange',
readonly=True, states={'draft': [('readonly', False)]},
- default=lambda self: self.env.user)
+ default=lambda self: self.env.user, copy=False)
fiscal_position_id = fields.Many2one('account.fiscal.position', string='Fiscal Position', oldname='fiscal_position',
readonly=True, states={'draft': [('readonly', False)]})
commercial_partner_id = fields.Many2one('res.partner', string='Commercial Entity', compute_sudo=True,
diff --git a/addons/account/views/res_config_view.xml b/addons/account/views/res_config_view.xml
index a58960c2b4e..e1415fdc009 100644
--- a/addons/account/views/res_config_view.xml
+++ b/addons/account/views/res_config_view.xml
@@ -155,6 +155,10 @@
, )
diff --git a/addons/mail/tests/test_mail_features.py b/addons/mail/tests/test_mail_features.py
index 92613f55e51..5a0fb8b9418 100644
--- a/addons/mail/tests/test_mail_features.py
+++ b/addons/mail/tests/test_mail_features.py
@@ -23,7 +23,6 @@ class TestMailFeatures(TestMail):
self.env['res.partner'].create({'name': 'Actual Partner'})
self.assertTrue(record.name)
-
@mute_logger('odoo.addons.mail.models.mail_mail')
def test_needaction(self):
# needaction use Inbox notification
diff --git a/addons/mail/tests/test_mail_message.py b/addons/mail/tests/test_mail_message.py
index db6dc9457a5..5d3471c5f80 100644
--- a/addons/mail/tests/test_mail_message.py
+++ b/addons/mail/tests/test_mail_message.py
@@ -288,3 +288,70 @@ class TestMailMessageAccess(TestMail):
msg_cnt = len(self.test_pigs.message_ids)
self.test_pigs.message_post(body='Hi!', subject='test')
self.assertEqual(len(self.test_pigs.message_ids), msg_cnt + 1)
+
+ @mute_logger('openerp.addons.mail.models.mail_mail')
+ def test_mark_all_as_read(self):
+ self.user_employee.notification_type = 'inbox'
+ emp_partner = self.user_employee.partner_id.sudo(self.user_employee.id)
+
+ group_private = self.env['mail.channel'].with_context({
+ 'mail_create_nolog': True,
+ 'mail_create_nosubscribe': True,
+ 'mail_channel_noautofollow': True,
+ }).create({
+ 'name': 'Private',
+ 'description': 'Private James R.',
+ 'public': 'private',
+ 'alias_name': 'private',
+ 'alias_contact': 'followers'}
+ ).with_context({'mail_create_nosubscribe': False})
+
+ # mark all as read clear needactions
+ group_private.message_post(body='Test', message_type='comment', subtype='mail.mt_comment', partner_ids=[emp_partner.id])
+ emp_partner.env['mail.message'].mark_all_as_read(channel_ids=[], domain=[])
+ na_count = emp_partner.get_needaction_count()
+ self.assertEqual(na_count, 0, "mark all as read should conclude all needactions")
+
+ # mark all as read also clear inaccessible needactions
+ new_msg = group_private.message_post(body='Zest', message_type='comment', subtype='mail.mt_comment', partner_ids=[emp_partner.id])
+ needaction_accessible = len(emp_partner.env['mail.message'].search([['needaction', '=', True]]))
+ self.assertEqual(needaction_accessible, 1, "a new message to a partner is readable to that partner")
+
+ new_msg.sudo().partner_ids = self.env['res.partner']
+ emp_partner.env['mail.message'].search([['needaction', '=', True]])
+ needaction_length = len(emp_partner.env['mail.message'].search([['needaction', '=', True]]))
+ self.assertEqual(needaction_length, 1, "message should still be readable when notified")
+
+ na_count = emp_partner.get_needaction_count()
+ self.assertEqual(na_count, 1, "message not accessible is currently still counted")
+
+ emp_partner.env['mail.message'].mark_all_as_read(channel_ids=[], domain=[])
+ na_count = emp_partner.get_needaction_count()
+ self.assertEqual(na_count, 0, "mark all read should conclude all needactions even inacessible ones")
+
+ @mute_logger('openerp.addons.mail.models.mail_mail')
+ def test_mark_all_as_read_share(self):
+ self.user_portal.notification_type = 'inbox'
+ portal_partner = self.user_portal.partner_id.sudo(self.user_portal.id)
+
+ # mark all as read clear needactions
+ self.group_pigs.message_post(body='Test', message_type='comment', subtype='mail.mt_comment', partner_ids=[portal_partner.id])
+ portal_partner.env['mail.message'].mark_all_as_read(channel_ids=[], domain=[])
+ na_count = portal_partner.get_needaction_count()
+ self.assertEqual(na_count, 0, "mark all as read should conclude all needactions")
+
+ # mark all as read also clear inaccessible needactions
+ new_msg = self.group_pigs.message_post(body='Zest', message_type='comment', subtype='mail.mt_comment', partner_ids=[portal_partner.id])
+ needaction_accessible = len(portal_partner.env['mail.message'].search([['needaction', '=', True]]))
+ self.assertEqual(needaction_accessible, 1, "a new message to a partner is readable to that partner")
+
+ new_msg.sudo().partner_ids = self.env['res.partner']
+ needaction_length = len(portal_partner.env['mail.message'].search([['needaction', '=', True]]))
+ self.assertEqual(needaction_length, 1, "message should still be readable when notified")
+
+ na_count = portal_partner.get_needaction_count()
+ self.assertEqual(na_count, 1, "message not accessible is currently still counted")
+
+ portal_partner.env['mail.message'].mark_all_as_read(channel_ids=[], domain=[])
+ na_count = portal_partner.get_needaction_count()
+ self.assertEqual(na_count, 0, "mark all read should conclude all needactions even inacessible ones")
diff --git a/addons/maintenance/models/maintenance.py b/addons/maintenance/models/maintenance.py
index 3e14687d35e..90a6ad1a4a1 100644
--- a/addons/maintenance/models/maintenance.py
+++ b/addons/maintenance/models/maintenance.py
@@ -213,6 +213,15 @@ class MaintenanceEquipment(models.Model):
self.message_subscribe_users(user_ids=[vals['owner_user_id']])
return super(MaintenanceEquipment, self).write(vals)
+ @api.model
+ def _message_get_auto_subscribe_fields(self, updated_fields, auto_follow_fields=None):
+ """ mail.thread override so user_id which has no special access allowance is not
+ automatically subscribed.
+ """
+ if auto_follow_fields is None:
+ auto_follow_fields = []
+ return super(MaintenanceEquipment, self)._message_get_auto_subscribe_fields(updated_fields, auto_follow_fields)
+
@api.model
def _read_group_category_ids(self, categories, domain, order):
""" Read group customization in order to display all the categories in
diff --git a/addons/website_form/static/src/js/website_form.js b/addons/website_form/static/src/js/website_form.js
index e95f37ef335..234ce4da1b4 100644
--- a/addons/website_form/static/src/js/website_form.js
+++ b/addons/website_form/static/src/js/website_form.js
@@ -23,7 +23,7 @@ odoo.define('website_form.animation', function (require) {
start: function() {
var self = this;
- qweb.add_template('/website_form/static/src/xml/website_form.xml');
+ this.templates_loaded = ajax.loadXML('/website_form/static/src/xml/website_form.xml', qweb);
this.$target.find('.o_website_form_send').on('click',function(e) {self.send(e);});
// Initialize datetimepickers
@@ -233,7 +233,10 @@ odoo.define('website_form.animation', function (require) {
if (status != 'success') { // Restore send button behavior if result is an error
this.$target.find('.o_website_form_send').on('click',function(e) {self.send(e);});
}
- this.$target.find('#o_website_form_result').replaceWith(qweb.render("website_form.status_" + status))
+ var $result = this.$('#o_website_form_result');
+ this.templates_loaded.done(function () {
+ $result.replaceWith(qweb.render("website_form.status_" + status));
+ });
},
});
});
diff --git a/addons/website_sale/views/templates.xml b/addons/website_sale/views/templates.xml
index 332c1bb238c..0a38c108ee1 100644
--- a/addons/website_sale/views/templates.xml
+++ b/addons/website_sale/views/templates.xml
@@ -725,6 +725,7 @@
+