summaryrefslogtreecommitdiff
path: root/addons/mail/static/src/models/user
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/mail/static/src/models/user
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/mail/static/src/models/user')
-rw-r--r--addons/mail/static/src/models/user/user.js254
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);
+
+});