94 lines
4.0 KiB
Python
94 lines
4.0 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
from ast import literal_eval
|
|
|
|
from odoo import api, models, fields, _
|
|
from odoo.http import request
|
|
|
|
class IrUiMenu(models.Model):
|
|
_name = 'ir.ui.menu'
|
|
_description = 'Menu'
|
|
_inherit = ['studio.mixin', 'ir.ui.menu']
|
|
|
|
is_studio_configuration = fields.Boolean(
|
|
string='Studio Configuration Menu',
|
|
help='Indicates that this menu was created by Studio to hold configuration sub-menus',
|
|
readonly=True)
|
|
|
|
def write(self, vals):
|
|
""" When renaming a menu will rename the windows action.
|
|
"""
|
|
for menu in self:
|
|
if menu._context.get('studio') and 'name' in vals and menu.action:
|
|
menu.action.name = vals['name']
|
|
return super().write(vals)
|
|
|
|
@api.model
|
|
def load_menus(self, debug):
|
|
menus = super(IrUiMenu, self).load_menus(debug)
|
|
cids = request and request.httprequest.cookies.get('cids')
|
|
if cids:
|
|
cids = [int(cid) for cid in cids.split(',')]
|
|
company = self.env['res.company'].browse(cids[0]) \
|
|
if cids and all([cid in self.env.user.company_ids.ids for cid in cids]) \
|
|
else self.env.user.company_id
|
|
menus['root']['backgroundImage'] = bool(company.background_image)
|
|
return menus
|
|
|
|
@api.model
|
|
def customize(self, to_move, to_delete):
|
|
""" Apply customizations on menus. The deleted elements will no longer be active.
|
|
When moving a menu, we needed to resequence it. Note that this customization will
|
|
not be kept when upgrading the module (we don't put the ir.model.data in noupdate)
|
|
|
|
:param to_move: a dict of modifications with menu ids as keys
|
|
ex: {10: {'parent_id': 1, 'sequence': 0}, 11: {'sequence': 1}}
|
|
:param to_delete: a list of ids
|
|
"""
|
|
|
|
for menu in to_move:
|
|
menu_id = self.browse(int(menu))
|
|
if 'parent_menu_id' in to_move[menu]:
|
|
menu_id.parent_id = to_move[menu]['parent_menu_id']
|
|
if 'sequence' in to_move[menu]:
|
|
menu_id.sequence = to_move[menu]['sequence']
|
|
|
|
self.browse(to_delete).write({'active': False})
|
|
|
|
return True
|
|
|
|
def _get_studio_configuration_menu(self):
|
|
"""
|
|
Get (or create) a configuration menu that will hold some Studio models.
|
|
|
|
Creating a model through Studio can create secondary models, such as tags
|
|
or stages. These models need their own menu+action, which should be stored
|
|
under a config menu (child of the app root menu). If this is a Studio app,
|
|
find or create the Configuration menu; if the app is not a Studio app, find or
|
|
create the 'Custom Configuration' menu, to avoid confusion with a potential
|
|
'Configuration' menu which could already be present.
|
|
"""
|
|
self.ensure_one()
|
|
root_id = int(self.parent_path.split('/')[0])
|
|
root_xmlids = self.env['ir.model.data'].search_read(
|
|
domain=[('model', '=', 'ir.ui.menu'), ('res_id', '=', root_id)],
|
|
fields=['module', 'name', 'studio']
|
|
)
|
|
# look for a studio config menu in the submenus
|
|
parent_path = '%s/' % root_id
|
|
new_context = dict(self._context)
|
|
new_context.update({'ir.ui.menu.full_list': True}) # allows to create a menu without action
|
|
config_menu = self.with_context(new_context).search([
|
|
('parent_path', 'like', parent_path), ('is_studio_configuration', '=', True)
|
|
])
|
|
if not config_menu:
|
|
is_studio_app = root_xmlids and any(map(lambda xmlid: xmlid['studio'], root_xmlids))
|
|
menu_name = _('Configuration') if is_studio_app else _('Custom Configuration')
|
|
config_menu = self.create({
|
|
'name': menu_name,
|
|
'is_studio_configuration': True,
|
|
'parent_id': root_id,
|
|
'sequence': 1000,
|
|
})
|
|
return config_menu
|