def __init__(self, **attrs): icon = attrs.get('name') attrs['name'] = attrs.get('name', 'Image').replace("-", "_") super(Image, self).__init__(**attrs) self.filename = attrs.get('filename', '') self.state = attrs.get('state') self.field = self.name.split('/')[-1] if attrs.get('widget'): extra_url_params = {} if not (self.id and self.id != 'None'): # during record creation provide current value (from default_get()) # so we do not need to call default_get() twice extra_url_params['default_value'] = self.value self.src = tools.url('/openerp/form/binary_image_get_image', model=self.model, id=self.id, field=self.field, nocache=random.randint(0, 2**32), **extra_url_params) self.height = attrs.get('img_height', attrs.get('height', None)) self.width = attrs.get('img_width', attrs.get('width', None)) self.validator = validators.Binary() else: self.src = icons.get_icon(icon) if self.readonly: self.editable = False
def create(self, params): view_id = (params.view_ids or False) and params.view_ids[0] domain = params.domain context = params.context ctx = dict(context, **rpc.session.context) res_id = params.ids or 0 model = params.model if view_id: view_base = rpc.session.execute('object', 'execute', 'ir.ui.view', 'read', [view_id], ['model', 'type'], context)[0] model = view_base['model'] view = cache.fields_view_get(model, view_id, view_base['type'], context) else: view = cache.fields_view_get(model, False, 'tree', context) fields = cache.fields_get(view['model'], False, context) tree = tree_view.ViewTree(view, model, res_id, domain=domain, context=context, action="/tree/action", fields=fields) if tree.toolbar: proxy = rpc.RPCProxy(model) for tool in tree.toolbar: if tool.get('icon'): tool['icon'] = icons.get_icon(tool['icon']) else: tool['icon'] = False id = tool['id'] ids = proxy.read([id], [tree.field_parent], ctx)[0][tree.field_parent] tool['ids'] = ids can_shortcut = self.can_shortcut_create() shortcut_ids = [] for sc in cherrypy.session.get('terp_shortcuts') or []: if isinstance(sc['res_id'], tuple): shortcut_ids.append(sc['res_id'][0]) else: shortcut_ids.append(sc['res_id']) return { 'tree': tree, 'model': model, 'can_shortcut': can_shortcut, 'shortcut_ids': shortcut_ids }
def __init__(self, **attrs): super(Filter, self).__init__(**attrs) default_domain = attrs.get('default_domain') self.global_domain = [] self.icon = attrs.get('icon') self.filter_domain = attrs.get('domain', []) self.help = attrs.get('help') self.filter_id = 'filter_%s' % (random.randint(0,10000)) filter_context = attrs.get('context') screen_context = attrs.get('screen_context', {}) self.def_checked = False self.groupcontext = [] default_search = get_search_default(attrs, screen_context, default_domain) # context implemented only for group_by. self.group_context = None if filter_context: self.filter_context = eval(filter_context) self.group_context = self.filter_context.get('group_by', False) if self.group_context: if isinstance(self.group_context, list): self.group_context = map(lambda x: 'group_' + x, self.group_context) else: self.group_context = 'group_' + self.group_context if default_search: self.def_checked = True self.global_domain += (expr_eval(self.filter_domain, {'context':screen_context})) if self.group_context: self.groupcontext = self.group_context self.nolabel = True self.readonly = False if self.filter_context: if not self.filter_context.get('group_by'): self.filter_context = self.filter_context else: self.filter_context = {} self.text_val = self.string or self.help if self.icon: self.icon = icons.get_icon(self.icon) if self.string == self.help: self.help = None self.first_box = attrs.get('first_box') self.last_box = attrs.get('last_box') self.first_last_box = attrs.get('first_last_box') if not self.def_checked and attrs.get('group_by_ctx'): if self.group_context in attrs['group_by_ctx']: self.def_checked = True
def get_record(self): items = {'string' : self.string, 'name' : self.name, 'localName' : self.localName, 'view_id' : self.view_id, 'delete': icons.get_icon('gtk-remove')} if self.localName != 'view': items.update( add=icons.get_icon('gtk-add'), up=icons.get_icon('gtk-go-up'), down=icons.get_icon('gtk-go-down')) if self.localName not in ('view', 'newline'): items['edit'] = icons.get_icon('gtk-edit') record = { 'id' : self.id, 'items' : items} if self.children: record['children'] = [c.get_record() for c in self.children] return record
def __init__(self, **attrs): super(Button, self).__init__(**attrs) # remove mnemonic self.string = re.sub('_(?!_)', '', self.string or '') self.btype = attrs.get('special', attrs.get('type', 'workflow')) self.context = attrs.get("context", {}) self.nolabel = True self.target = '' if self.icon: self.icon = icons.get_icon(self.icon) self.default_focus = attrs.get('default_focus', 0)
def get_record(self): items = { 'string': self.string, 'name': self.name, 'localName': self.localName, 'view_id': self.view_id, 'delete': icons.get_icon('gtk-remove') } if self.localName != 'view': items.update(add=icons.get_icon('gtk-add'), up=icons.get_icon('gtk-go-up'), down=icons.get_icon('gtk-go-down')) if self.localName not in ('view', 'newline'): items['edit'] = icons.get_icon('gtk-edit') record = {'id': self.id, 'items': items} if self.children: record['children'] = [c.get_record() for c in self.children] return record
def __init__(self, **attrs): super(Button, self).__init__(**attrs) # remove mnemonic self.string = re.sub('_(?!_)', '', self.string or '') if (getattr(cherrypy.request, 'terp_params', {}) and cherrypy.request.terp_params.o2m and not cherrypy.request.terp_params.o2m_id): self.readonly = True self.btype = attrs.get('special', attrs.get('type', 'workflow')) self.context = attrs.get("context", {}) self.nolabel = True self.target = '' if self.icon: self.icon = icons.get_icon(self.icon) self.default_focus = attrs.get('default_focus', 0)
def __init__(self, **attrs): icon = attrs.get('name') attrs['name'] = attrs.get('name', 'Image').replace("-","_") super(Image, self).__init__(**attrs) self.filename = attrs.get('filename', '') self.state = attrs.get('state') self.field = self.name.split('/')[-1] if attrs.get('widget'): self.src = tools.url('/openerp/form/binary_image_get_image', model=self.model, id=self.id, field=self.field, nocache=random.randint(0,2**32)) self.height = attrs.get('img_height', attrs.get('height', None)) self.width = attrs.get('img_width', attrs.get('width', None)) self.validator = validators.Binary() else: self.src = icons.get_icon(icon) if self.readonly: self.editable = False
def create(self, params): view_id = (params.view_ids or False) and params.view_ids[0] domain = params.domain context = params.context ctx = dict(context, **rpc.session.context) res_id = params.ids or 0 model = params.model if view_id: view_base = rpc.session.execute( 'object', 'execute', 'ir.ui.view', 'read', [view_id], ['model', 'type'], context)[0] model = view_base['model'] view = cache.fields_view_get(model, view_id, view_base['type'], context) else: view = cache.fields_view_get(model, False, 'tree', context) fields = cache.fields_get(view['model'], False, context) tree = tree_view.ViewTree(view, model, res_id, domain=domain, context=context, action="/tree/action", fields=fields) if tree.toolbar: proxy = rpc.RPCProxy(model) for tool in tree.toolbar: if tool.get('icon'): tool['icon'] = icons.get_icon(tool['icon']) else: tool['icon'] = False id = tool['id'] ids = proxy.read([id], [tree.field_parent], ctx)[0][tree.field_parent] tool['ids'] = ids can_shortcut = self.can_shortcut_create() shortcut_ids = [] for sc in cherrypy.session.get('terp_shortcuts') or []: if isinstance(sc['res_id'], tuple): shortcut_ids.append(sc['res_id'][0]) else: shortcut_ids.append(sc['res_id']) return {'tree': tree, 'model': model, 'can_shortcut': can_shortcut, 'shortcut_ids': shortcut_ids}
def __init__(self, **attrs): super(Button, self).__init__(**attrs) self.states = attrs.get('states') if self.states: self.states = self.states.split(',') self.btype = attrs.get('special', attrs.get('type', 'workflow')) self.icon = attrs.get('icon') self.attrs = attrs.get('attrs', {}) if self.icon: self.icon = icons.get_icon(self.icon) self.context = attrs.get('context', {}) self.help = self.help or self.string self.confirm = attrs.get('confirm') or '' self.readonly = False self.width = attrs.get('width', 16)
def __init__(self, **attrs): super(Button, self).__init__(**attrs) self.states = attrs.get("states") if self.states: self.states = self.states.split(",") self.btype = attrs.get("special", attrs.get("type", "workflow")) self.icon = attrs.get("icon") self.attrs = attrs.get("attrs", {}) if self.icon: self.icon = icons.get_icon(self.icon) self.context = attrs.get("context", {}) self.help = self.help or self.string self.confirm = attrs.get("confirm") or "" self.readonly = False self.width = attrs.get("width", 16)
def __init__(self, **attrs): icon = attrs.get('name') attrs['name'] = attrs.get('name', 'Image').replace("-", "_") super(Image, self).__init__(**attrs) self.filename = attrs.get('filename', '') self.state = attrs.get('state') self.field = self.name.split('/')[-1] if attrs.get('widget'): self.src = tools.url('/openerp/form/binary_image_get_image', model=self.model, id=self.id, field=self.field, nocache=random.randint(0, 2**32)) self.height = attrs.get('img_height', attrs.get('height', None)) self.width = attrs.get('img_width', attrs.get('width', None)) self.validator = validators.Binary() else: self.src = icons.get_icon(icon) if self.readonly: self.editable = False
def __init__(self, **attrs): icon = attrs.get('name') attrs['name'] = attrs.get('name', 'Image').replace("-","_") super(Image, self).__init__(**attrs) self.filename = attrs.get('filename', '') self.state = attrs.get('state') self.field = self.name.split('/')[-1] if attrs.get('widget'): extra_url_params = {} if not (self.id and self.id != 'None'): # during record creation provide current value (from default_get()) # so we do not need to call default_get() twice extra_url_params['default_value'] = self.value self.src = tools.url('/openerp/form/binary_image_get_image', model=self.model, id=self.id, field=self.field, nocache=random.randint(0,2**32), **extra_url_params) self.height = attrs.get('img_height', attrs.get('height', None)) self.width = attrs.get('img_width', attrs.get('width', None)) self.validator = validators.Binary() else: self.src = icons.get_icon(icon) if self.readonly: self.editable = False
def __init__(self, **attrs): icon = attrs.get("name") attrs["name"] = attrs.get("name", "Image").replace("-", "_") super(Image, self).__init__(**attrs) self.filename = attrs.get("filename", "") self.state = attrs.get("state") self.field = self.name.split("/")[-1] if attrs.get("widget"): self.src = tools.url( "/openerp/form/binary_image_get_image", model=self.model, id=self.id, field=self.field, nocache=random.randint(0, 2 ** 32), ) self.height = attrs.get("img_height", attrs.get("height", None)) self.width = attrs.get("img_width", attrs.get("width", None)) self.validator = validators.Binary() else: self.src = icons.get_icon(icon) if self.readonly: self.editable = False
def data(self, ids, model, fields, field_parent=None, icon_name=None, domain=[], context={}, sort_by=None, sort_order="asc", fields_info=None): if ids == 'None' or ids == '': ids = [] if isinstance(ids, basestring): ids = map(int, ids.split(',')) elif isinstance(ids, list): ids = map(int, ids) if isinstance(fields, basestring): fields = eval(fields) if isinstance(domain, basestring): domain = eval(domain) if isinstance(context, basestring): context = eval(context) if isinstance(fields_info, basestring): fields_info = simplejson.loads(fields_info) if field_parent and field_parent not in fields: fields.append(field_parent) proxy = rpc.RPCProxy(model) ctx = dict(context, **rpc.session.context) if icon_name: fields.append(icon_name) if model == 'ir.ui.menu' and 'action' not in fields: fields.append('action') result = proxy.read(ids, fields, ctx) if sort_by: fields_info_type = simplejson.loads(fields_info[sort_by]) result.sort(lambda a,b: self.sort_callback(a, b, sort_by, sort_order, type=fields_info_type['type'])) # format the data for field in fields: field_info = simplejson.loads(fields_info[field]) formatter = FORMATTERS.get(field_info['type']) for x in result: if x[field] and formatter: x[field] = formatter(x[field], field_info) records = [] for item in result: # empty string instead of False or None for k, v in item.items(): if v is None or v is False: item[k] = '' id = item.pop('id') record = { 'id': id, 'action': url('/openerp/tree/open', model=model, id=id, context=ctx), 'target': None, 'icon': None, 'children': [], 'items': item } if icon_name and item.get(icon_name): icon = item.pop(icon_name) record['icon'] = icons.get_icon(icon) if field_parent and field_parent in item: record['children'] = item.pop(field_parent) or None # For nested menu items, remove void action url # to suppress 'No action defined' error. if (model == 'ir.ui.menu' and record['children'] and not item['action']): record['action'] = None records.append(record) return {'records': records}
def execute(self, params): action = params.name model = params.model state = params.state datas = params.datas form = None buttons = [] if model: action = model.replace("wizard.", "", 1) else: model = "wizard." + action params.name = action params.model = model params.view_mode = [] if "form" not in datas: datas["form"] = {} wiz_id = params.wiz_id or rpc.Wizard().create(action) while state != "end": ctx = rpc.get_session().context.copy() ctx.update(datas.get("context" or {}) or {}) res = rpc.Wizard().execute(wiz_id, datas, state, ctx) if "datas" in res: datas["form"].update(res["datas"]) else: res["datas"] = {} if res["type"] == "form": fields = res["fields"] form_values = {} for f in fields: if "value" in fields[f]: form_values[f] = fields[f]["value"] if f in datas["form"] and fields[f]["type"] == "one2many": datas["form"][f] = [(1, d, {}) for d in datas["form"][f]] form_values.update(datas["form"]) datas["form"] = form_values res["datas"].update(datas["form"]) params.is_wizard = True params.view_mode = ["form"] params.view_type = "form" params.views = {"form": res} # keep track of datas and some other required information params.hidden_fields = [ tw.form.Hidden(name="_terp_datas", default=ustr(datas)), tw.form.Hidden(name="_terp_state2", default=state), tw.form.Hidden(name="_terp_wiz_id", default=wiz_id), ] form = tw.form_view.ViewForm(params, name="view_form", action="/openerp/wizard/action") buttons = [] for x in res.get("state", []): x = list(x) x[1] = re.sub("_(?!_)", "", x[1]) # remove mnemonic if len(x) >= 3: x[2] = icons.get_icon(x[2]) buttons.append(tuple(x)) params.state = state return dict(form=form, buttons=buttons) elif res["type"] == "action": import actions # If configuration is done if res.get("action") and res.get("action").get("res_model") == "ir.ui.menu" and res["state"] == "end": return self.end() act_res = actions.execute(res["action"], **datas) if act_res: return act_res state = res["state"] elif res["type"] == "print": import actions datas["report_id"] = res.get("report_id", False) if res.get("get_id_from_action", False): backup_ids = datas["ids"] datas["ids"] = datas["form"]["ids"] return actions.execute_report(res["report"], **datas) elif res["type"] == "state": state = res["state"] raise redirect("/openerp/wizard/end")
def __init__(self, **attrs): super(Filter, self).__init__(**attrs) default_domain = attrs.get('default_domain') self.global_domain = [] self.icon = attrs.get('icon') self.filter_domain = attrs.get('domain', []) self.help = attrs.get('help') self.filter_id = 'filter_%s' % (random.randint(0, 10000)) self.filter_name = attrs.get('name', '') self.filter_status = attrs.get('filter_status', {}).get(self.name) filter_context = attrs.get('context') screen_context = attrs.get('screen_context', {}) self.def_checked = False self.groupcontext = [] default_search = get_search_default(attrs, screen_context, default_domain) # context implemented only for group_by. self.group_context = None if filter_context: self.filter_context = eval(filter_context) self.group_context = self.filter_context.get('group_by', False) if self.group_context: if isinstance(self.group_context, list): self.group_context = map(lambda x: 'group_' + x, self.group_context) else: self.group_context = 'group_' + self.group_context if default_search: self.def_checked = True self.global_domain += (expr_eval(self.filter_domain, {'context': screen_context})) if self.group_context: self.groupcontext = self.group_context self.nolabel = True self.readonly = False if self.filter_context: if not self.filter_context.get('group_by'): self.filter_context = self.filter_context else: self.filter_context = {} self.text_val = self.string or self.help if self.icon: self.icon = icons.get_icon(self.icon) if self.string == self.help: self.help = None self.first_box = attrs.get('first_box') self.last_box = attrs.get('last_box') self.first_last_box = attrs.get('first_last_box') if not self.def_checked and attrs.get('group_by_ctx'): if self.group_context in attrs['group_by_ctx']: self.def_checked = True if self.filter_status is not None: # if filter_status is defined that means user have manually # check/unchecked the filter, so we override default choice # by user's choice. self.def_checked = bool(self.filter_status)
def execute(self, params): action = params.name model = params.model state = params.state datas = params.datas form = None buttons = [] if model: action = model.replace('wizard.', '', 1) else: model = 'wizard.' + action params.name = action params.model = model params.view_mode = [] if 'form' not in datas: datas['form'] = {} wiz_id = params.wiz_id or rpc.session.execute('wizard', 'create', action) while state != 'end': ctx = rpc.session.context.copy() ctx.update(datas.get('context' or {}) or {}) res = rpc.session.execute('wizard', 'execute', wiz_id, datas, state, ctx) if 'datas' in res: datas['form'].update(res['datas']) else: res['datas'] = {} if res['type']=='form': fields = res['fields'] form_values = {} for f in fields: if 'value' in fields[f]: form_values[f] = fields[f]['value'] if f in datas['form'] and fields[f]['type'] == "one2many": datas['form'][f] = [(1, d, {}) for d in datas['form'][f]] form_values.update(datas['form']) datas['form'] = form_values res['datas'].update(datas['form']) params.is_wizard = True params.view_mode = ['form'] params.view_type = 'form' params.views = {'form': res} # keep track of datas and some other required information params.hidden_fields = [tw.form.Hidden(name='_terp_datas', default=ustr(datas)), tw.form.Hidden(name='_terp_state2', default=state), tw.form.Hidden(name='_terp_wiz_id', default=wiz_id)] form = tw.form_view.ViewForm(params, name="view_form", action="/openerp/wizard/action") buttons = [] for x in res.get('state', []): x = list(x) x[1] = re.sub('_(?!_)', '', x[1]) # remove mnemonic if len(x) >= 3: x[2] = icons.get_icon(x[2]) buttons.append(tuple(x)) params.state = state return dict(form=form, buttons=buttons) elif res['type']=='action': import actions # If configuration is done if res.get('action') and res.get('action').get('res_model') == 'ir.ui.menu' and res['state'] == 'end': return self.end() act_res = actions.execute(res['action'], **datas) if act_res: return act_res state = res['state'] elif res['type']=='print': import actions datas['report_id'] = res.get('report_id', False) if res.get('get_id_from_action', False): backup_ids = datas['ids'] datas['ids'] = datas['form']['ids'] return actions.execute_report(res['report'], **datas) elif res['type']=='state': state = res['state'] raise redirect('/openerp/wizard/end')
def execute(self, params): action = params.name model = params.model state = params.state datas = params.datas form = None buttons = [] if model: action = model.replace('wizard.', '', 1) else: model = 'wizard.' + action params.name = action params.model = model params.view_mode = [] if 'form' not in datas: datas['form'] = {} wiz_id = params.wiz_id or rpc.session.execute('wizard', 'create', action) while state != 'end': ctx = rpc.session.context.copy() ctx.update(datas.get('context' or {}) or {}) res = rpc.session.execute('wizard', 'execute', wiz_id, datas, state, ctx) if 'datas' in res: datas['form'].update(res['datas']) else: res['datas'] = {} if res['type'] == 'form': fields = res['fields'] form_values = {} for f in fields: if 'value' in fields[f]: form_values[f] = fields[f]['value'] if f in datas['form'] and fields[f]['type'] == "one2many": datas['form'][f] = [(1, d, {}) for d in datas['form'][f]] form_values.update(datas['form']) datas['form'] = form_values res['datas'].update(datas['form']) params.is_wizard = True params.view_mode = ['form'] params.view_type = 'form' params.views = {'form': res} # keep track of datas and some other required information params.hidden_fields = [ tw.form.Hidden(name='_terp_datas', default=ustr(datas)), tw.form.Hidden(name='_terp_state2', default=state), tw.form.Hidden(name='_terp_wiz_id', default=wiz_id) ] form = tw.form_view.ViewForm(params, name="view_form", action="/openerp/wizard/action") buttons = [] for x in res.get('state', []): x = list(x) x[1] = re.sub('_(?!_)', '', x[1]) # remove mnemonic if len(x) >= 3: x[2] = icons.get_icon(x[2]) buttons.append(tuple(x)) params.state = state return dict(form=form, buttons=buttons) elif res['type'] == 'action': import actions # If configuration is done if res.get('action') and res.get('action').get( 'res_model') == 'ir.ui.menu' and res['state'] == 'end': return self.end() act_res = actions.execute(res['action'], **datas) if act_res: return act_res state = res['state'] elif res['type'] == 'print': import actions datas['report_id'] = res.get('report_id', False) if res.get('get_id_from_action', False): backup_ids = datas['ids'] datas['ids'] = datas['form']['ids'] return actions.execute_report(res['report'], **datas) elif res['type'] == 'state': state = res['state'] raise redirect('/openerp/wizard/end')
def __init__(self, **attrs): super(Filter, self).__init__(**attrs) default_domain = attrs.get('default_domain') self.global_domain = [] self.icon = attrs.get('icon') self.filter_domain = attrs.get('domain', []) self.help = attrs.get('help') self.filter_id = 'filter_%s' % (random.randint(0,10000)) self.filter_name = attrs.get('name', attrs.get('string', '')).replace('/', '-') self.filter_status = attrs.get('filter_status', {}).get(self.filter_name) filter_context = attrs.get('context') screen_context = attrs.get('screen_context', {}) self.def_checked = False self.groupcontext = [] default_search = get_search_default(attrs, screen_context, default_domain) # context implemented only for group_by. self.group_context = None if filter_context: self.filter_context = eval(filter_context) self.group_context = self.filter_context.get('group_by', False) if self.group_context: if isinstance(self.group_context, list): self.group_context = map(lambda x: 'group_' + x, self.group_context) else: self.group_context = 'group_' + self.group_context if default_search: self.def_checked = True self.global_domain += (expr_eval(self.filter_domain, {'context':screen_context})) if self.group_context: self.groupcontext = self.group_context self.nolabel = True self.readonly = False if self.filter_context: if not self.filter_context.get('group_by'): self.filter_context = self.filter_context else: self.filter_context = {} self.text_val = self.string or self.help if self.icon: self.icon = icons.get_icon(self.icon) if self.string == self.help: self.help = None self.first_box = attrs.get('first_box') self.last_box = attrs.get('last_box') self.first_last_box = attrs.get('first_last_box') if not self.def_checked and attrs.get('group_by_ctx'): if self.group_context in attrs['group_by_ctx']: self.def_checked = True if self.filter_status is not None: # if filter_status is defined that means user have manually # check/unchecked the filter, so we override default choice # by user's choice. self.def_checked = bool(self.filter_status)
def data(self, ids, model, fields, field_parent=None, icon_name=None, domain=[], context={}, sort_by=None, sort_order="asc", fields_info=None): if ids == 'None' or ids == '': ids = [] if isinstance(ids, basestring): ids = map(int, ids.split(',')) elif isinstance(ids, list): ids = map(int, ids) if isinstance(fields, basestring): fields = eval(fields) if isinstance(domain, basestring): domain = eval(domain) if isinstance(context, basestring): context = eval(context) if isinstance(fields_info, basestring): fields_info = simplejson.loads(fields_info) if field_parent and field_parent not in fields: fields.append(field_parent) proxy = rpc.RPCProxy(model) ctx = dict(context, **rpc.session.context) if icon_name: fields.append(icon_name) if model == 'ir.ui.menu' and 'action' not in fields: fields.append('action') result = proxy.read(ids, fields, ctx) if sort_by: fields_info_type = simplejson.loads(fields_info[sort_by]) result.sort(lambda a, b: self.sort_callback( a, b, sort_by, sort_order, type=fields_info_type['type'])) # format the data for field in fields: field_info = simplejson.loads(fields_info[field]) formatter = FORMATTERS.get(field_info['type']) for x in result: if x[field] and formatter: x[field] = formatter(x[field], field_info) records = [] for item in result: # empty string instead of False or None for k, v in item.items(): if v is None or v is False: item[k] = '' id = item.pop('id') record = { 'id': id, 'action': url('/openerp/tree/open', model=model, id=id, context=ctx), 'target': None, 'icon': None, 'children': [], 'items': item } if icon_name and item.get(icon_name): icon = item.pop(icon_name) record['icon'] = icons.get_icon(icon) if field_parent and field_parent in item: record['children'] = item.pop(field_parent) or None # For nested menu items, remove void action url # to suppress 'No action defined' error. if (model == 'ir.ui.menu' and record['children'] and not item['action']): record['action'] = None records.append(record) return {'records': records}