[REF] web, base, mail: move res.users.settings from mail to base

This commit moves and adapt the res.users.settings model from mail to base and
and allows to access and modify its content with web's user service.
This allows to access user settings without needing the mail module.

closes odoo/odoo#116005

Related: odoo/enterprise#38360
Signed-off-by: Michaël Mattiello (mcm) <mcm@odoo.com>
This commit is contained in:
Julien Carion (juca)
2023-06-22 15:40:43 +02:00
parent 23e0ac2a1a
commit 2a37a3d06f
10 changed files with 109 additions and 43 deletions
-12
View File
@@ -24,9 +24,6 @@ class Users(models.Model):
help="Policy on how to handle Chatter notifications:\n"
"- Handle by Emails: notifications are sent to your email address\n"
"- Handle in Odoo: notifications appear in your Odoo Inbox")
res_users_settings_ids = fields.One2many('res.users.settings', 'user_id')
# Provide a target for relateds that is not a x2Many field.
res_users_settings_id = fields.Many2one('res.users.settings', string="Settings", compute='_compute_res_users_settings_id', search='_search_res_users_settings_id')
_sql_constraints = [(
"notification_type",
@@ -62,15 +59,6 @@ class Users(models.Model):
else:
user.groups_id -= inbox_group
@api.depends('res_users_settings_ids')
def _compute_res_users_settings_id(self):
for user in self:
user.res_users_settings_id = user.res_users_settings_ids and user.res_users_settings_ids[0]
@api.model
def _search_res_users_settings_id(self, operator, operand):
return [('res_users_settings_ids', operator, operand)]
# ------------------------------------------------------------
# CRUD
# ------------------------------------------------------------
+6 -28
View File
@@ -5,11 +5,8 @@ from odoo import api, fields, models
class ResUsersSettings(models.Model):
_name = 'res.users.settings'
_description = 'User Settings'
_rec_name = 'user_id'
_inherit = 'res.users.settings'
user_id = fields.Many2one('res.users', string="User", required=True, readonly=True, ondelete='cascade')
is_discuss_sidebar_category_channel_open = fields.Boolean(string="Is discuss sidebar category channel open?", default=True)
is_discuss_sidebar_category_chat_open = fields.Boolean(string="Is discuss sidebar category chat open?", default=True)
@@ -19,37 +16,18 @@ class ResUsersSettings(models.Model):
voice_active_duration = fields.Integer(string="Duration of voice activity in ms", help="How long the audio broadcast will remain active after passing the volume threshold")
volume_settings_ids = fields.One2many('res.users.settings.volumes', 'user_setting_id', string="Volumes of other partners")
_sql_constraints = [
('unique_user_id', 'UNIQUE(user_id)', 'One user should only have one mail user settings.')
]
@api.model
def _find_or_create_for_user(self, user):
settings = user.sudo().res_users_settings_ids
if not settings:
settings = self.sudo().create({'user_id': user.id})
return settings
def _res_users_settings_format(self, fields_to_format=None):
self.ensure_one()
if not fields_to_format:
fields_to_format = [name for name, field in self._fields.items() if name == 'id' or not field.automatic]
res = self._read_format(fnames=fields_to_format)[0]
if 'user_id' in fields_to_format:
res['user_id'] = {'id': self.user_id.id}
def _format_settings(self, fields_to_format):
res = super()._format_settings(fields_to_format)
if 'volume_settings_ids' in fields_to_format:
volume_settings = self.volume_settings_ids._discuss_users_settings_volume_format()
res['volume_settings_ids'] = [('insert', volume_settings)]
return res
def set_res_users_settings(self, new_settings):
self.ensure_one()
changed_settings = {}
for setting in new_settings.keys():
if setting in self._fields and new_settings[setting] != self[setting]:
changed_settings[setting] = new_settings[setting]
self.write(changed_settings)
self.env['bus.bus']._sendone(self.user_id.partner_id, 'mail.record/insert', {'res.users.settings': self._res_users_settings_format([*changed_settings.keys(), 'id'])})
formated = super().set_res_users_settings(new_settings)
self.env['bus.bus']._sendone(self.user_id.partner_id, 'mail.record/insert', {'res.users.settings': formated})
return formated
def set_volume_setting(self, partner_id, volume, guest_id=None):
"""
-2
View File
@@ -59,8 +59,6 @@ access_mail_guest_user,mail.guest,model_mail_guest,base.group_user,1,0,0,0
access_mail_guest_system,mail.guest,model_mail_guest,base.group_system,1,1,1,1
access_mail_ice_server_all,mail.ice.server.all,model_mail_ice_server,,0,0,0,0
access_mail_ice_server_system,mail.ice.server.system,model_mail_ice_server,base.group_system,1,1,1,1
access_res_users_settings_all,res.users.settings,model_res_users_settings,,0,0,0,0
access_res_users_settings_user,res.users.settings,model_res_users_settings,base.group_user,1,1,1,1
access_res_users_settings_volumes_all,res.users.settings.volumes,model_res_users_settings_volumes,,0,0,0,0
access_res_users_settings_volumes_user,res.users.settings.volumes,model_res_users_settings_volumes,base.group_user,1,1,1,1
access_mail_template_reset,access.mail.template.reset,model_mail_template_reset,mail.group_mail_template_editor,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
59 access_mail_guest_system mail.guest model_mail_guest base.group_system 1 1 1 1
60 access_mail_ice_server_all mail.ice.server.all model_mail_ice_server 0 0 0 0
61 access_mail_ice_server_system mail.ice.server.system model_mail_ice_server base.group_system 1 1 1 1
access_res_users_settings_all res.users.settings model_res_users_settings 0 0 0 0
access_res_users_settings_user res.users.settings model_res_users_settings base.group_user 1 1 1 1
62 access_res_users_settings_volumes_all res.users.settings.volumes model_res_users_settings_volumes 0 0 0 0
63 access_res_users_settings_volumes_user res.users.settings.volumes model_res_users_settings_volumes base.group_user 1 1 1 1
64 access_mail_template_reset access.mail.template.reset model_mail_template_reset mail.group_mail_template_editor 1 1 1 1
+1
View File
@@ -95,6 +95,7 @@ class Http(models.AbstractModel):
"is_admin": user._is_admin() if session_uid else False,
"user_context": user_context,
"db": self.env.cr.dbname,
"user_settings": self.env['res.users.settings']._find_or_create_for_user(user)._res_users_settings_format(),
"server_version": version_info.get('server_version'),
"server_version_info": version_info.get('server_version_info'),
"support_url": "https://www.odoo.com/buy",
+17 -1
View File
@@ -33,6 +33,8 @@ export const userService = {
...session.user_context,
uid: session.uid,
};
let settings = session.user_settings;
delete session.user_settings;
return {
get context() {
return Object.assign({}, context);
@@ -49,7 +51,21 @@ export const userService = {
async checkAccessRight(model, operation) {
return accessRightCache.read(model, operation);
},
get settings() {
return settings;
},
async setUserSettings(key, value) {
settings = await env.services.orm.call(
"res.users.settings",
"set_res_users_settings",
[[this.settings.id]],
{
new_settings: {
[key]: value,
},
}
);
},
name: session.name,
userName: session.username,
isAdmin: session.is_admin,
@@ -61,3 +61,26 @@ export function computeAppsAndMenuItems(menuTree) {
});
return { apps, menuItems };
}
/**
* @param {Array} order
* Sorts the apps in the homescreen menu according to the given order as an array of xmlid strings
*/
export function reorderApps(apps, order) {
apps.sort((a, b) => {
const aIndex = order.indexOf(a.xmlid);
const bIndex = order.indexOf(b.xmlid);
if (aIndex === -1 && bIndex === -1) {
// if both items are not present, sort by original order
return apps.indexOf(a) - apps.indexOf(b);
}
// not found items always before found ones
if (aIndex === -1) {
return -1;
}
if (bIndex === -1) {
return 1;
}
return aIndex - bIndex; // sort by order array
});
}
+1
View File
@@ -43,6 +43,7 @@ from . import res_config
from . import res_currency
from . import res_company
from . import res_users
from . import res_users_settings
from . import res_users_deletion
from . import decimal_precision
+12
View File
@@ -326,6 +326,9 @@ class Users(models.Model):
help="External user with limited access, created only for the purpose of sharing data.")
companies_count = fields.Integer(compute='_compute_companies_count', string="Number of Companies")
tz_offset = fields.Char(compute='_compute_tz_offset', string='Timezone offset', invisible=True)
res_users_settings_ids = fields.One2many('res.users.settings', 'user_id')
# Provide a target for relateds that is not a x2Many field.
res_users_settings_id = fields.Many2one('res.users.settings', string="Settings", compute='_compute_res_users_settings_id', search='_search_res_users_settings_id')
# Special behavior for this field: res.company.search() will only return the companies
# available to the current user (should be the user's companies?), when the user_preference
@@ -459,6 +462,15 @@ class Users(models.Model):
user.rules_count = len(groups.rule_groups)
user.groups_count = len(groups)
@api.depends('res_users_settings_ids')
def _compute_res_users_settings_id(self):
for user in self:
user.res_users_settings_id = user.res_users_settings_ids and user.res_users_settings_ids[0]
@api.model
def _search_res_users_settings_id(self, operator, operand):
return [('res_users_settings_ids', operator, operand)]
@api.onchange('login')
def on_change_login(self):
if self.login and tools.single_email_re.match(self.login):
@@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
class ResUsersSettings(models.Model):
_name = 'res.users.settings'
_description = 'User Settings'
_rec_name = 'user_id'
user_id = fields.Many2one('res.users', string="User", required=True, readonly=True, ondelete='cascade')
_sql_constraints = [
('unique_user_id', 'UNIQUE(user_id)', 'One user should only have one user settings.')
]
@api.model
def _find_or_create_for_user(self, user):
settings = user.sudo().res_users_settings_ids
if not settings:
settings = self.sudo().create({'user_id': user.id})
return settings
def _res_users_settings_format(self, fields_to_format=None):
self.ensure_one()
if not fields_to_format:
fields_to_format = [name for name, field in self._fields.items() if name == 'id' or not field.automatic]
res = self._format_settings(fields_to_format)
return res
def _format_settings(self, fields_to_format):
res = self._read_format(fnames=fields_to_format)[0]
if 'user_id' in fields_to_format:
res = self._read_format(fnames=fields_to_format)[0]
res['user_id'] = {'id': self.user_id.id}
return res
def set_res_users_settings(self, new_settings):
self.ensure_one()
changed_settings = {}
for setting in new_settings.keys():
if setting in self._fields and new_settings[setting] != self[setting]:
changed_settings[setting] = new_settings[setting]
self.write(changed_settings)
formated = self._res_users_settings_format([*changed_settings.keys(), 'id'])
return formated
@@ -78,6 +78,8 @@
"access_res_users_apikeys_description_employee","API key wizard employees","model_res_users_apikeys_description","group_user",1,0,1,0
"access_res_users_apikeys_description_portal","API key wizard","model_res_users_apikeys_description","group_portal",1,0,1,0
"access_res_users_apikeys_show_employee","API key result employees","model_res_users_apikeys_show","group_user",1,0,1,0
access_res_users_settings_all,res.users.settings,model_res_users_settings,,0,0,0,0
access_res_users_settings_user,res.users.settings,model_res_users_settings,group_user,1,1,1,1
"access_ir_asset_group_system","ir_asset_group_system","model_ir_asset","group_system",1,1,1,1
"access_ir_actions_group_system","ir_actions_group_system","model_ir_actions_actions","group_system",1,1,1,1
"access_ir_actions_act_window_system","ir_actions_act_window_system","model_ir_actions_act_window","group_system",1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
78 access_res_users_apikeys_description_employee API key wizard employees model_res_users_apikeys_description group_user 1 0 1 0
79 access_res_users_apikeys_description_portal API key wizard model_res_users_apikeys_description group_portal 1 0 1 0
80 access_res_users_apikeys_show_employee API key result employees model_res_users_apikeys_show group_user 1 0 1 0
81 access_res_users_settings_all res.users.settings model_res_users_settings 0 0 0 0
82 access_res_users_settings_user res.users.settings model_res_users_settings group_user 1 1 1 1
83 access_ir_asset_group_system ir_asset_group_system model_ir_asset group_system 1 1 1 1
84 access_ir_actions_group_system ir_actions_group_system model_ir_actions_actions group_system 1 1 1 1
85 access_ir_actions_act_window_system ir_actions_act_window_system model_ir_actions_act_window group_system 1 1 1 1