[MERGE] *: remove read access on ir.model.*

Remove read access on `ir.model`, `ir.model.fields`, `ir.model.fields.selection` and `ir.model.data` for employees.
To access such records, the code must use the helpers (`_get`, `ref`,...) instead of CRUD operations directly.

Simplify the helpers to ir.model.data that were public and redundant.
self.env.ref is encouraged instead but with the slight drawback that `ref` makes a call to `exists()` (`_xmlid_lookup` can be used if this wants to be avoided).

Part of task-id 8203

closes odoo/odoo#69120

Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
This commit is contained in:
Odoo's Mergebot
2021-08-10 21:12:46 +02:00
committed by GitHub
81 changed files with 199 additions and 295 deletions
+1 -1
View File
@@ -344,7 +344,7 @@ class AccountChartTemplate(models.Model):
:return (Model<account.account>): the most appropriate record found
"""
return (
self.env['account.account'].browse(self.env['ir.model.data'].search([
self.env['account.account'].browse(self.env['ir.model.data'].sudo().search([
('name', '=', '%d_%s' % (company.id, xml_id)),
('model', '=', 'account.account'),
('module', '=like', 'l10n%')
-9
View File
@@ -426,15 +426,6 @@ class AccountChartTemplate(models.Model):
"""
return [{'acc_name': _('Cash'), 'account_type': 'cash'}, {'acc_name': _('Bank'), 'account_type': 'bank'}]
def open_select_template_wizard(self):
# Add action to open wizard to select between several templates
if not self.company_id.chart_template_id:
todo = self.env['ir.actions.todo']
action_rec = self.env['ir.model.data'].xmlid_to_object('account.action_wizard_multi_chart')
if action_rec:
todo.create({'action_id': action_rec.id, 'name': _('Choose Accounting Template')})
return True
@api.model
def _prepare_transfer_account_for_direct_creation(self, name, company):
""" Prepare values to create a transfer account directly, based on the
+1 -1
View File
@@ -61,7 +61,7 @@ class TestTransferWizard(AccountTestInvoicingCommon):
cls.test_currency_account = cls.env['account.account'].create({
'name': 'test destination account',
'code': 'test_dest_acc',
'user_type_id': cls.env['ir.model.data'].xmlid_to_res_id('account.data_account_type_current_assets'),
'user_type_id': cls.env['ir.model.data']._xmlid_to_res_id('account.data_account_type_current_assets'),
'currency_id': cls.test_currency_3.id,
})
+3
View File
@@ -40,11 +40,14 @@ class BaseSetup(http.Controller):
LIMIT 10
""")
pending_users = cr.fetchall()
action_pending_users = request.env['res.users'].browse(
[uid for (uid, login) in pending_users])._action_show()
return {
'active_users': active_count,
'pending_count': pending_count,
'pending_users': pending_users,
'action_pending_users': action_pending_users,
}
@http.route('/base_setup/demo_active', type='json', auth='user')
@@ -41,6 +41,7 @@ odoo.define('base_setup.ResConfigInviteUsers', function (require) {
}).then(function (data) {
self.active_users = data.active_users;
self.pending_users = data.pending_users;
self.action_pending_users = data.action_pending_users;
self.pending_count = data.pending_count;
self.resend_invitation = data.resend_invitation || false;
});
@@ -141,49 +142,19 @@ odoo.define('base_setup.ResConfigInviteUsers', function (require) {
* @param {MouseEvent} ev
*/
_onClickMore: function (ev) {
var self = this;
ev.preventDefault();
this._rpc({
model: 'ir.model.data',
method: 'xmlid_to_res_model_res_id',
args: ["base.view_users_form"],
})
.then(function (data) {
self.do_action({
name: _t('Users'),
type: 'ir.actions.act_window',
view_mode: 'tree,form',
res_model: 'res.users',
domain: [['log_ids', '=', false]],
context: {
search_default_no_share: true,
},
views: [[false, 'list'], [data[1], 'form']],
});
});
this.do_action(this.action_pending_users);
},
/**
* @private
* @param {MouseEvent} ev
*/
_onClickUser: function (ev) {
var self = this;
ev.preventDefault();
var user_id = $(ev.currentTarget).data('user-id');
this._rpc({
model: 'ir.model.data',
method: 'xmlid_to_res_model_res_id',
args: ["base.view_users_form"],
})
.then(function (data) {
self.do_action({
type: 'ir.actions.act_window',
res_model: 'res.users',
view_mode: 'form',
res_id: user_id,
views: [[data[1], 'form']],
});
});
var action = Object.assign({}, this.action_pending_users, {res_id: user_id});
this.do_action(action);
},
/**
* @private
+1 -1
View File
@@ -44,7 +44,7 @@ class Alarm(models.Model):
def _compute_mail_template_id(self):
for alarm in self:
if alarm.alarm_type == 'email' and not alarm.mail_template_id:
alarm.mail_template_id = self.env['ir.model.data'].xmlid_to_res_id('calendar.calendar_template_meeting_reminder')
alarm.mail_template_id = self.env['ir.model.data']._xmlid_to_res_id('calendar.calendar_template_meeting_reminder')
elif alarm.alarm_type != 'email' or not alarm.mail_template_id:
alarm.mail_template_id = False
+2 -2
View File
@@ -195,7 +195,7 @@ class TestCalendar(SavepointCaseWithUserDemo):
activity_id = self.env['mail.activity'].create({
'summary': 'Meeting with partner',
'activity_type_id': activty_type.id,
'res_model_id': self.env['ir.model'].search([('model', '=', 'res.partner')], limit=1).id,
'res_model_id': self.env['ir.model']._get_id('res.partner'),
'res_id': self.env['res.partner'].create({'name': 'A Partner'}).id,
})
@@ -228,7 +228,7 @@ class TestCalendar(SavepointCaseWithUserDemo):
activity_id = self.env['mail.activity'].create({
'summary': 'Meeting with partner',
'activity_type_id': activty_type.id,
'res_model_id': self.env['ir.model'].search([('model', '=', 'res.partner')], limit=1).id,
'res_model_id': self.env['ir.model']._get_id('res.partner'),
'res_id': self.env['res.partner'].create({'name': 'A Partner'}).id,
})
@@ -48,7 +48,7 @@ class TestMailActivityMixin(MailCommon):
meeting.calendar_event_id = calendar_event
return meeting
group_partner_manager = self.env['ir.model.data'].xmlid_to_res_id('base.group_partner_manager')
group_partner_manager = self.env['ir.model.data']._xmlid_to_res_id('base.group_partner_manager')
self.user_employee.write({
'tz': self.user_admin.tz,
'groups_id': [Command.link(group_partner_manager)]
+1 -1
View File
@@ -20,6 +20,6 @@ class CalendarAlarm(models.Model):
def _compute_sms_template_id(self):
for alarm in self:
if alarm.alarm_type == 'sms' and not alarm.sms_template_id:
alarm.sms_template_id = self.env['ir.model.data'].xmlid_to_res_id('calendar_sms.sms_template_data_calendar_reminder')
alarm.sms_template_id = self.env['ir.model.data']._xmlid_to_res_id('calendar_sms.sms_template_data_calendar_reminder')
elif alarm.alarm_type != 'sms' or not alarm.sms_template_id:
alarm.sms_template_id = False
+1 -1
View File
@@ -1244,7 +1244,7 @@ class Lead(models.Model):
for lead in self:
title = "%s : %s\n" % (_('Merged opportunity') if lead.type == 'opportunity' else _('Merged lead'), lead.name)
body = [title]
_fields = self.env['ir.model.fields'].search([
_fields = self.env['ir.model.fields'].sudo().search([
('name', 'in', self._merge_get_fields()),
('model_id.model', '=', lead._name),
])
+2 -2
View File
@@ -80,12 +80,12 @@ class TestEventCommon(common.TransactionCase):
(0, 0, { # right at subscription
'interval_unit': 'now',
'interval_type': 'after_sub',
'template_ref': 'mail.template,%i' % cls.env['ir.model.data'].xmlid_to_res_id('event.event_subscription')}),
'template_ref': 'mail.template,%i' % cls.env['ir.model.data']._xmlid_to_res_id('event.event_subscription')}),
(0, 0, { # 1 days before event
'interval_nbr': 1,
'interval_unit': 'days',
'interval_type': 'before_event',
'template_ref': 'mail.template,%i' % cls.env['ir.model.data'].xmlid_to_res_id('event.event_reminder')}),
'template_ref': 'mail.template,%i' % cls.env['ir.model.data']._xmlid_to_res_id('event.event_reminder')}),
],
})
cls.event_0 = cls.env['event.event'].create({
+3 -3
View File
@@ -104,7 +104,7 @@ class TestEventData(TestEventCommon):
event_type.write({
'event_type_mail_ids': [(5, 0), (0, 0, {
'interval_nbr': 1, 'interval_unit': 'days', 'interval_type': 'before_event',
'template_ref': 'mail.template,%i' % self.env['ir.model.data'].xmlid_to_res_id('event.event_reminder')})
'template_ref': 'mail.template,%i' % self.env['ir.model.data']._xmlid_to_res_id('event.event_reminder')})
],
'event_type_ticket_ids': [(5, 0), (0, 0, {'name': 'TestRegistration'})],
})
@@ -162,7 +162,7 @@ class TestEventData(TestEventCommon):
'interval_nbr': 77,
'interval_unit': 'days',
'interval_type': 'after_event',
'template_ref': 'mail.template,%i' % self.env['ir.model.data'].xmlid_to_res_id('event.event_reminder'),
'template_ref': 'mail.template,%i' % self.env['ir.model.data']._xmlid_to_res_id('event.event_reminder'),
})
]
})
@@ -179,7 +179,7 @@ class TestEventData(TestEventCommon):
'notification_type': 'mail',
'interval_unit': 'now',
'interval_type': 'after_sub',
'template_ref': 'mail.template,%i' % self.env['ir.model.data'].xmlid_to_res_id('event.event_subscription'),
'template_ref': 'mail.template,%i' % self.env['ir.model.data']._xmlid_to_res_id('event.event_subscription'),
})
]
})
@@ -39,22 +39,22 @@ class TestMailSchedule(TestEventCommon, MockEmail):
(0, 0, { # right at subscription
'interval_unit': 'now',
'interval_type': 'after_sub',
'template_ref': 'mail.template,%i' % self.env['ir.model.data'].xmlid_to_res_id('event.event_subscription')}),
'template_ref': 'mail.template,%i' % self.env['ir.model.data']._xmlid_to_res_id('event.event_subscription')}),
(0, 0, { # one day after subscription
'interval_nbr': 1,
'interval_unit': 'hours',
'interval_type': 'after_sub',
'template_ref': 'mail.template,%i' % self.env['ir.model.data'].xmlid_to_res_id('event.event_subscription')}),
'template_ref': 'mail.template,%i' % self.env['ir.model.data']._xmlid_to_res_id('event.event_subscription')}),
(0, 0, { # 1 days before event
'interval_nbr': 1,
'interval_unit': 'days',
'interval_type': 'before_event',
'template_ref': 'mail.template,%i' % self.env['ir.model.data'].xmlid_to_res_id('event.event_reminder')}),
'template_ref': 'mail.template,%i' % self.env['ir.model.data']._xmlid_to_res_id('event.event_reminder')}),
(0, 0, { # immediately after event
'interval_nbr': 1,
'interval_unit': 'hours',
'interval_type': 'after_event',
'template_ref': 'mail.template,%i' % self.env['ir.model.data'].xmlid_to_res_id('event.event_reminder')}),
'template_ref': 'mail.template,%i' % self.env['ir.model.data']._xmlid_to_res_id('event.event_reminder')}),
]
})
self.assertEqual(test_event.create_date, now)
+3 -3
View File
@@ -54,7 +54,7 @@ class GoogleDrive(models.Model):
user_is_admin = self.env.is_admin()
if not google_drive_refresh_token:
if user_is_admin:
dummy, action_id = self.env['ir.model.data'].get_object_reference('base_setup', 'action_general_configuration')
action_id = self.env['ir.model.data']._xmlid_lookup('base_setup.action_general_configuration')[2]
msg = _("There is no refresh code set for Google Drive. You can set it up from the configuration panel.")
raise RedirectWarning(msg, action_id, _('Go to the configuration panel'))
else:
@@ -75,7 +75,7 @@ class GoogleDrive(models.Model):
req.raise_for_status()
except requests.HTTPError:
if user_is_admin:
dummy, action_id = self.env['ir.model.data'].get_object_reference('base_setup', 'action_general_configuration')
action_id = self.env['ir.model.data']._xmlid_lookup('base_setup.action_general_configuration')[2]
msg = _("Something went wrong during the token generation. Please request again an authorization code .")
raise RedirectWarning(msg, action_id, _('Go to the configuration panel'))
else:
@@ -154,7 +154,7 @@ class GoogleDrive(models.Model):
'''
# TO DO in master: fix my signature and my model
if isinstance(res_model, str):
res_model = self.env['ir.model'].search([('model', '=', res_model)]).id
res_model = self.env['ir.model'].sudo().search([('model', '=', res_model)]).id
if not res_id:
raise UserError(_("Creating google drive may only be done by one at a time."))
# check if a model is configured with a template
@@ -91,11 +91,7 @@ class GoogleDrive(models.Model):
@api.model
def set_spreadsheet(self, model, domain, groupbys, view_id):
try:
config_id = self.env['ir.model.data'].get_object_reference('google_spreadsheet', 'google_spreadsheet_template')[1]
except ValueError:
raise
config = self.browse(config_id)
config = self.env.ref('google_spreadsheet.google_spreadsheet_template')
title = 'Spreadsheet %s' % model
res = self.copy_doc(False, config.google_drive_resource_id, title, model)
+1 -1
View File
@@ -432,7 +432,7 @@ Or send your receipts at <a href="mailto:%(email)s?subject=Lunch%%20with%%20cust
return res
def action_approve_duplicates(self):
root = self.env['ir.model.data'].xmlid_to_res_id("base.partner_root")
root = self.env['ir.model.data']._xmlid_to_res_id("base.partner_root")
for expense in self.duplicate_expense_ids:
expense.message_post(
body=_('%(user)s confirms this expense is not a duplicate with similar expense.', user=self.env.user.name),
@@ -401,7 +401,7 @@ class Applicant(models.Model):
if 'stage_id' in changes and applicant.stage_id.template_id:
res['stage_id'] = (applicant.stage_id.template_id, {
'auto_delete_message': True,
'subtype_id': self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note'),
'subtype_id': self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note'),
'email_layout_xmlid': 'mail.mail_notification_light'
})
return res
@@ -47,6 +47,6 @@ class ApplicantGetRefuseReason(models.TransientModel):
applicants = self.applicant_ids.filtered(lambda x: x.email_from or x.partner_id.email)
applicants.message_post_with_template(self.template_id.id, **{
'auto_delete_message': True,
'subtype_id': self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note'),
'subtype_id': self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note'),
'email_layout_xmlid': 'mail.mail_notification_light'
})
+2 -2
View File
@@ -53,7 +53,7 @@ class Company(models.Model):
if tax_amount and domestic_tax not in fpos.tax_ids.tax_src_id:
if not foreign_taxes.get(tax_amount, False):
tax_group_fid = 'oss_tax_group_%s' % str(tax_amount).replace('.', '_')
if not self.env['ir.model.data'].xmlid_to_object('l10n_eu_service.%s' % tax_group_fid):
if not self.env.ref('l10n_eu_service.%s' % tax_group_fid, raise_if_not_found=False):
self.env['ir.model.data'].create({
'name': tax_group_fid,
'module': 'l10n_eu_service',
@@ -90,7 +90,7 @@ class Company(models.Model):
def _get_oss_account(self):
self.ensure_one()
if not self.env['ir.model.data'].xmlid_to_object('l10n_eu_service.oss_tax_account_company_%s' % self.id):
if not self.env.ref('l10n_eu_service.oss_tax_account_company_%s' % self.id, raise_if_not_found=False):
sales_tax_accounts = self.env['account.tax'].search([
('type_tax_use', '=', 'sale'),
('company_id', '=', self.id)
+1
View File
@@ -94,6 +94,7 @@ class LunchController(http.Controller):
'userimage': '/web/image?model=res.users&id=%s&field=avatar_128' % user.id,
'wallet': request.env['lunch.cashmove'].get_wallet_balance(user, False),
'is_manager': is_manager,
'group_portal_id': request.env.ref('base.group_portal').id,
'locations': request.env['lunch.location'].search_read([], ['name']),
'currency': {'symbol': currency.symbol, 'position': currency.position},
})
+7 -17
View File
@@ -34,13 +34,12 @@ var LunchWidget = Widget.extend({
this._super.apply(this, arguments);
this.is_manager = params.is_manager || false;
this.group_portal_id = params.group_portal_id || false;
this.userimage = params.userimage || '';
this.username = params.username || '';
this.lunchUserField = null;
this.group_portal_id = undefined;
this.locations = params.locations || [];
this.userLocation = params.user_location[1] || '';
@@ -57,23 +56,14 @@ var LunchWidget = Widget.extend({
this.currency = params.currency || session.get_currency(session.company_currency_id);
},
willStart: function () {
var self = this;
var superDef = this._super.apply(this, arguments);
var def = this._rpc({
model: 'ir.model.data',
method: 'xmlid_to_res_id',
kwargs: {xmlid: 'base.group_portal'},
}).then(function (id) {
self.group_portal_id = id;
if (self.is_manager) {
self.lunchUserField = self._createMany2One('users', 'res.users', self.username, function () {
return [['groups_id', 'not in', [self.group_portal_id]]];
});
}
});
return Promise.all([superDef, def]);
if (this.is_manager) {
this.lunchUserField = this._createMany2One('users', 'res.users', this.username,
() => [['groups_id', 'not in', [this.group_portal_id]]]
);
}
return superDef;
},
renderElement: function () {
this._super.apply(this, arguments);
@@ -37,12 +37,6 @@ QUnit.module('LunchKanbanView Mobile', {
fields: {},
records: [],
},
'ir.model.data': {
fields: {},
xmlid_to_res_id() {
return Promise.resolve(PORTAL_GROUP_ID);
},
},
'lunch.location': {
fields: {
name: {string: 'Name', type: 'char'},
@@ -37,12 +37,6 @@ QUnit.module('LunchKanbanView', {
fields: {},
records: [],
},
'ir.model.data': {
fields: {},
xmlid_to_res_id() {
return Promise.resolve(PORTAL_GROUP_ID);
},
},
'lunch.location': {
fields: {
name: {string: 'Name', type: 'char'},
@@ -68,6 +62,7 @@ QUnit.module('LunchKanbanView', {
username: "Marc Demo",
wallet: 36.5,
is_manager: false,
group_portal_id: PORTAL_GROUP_ID,
currency: {
symbol: "\u20ac",
position: "after"
@@ -78,6 +73,7 @@ QUnit.module('LunchKanbanView', {
username: "Mitchell Admin",
wallet: 47.6,
is_manager: true,
group_portal_id: PORTAL_GROUP_ID,
currency: {
symbol: "\u20ac",
position: "after"
@@ -212,7 +208,7 @@ QUnit.module('LunchKanbanView', {
});
QUnit.test('search panel domain location', async function (assert) {
assert.expect(20);
assert.expect(18);
let expectedLocation = 1;
let locationId = this.data['lunch.location'].records[0].id;
const regularInfos = _.extend({}, this.regularInfos);
@@ -266,7 +262,6 @@ QUnit.module('LunchKanbanView', {
'/web/dataset/call_kw/product/search_panel_select_multi_range',
'/web/dataset/search_read',
'/lunch/infos',
'/web/dataset/call_kw/ir.model.data/xmlid_to_res_id',
// Click m2o
'/web/dataset/call_kw/lunch.location/name_search',
// Click new location
@@ -275,14 +270,13 @@ QUnit.module('LunchKanbanView', {
'/web/dataset/call_kw/product/search_panel_select_multi_range',
'/web/dataset/search_read',
'/lunch/infos',
'/web/dataset/call_kw/ir.model.data/xmlid_to_res_id',
]);
kanban.destroy();
});
QUnit.test('search panel domain location false: fetch products in all locations', async function (assert) {
assert.expect(10);
assert.expect(9);
const regularInfos = _.extend({}, this.regularInfos);
const kanban = await createLunchView({
@@ -324,7 +318,6 @@ QUnit.module('LunchKanbanView', {
'/web/dataset/call_kw/product/search_panel_select_multi_range',
'/web/dataset/search_read',
'/lunch/infos',
'/web/dataset/call_kw/ir.model.data/xmlid_to_res_id',
])
kanban.destroy();
+3 -11
View File
@@ -37,12 +37,6 @@ QUnit.module('LunchListView', {
fields: {},
records: [],
},
'ir.model.data': {
fields: {},
xmlid_to_res_id() {
return Promise.resolve(PORTAL_GROUP_ID);
},
},
'lunch.location': {
fields: {
name: {string: 'Name', type: 'char'},
@@ -68,6 +62,7 @@ QUnit.module('LunchListView', {
username: "Marc Demo",
wallet: 36.5,
is_manager: false,
group_portal_id: PORTAL_GROUP_ID,
currency: {
symbol: "\u20ac",
position: "after"
@@ -120,7 +115,7 @@ QUnit.module('LunchListView', {
QUnit.module('LunchWidget', function () {
QUnit.test('search panel domain location', async function (assert) {
assert.expect(20);
assert.expect(18);
let expectedLocation = 1;
let locationId = this.data['lunch.location'].records[0].id;
const regularInfos = _.extend({}, this.regularInfos);
@@ -170,7 +165,6 @@ QUnit.module('LunchListView', {
'/web/dataset/call_kw/product/search_panel_select_multi_range',
'/web/dataset/search_read',
'/lunch/infos',
'/web/dataset/call_kw/ir.model.data/xmlid_to_res_id',
// Click m2o
'/web/dataset/call_kw/lunch.location/name_search',
// Click new location
@@ -179,14 +173,13 @@ QUnit.module('LunchListView', {
'/web/dataset/call_kw/product/search_panel_select_multi_range',
'/web/dataset/search_read',
'/lunch/infos',
'/web/dataset/call_kw/ir.model.data/xmlid_to_res_id',
]);
list.destroy();
});
QUnit.test('search panel domain location false: fetch products in all locations', async function (assert) {
assert.expect(10);
assert.expect(9);
const regularInfos = _.extend({}, this.regularInfos);
const list = await createLunchView({
@@ -224,7 +217,6 @@ QUnit.module('LunchListView', {
'/web/dataset/call_kw/product/search_panel_select_multi_range',
'/web/dataset/search_read',
'/lunch/infos',
'/web/dataset/call_kw/ir.model.data/xmlid_to_res_id',
])
list.destroy();
+1 -1
View File
@@ -262,7 +262,7 @@ class MailController(http.Controller):
'mail_failures': request.env['mail.message'].message_fetch_failed(),
'commands': request.env['mail.channel'].get_mention_commands(),
'shortcodes': request.env['mail.shortcode'].sudo().search_read([], ['source', 'substitution', 'description']),
'menu_id': request.env['ir.model.data'].xmlid_to_res_id('mail.menu_root_discuss'),
'menu_id': request.env['ir.model.data']._xmlid_to_res_id('mail.menu_root_discuss'),
'partner_root': request.env.ref('base.partner_root').sudo().mail_partner_format(),
'public_partners': [partner.mail_partner_format() for partner in request.env.ref('base.group_public').sudo().with_context(active_test=False).users.partner_id],
'current_partner': request.env.user.partner_id.mail_partner_format(),
+7 -6
View File
@@ -675,7 +675,7 @@ class MailActivity(models.Model):
'feedback': feedback,
'display_assignee': activity.user_id != self.env.user
},
subtype_id=self.env['ir.model.data'].xmlid_to_res_id('mail.mt_activities'),
subtype_id=self.env['ir.model.data']._xmlid_to_res_id('mail.mt_activities'),
mail_activity_type_id=activity.activity_type_id.id,
attachment_ids=[Command.link(attachment_id) for attachment_id in attachment_ids] if attachment_ids else [],
)
@@ -740,7 +740,8 @@ class MailActivity(models.Model):
'o_closest_deadline': group['date_deadline'],
}
activity_type_infos = []
activity_type_ids = self.env['mail.activity.type'].search(['|', ('res_model_id.model', '=', res_model), ('res_model_id', '=', False)])
activity_type_ids = self.env['mail.activity.type'].sudo().search(
['|', ('res_model_id.model', '=', res_model), ('res_model_id', '=', False)])
for elem in sorted(activity_type_ids, key=lambda item: item.sequence):
mail_template_info = []
for mail_template_id in elem.mail_template_ids:
@@ -1102,7 +1103,7 @@ class MailActivityMixin(models.AbstractModel):
return False
Data = self.env['ir.model.data'].sudo()
activity_types_ids = [type_id for type_id in (Data.xmlid_to_res_id(xmlid, raise_if_not_found=False) for xmlid in act_type_xmlids) if type_id]
activity_types_ids = [type_id for type_id in (Data._xmlid_to_res_id(xmlid, raise_if_not_found=False) for xmlid in act_type_xmlids) if type_id]
if not any(activity_types_ids):
return False
@@ -1200,7 +1201,7 @@ class MailActivityMixin(models.AbstractModel):
return False
Data = self.env['ir.model.data'].sudo()
activity_types_ids = [Data.xmlid_to_res_id(xmlid, raise_if_not_found=False) for xmlid in act_type_xmlids]
activity_types_ids = [Data._xmlid_to_res_id(xmlid, raise_if_not_found=False) for xmlid in act_type_xmlids]
activity_types_ids = [act_type_id for act_type_id in activity_types_ids if act_type_id]
if not any(activity_types_ids):
return False
@@ -1221,7 +1222,7 @@ class MailActivityMixin(models.AbstractModel):
return False
Data = self.env['ir.model.data'].sudo()
activity_types_ids = [Data.xmlid_to_res_id(xmlid, raise_if_not_found=False) for xmlid in act_type_xmlids]
activity_types_ids = [Data._xmlid_to_res_id(xmlid, raise_if_not_found=False) for xmlid in act_type_xmlids]
activity_types_ids = [act_type_id for act_type_id in activity_types_ids if act_type_id]
if not any(activity_types_ids):
return False
@@ -1237,7 +1238,7 @@ class MailActivityMixin(models.AbstractModel):
return False
Data = self.env['ir.model.data'].sudo()
activity_types_ids = [Data.xmlid_to_res_id(xmlid, raise_if_not_found=False) for xmlid in act_type_xmlids]
activity_types_ids = [Data._xmlid_to_res_id(xmlid, raise_if_not_found=False) for xmlid in act_type_xmlids]
activity_types_ids = [act_type_id for act_type_id in activity_types_ids if act_type_id]
if not any(activity_types_ids):
return False
+2 -2
View File
@@ -863,8 +863,8 @@ class Message(models.Model):
"""
vals_list = self._message_format(self._get_message_format_fields())
com_id = self.env['ir.model.data'].xmlid_to_res_id('mail.mt_comment')
note_id = self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note')
com_id = self.env['ir.model.data']._xmlid_to_res_id('mail.mt_comment')
note_id = self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note')
for vals in vals_list:
message_sudo = self.browse(vals['id']).sudo().with_prefetch(self.ids)
+17 -15
View File
@@ -469,7 +469,7 @@ class MailThread(models.AbstractModel):
"""
self.ensure_one()
# get the subtype of the comment Message
subtype_comment = self.env['ir.model.data'].xmlid_to_res_id('mail.mt_comment')
subtype_comment = self.env['ir.model.data']._xmlid_to_res_id('mail.mt_comment')
# get the ids of the comment and not-comment of the thread
# TDE check: sudo on mail.message, to be sure all messages are moved ?
@@ -924,20 +924,22 @@ class MailThread(models.AbstractModel):
# if destination = alias with different model -> consider it is a forward and not a reply
# if destination = alias with same model -> check contact settings as they still apply
if reply_model and reply_thread_id:
reply_model_id = self.env['ir.model']._get_id(reply_model)
other_model_aliases = self.env['mail.alias'].search([
'&', '&',
('alias_name', '!=', False),
('alias_name', 'in', email_to_localparts),
('alias_model_id.model', '!=', reply_model),
('alias_model_id', '!=', reply_model_id),
])
if other_model_aliases:
is_a_reply = False
rcpt_tos_valid_localparts = [to for to in rcpt_tos_valid_localparts if to in other_model_aliases.mapped('alias_name')]
if is_a_reply:
reply_model_id = self.env['ir.model']._get_id(reply_model)
dest_aliases = self.env['mail.alias'].search([
('alias_name', 'in', rcpt_tos_localparts),
('alias_model_id.model', '=', reply_model)
('alias_model_id', '=', reply_model_id)
], limit=1)
user_id = self._mail_find_user_for_gateway(email_from, alias=dest_aliases).id or self._uid
@@ -972,7 +974,7 @@ class MailThread(models.AbstractModel):
routes = []
for alias in dest_aliases:
user_id = self._mail_find_user_for_gateway(email_from, alias=alias).id or self._uid
route = (alias.alias_model_id.model, alias.alias_force_thread_id, ast.literal_eval(alias.alias_defaults), user_id, alias)
route = (alias.sudo().alias_model_id.model, alias.alias_force_thread_id, ast.literal_eval(alias.alias_defaults), user_id, alias)
route = self._routing_check_route(message, message_dict, route, raise_exception=True)
if route:
_logger.info(
@@ -1040,11 +1042,11 @@ class MailThread(models.AbstractModel):
partner_ids = []
if not subtype_id:
if message_dict.get('is_internal'):
subtype_id = self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note')
subtype_id = self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note')
if parent_message and parent_message.author_id:
partner_ids = [parent_message.author_id.id]
else:
subtype_id = self.env['ir.model.data'].xmlid_to_res_id('mail.mt_comment')
subtype_id = self.env['ir.model.data']._xmlid_to_res_id('mail.mt_comment')
post_params = dict(subtype_id=subtype_id, partner_ids=partner_ids, **message_dict)
# remove computational values not stored on mail.message and avoid warnings when creating it
@@ -1055,7 +1057,7 @@ class MailThread(models.AbstractModel):
new_msg = thread.message_notify(**post_params)
else:
# parsing should find an author independently of user running mail gateway, and ensure it is not odoobot
partner_from_found = message_dict.get('author_id') and message_dict['author_id'] != self.env['ir.model.data'].xmlid_to_res_id('base.partner_root')
partner_from_found = message_dict.get('author_id') and message_dict['author_id'] != self.env['ir.model.data']._xmlid_to_res_id('base.partner_root')
thread = thread.with_context(mail_create_nosubscribe=not partner_from_found)
new_msg = thread.message_post(**post_params)
@@ -1536,7 +1538,7 @@ class MailThread(models.AbstractModel):
if alias and alias.alias_parent_model_id and alias.alias_parent_thread_id:
followers = self.env['mail.followers'].search([
('res_model', '=', alias.alias_parent_model_id.model),
('res_model', '=', alias.alias_parent_model_id.sudo().model),
('res_id', '=', alias.alias_parent_thread_id)]
).mapped('partner_id')
else:
@@ -1805,9 +1807,9 @@ class MailThread(models.AbstractModel):
author_id, email_from = self._message_compute_author(author_id, email_from, raise_exception=True)
if subtype_xmlid:
subtype_id = self.env['ir.model.data'].xmlid_to_res_id(subtype_xmlid)
subtype_id = self.env['ir.model.data']._xmlid_to_res_id(subtype_xmlid)
if not subtype_id:
subtype_id = self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note')
subtype_id = self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note')
# automatically subscribe recipients if asked to
if self._context.get('mail_post_autofollow') and partner_ids:
@@ -1977,7 +1979,7 @@ class MailThread(models.AbstractModel):
'author_id': author_id,
'email_from': email_from,
'partner_ids': partner_ids,
'subtype_id': self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note'),
'subtype_id': self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note'),
'is_internal': True,
'record_name': False,
'reply_to': MailThread._notify_get_reply_to(default=email_from, records=None)[False],
@@ -2010,7 +2012,7 @@ class MailThread(models.AbstractModel):
'message_type': message_type,
'model': kwargs.get('model', self._name),
'res_id': self.ids[0] if self.ids else False,
'subtype_id': self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note'),
'subtype_id': self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note'),
'is_internal': True,
'record_name': False,
'reply_to': self.env['mail.thread']._notify_get_reply_to(default=email_from, records=None)[False],
@@ -2033,7 +2035,7 @@ class MailThread(models.AbstractModel):
'email_from': email_from,
'message_type': message_type,
'model': self._name,
'subtype_id': self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note'),
'subtype_id': self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note'),
'is_internal': True,
'record_name': False,
'reply_to': self.env['mail.thread']._notify_get_reply_to(default=email_from, records=None)[False],
@@ -2344,7 +2346,7 @@ class MailThread(models.AbstractModel):
tracking_value.get_old_display_value()[0],
tracking_value.get_new_display_value()[0]))
is_discussion = subtype_id == self.env['ir.model.data'].xmlid_to_res_id('mail.mt_comment')
is_discussion = subtype_id == self.env['ir.model.data']._xmlid_to_res_id('mail.mt_comment')
return {
'message': message,
@@ -2689,7 +2691,7 @@ class MailThread(models.AbstractModel):
if not self.env.registry.ready: # Don't send notification during install
return
view = self.env['ir.ui.view'].browse(self.env['ir.model.data'].xmlid_to_res_id(template))
view = self.env['ir.ui.view'].browse(self.env['ir.model.data']._xmlid_to_res_id(template))
for record in self:
model_description = self.env['ir.model']._get(record._name).display_name
+1 -1
View File
@@ -28,7 +28,7 @@ class Partner(models.Model):
def _compute_im_status(self):
super()._compute_im_status()
odoobot_id = self.env['ir.model.data'].xmlid_to_res_id('base.partner_root')
odoobot_id = self.env['ir.model.data']._xmlid_to_res_id('base.partner_root')
odoobot = self.env['res.partner'].browse(odoobot_id)
if odoobot in self:
odoobot.im_status = 'bot'
+1 -1
View File
@@ -99,7 +99,7 @@ class Users(models.Model):
})
activity_data = self.env.cr.dictfetchall()
model_ids = [a['id'] for a in activity_data]
model_names = {n[0]: n[1] for n in self.env['ir.model'].browse(model_ids).name_get()}
model_names = {n[0]: n[1] for n in self.env['ir.model'].sudo().browse(model_ids).name_get()}
user_activities = {}
for activity in activity_data:
+2 -2
View File
@@ -119,7 +119,7 @@ class MailComposer(models.TransientModel):
"message, comment for other messages such as user replies")
subtype_id = fields.Many2one(
'mail.message.subtype', 'Subtype', ondelete='set null', index=True,
default=lambda self: self.env['ir.model.data'].xmlid_to_res_id('mail.mt_comment'))
default=lambda self: self.env['ir.model.data']._xmlid_to_res_id('mail.mt_comment'))
mail_activity_type_id = fields.Many2one(
'mail.activity.type', 'Mail Activity Type',
index=True, ondelete='set null')
@@ -249,7 +249,7 @@ class MailComposer(models.TransientModel):
elif wizard.subtype_id:
subtype_id = wizard.subtype_id.id
else:
subtype_id = self.env['ir.model.data'].xmlid_to_res_id('mail.mt_comment')
subtype_id = self.env['ir.model.data']._xmlid_to_res_id('mail.mt_comment')
for res_ids in sliced_res_ids:
# mass mail mode: mail are sudo-ed, as when going through get_mail_values
+1 -1
View File
@@ -13,7 +13,7 @@ class MailTemplatePreview(models.TransientModel):
@api.model
def _selection_target_model(self):
return [(model.model, model.name) for model in self.env['ir.model'].search([])]
return [(model.model, model.name) for model in self.env['ir.model'].sudo().search([])]
@api.model
def _selection_languages(self):
+4 -4
View File
@@ -21,7 +21,7 @@ class MailBot(models.AbstractModel):
:param values: msg_values of the message_post or other values needed by logic
:param command: the name of the called command if the logic is not triggered by a message_post
"""
odoobot_id = self.env['ir.model.data'].xmlid_to_res_id("base.partner_root")
odoobot_id = self.env['ir.model.data']._xmlid_to_res_id("base.partner_root")
if len(record) != 1 or values.get("author_id") == odoobot_id:
return
if self._is_bot_pinged(values) or self._is_bot_in_private_channel(record):
@@ -29,7 +29,7 @@ class MailBot(models.AbstractModel):
answer = self._get_answer(record, body, values, command)
if answer:
message_type = values.get('message_type', 'comment')
subtype_id = values.get('subtype_id', self.env['ir.model.data'].xmlid_to_res_id('mail.mt_comment'))
subtype_id = values.get('subtype_id', self.env['ir.model.data']._xmlid_to_res_id('mail.mt_comment'))
record.with_context(mail_create_nosubscribe=True).sudo().message_post(body=answer, author_id=odoobot_id, message_type=message_type, subtype_id=subtype_id)
def _get_answer(self, record, body, values, command=False):
@@ -222,11 +222,11 @@ class MailBot(models.AbstractModel):
return False
def _is_bot_pinged(self, values):
odoobot_id = self.env['ir.model.data'].xmlid_to_res_id("base.partner_root")
odoobot_id = self.env['ir.model.data']._xmlid_to_res_id("base.partner_root")
return odoobot_id in values.get('partner_ids', [])
def _is_bot_in_private_channel(self, record):
odoobot_id = self.env['ir.model.data'].xmlid_to_res_id("base.partner_root")
odoobot_id = self.env['ir.model.data']._xmlid_to_res_id("base.partner_root")
if record._name == 'mail.channel' and record.channel_type == 'chat':
return odoobot_id in record.with_context(active_test=False).channel_partner_ids.ids
return False
+1 -1
View File
@@ -14,7 +14,7 @@ class Channel(models.Model):
@api.model
def init_odoobot(self):
if self.env.user.odoobot_state in [False, 'not_initialized']:
odoobot_id = self.env['ir.model.data'].xmlid_to_res_id("base.partner_root")
odoobot_id = self.env['ir.model.data']._xmlid_to_res_id("base.partner_root")
channel_info = self.channel_get([odoobot_id])
channel = self.browse(channel_info['id'])
message = _("Hello,<br/>Odoo's chat helps employees collaborate efficiently. I'm here to help you discover its features.<br/><b>Try to send me an emoji</b> <span class=\"o_odoobot_command\">:)</span>")
@@ -12,6 +12,7 @@ access_mailing_trace_mm_user,access.mailing.trace.mm.user,model_mailing_trace,ma
access_mailing_trace_report_mm_user,access.mailing.trace.report.mm.user,model_mailing_trace_report,mass_mailing.group_mass_mailing_user,1,1,1,1
access_utm_source,access_utm_source,utm.model_utm_source,mass_mailing.group_mass_mailing_user,1,1,1,0
access_ir_mail_server,access_ir_mail_server,base.model_ir_mail_server,mass_mailing.group_mass_mailing_user,1,0,0,0
access_ir_model,access_ir_model,base.model_ir_model,mass_mailing.group_mass_mailing_user,1,0,0,0
access_mail_blacklist_mass_mailing_user,access.mail.blacklist.mass_mailing_user,mail.model_mail_blacklist,mass_mailing.group_mass_mailing_user,1,1,1,1
access_mail_blacklist_remove_mass_mailing_user,acesss.mail.blacklist.remove.mass_mailing_user,mail.model_mail_blacklist_remove,mass_mailing.group_mass_mailing_user,1,1,1,1
access_link_tracker_mailing,access.link.tracker.mailing,link_tracker.model_link_tracker,mass_mailing.group_mass_mailing_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
12 access_mailing_trace_report_mm_user access.mailing.trace.report.mm.user model_mailing_trace_report mass_mailing.group_mass_mailing_user 1 1 1 1
13 access_utm_source access_utm_source utm.model_utm_source mass_mailing.group_mass_mailing_user 1 1 1 0
14 access_ir_mail_server access_ir_mail_server base.model_ir_mail_server mass_mailing.group_mass_mailing_user 1 0 0 0
15 access_ir_model access_ir_model base.model_ir_model mass_mailing.group_mass_mailing_user 1 0 0 0
16 access_mail_blacklist_mass_mailing_user access.mail.blacklist.mass_mailing_user mail.model_mail_blacklist mass_mailing.group_mass_mailing_user 1 1 1 1
17 access_mail_blacklist_remove_mass_mailing_user acesss.mail.blacklist.remove.mass_mailing_user mail.model_mail_blacklist_remove mass_mailing.group_mass_mailing_user 1 1 1 1
18 access_link_tracker_mailing access.link.tracker.mailing link_tracker.model_link_tracker mass_mailing.group_mass_mailing_user 1 1 1 1
+2 -2
View File
@@ -1526,8 +1526,8 @@ class TestMrpOrder(TestMrpCommon):
def test_immediate_validate_uom_2(self):
"""The rounding precision of a component should be based on the UoM used in the MO for this component,
not on the produced product's UoM nor the default UoM of the component"""
uom_units = self.env['ir.model.data'].xmlid_to_object('uom.product_uom_unit')
uom_L = self.env['ir.model.data'].xmlid_to_object('uom.product_uom_litre')
uom_units = self.env.ref('uom.product_uom_unit')
uom_L = self.env.ref('uom.product_uom_litre')
uom_cL = self.env['uom.uom'].create({
'name': 'cL',
'category_id': uom_L.category_id.id,
@@ -10,7 +10,7 @@ class TestMultistepManufacturingWarehouse(TestMrpCommon):
def setUp(self):
super(TestMultistepManufacturingWarehouse, self).setUp()
# Create warehouse
self.customer_location = self.env['ir.model.data'].xmlid_to_res_id('stock.stock_location_customers')
self.customer_location = self.env['ir.model.data']._xmlid_to_res_id('stock.stock_location_customers')
warehouse_form = Form(self.env['stock.warehouse'])
warehouse_form.name = 'Test Warehouse'
warehouse_form.code = 'TWH'
@@ -138,7 +138,7 @@ class TestMultistepManufacturingWarehouse(TestMrpCommon):
picking_customer = self.env['stock.picking'].create({
'location_id': self.warehouse.wh_output_stock_loc_id.id,
'location_dest_id': self.customer_location,
'partner_id': self.env['ir.model.data'].xmlid_to_res_id('base.res_partner_4'),
'partner_id': self.env['ir.model.data']._xmlid_to_res_id('base.res_partner_4'),
'picking_type_id': self.warehouse.out_type_id.id,
})
self.env['stock.move'].create({
@@ -218,7 +218,7 @@ class TestMultistepManufacturingWarehouse(TestMrpCommon):
picking_customer = self.env['stock.picking'].create({
'location_id': self.warehouse.lot_stock_id.id,
'location_dest_id': self.customer_location,
'partner_id': self.env['ir.model.data'].xmlid_to_res_id('base.res_partner_4'),
'partner_id': self.env['ir.model.data']._xmlid_to_res_id('base.res_partner_4'),
'picking_type_id': self.warehouse.out_type_id.id,
})
self.env['stock.move'].create({
+1 -1
View File
@@ -15,7 +15,7 @@ class Users(models.Model):
@api.model_create_multi
def create(self, vals_list):
users = super().create(vals_list)
user_group_id = self.env['ir.model.data'].xmlid_to_res_id('base.group_user')
user_group_id = self.env['ir.model.data']._xmlid_to_res_id('base.group_user')
# for new employee, create his own 5 base note stages
users.filtered_domain([('groups_id', 'in', [user_group_id])])._create_note_stages()
return users
@@ -22,14 +22,14 @@ class ProductMargin(models.TransientModel):
self.ensure_one()
context = dict(self.env.context, create=False, edit=False)
def ref(module, xml_id):
def ref(xml_id):
proxy = self.env['ir.model.data']
return proxy.get_object_reference(module, xml_id)
return proxy._xmlid_lookup(xml_id)[2]
model, search_view_id = ref('product', 'product_search_form_view')
model, graph_view_id = ref('product_margin', 'view_product_margin_graph')
model, form_view_id = ref('product_margin', 'view_product_margin_form')
model, tree_view_id = ref('product_margin', 'view_product_margin_tree')
search_view_id = ref('product.product_search_form_view')
graph_view_id = ref('product_margin.view_product_margin_graph')
form_view_id = ref('product_margin.view_product_margin_form')
tree_view_id = ref('product_margin.view_product_margin_tree')
context.update(invoice_state=self.invoice_state)
+1 -1
View File
@@ -1311,7 +1311,7 @@ class Task(models.Model):
if 'stage_id' in changes and test_task.stage_id.mail_template_id:
res['stage_id'] = (test_task.stage_id.mail_template_id, {
'auto_delete_message': True,
'subtype_id': self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note'),
'subtype_id': self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note'),
'email_layout_xmlid': 'mail.mail_notification_light'
})
return res
+4 -4
View File
@@ -354,13 +354,13 @@ class PurchaseOrder(models.Model):
ir_model_data = self.env['ir.model.data']
try:
if self.env.context.get('send_rfq', False):
template_id = ir_model_data.get_object_reference('purchase', 'email_template_edi_purchase')[1]
template_id = ir_model_data._xmlid_lookup('purchase.email_template_edi_purchase')[2]
else:
template_id = ir_model_data.get_object_reference('purchase', 'email_template_edi_purchase_done')[1]
template_id = ir_model_data._xmlid_lookup('purchase.email_template_edi_purchase_done')[2]
except ValueError:
template_id = False
try:
compose_form_id = ir_model_data.get_object_reference('mail', 'email_compose_message_wizard_form')[1]
compose_form_id = ir_model_data._xmlid_lookup('mail.email_compose_message_wizard_form')[2]
except ValueError:
compose_form_id = False
ctx = dict(self.env.context or {})
@@ -723,7 +723,7 @@ class PurchaseOrder(models.Model):
def _send_reminder_open_composer(self,template_id):
self.ensure_one()
try:
compose_form_id = self.env['ir.model.data'].get_object_reference('mail', 'email_compose_message_wizard_form')[1]
compose_form_id = self.env['ir.model.data']._xmlid_lookup('mail.email_compose_message_wizard_form')[2]
except ValueError:
compose_form_id = False
ctx = dict(self.env.context or {})
+2 -2
View File
@@ -218,8 +218,8 @@ class TestPurchase(AccountTestInvoicingCommon):
def test_with_different_uom(self):
""" This test ensures that the unit price is correctly computed"""
uom_units = self.env['ir.model.data'].xmlid_to_object('uom.product_uom_unit')
uom_dozens = self.env['ir.model.data'].xmlid_to_object('uom.product_uom_dozen')
uom_units = self.env.ref('uom.product_uom_unit')
uom_dozens = self.env.ref('uom.product_uom_dozen')
uom_pairs = self.env['uom.uom'].create({
'name': 'Pairs',
'category_id': uom_units.category_id.id,
@@ -277,7 +277,7 @@ class TestPurchaseToInvoice(AccountTestInvoicingCommon):
self.assertEqual(amls[1].amount_currency, 500)
def test_product_price_decimal_accuracy(self):
self.env['ir.model.data'].xmlid_to_object('product.decimal_price').digits = 3
self.env.ref('product.decimal_price').digits = 3
self.env.company.currency_id.rounding = 0.01
po = self.env['purchase.order'].with_context(tracking_disable=True).create({
@@ -94,7 +94,7 @@ class PurchaseOrder(models.Model):
if purchase.requisition_id:
purchase.message_post_with_view('mail.message_origin_link',
values={'self': purchase, 'origin': purchase.requisition_id},
subtype_id=self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note'))
subtype_id=self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note'))
return purchase
def write(self, vals):
@@ -102,7 +102,7 @@ class PurchaseOrder(models.Model):
if vals.get('requisition_id'):
self.message_post_with_view('mail.message_origin_link',
values={'self': self, 'origin': self.requisition_id, 'edit': True},
subtype_id=self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note'))
subtype_id=self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note'))
return result
@@ -100,9 +100,9 @@ class TestCreatePicking(common.TestProductCommon):
following move to MTS in order to be able to link it to a
manually created purchase order.
"""
stock_location = self.env['ir.model.data'].xmlid_to_object('stock.stock_location_stock')
customer_location = self.env['ir.model.data'].xmlid_to_object('stock.stock_location_customers')
picking_type_out = self.env['ir.model.data'].xmlid_to_object('stock.picking_type_out')
stock_location = self.env.ref('stock.stock_location_stock')
customer_location = self.env.ref('stock.stock_location_customers')
picking_type_out = self.env.ref('stock.picking_type_out')
# route buy should be there by default
partner = self.env['res.partner'].create({
'name': 'Jhon'
@@ -238,9 +238,9 @@ class TestCreatePicking(common.TestProductCommon):
and receipt the picking then try to reserve the delivery
picking.
"""
stock_location = self.env['ir.model.data'].xmlid_to_object('stock.stock_location_stock')
customer_location = self.env['ir.model.data'].xmlid_to_object('stock.stock_location_customers')
picking_type_out = self.env['ir.model.data'].xmlid_to_object('stock.picking_type_out')
stock_location = self.env.ref('stock.stock_location_stock')
customer_location = self.env.ref('stock.stock_location_customers')
picking_type_out = self.env.ref('stock.picking_type_out')
# route buy should be there by default
partner = self.env['res.partner'].create({
'name': 'Jhon'
@@ -383,10 +383,10 @@ class TestCreatePicking(common.TestProductCommon):
self.assertEqual(move2.product_qty, 24)
def create_delivery_order(self):
stock_location = self.env['ir.model.data'].xmlid_to_object('stock.stock_location_stock')
customer_location = self.env['ir.model.data'].xmlid_to_object('stock.stock_location_customers')
stock_location = self.env.ref('stock.stock_location_stock')
customer_location = self.env.ref('stock.stock_location_customers')
unit = self.ref("uom.product_uom_unit")
picking_type_out = self.env['ir.model.data'].xmlid_to_object('stock.picking_type_out')
picking_type_out = self.env.ref('stock.picking_type_out')
partner = self.env['res.partner'].create({'name': 'AAA', 'email': 'from.test@example.com'})
supplier_info1 = self.env['product.supplierinfo'].create({
'name': partner.id,
@@ -323,7 +323,7 @@ class TestFifoPrice(ValuationReconciliationTestCommon):
def test_01_test_fifo(self):
"""" This test ensures that unit price keeps its decimal precision """
unit_price_precision = self.env['ir.model.data'].xmlid_to_object('product.decimal_price')
unit_price_precision = self.env.ref('product.decimal_price')
unit_price_precision.digits = 3
tax = self.env["account.tax"].create({
@@ -251,9 +251,9 @@ class TestMoveCancelPropagation(PurchaseTestCommon):
"""Check for done and cancelled moves. Ensure that the RFQ cancellation
will not impact the delivery state if it's already cancelled.
"""
stock_location = self.env['ir.model.data'].xmlid_to_object('stock.stock_location_stock')
customer_location = self.env['ir.model.data'].xmlid_to_object('stock.stock_location_customers')
picking_type_out = self.env['ir.model.data'].xmlid_to_object('stock.picking_type_out')
stock_location = self.env.ref('stock.stock_location_stock')
customer_location = self.env.ref('stock.stock_location_customers')
picking_type_out = self.env.ref('stock.picking_type_out')
partner = self.env['res.partner'].create({
'name': 'Steve'
+1 -1
View File
@@ -33,7 +33,7 @@ class Rating(models.Model):
@api.model
def _selection_target_model(self):
return [(model.model, model.name) for model in self.env['ir.model'].search([])]
return [(model.model, model.name) for model in self.env['ir.model'].sudo().search([])]
create_date = fields.Datetime(string="Submitted on")
res_name = fields.Char(string='Resource name', compute='_compute_res_name', store=True, help="The name of the rated resource.")
+1 -1
View File
@@ -160,7 +160,7 @@ class RatingMixin(models.AbstractModel):
if lang:
template = template.with_context(lang=lang)
if subtype_id is False:
subtype_id = self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note')
subtype_id = self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note')
if force_send:
self = self.with_context(mail_notify_force_send=True) # default value is True, should be set to false if not?
for record in self:
+2 -2
View File
@@ -855,9 +855,9 @@ class SaleOrder(models.Model):
template_id = int(self.env['ir.config_parameter'].sudo().get_param('sale.default_confirmation_template'))
template_id = self.env['mail.template'].search([('id', '=', template_id)]).id
if not template_id:
template_id = self.env['ir.model.data'].xmlid_to_res_id('sale.mail_template_sale_confirmation', raise_if_not_found=False)
template_id = self.env['ir.model.data']._xmlid_to_res_id('sale.mail_template_sale_confirmation', raise_if_not_found=False)
if not template_id:
template_id = self.env['ir.model.data'].xmlid_to_res_id('sale.email_template_edi_sale', raise_if_not_found=False)
template_id = self.env['ir.model.data']._xmlid_to_res_id('sale.email_template_edi_sale', raise_if_not_found=False)
return template_id
@@ -76,7 +76,7 @@ class TestSaleMrpProcurement(TransactionCase):
"""
self.env.ref('stock.route_warehouse0_mto').active = True
# Create warehouse
self.customer_location = self.env['ir.model.data'].xmlid_to_res_id('stock.stock_location_customers')
self.customer_location = self.env['ir.model.data']._xmlid_to_res_id('stock.stock_location_customers')
self.warehouse = self.env['stock.warehouse'].create({
'name': 'Test Warehouse',
'code': 'TWH'
+1 -1
View File
@@ -1066,7 +1066,7 @@ class TestSaleStock(TestSaleCommon, ValuationReconciliationTestCommon):
policy set to "Delivered quantities". When cancelling the delivery of such a product, the
invoice status of the associated SO should be 'Nothing to Invoice'
"""
group_auto_done = self.env['ir.model.data'].xmlid_to_object('sale.group_auto_done_setting')
group_auto_done = self.env.ref('sale.group_auto_done_setting')
self.env.user.groups_id = [(4, group_auto_done.id)]
product = self.product_a
+1 -1
View File
@@ -225,7 +225,7 @@ class MailThread(models.AbstractModel):
sms_numbers = [False]
if subtype_id is False:
subtype_id = self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note')
subtype_id = self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note')
return self.message_post(
body=plaintext2html(html2plaintext(body)), partner_ids=partner_ids or [], # TDE FIXME: temp fix otherwise crash mail_thread.py
+1 -1
View File
@@ -236,7 +236,7 @@ class SendSMS(models.TransientModel):
def _action_send_sms_comment(self, records=None):
records = records if records is not None else self._get_records()
subtype_id = self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note')
subtype_id = self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note')
messages = self.env['mail.message']
for record in records:
+1 -2
View File
@@ -10,8 +10,7 @@ class SMSTemplatePreview(models.TransientModel):
@api.model
def _selection_target_model(self):
models = self.env['ir.model'].search([])
return [(model.model, model.name) for model in models]
return [(model.model, model.name) for model in self.env['ir.model'].sudo().search([])]
@api.model
def _selection_languages(self):
+1 -1
View File
@@ -610,7 +610,7 @@ class StockMove(models.Model):
# Avoids to write the exact same message multiple times.
if last_message and last_message.subject == msg_subject:
continue
odoobot_id = self.env['ir.model.data'].xmlid_to_res_id("base.partner_root")
odoobot_id = self.env['ir.model.data']._xmlid_to_res_id("base.partner_root")
doc.message_post(body=msg, author_id=odoobot_id, subject=msg_subject)
def action_show_details(self):
+7 -7
View File
@@ -19,20 +19,20 @@ class TestStockCommon(common.TransactionCase):
cls.LotObj = cls.env['stock.production.lot']
# Model Data
cls.picking_type_in = cls.ModelDataObj.xmlid_to_res_id('stock.picking_type_in')
cls.picking_type_out = cls.ModelDataObj.xmlid_to_res_id('stock.picking_type_out')
cls.picking_type_in = cls.ModelDataObj._xmlid_to_res_id('stock.picking_type_in')
cls.picking_type_out = cls.ModelDataObj._xmlid_to_res_id('stock.picking_type_out')
cls.env['stock.picking.type'].browse(cls.picking_type_out).reservation_method = 'manual'
cls.supplier_location = cls.ModelDataObj.xmlid_to_res_id('stock.stock_location_suppliers')
cls.stock_location = cls.ModelDataObj.xmlid_to_res_id('stock.stock_location_stock')
cls.supplier_location = cls.ModelDataObj._xmlid_to_res_id('stock.stock_location_suppliers')
cls.stock_location = cls.ModelDataObj._xmlid_to_res_id('stock.stock_location_stock')
pack_location = cls.env.ref('stock.location_pack_zone')
pack_location.active = True
cls.pack_location = pack_location.id
output_location = cls.env.ref('stock.stock_location_output')
output_location.active = True
cls.output_location = output_location.id
cls.customer_location = cls.ModelDataObj.xmlid_to_res_id('stock.stock_location_customers')
cls.categ_unit = cls.ModelDataObj.xmlid_to_res_id('uom.product_uom_categ_unit')
cls.categ_kgm = cls.ModelDataObj.xmlid_to_res_id('uom.product_uom_categ_kgm')
cls.customer_location = cls.ModelDataObj._xmlid_to_res_id('stock.stock_location_customers')
cls.categ_unit = cls.ModelDataObj._xmlid_to_res_id('uom.product_uom_categ_unit')
cls.categ_kgm = cls.ModelDataObj._xmlid_to_res_id('uom.product_uom_categ_kgm')
# Product Created A, B, C, D
cls.productA = cls.ProductObj.create({'name': 'Product A', 'type': 'product'})
+4 -4
View File
@@ -12,10 +12,10 @@ class TestReportsCommon(TransactionCase):
super().setUpClass()
cls.partner = cls.env['res.partner'].create({'name': 'Partner'})
cls.ModelDataObj = cls.env['ir.model.data']
cls.picking_type_in = cls.env['stock.picking.type'].browse(cls.ModelDataObj.xmlid_to_res_id('stock.picking_type_in'))
cls.picking_type_out = cls.env['stock.picking.type'].browse(cls.ModelDataObj.xmlid_to_res_id('stock.picking_type_out'))
cls.supplier_location = cls.env['stock.location'].browse(cls.ModelDataObj.xmlid_to_res_id('stock.stock_location_suppliers'))
cls.stock_location = cls.env['stock.location'].browse(cls.ModelDataObj.xmlid_to_res_id('stock.stock_location_stock'))
cls.picking_type_in = cls.env['stock.picking.type'].browse(cls.ModelDataObj._xmlid_to_res_id('stock.picking_type_in'))
cls.picking_type_out = cls.env['stock.picking.type'].browse(cls.ModelDataObj._xmlid_to_res_id('stock.picking_type_out'))
cls.supplier_location = cls.env['stock.location'].browse(cls.ModelDataObj._xmlid_to_res_id('stock.stock_location_suppliers'))
cls.stock_location = cls.env['stock.location'].browse(cls.ModelDataObj._xmlid_to_res_id('stock.stock_location_stock'))
product_form = Form(cls.env['product.product'])
product_form.type = 'product'
@@ -15,7 +15,7 @@ class TestBatchPicking(TransactionCase):
super(TestBatchPicking, self).setUp()
self.stock_location = self.env.ref('stock.stock_location_stock')
self.customer_location = self.env.ref('stock.stock_location_customers')
self.picking_type_out = self.env['ir.model.data'].xmlid_to_res_id('stock.picking_type_out')
self.picking_type_out = self.env['ir.model.data']._xmlid_to_res_id('stock.picking_type_out')
self.env['stock.picking.type'].browse(self.picking_type_out).reservation_method = 'manual'
self.productA = self.env['product.product'].create({
'name': 'Product A',
@@ -94,7 +94,7 @@ class TestEventSecurity(TestEventCommon):
'name': 'ManagerEventType',
'event_type_mail_ids': [(5, 0), (0, 0, {
'interval_nbr': 1, 'interval_unit': 'days', 'interval_type': 'before_event',
'template_ref': 'mail.template,%i' % self.env['ir.model.data'].xmlid_to_res_id('event.event_reminder')})]
'template_ref': 'mail.template,%i' % self.env['ir.model.data']._xmlid_to_res_id('event.event_reminder')})]
})
@users('user_eventmanager')
@@ -105,7 +105,7 @@ class TestEventSecurity(TestEventCommon):
'name': 'ManagerEventType',
'event_type_mail_ids': [(5, 0), (0, 0, {
'interval_nbr': 1, 'interval_unit': 'days', 'interval_type': 'before_event',
'template_ref': 'mail.template,%i' % self.env['ir.model.data'].xmlid_to_res_id('event.event_reminder')})]
'template_ref': 'mail.template,%i' % self.env['ir.model.data']._xmlid_to_res_id('event.event_reminder')})]
})
event_type.write({'name': 'New Name'})
+2 -2
View File
@@ -748,7 +748,7 @@ class TestMailComplexPerformance(BaseMailPerformance):
'email_from': self.partners[0].email,
'model': 'mail.test.container',
'res_id': self.container.id,
'subtype_id': self.env['ir.model.data'].xmlid_to_res_id('mail.mt_comment'),
'subtype_id': self.env['ir.model.data']._xmlid_to_res_id('mail.mt_comment'),
'attachment_ids': [
(0, 0, {
'name': 'test file 0 - %d' % j,
@@ -792,7 +792,7 @@ class TestMailComplexPerformance(BaseMailPerformance):
'email_from': self.partners[1].email,
'model': 'mail.test.container',
'res_id': self.container.id,
'subtype_id': self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note'),
'subtype_id': self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note'),
'attachment_ids': [
(0, 0, {
'name': 'test file 1 - %d' % j,
+1 -1
View File
@@ -70,7 +70,7 @@ class TestOdoobot(TestMailCommon, TestRecipients):
answer=("@OdooBot",)
)
kwargs['body'] = ''
kwargs['partner_ids'] = [self.env['ir.model.data'].xmlid_to_res_id("base.partner_root")]
kwargs['partner_ids'] = [self.env['ir.model.data']._xmlid_to_res_id("base.partner_root")]
self.assertNextMessage(
channel.message_post(**kwargs),
sender=self.odoobot,
+1 -1
View File
@@ -264,7 +264,7 @@ class WebsiteForm(http.Controller):
'message_type': 'comment',
'res_id': id_record,
'attachment_ids': [(6, 0, orphan_attachment_ids)],
'subtype_id': request.env['ir.model.data'].xmlid_to_res_id('mail.mt_comment'),
'subtype_id': request.env['ir.model.data']._xmlid_to_res_id('mail.mt_comment'),
}
mail_id = request.env['mail.message'].with_user(SUPERUSER_ID).create(values)
else:
+1 -1
View File
@@ -420,7 +420,7 @@ class IrModuleModule(models.Model):
def get_themes_domain(self):
"""Returns the 'ir.module.module' search domain matching all available themes."""
def get_id(model_id):
return self.env['ir.model.data'].xmlid_to_res_id(model_id)
return self.env['ir.model.data']._xmlid_to_res_id(model_id)
return [
('category_id', 'not in', [
get_id('base.module_category_hidden'),
+1 -1
View File
@@ -417,7 +417,7 @@ class View(models.Model):
if values and 'main_object' in values:
if request.env.user.has_group('website.group_website_publisher'):
func = getattr(values['main_object'], 'get_backend_menu_id', False)
values['backend_menu_id'] = func and func() or self.env['ir.model.data'].xmlid_to_res_id('website.menu_website_configuration')
values['backend_menu_id'] = func and func() or self.env['ir.model.data']._xmlid_to_res_id('website.menu_website_configuration')
if self._context != new_context:
self = self.with_context(new_context)
+1 -1
View File
@@ -1977,7 +1977,7 @@
<button type="button" t-attf-class="btn btn-default dropdown-toggle dropdown-toggle-split" t-att-id="'dopprod-%s' % object.id" data-toggle="dropdown"/>
<div class="dropdown-menu" role="menu" t-att-aria-labelledby="'dopprod-%s' % object.id">
<t t-out="0"/>
<a role="menuitem" t-attf-href="/web#view_type=form&amp;model=#{object._name}&amp;id=#{object.id}&amp;action=#{action}&amp;menu_id=#{menu or object.env['ir.model.data'].xmlid_to_res_id('website.menu_website_configuration')}"
<a role="menuitem" t-attf-href="/web#view_type=form&amp;model=#{object._name}&amp;id=#{object.id}&amp;action=#{action}&amp;menu_id=#{menu or object.env['ir.model.data']._xmlid_to_res_id('website.menu_website_configuration')}"
title='Edit in backend' class="dropdown-item" t-if="publish_edit">Edit</a>
</div>
</div>
+1 -1
View File
@@ -190,7 +190,7 @@ class BlogPost(models.Model):
'website_blog.blog_post_template_new_post',
subject=post.name,
values={'post': post},
subtype_id=self.env['ir.model.data'].xmlid_to_res_id('website_blog.mt_blog_blog_published'))
subtype_id=self.env['ir.model.data']._xmlid_to_res_id('website_blog.mt_blog_blog_published'))
return True
return False
@@ -479,7 +479,7 @@ class Track(models.Model):
res['stage_id'] = (track.stage_id.mail_template_id, {
'composition_mode': 'comment',
'auto_delete_message': True,
'subtype_id': self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note'),
'subtype_id': self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note'),
'email_layout_xmlid': 'mail.mail_notification_light'
})
return res
+1 -1
View File
@@ -637,7 +637,7 @@ class WebsiteForum(WebsiteProfile):
vote_ids = Vote.search([('user_id', '=', user.id)])
# activity by user.
model, comment = Data.get_object_reference('mail', 'mt_comment')
comment = Data._xmlid_lookup('mail.mt_comment')[2]
activities = Activity.search(
[('res_id', 'in', (user_question_ids + user_answer_ids).ids), ('model', '=', 'forum.post'),
('subtype_id', '!=', comment)],
+3 -3
View File
@@ -588,13 +588,13 @@ class Post(models.Model):
'website_forum.forum_post_template_new_answer',
subject=_('Re: %s', post.parent_id.name),
partner_ids=[(4, p.id) for p in tag_partners],
subtype_id=self.env['ir.model.data'].xmlid_to_res_id('website_forum.mt_answer_new'))
subtype_id=self.env['ir.model.data']._xmlid_to_res_id('website_forum.mt_answer_new'))
elif post.state == 'active' and not post.parent_id:
post.message_post_with_view(
'website_forum.forum_post_template_new_question',
subject=post.name,
partner_ids=[(4, p.id) for p in tag_partners],
subtype_id=self.env['ir.model.data'].xmlid_to_res_id('website_forum.mt_question_new'))
subtype_id=self.env['ir.model.data']._xmlid_to_res_id('website_forum.mt_question_new'))
elif post.state == 'pending' and not post.parent_id:
# TDE FIXME: in master, you should probably use a subtype;
# however here we remove subtype but set partner_ids
@@ -605,7 +605,7 @@ class Post(models.Model):
'website_forum.forum_post_template_validation',
subject=post.name,
partner_ids=partners.ids,
subtype_id=self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note'))
subtype_id=self.env['ir.model.data']._xmlid_to_res_id('mail.mt_note'))
return True
def reopen(self):
@@ -50,7 +50,7 @@ class Job(models.Model):
_inherit = ['hr.job', 'website.seo.metadata', 'website.published.multi.mixin']
def _get_default_website_description(self):
default_description = self.env["ir.model.data"].xmlid_to_object("website_hr_recruitment.default_website_description")
default_description = self.env.ref("website_hr_recruitment.default_website_description", raise_if_not_found=False)
return (default_description._render() if default_description else "")
website_published = fields.Boolean(help='Set if the application is published on the website of the company.')
@@ -204,14 +204,14 @@ class Channel(models.Model):
publish_template_id = fields.Many2one(
'mail.template', string='New Content Email',
help="Email attendees once a new content is published",
default=lambda self: self.env['ir.model.data'].xmlid_to_res_id('website_slides.slide_template_published'))
default=lambda self: self.env['ir.model.data']._xmlid_to_res_id('website_slides.slide_template_published'))
share_template_id = fields.Many2one(
'mail.template', string='Share Template',
help="Email template used when sharing a slide",
default=lambda self: self.env['ir.model.data'].xmlid_to_res_id('website_slides.slide_template_shared'))
default=lambda self: self.env['ir.model.data']._xmlid_to_res_id('website_slides.slide_template_shared'))
completed_template_id = fields.Many2one(
'mail.template', string='Completion Email', help="Email attendees once they've finished the course",
default=lambda self: self.env['ir.model.data'].xmlid_to_res_id('website_slides.mail_template_channel_completed'))
default=lambda self: self.env['ir.model.data']._xmlid_to_res_id('website_slides.mail_template_channel_completed'))
enroll = fields.Selection([
('public', 'Public'), ('invite', 'On Invitation')],
default='public', string='Enroll Policy', required=True,
+1 -7
View File
@@ -393,11 +393,6 @@ class IrActionsServer(models.Model):
# - Command: x2Many commands namespace
# To return an action, assign: action = {...}\n\n\n\n"""
@api.model
def _select_objects(self):
records = self.env['ir.model'].search([])
return [(record.model, record.name) for record in records] + [('', '')]
name = fields.Char(string='Action Name', translate=True)
type = fields.Char(default='ir.actions.server')
usage = fields.Selection([
@@ -679,8 +674,7 @@ class IrServerObjectLines(models.Model):
@api.model
def _selection_target_model(self):
models = self.env['ir.model'].search([])
return [(model.model, model.name) for model in models]
return [(model.model, model.name) for model in self.env['ir.model'].sudo().search([])]
@api.depends('col1.relation', 'value', 'evaluation_type')
def _compute_resource_ref(self):
+7 -41
View File
@@ -1912,7 +1912,7 @@ class IrModelData(models.Model):
# NEW V8 API
@api.model
@tools.ormcache('xmlid')
def xmlid_lookup(self, xmlid):
def _xmlid_lookup(self, xmlid):
"""Low level xmlid lookup
Return (id, res_model, res_id) or raise ValueError if not found
"""
@@ -1925,51 +1925,25 @@ class IrModelData(models.Model):
return result
@api.model
def xmlid_to_res_model_res_id(self, xmlid, raise_if_not_found=False):
def _xmlid_to_res_model_res_id(self, xmlid, raise_if_not_found=False):
""" Return (res_model, res_id)"""
try:
return self.xmlid_lookup(xmlid)[1:3]
return self._xmlid_lookup(xmlid)[1:3]
except ValueError:
if raise_if_not_found:
raise
return (False, False)
@api.model
def xmlid_to_res_id(self, xmlid, raise_if_not_found=False):
def _xmlid_to_res_id(self, xmlid, raise_if_not_found=False):
""" Returns res_id """
return self.xmlid_to_res_model_res_id(xmlid, raise_if_not_found)[1]
@api.model
def xmlid_to_object(self, xmlid, raise_if_not_found=False):
""" Return a Model object, or ``None`` if ``raise_if_not_found`` is
set
"""
t = self.xmlid_to_res_model_res_id(xmlid, raise_if_not_found)
res_model, res_id = t
if res_model and res_id:
record = self.env[res_model].browse(res_id)
if record.exists():
return record
if raise_if_not_found:
raise ValueError('No record found for unique ID %s. It may have been deleted.' % (xmlid))
return None
@api.model
def _get_id(self, module, xml_id):
"""Returns the id of the ir.model.data record corresponding to a given module and xml_id (cached) or raise a ValueError if not found"""
return self.xmlid_lookup("%s.%s" % (module, xml_id))[0]
@api.model
def get_object_reference(self, module, xml_id):
"""Returns (model, res_id) corresponding to a given module and xml_id (cached) or raise ValueError if not found"""
return self.xmlid_lookup("%s.%s" % (module, xml_id))[1:3]
return self._xmlid_to_res_model_res_id(xmlid, raise_if_not_found)[1]
@api.model
def check_object_reference(self, module, xml_id, raise_on_access_error=False):
"""Returns (model, res_id) corresponding to a given module and xml_id (cached), if and only if the user has the necessary access rights
to see that object, otherwise raise a ValueError if raise_on_access_error is True or returns a tuple (model found, False)"""
model, res_id = self.get_object_reference(module, xml_id)
model, res_id = self._xmlid_lookup("%s.%s" % (module, xml_id))[1:3]
#search on id found in result to check if current user has read access right
if self.env[model].search([('id', '=', res_id)]):
return model, res_id
@@ -1977,14 +1951,6 @@ class IrModelData(models.Model):
raise AccessError(_('Not enough access rights on the external ID:') + ' %s.%s' % (module, xml_id))
return model, False
@api.model
def get_object(self, module, xml_id):
""" Returns a browsable record for the given module name and xml_id.
If not found, raise a ValueError or return None, depending
on the value of `raise_exception`.
"""
return self.xmlid_to_object("%s.%s" % (module, xml_id), raise_if_not_found=True)
def unlink(self):
""" Regular unlink method, but make sure to clear the caches. """
self.clear_caches()
@@ -2067,7 +2033,7 @@ class IrModelData(models.Model):
""" Simply mark the given XML id as being loaded, and return the
corresponding record.
"""
record = self.xmlid_to_object(xml_id)
record = self.env.ref(xml_id, raise_if_not_found=False)
if record:
self.pool.loaded_xmlids.add(xml_id)
return record
+5 -5
View File
@@ -279,7 +279,7 @@ actual arch.
xmlid = m.group('xmlid')
if '.' not in xmlid:
xmlid = '%s.%s' % (view_xml_id.split('.')[0], xmlid)
return m.group('prefix') + str(self.env['ir.model.data'].xmlid_to_res_id(xmlid))
return m.group('prefix') + str(self.env['ir.model.data']._xmlid_to_res_id(xmlid))
return re.sub(r'(?P<prefix>[^%])%\((?P<xmlid>.*?)\)[ds]', replacer, arch_fs)
for view in self:
@@ -1246,7 +1246,7 @@ actual arch.
try:
action_id = int(name)
except ValueError:
model, action_id = self.env['ir.model.data'].xmlid_to_res_model_res_id(name, raise_if_not_found=False)
model, action_id = self.env['ir.model.data']._xmlid_to_res_model_res_id(name, raise_if_not_found=False)
if not action_id:
msg = _("Invalid xmlid %(xmlid)s for button of type action.", xmlid=name)
self.handle_view_error(msg, node)
@@ -1452,7 +1452,7 @@ actual arch.
for group in expr.replace('!', '').split(','):
# further improvement: add all groups to name_manager in
# order to batch check them at the end
if not self.env['ir.model.data'].xmlid_to_res_id(group.strip(), raise_if_not_found=False):
if not self.env['ir.model.data']._xmlid_to_res_id(group.strip(), raise_if_not_found=False):
msg = "The group %r defined in view does not exist!"
self.handle_view_error(msg % group, node, raise_exception=False)
@@ -1691,14 +1691,14 @@ actual arch.
kinds of template values.
This method could return the ID of something that is not a view (when
using fallback to `xmlid_to_res_id`).
using fallback to `_xmlid_to_res_id`).
"""
if isinstance(template, int):
return template
if '.' not in template:
raise ValueError('Invalid template id: %r' % template)
view = self.sudo().search([('key', '=', template)], limit=1)
return view and view.id or self.env['ir.model.data'].xmlid_to_res_id(template, raise_if_not_found=True)
return view and view.id or self.env['ir.model.data']._xmlid_to_res_id(template, raise_if_not_found=True)
def clear_cache(self):
""" Deprecated, use `clear_caches` instead. """
+3 -3
View File
@@ -281,7 +281,7 @@ class Users(models.Model):
return ['signature', 'action_id', 'company_id', 'email', 'name', 'image_1920', 'lang', 'tz']
def _default_groups(self):
default_user_id = self.env['ir.model.data'].xmlid_to_res_id('base.default_user', raise_if_not_found=False)
default_user_id = self.env['ir.model.data']._xmlid_to_res_id('base.default_user', raise_if_not_found=False)
return self.env['res.users'].browse(default_user_id).sudo().groups_id if default_user_id else []
partner_id = fields.Many2one('res.partner', required=True, ondelete='restrict', auto_join=True,
@@ -415,7 +415,7 @@ class Users(models.Model):
@api.depends('groups_id')
def _compute_share(self):
user_group_id = self.env['ir.model.data'].xmlid_to_res_id('base.group_user')
user_group_id = self.env['ir.model.data']._xmlid_to_res_id('base.group_user')
internal_users = self.filtered_domain([('groups_id', 'in', [user_group_id])])
internal_users.share = False
(self - internal_users).share = True
@@ -1347,7 +1347,7 @@ class UsersView(models.Model):
for values in vals_list:
new_vals_list.append(self._remove_reified_groups(values))
users = super(UsersView, self).create(new_vals_list)
group_multi_company_id = self.env['ir.model.data'].xmlid_to_res_id(
group_multi_company_id = self.env['ir.model.data']._xmlid_to_res_id(
'base.group_multi_company', raise_if_not_found=False)
if group_multi_company_id:
for user in users:
@@ -13,10 +13,10 @@
"access_ir_model_data_group_erp_manager","ir_model_data group_erp_manager","model_ir_model_data","group_erp_manager",1,1,1,1
"access_ir_model_fields_group_erp_manager","ir_model_fields group_erp_manager","model_ir_model_fields","group_erp_manager",1,1,1,1
"access_ir_model_fields_selection_group_erp_manager","ir_model_fields_selection group_erp_manager","model_ir_model_fields_selection","group_erp_manager",1,1,1,1
"access_ir_model_user","ir_model_all","model_ir_model",base.group_user,1,0,0,0
"access_ir_model_data_user","ir_model_data user","model_ir_model_data",base.group_user,1,0,1,0
"access_ir_model_fields_user","ir_model_fields all","model_ir_model_fields",base.group_user,1,0,0,0
"access_ir_model_fields_selection_user","ir_model_fields_selection all","model_ir_model_fields_selection",base.group_user,1,0,0,0
"access_ir_model_user","ir_model_all","model_ir_model",base.group_user,0,0,0,0
"access_ir_model_data_user","ir_model_data user","model_ir_model_data",base.group_user,0,0,0,0
"access_ir_model_fields_user","ir_model_fields all","model_ir_model_fields",base.group_user,0,0,0,0
"access_ir_model_fields_selection_user","ir_model_fields_selection all","model_ir_model_fields_selection",base.group_user,0,0,0,0
"access_ir_module_category_group_user","ir_module_category group_user","model_ir_module_category","group_erp_manager",1,0,0,0
"access_ir_module_module_group_user","ir_module_module group_user","model_ir_module_module","group_system",1,1,1,1
"access_ir_module_module_dependency_group_system","ir_module_module_dependency group_system","model_ir_module_module_dependency","group_system",1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
13 access_ir_model_data_group_erp_manager ir_model_data group_erp_manager model_ir_model_data group_erp_manager 1 1 1 1
14 access_ir_model_fields_group_erp_manager ir_model_fields group_erp_manager model_ir_model_fields group_erp_manager 1 1 1 1
15 access_ir_model_fields_selection_group_erp_manager ir_model_fields_selection group_erp_manager model_ir_model_fields_selection group_erp_manager 1 1 1 1
16 access_ir_model_user ir_model_all model_ir_model base.group_user 1 0 0 0 0
17 access_ir_model_data_user ir_model_data user model_ir_model_data base.group_user 1 0 0 1 0 0
18 access_ir_model_fields_user ir_model_fields all model_ir_model_fields base.group_user 1 0 0 0 0
19 access_ir_model_fields_selection_user ir_model_fields_selection all model_ir_model_fields_selection base.group_user 1 0 0 0 0
20 access_ir_module_category_group_user ir_module_category group_user model_ir_module_category group_erp_manager 1 0 0 0
21 access_ir_module_module_group_user ir_module_module group_user model_ir_module_module group_system 1 1 1 1
22 access_ir_module_module_dependency_group_system ir_module_module_dependency group_system model_ir_module_module_dependency group_system 1 1 1 1
+3 -3
View File
@@ -12,12 +12,12 @@ class TestOrmcache(TransactionCase):
XMLID = 'base.group_no_one'
# retrieve the cache, its key and stat counter
cache, key, counter = get_cache_key_counter(IMD.xmlid_lookup, XMLID)
cache, key, counter = get_cache_key_counter(IMD._xmlid_lookup, XMLID)
hit = counter.hit
miss = counter.miss
# clear the cache of ir.model.data.xmlid_lookup, retrieve its key and
IMD.xmlid_lookup.clear_cache(IMD)
# clear the caches of ir.model.data, retrieve its key and
IMD.clear_caches()
self.assertNotIn(key, cache)
# lookup some reference
+11 -1
View File
@@ -573,7 +573,17 @@ class Environment(Mapping):
def ref(self, xml_id, raise_if_not_found=True):
"""Return the record corresponding to the given ``xml_id``."""
return self['ir.model.data'].xmlid_to_object(xml_id, raise_if_not_found=raise_if_not_found)
res_model, res_id = self['ir.model.data']._xmlid_to_res_model_res_id(
xml_id, raise_if_not_found=raise_if_not_found
)
if res_model and res_id:
record = self[res_model].browse(res_id)
if record.exists():
return record
if raise_if_not_found:
raise ValueError('No record found for unique ID %s. It may have been deleted.' % (xml_id))
return None
def is_superuser(self):
""" Return whether the environment is in superuser mode. """
+1 -1
View File
@@ -365,7 +365,7 @@ class BaseCase(unittest.TestCase, metaclass=MetaCase):
def ref(self, xid):
""" Returns database ID for the provided :term:`external identifier`,
shortcut for ``get_object_reference``
shortcut for ``_xmlid_lookup``
:param xid: fully-qualified :term:`external identifier`, in the form
:samp:`{module}.{identifier}`
+1 -1
View File
@@ -666,7 +666,7 @@ form: module.record_id""" % (xml_id,)
def model_id_get(self, id_str, raise_if_not_found=True):
if '.' not in id_str:
id_str = '%s.%s' % (self.module, id_str)
return self.env['ir.model.data'].xmlid_to_res_model_res_id(id_str, raise_if_not_found=raise_if_not_found)
return self.env['ir.model.data']._xmlid_to_res_model_res_id(id_str, raise_if_not_found=raise_if_not_found)
def _tag_root(self, el):
for rec in el: