[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:
@@ -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
|
||||
# ------------------------------------------------------------
|
||||
|
||||
@@ -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):
|
||||
"""
|
||||
|
||||
@@ -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
|
||||
|
||||
|
@@ -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",
|
||||
|
||||
@@ -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
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user