[IMP] mail, *: batch channels at init messaging
* = im_livechat, test_discuss_full Less code, less queries. Part of task-2622462
This commit is contained in:
@@ -35,13 +35,12 @@ class Partners(models.Model):
|
||||
return result
|
||||
|
||||
def _get_channels_as_member(self):
|
||||
values = super()._get_channels_as_member()
|
||||
livechat_channels = self.env['mail.channel'].search([
|
||||
channels = super()._get_channels_as_member()
|
||||
channels |= self.env['mail.channel'].search([
|
||||
('channel_type', '=', 'livechat'),
|
||||
('channel_last_seen_partner_ids', 'in', self.env['mail.channel.partner'].sudo()._search([
|
||||
('partner_id', '=', self.id),
|
||||
('is_pinned', '=', True),
|
||||
])),
|
||||
])
|
||||
values['channel_livechat'] = livechat_channels.channel_info()
|
||||
return values
|
||||
return channels
|
||||
|
||||
@@ -1,33 +1,9 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { registerInstancePatchModel } from '@mail/model/model_core';
|
||||
import { executeGracefully } from '@mail/utils/utils';
|
||||
import { insert } from '@mail/model/model_field_command';
|
||||
|
||||
registerInstancePatchModel('mail.messaging_initializer', 'im_livechat/static/src/models/messaging_initializer/messaging_initializer.js', {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Private
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @param {Object[]} [param0.channel_livechat=[]]
|
||||
*/
|
||||
async _initChannels(initMessagingData) {
|
||||
await this.async(() => this._super(initMessagingData));
|
||||
const { channel_livechat = [] } = initMessagingData;
|
||||
return executeGracefully(channel_livechat.map(data => () => {
|
||||
const channel = this.env.models['mail.thread'].insert(
|
||||
this.env.models['mail.thread'].convertData(data),
|
||||
);
|
||||
// flux specific: channels received at init have to be
|
||||
// considered pinned. task-2284357
|
||||
if (!channel.isPinned) {
|
||||
channel.pin();
|
||||
}
|
||||
}));
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
|
||||
@@ -249,9 +249,9 @@ MockServer.include({
|
||||
['is_pinned', '=', true],
|
||||
['members', 'in', partner.id],
|
||||
]);
|
||||
return {
|
||||
channel_livechat: this._mockMailChannelChannelInfo(livechats.map(channel => channel.id)),
|
||||
return [
|
||||
...this._super(ids),
|
||||
};
|
||||
...livechats,
|
||||
];
|
||||
},
|
||||
});
|
||||
|
||||
@@ -99,4 +99,4 @@ class TestGetMailChannel(TransactionCase):
|
||||
self.assertFalse(operator_channel_partner.is_pinned, "channel should not be pinned for operator initially")
|
||||
self.env['mail.channel'].browse(channel_info['id']).message_post(body='cc')
|
||||
self.assertTrue(operator_channel_partner.is_pinned, "channel should be pinned for operator after visitor sent a message")
|
||||
self.assertIn(channel_info['id'], [init_channel_info['id'] for init_channel_info in operator_channel_partner.partner_id._get_channels_as_member()['channel_livechat']], "channel should be fetched by operator on new page")
|
||||
self.assertIn(channel_info['id'], operator_channel_partner.partner_id._get_channels_as_member().ids, "channel should be fetched by operator on new page")
|
||||
|
||||
@@ -119,32 +119,23 @@ class Partner(models.Model):
|
||||
return messages._message_notification_format()
|
||||
|
||||
def _get_channels_as_member(self):
|
||||
""" Return the channels of the partner grouped by 'slot' (channel, direct_message or private_group), and
|
||||
the mapping between partner_id/channel_id for direct_message channels.
|
||||
:returns dict : the grouped channels and the mapping
|
||||
"""
|
||||
"""Returns the channels of the partner."""
|
||||
self.ensure_one()
|
||||
values = {}
|
||||
pinned_channels = self.env['mail.channel.partner'].search([('partner_id', '=', self.id), ('is_pinned', '=', True)]).mapped('channel_id')
|
||||
# get the group/public channels
|
||||
values['channel_channel'] = self.env['mail.channel'].search([
|
||||
channels = self.env['mail.channel']
|
||||
# get the channels
|
||||
channels |= self.env['mail.channel'].search([
|
||||
('channel_type', '=', 'channel'),
|
||||
('public', 'in', ['public', 'groups']),
|
||||
('channel_partner_ids', 'in', [self.id]),
|
||||
]).channel_info()
|
||||
# get the pinned 'direct message' channel
|
||||
direct_message_channels = self.env['mail.channel'].search([
|
||||
('channel_type', '=', 'chat'),
|
||||
('id', 'in', pinned_channels.ids),
|
||||
])
|
||||
values['channel_direct_message'] = direct_message_channels.channel_info()
|
||||
# get the private group
|
||||
values['channel_private_group'] = self.env['mail.channel'].search([
|
||||
('channel_type', '=', 'channel'),
|
||||
('public', '=', 'private'),
|
||||
('channel_partner_ids', 'in', [self.id]),
|
||||
]).channel_info()
|
||||
return values
|
||||
# get the pinned direct messages
|
||||
channels |= self.env['mail.channel'].search([
|
||||
('channel_type', '=', 'chat'),
|
||||
('channel_last_seen_partner_ids', 'in', self.env['mail.channel.partner'].sudo()._search([
|
||||
('partner_id', '=', self.id),
|
||||
('is_pinned', '=', True),
|
||||
])),
|
||||
])
|
||||
return channels
|
||||
|
||||
@api.model
|
||||
def search_for_channel_invite(self, search_term, channel_id=None, limit=30):
|
||||
|
||||
@@ -83,7 +83,7 @@ class Users(models.Model):
|
||||
def _init_messaging(self):
|
||||
self.ensure_one()
|
||||
values = {
|
||||
'channel_slots': self.partner_id._get_channels_as_member(),
|
||||
'channels': self.partner_id._get_channels_as_member().channel_info(),
|
||||
'current_partner': self.partner_id.mail_partner_format(),
|
||||
'current_user_id': self.id,
|
||||
'mail_failures': self.partner_id._message_fetch_failed(),
|
||||
|
||||
@@ -65,7 +65,7 @@ function factory(dependencies) {
|
||||
/**
|
||||
* @private
|
||||
* @param {Object} param0
|
||||
* @param {Object} param0.channel_slots
|
||||
* @param {Object[]} param0.channels
|
||||
* @param {Object} param0.current_partner
|
||||
* @param {integer} param0.current_user_id
|
||||
* @param {Object} [param0.mail_failures={}]
|
||||
@@ -76,7 +76,7 @@ function factory(dependencies) {
|
||||
* @param {integer} [param0.starred_counter=0]
|
||||
*/
|
||||
async _init({
|
||||
channel_slots,
|
||||
channels,
|
||||
commands = [],
|
||||
current_partner,
|
||||
current_user_id,
|
||||
@@ -106,7 +106,7 @@ function factory(dependencies) {
|
||||
this._initCannedResponses(shortcodes);
|
||||
this._initCommands();
|
||||
// channels when the rest of messaging is ready
|
||||
await this.async(() => this._initChannels(channel_slots));
|
||||
await this.async(() => this._initChannels(channels));
|
||||
// failures after channels
|
||||
this._initMailFailures(mail_failures);
|
||||
discuss.update({ menu_id });
|
||||
@@ -124,17 +124,9 @@ function factory(dependencies) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Object} [param0={}]
|
||||
* @param {Object[]} [param0.channel_channel=[]]
|
||||
* @param {Object[]} [param0.channel_direct_message=[]]
|
||||
* @param {Object[]} [param0.channel_private_group=[]]
|
||||
* @param {Object[]} channelsData
|
||||
*/
|
||||
async _initChannels({
|
||||
channel_channel = [],
|
||||
channel_direct_message = [],
|
||||
channel_private_group = [],
|
||||
} = {}) {
|
||||
const channelsData = channel_channel.concat(channel_direct_message, channel_private_group);
|
||||
async _initChannels(channelsData) {
|
||||
return executeGracefully(channelsData.map(channelData => () => {
|
||||
const convertedData = this.env.models['mail.thread'].convertData(channelData);
|
||||
if (!convertedData.members) {
|
||||
|
||||
@@ -1617,11 +1617,11 @@ MockServer.include({
|
||||
['members', 'in', partner.id],
|
||||
['public', '=', 'private'],
|
||||
]);
|
||||
return {
|
||||
channel_channel: this._mockMailChannelChannelInfo(channels.map(channel => channel.id)),
|
||||
channel_direct_message: this._mockMailChannelChannelInfo(directMessages.map(channel => channel.id)),
|
||||
channel_private_group: this._mockMailChannelChannelInfo(privateGroups.map(channel => channel.id)),
|
||||
};
|
||||
return [
|
||||
...channels,
|
||||
...privateGroups,
|
||||
...directMessages,
|
||||
];
|
||||
},
|
||||
/**
|
||||
* Simulates `get_mention_suggestions` on `res.partner`.
|
||||
@@ -1797,7 +1797,7 @@ MockServer.include({
|
||||
_mockResUsers_InitMessaging(ids) {
|
||||
const user = this._getRecords('res.users', [['id', 'in', ids]])[0];
|
||||
return {
|
||||
channel_slots: this._mockResPartner_GetChannelsAsMember(user.partner_id),
|
||||
channels: this._mockMailChannelChannelInfo(this._mockResPartner_GetChannelsAsMember(user.partner_id).map(channel => channel.id)),
|
||||
current_partner: this._mockResPartnerMailPartnerFormat(user.partner_id),
|
||||
current_user_id: this.currentUserId,
|
||||
mail_failures: this._mockResPartner_MessageFetchFailed(user.partner_id),
|
||||
|
||||
@@ -94,13 +94,13 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
|
||||
self.users[0].flush()
|
||||
self.users[0].invalidate_cache()
|
||||
with self.assertQueryCount(emp=69):
|
||||
with self.assertQueryCount(emp=42):
|
||||
init_messaging = self.users[0]._init_messaging()
|
||||
|
||||
self.assertEqual(init_messaging, {
|
||||
'needaction_inbox_counter': 1,
|
||||
'starred_counter': 1,
|
||||
'channel_slots': {'channel_channel': [
|
||||
'channels': [
|
||||
{
|
||||
'channel_type': 'channel',
|
||||
'create_uid': user_root.id,
|
||||
@@ -179,7 +179,6 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
'state': 'open',
|
||||
'uuid': channel_group_2.uuid,
|
||||
},
|
||||
], 'channel_private_group': [
|
||||
{
|
||||
'channel_type': 'channel',
|
||||
'create_uid': self.env.user.id,
|
||||
@@ -210,7 +209,6 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
'state': 'open',
|
||||
'uuid': channel_private_2.uuid,
|
||||
},
|
||||
], 'channel_direct_message': [
|
||||
{
|
||||
'channel_type': 'chat',
|
||||
'create_uid': self.env.user.id,
|
||||
@@ -391,7 +389,6 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
'state': 'open',
|
||||
'uuid': channel_dm_4.uuid,
|
||||
},
|
||||
], 'channel_livechat': [
|
||||
{
|
||||
'channel_type': 'livechat',
|
||||
'create_uid': self.env.user.id,
|
||||
@@ -410,7 +407,8 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
'email': 'e.e@example.com',
|
||||
'id': self.users[0].partner_id.id,
|
||||
'name': 'Ernest Employee',
|
||||
'out_of_office_date_end': False,
|
||||
'im_status': 'leave_offline',
|
||||
'out_of_office_date_end': self.leaves.filtered(lambda l: l.employee_id.user_id == self.users[0]).date_to,
|
||||
},
|
||||
{
|
||||
'email': 'test1@example.com',
|
||||
@@ -464,8 +462,9 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
{
|
||||
'email': 'e.e@example.com',
|
||||
'id': self.users[0].partner_id.id,
|
||||
'im_status': 'leave_offline',
|
||||
'name': 'Ernest Employee',
|
||||
'out_of_office_date_end': False,
|
||||
'out_of_office_date_end': self.leaves.filtered(lambda l: l.employee_id.user_id == self.users[0]).date_to,
|
||||
},
|
||||
],
|
||||
'message_needaction_counter': 0,
|
||||
@@ -490,7 +489,7 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
'state': 'open',
|
||||
'uuid': channel_livechat_2.uuid,
|
||||
},
|
||||
]},
|
||||
],
|
||||
'mail_failures': [],
|
||||
'shortcodes': [
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user