diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/mail/static/src/models/user/user.js | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/mail/static/src/models/user/user.js')
| -rw-r--r-- | addons/mail/static/src/models/user/user.js | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/addons/mail/static/src/models/user/user.js b/addons/mail/static/src/models/user/user.js new file mode 100644 index 00000000..721b586f --- /dev/null +++ b/addons/mail/static/src/models/user/user.js @@ -0,0 +1,254 @@ +odoo.define('mail/static/src/models/user/user.js', function (require) { +'use strict'; + +const { registerNewModel } = require('mail/static/src/model/model_core.js'); +const { attr, one2one } = require('mail/static/src/model/model_field.js'); + +function factory(dependencies) { + + class User extends dependencies['mail.model'] { + + /** + * @override + */ + _willDelete() { + if (this.env.messaging) { + if (this === this.env.messaging.currentUser) { + this.env.messaging.update({ currentUser: [['unlink']] }); + } + } + return super._willDelete(...arguments); + } + + //---------------------------------------------------------------------- + // Public + //---------------------------------------------------------------------- + + /** + * @static + * @param {Object} data + * @returns {Object} + */ + static convertData(data) { + const data2 = {}; + if ('id' in data) { + data2.id = data.id; + } + if ('partner_id' in data) { + if (!data.partner_id) { + data2.partner = [['unlink']]; + } else { + const partnerNameGet = data['partner_id']; + const partnerData = { + display_name: partnerNameGet[1], + id: partnerNameGet[0], + }; + data2.partner = [['insert', partnerData]]; + } + } + return data2; + } + + /** + * Performs the `read` RPC on `res.users`. + * + * @static + * @param {Object} param0 + * @param {Object} param0.context + * @param {string[]} param0.fields + * @param {integer[]} param0.ids + */ + static async performRpcRead({ context, fields, ids }) { + const usersData = await this.env.services.rpc({ + model: 'res.users', + method: 'read', + args: [ids], + kwargs: { + context, + fields, + }, + }, { shadow: true }); + return this.env.models['mail.user'].insert(usersData.map(userData => + this.env.models['mail.user'].convertData(userData) + )); + } + + /** + * Fetches the partner of this user. + */ + async fetchPartner() { + return this.env.models['mail.user'].performRpcRead({ + ids: [this.id], + fields: ['partner_id'], + context: { active_test: false }, + }); + } + + /** + * Gets the chat between this user and the current user. + * + * If a chat is not appropriate, a notification is displayed instead. + * + * @returns {mail.thread|undefined} + */ + async getChat() { + if (!this.partner) { + await this.async(() => this.fetchPartner()); + } + if (!this.partner) { + // This user has been deleted from the server or never existed: + // - Validity of id is not verified at insert. + // - There is no bus notification in case of user delete from + // another tab or by another user. + this.env.services['notification'].notify({ + message: this.env._t("You can only chat with existing users."), + type: 'warning', + }); + return; + } + // in other cases a chat would be valid, find it or try to create it + let chat = this.env.models['mail.thread'].find(thread => + thread.channel_type === 'chat' && + thread.correspondent === this.partner && + thread.model === 'mail.channel' && + thread.public === 'private' + ); + if (!chat ||!chat.isPinned) { + // if chat is not pinned then it has to be pinned client-side + // and server-side, which is a side effect of following rpc + chat = await this.async(() => + this.env.models['mail.thread'].performRpcCreateChat({ + partnerIds: [this.partner.id], + }) + ); + } + if (!chat) { + this.env.services['notification'].notify({ + message: this.env._t("An unexpected error occurred during the creation of the chat."), + type: 'warning', + }); + return; + } + return chat; + } + + /** + * Opens a chat between this user and the current user and returns it. + * + * If a chat is not appropriate, a notification is displayed instead. + * + * @param {Object} [options] forwarded to @see `mail.thread:open()` + * @returns {mail.thread|undefined} + */ + async openChat(options) { + const chat = await this.async(() => this.getChat()); + if (!chat) { + return; + } + await this.async(() => chat.open(options)); + return chat; + } + + /** + * Opens the most appropriate view that is a profile for this user. + * Because user is a rather technical model to allow login, it's the + * partner profile that contains the most useful information. + * + * @override + */ + async openProfile() { + if (!this.partner) { + await this.async(() => this.fetchPartner()); + } + if (!this.partner) { + // This user has been deleted from the server or never existed: + // - Validity of id is not verified at insert. + // - There is no bus notification in case of user delete from + // another tab or by another user. + this.env.services['notification'].notify({ + message: this.env._t("You can only open the profile of existing users."), + type: 'warning', + }); + return; + } + return this.partner.openProfile(); + } + + //---------------------------------------------------------------------- + // Private + //---------------------------------------------------------------------- + + /** + * @override + */ + static _createRecordLocalId(data) { + return `${this.modelName}_${data.id}`; + } + + /** + * @private + * @returns {string|undefined} + */ + _computeDisplayName() { + return this.display_name || this.partner && this.partner.display_name; + } + + /** + * @private + * @returns {string|undefined} + */ + _computeNameOrDisplayName() { + return this.partner && this.partner.nameOrDisplayName || this.display_name; + } + } + + User.fields = { + id: attr(), + /** + * Determines whether this user is an internal user. An internal user is + * a member of the group `base.group_user`. This is the inverse of the + * `share` field in python. + */ + isInternalUser: attr(), + display_name: attr({ + compute: '_computeDisplayName', + dependencies: [ + 'display_name', + 'partnerDisplayName', + ], + }), + model: attr({ + default: 'res.user', + }), + nameOrDisplayName: attr({ + compute: '_computeNameOrDisplayName', + dependencies: [ + 'display_name', + 'partnerNameOrDisplayName', + ] + }), + partner: one2one('mail.partner', { + inverse: 'user', + }), + /** + * Serves as compute dependency. + */ + partnerDisplayName: attr({ + related: 'partner.display_name', + }), + /** + * Serves as compute dependency. + */ + partnerNameOrDisplayName: attr({ + related: 'partner.nameOrDisplayName', + }), + }; + + User.modelName = 'mail.user'; + + return User; +} + +registerNewModel('mail.user', factory); + +}); |
