diff --git a/addons/calendar/calendar.py b/addons/calendar/calendar.py index d37f3149aa7..726056047af 100644 --- a/addons/calendar/calendar.py +++ b/addons/calendar/calendar.py @@ -221,6 +221,7 @@ class calendar_attendee(osv.Model): 'datas_fname': 'invitation.ics', 'datas': str(ics_file).encode('base64')})] vals['model'] = None # We don't want to have the mail in the tchatter while in queue! + vals['res_id'] = False the_mailmess = mail_pool.browse(cr, uid, mail_id, context=context).mail_message_id mailmess_pool.write(cr, uid, [the_mailmess.id], vals, context=context) mail_ids.append(mail_id) @@ -1615,11 +1616,11 @@ class calendar_event(osv.Model): super(calendar_event, self).write(cr, uid, real_ids, values, context=context) # set end_date for calendar searching - if values.get('recurrency') and values.get('end_type', 'count') in ('count', unicode('count')) and \ - (values.get('rrule_type') or values.get('count') or values.get('start') or values.get('stop')): - for id in real_ids: - final_date = self._get_recurrency_end_date(cr, uid, id, context=context) - super(calendar_event, self).write(cr, uid, [id], {'final_date': final_date}, context=context) + if any(field in values for field in ['recurrency', 'end_type', 'count', 'rrule_type', 'start', 'stop']): + for event in self.browse(cr, uid, real_ids, context=context): + if event.recurrency and event.end_type in ('count', unicode('count')): + final_date = self._get_recurrency_end_date(cr, uid, event.id, context=context) + super(calendar_event, self).write(cr, uid, [event.id], {'final_date': final_date}, context=context) attendees_create = False if values.get('partner_ids', False): @@ -1714,7 +1715,8 @@ class calendar_event(osv.Model): for r in result: if r['user_id']: user_id = type(r['user_id']) in (tuple, list) and r['user_id'][0] or r['user_id'] - if user_id == uid: + partner_id = self.pool['res.users'].browse(cr, uid, uid, context).partner_id.id + if user_id == uid or partner_id in r.get("partner_ids", []): continue if r['class'] == 'private': for f in r.keys(): diff --git a/addons/mail/models/mail_followers.py b/addons/mail/models/mail_followers.py index 6c066b123dd..14c1cbddbda 100644 --- a/addons/mail/models/mail_followers.py +++ b/addons/mail/models/mail_followers.py @@ -112,23 +112,31 @@ class Followers(models.Model): # Modifying followers change access rights to individual documents. As the # cache may contain accessible/inaccessible data, one has to refresh it. # + @api.multi + def _invalidate_documents(self): + """ Invalidate the cache of the documents followed by ``self``. """ + for record in self: + if record.res_id: + self.env[record.res_model].invalidate_cache(ids=[record.res_id]) + @api.model def create(self, vals): res = super(Followers, self).create(vals) - self.invalidate_cache() + res._invalidate_documents() return res @api.multi def write(self, vals): + if 'res_model' in vals or 'res_id' in vals: + self._invalidate_documents() res = super(Followers, self).write(vals) - self.invalidate_cache() + self._invalidate_documents() return res @api.multi def unlink(self): - res = super(Followers, self).unlink() - self.invalidate_cache() - return res + self._invalidate_documents() + return super(Followers, self).unlink() _sql_constraints = [ ('mail_followers_res_partner_res_model_id_uniq', 'unique(res_model,res_id,partner_id)', 'Error, a partner cannot follow twice the same object.'), diff --git a/addons/mail/models/mail_message.py b/addons/mail/models/mail_message.py index 025afc90b20..aa10557d583 100644 --- a/addons/mail/models/mail_message.py +++ b/addons/mail/models/mail_message.py @@ -853,6 +853,13 @@ class Message(models.Model): message_id = tools.generate_tracking_message_id('private') return message_id + @api.multi + def _invalidate_documents(self): + """ Invalidate the cache of the documents followed by ``self``. """ + for record in self: + if record.res_id: + self.env[record.model].invalidate_cache(ids=[record.res_id]) + @api.model def create(self, values): # coming from mail.js that does not have pid in its values @@ -869,6 +876,7 @@ class Message(models.Model): values['record_name'] = self._get_record_name(values) message = super(Message, self).create(values) + message._invalidate_documents() message._notify(force_send=self.env.context.get('mail_notify_force_send', True), user_signature=self.env.context.get('mail_notify_user_signature', True)) @@ -881,6 +889,14 @@ class Message(models.Model): self.check_access_rule('read') return super(Message, self).read(fields=fields, load=load) + @api.multi + def write(self, vals): + if 'model' in vals or 'res_id' in vals: + self._invalidate_documents() + res = super(Message, self).write(vals) + self._invalidate_documents() + return res + @api.multi def unlink(self): # cascade-delete attachments that are directly attached to the message (should only happen @@ -889,6 +905,7 @@ class Message(models.Model): self.mapped('attachment_ids').filtered( lambda attach: attach.res_model == self._name and (attach.res_id in self.ids or attach.res_id == 0) ).unlink() + self._invalidate_documents() return super(Message, self).unlink() #------------------------------------------------------ diff --git a/addons/mail/tests/test_mail_features.py b/addons/mail/tests/test_mail_features.py index 2766d0d7ced..82dc2e05363 100644 --- a/addons/mail/tests/test_mail_features.py +++ b/addons/mail/tests/test_mail_features.py @@ -25,6 +25,17 @@ class TestMailFeatures(TestMail): 'login': 'b4r+_#_R3wl$$', 'alias_name': 'b4r+_#_R3wl$$'}) self.assertEqual(user_barty.alias_name, 'b4r+_-_r3wl-', 'Disallowed chars should be replaced by hyphens') + def test_10_cache_invalidation(self): + """ Test that creating a mail-thread record does not invalidate the whole cache. """ + # make a new record in cache + record = self.env['res.partner'].new({'name': 'Brave New Partner'}) + self.assertTrue(record.name) + + # creating a mail-thread record should not invalidate the whole cache + self.env['res.partner'].create({'name': 'Actual Partner'}) + self.assertTrue(record.name) + + @mute_logger('openerp.addons.mail.models.mail_mail') def test_needaction(self): na_emp1_base = self.env['mail.message'].sudo(self.user_employee)._needaction_count(domain=[]) diff --git a/addons/mail/tests/test_mail_message.py b/addons/mail/tests/test_mail_message.py index edd0f0eae9a..5fcdb42beaa 100644 --- a/addons/mail/tests/test_mail_message.py +++ b/addons/mail/tests/test_mail_message.py @@ -251,3 +251,8 @@ class TestMailMessage(TestMail): msg.set_message_starred(False) self.assertFalse(msg.starred) self.assertTrue(msg_emp.starred) + + def test_60_cache_invalidation(self): + msg_cnt = len(self.group_pigs.message_ids) + self.group_pigs.message_post(body='Hi!', subject='test') + self.assertEqual(len(self.group_pigs.message_ids), msg_cnt + 1) diff --git a/addons/website/views/website_templates.xml b/addons/website/views/website_templates.xml index 84b83af4f5e..6a67acf7dc5 100644 --- a/addons/website/views/website_templates.xml +++ b/addons/website/views/website_templates.xml @@ -84,7 +84,7 @@