diff --git a/addons/hr_holidays/models/mail_channel.py b/addons/hr_holidays/models/mail_channel.py index b6d22625411..3d5992dd856 100644 --- a/addons/hr_holidays/models/mail_channel.py +++ b/addons/hr_holidays/models/mail_channel.py @@ -8,14 +8,10 @@ class Channel(models.Model): _inherit = 'mail.channel' @api.multi - def channel_info(self, extra_info=False): - channel_infos = super(Channel, self).channel_info(extra_info) - partners_on_leave = [] - for channel_info in channel_infos: - if 'direct_partner' in channel_info: - for direct_partner in channel_info['direct_partner']: - if 'leave' in direct_partner['im_status']: - partners_on_leave.append(direct_partner['id']) + def partner_info(self, all_partners, direct_partners): + partner_infos = super(Channel, self).partner_info(all_partners, direct_partners) + # only search for leave out_of_office_message if im_status is on leave + partners_on_leave = [partner_id for partner_id in direct_partners.ids if 'leave' in partner_infos[partner_id]['im_status']] if partners_on_leave: now = fields.Datetime.now() self.env.cr.execute('''SELECT res_users.partner_id as partner_id, hr_leave.out_of_office_message as out_of_office_message, hr_leave.date_to as date_to @@ -26,11 +22,8 @@ class Channel(models.Model): AND hr_leave.date_from <= %s AND hr_leave.date_to >= %s AND res_users.partner_id in %s''', (now, now, tuple(partners_on_leave))) - out_of_office_info = dict(((res['partner_id'], res) for res in self.env.cr.dictfetchall())) - for channel_info in channel_infos: - if 'direct_partner' in channel_info: - for direct_partner in channel_info['direct_partner']: - if 'leave' in direct_partner['im_status']: - direct_partner['out_of_office_date_end'] = out_of_office_info.get(direct_partner['id'], {}).get('date_to') - direct_partner['out_of_office_message'] = out_of_office_info.get(direct_partner['id'], {}).get('out_of_office_message') - return channel_infos + out_of_office_infos = dict(((res['partner_id'], res) for res in self.env.cr.dictfetchall())) + for partner_id, out_of_office_info in out_of_office_infos.items(): + partner_infos[partner_id]['out_of_office_date_end'] = out_of_office_info['date_to'] + partner_infos[partner_id]['out_of_office_message'] = out_of_office_info['out_of_office_message'] + return partner_infos diff --git a/addons/mail/models/mail_channel.py b/addons/mail/models/mail_channel.py index fe33a2da77a..3a83cd8f9bd 100644 --- a/addons/mail/models/mail_channel.py +++ b/addons/mail/models/mail_channel.py @@ -540,21 +540,47 @@ class Channel(models.Model): notifications.append([channel.uuid, dict(message_values)]) return notifications + @api.model + def partner_info(self, all_partners, direct_partners): + """ + Return the information needed by channel to display channel members + :param all_partners: list of res.parner(): + :param direct_partners: list of res.parner(): + :returns: a list of {'id', 'name', 'email'} for each partner and adds {im_status, out_of_office_message} for direct_partners. + :rtype : list(dict) + """ + partner_infos = {partner['id']: partner for partner in all_partners.sudo().read(['id', 'name', 'email'])} + # add im _status and out_of_office_message for direct_partners + direct_partners_im_status = {partner['id']: partner for partner in direct_partners.sudo().read(['im_status'])} + partner_infos.update(direct_partners_im_status) + for user in self.env['res.users'].search([('partner_id', 'in', direct_partners.ids), ('out_of_office_message', '!=', False)]): + partner_infos[user.partner_id.id]['out_of_office_message'] = user.out_of_office_message + return partner_infos + @api.multi - def channel_info(self, extra_info = False): + def channel_info(self, extra_info=False): """ Get the informations header for the current channels :returns a list of channels values :rtype : list(dict) """ + if not self: + return [] channel_infos = [] - # all relations partner_channel on those channels all_partner_channel = self.env['mail.channel.partner'].search([('channel_id', 'in', self.ids)]) # all partner infos on those channels - partner_infos = all_partner_channel.mapped('partner_id').read(['id', 'name', 'email']) + channel_dict = {channel.id: channel for channel in self} + all_partners = all_partner_channel.mapped('partner_id') + direct_channel_partners = all_partner_channel.filtered(lambda pc: channel_dict[pc.channel_id.id].channel_type == 'chat') + direct_partners = direct_channel_partners.mapped('partner_id') + partner_infos = self.partner_info(all_partners, direct_partners) + + # add last message preview (only used in mobile) + addPreview = self._context.get('isMobile', False) + if addPreview: + channel_previews = {channel_preview['id']: channel_preview for channel_preview in self.channel_fetch_preview()} - # for each channel, build the information header and include the logged partner information for channel in self: info = { 'id': channel.id, @@ -572,46 +598,39 @@ class Channel(models.Model): } if extra_info: info['info'] = extra_info - # add the partner for 'direct mesage' channel - if channel.channel_type == 'chat': - info['direct_partner'] = (channel.sudo() - .with_context(active_test=False) - .channel_partner_ids - .filtered(lambda p: p.id != self.env.user.partner_id.id) - .read(['id', 'name', 'im_status'])) - for direct_partner in info['direct_partner']: - users = self.env['res.partner'].browse(direct_partner['id']).user_ids - if users: - direct_partner['out_of_office_message'] = users[0].out_of_office_message # add last message preview (only used in mobile) - if self._context.get('isMobile', False): - last_message = channel.channel_fetch_preview() - if last_message: - info['last_message'] = last_message[0].get('last_message') + if addPreview: + if channel in channel_previews: + info['last_message'] = channel_previews[channel] # listeners of the channel channel_partners = all_partner_channel.filtered(lambda pc: channel.id == pc.channel_id.id) # find the channel partner state, if logged user - partner_channel = self.env['mail.channel.partner'] if self.env.user and self.env.user.partner_id: - partner_channel = channel_partners.filtered(lambda pc: pc.partner_id.id == self.env.user.partner_id.id) + # add the partner for 'direct mesage' channel + if channel.channel_type == 'chat': + # direct_partner should be removed from channel info since we can find it from members and channel_type + # we keep it know to avoid change tests and javascript + direct_partner = direct_channel_partners.filtered(lambda pc: pc.partner_id.id != self.env.user.partner_id.id) + info['direct_partner'] = [partner_infos[direct_partner[0].partner_id.id]] # add needaction and unread counter, since the user is logged info['message_needaction_counter'] = channel.message_needaction_counter info['message_unread_counter'] = channel.message_unread_counter - # add user session state, if available and if user is logged - if len(partner_channel.ids): - partner_channel = partner_channel[0] - info['state'] = partner_channel.fold_state or 'open' - info['is_minimized'] = partner_channel.is_minimized - info['seen_message_id'] = partner_channel.seen_message_id.id - info['custom_channel_name'] = partner_channel.custom_channel_name + # add user session state, if available and if user is logged + partner_channel = channel_partners.filtered(lambda pc: pc.partner_id.id == self.env.user.partner_id.id) + if partner_channel: + partner_channel = partner_channel[0] + info['state'] = partner_channel.fold_state or 'open' + info['is_minimized'] = partner_channel.is_minimized + info['seen_message_id'] = partner_channel.seen_message_id.id + info['custom_channel_name'] = partner_channel.custom_channel_name # add members infos partner_ids = channel_partners.mapped('partner_id').ids - info['members'] = [partner_info for partner_info in partner_infos if partner_info['id'] in partner_ids] + info['members'] = [partner_infos[partner] for partner in partner_ids] info['seen_partners_info'] = [{ 'partner_id': cp.partner_id.id, 'fetched_message_id': cp.fetched_message_id.id, @@ -929,6 +948,8 @@ class Channel(models.Model): @api.multi def channel_fetch_preview(self): """ Return the last message of the given channels """ + if not self: + return [] self._cr.execute(""" SELECT mail_channel_id AS id, MAX(mail_message_id) AS message_id FROM mail_message_mail_channel_rel