def update_dashboard(self, view_id, dst, src, ref=None): error = None view_id = int(view_id) views = rpc.RPCProxy('ir.ui.view') data = views.read([view_id])[0] doc = xml.dom.minidom.parseString(data['arch'].encode('utf-8')) pnode = utils.xml_locate(dst, doc)[0] src = xml_getElementsByTagAndName('*', src, doc)[0] if ref: ref = xml_getElementsByTagAndName('*', ref, doc)[0] pnode.insertBefore(src, ref) del data['id'] try: views.write(view_id, {'arch': doc.toxml(encoding="utf-8")}) except Exception, e: error = str(e)
def __init__(self, model, submenu=None, toolbar=None, id=None, view_type="form", multi=True, context=None, **kw): super(Sidebar, self).__init__(model=model, id=id) self.multi = multi self.context = context or {} self.ctx = context self.view_type = view_type toolbar = toolbar or {} submenu = submenu self.id = id or None self.reports = toolbar.get('print', []) self.actions = toolbar.get('action', []) self.relates = toolbar.get('relate', []) self.attachments = [] self.sub_menu = None action = 'client_action_multi' if self.view_type == 'form': action = 'tree_but_action' self.add_remote_action_values(action, self.actions) self.add_remote_action_values('client_print_multi', self.reports) if self.view_type == 'form' and id: attachments = rpc.RPCProxy('ir.attachment') attachment_ids = attachments.search( [('res_model', '=', model), ('res_id', '=', id), ('type', 'in', ['binary', 'url'])], 0, 0, 0, self.context) if attachment_ids: self.attachments = attachments.read(attachment_ids, ['name', 'url', 'type']) self.sub_menu = submenu
def get(self, id, res_model=None, res_id=False, title=None): id = int(id) res_id = eval(str(res_id)) proxy = rpc.RPCProxy('process.process') graph = proxy.graph_get(id, res_model, res_id, (80, 80, 150, 100), rpc.session.context) related = (res_model or None) and proxy.search_by_model(res_model, rpc.session.context) graph['related'] = dict(related or {}) if graph.get('resource'): graph['title'] = _("%(name)s - Resource: %(resource)s, State: %(state)s") % graph else: graph['title'] = graph['name'] def update_perm(perm): perm = perm or {} try: perm['date'] = format.format_datetime(perm['write_date'] or perm['create_date']) except: pass perm['text'] = _("Last modified by:") perm['value'] = perm.get('write_uid') or perm.get('create_uid') if perm['value']: perm['value'] = '%s (%s)' % (perm['value'][1], perm.get('date') or 'N/A') else: perm['value'] = 'N/A' return perm # last modified by graph['perm'] = update_perm(graph['perm'] or {}) for nid, node in graph['nodes'].items(): if not node.get('res'): continue node['res']['perm'] = update_perm(node['res']['perm'] or {}) return graph
def get_new_modules(self): if not addons.writeable: return [] modules = rpc.RPCProxy('ir.module.module') web_modules = modules.list_web() if not web_modules: return [] addons_to_load = map(operator.itemgetter(0), web_modules) addons_to_download = [ name for (name, version) in web_modules if (not addons.exists(name) or version > addons.get_info(name).get('version', '0')) ] # avoid querying for 0 addons if we have everything already if not addons_to_download: return addons_to_load web_payload = modules.get_web(addons_to_download) for module in web_payload: # Due to the way zip_directory works on the server, we get a toplevel dir called "web" for our addon, # rather than having it named "the right way". Dump to temp directory and move to right name. temp_dir = tempfile.mkdtemp() extract_zip_file(StringIO(module['content'].decode('base64')), temp_dir) # cleanup any existing addon of the same name module_dir = paths.addons(module['name']) shutil.rmtree(module_dir, ignore_errors=True) shutil.move(os.path.join(temp_dir, 'web'), module_dir) shutil.rmtree(temp_dir) dependencies = map(lambda u: u.encode('utf-8'), module['depends']) descriptor = open(os.path.join(module_dir, '__openerp__.py'), 'wb') descriptor.write('# -*- coding: utf-8 -*-\n') descriptor.write("%s" % ( { 'name': module['name'].encode('utf-8'), 'version': module['version'].encode('utf-8'), # addons depend at least of openerp 'depends': dependencies or ['openerp'], }, )) descriptor.close() return addons_to_load
def save(self, terp_save_only=False, **kw): params, data = TinyDict.split(kw) # remember the current page (tab) of notebooks cherrypy.session['remember_notebooks'] = True # bypass save, for button action in non-editable view if not (params.button and not params.editable and params.id): proxy = rpc.RPCProxy(params.model) if not params.id: id = proxy.create(data, params.context) params.ids = (params.ids or []) + [int(id)] params.id = int(id) params.count += 1 else: ctx = context_with_concurrency_info(params.context, params.concurrency_info) id = proxy.write([params.id], data, ctx) button = (params.button or False) and True # perform button action if params.button: res = self.button_action(params) if res: return res current = params.chain_get(params.source or '') if current: current.id = None if not params.id: params.id = int(id) elif not button: params.editable = False if not current and not button: params.load_counter = 2 return self.create(params)
def count_sum(self, model, ids, sum_fields): selected_ids = ast.literal_eval(ids) sum_fields = sum_fields.split(",") ctx = rpc.session.context.copy() proxy = rpc.RPCProxy(model) res = proxy.read(selected_ids, sum_fields, ctx) total = [] for field in sum_fields: total.append([]) for i in range(len(selected_ids)): for k in range(len(sum_fields)): total[k].append(res[i][sum_fields[k]]) total_sum = [] for s in total: total_sum.append(str(sum(s))) return dict(sum=total_sum)
def exp(self, import_compat="1", **kw): params, data = TinyDict.split(kw) ctx = dict((params.context or {}), **rpc.session.context) if ctx.get("group_by_no_leaf", 0): raise common.warning(_("You cannot export these record(s) !"), _('Error')) views = {} if params.view_mode and params.view_ids: for i, view in enumerate(params.view_mode): views[view] = params.view_ids[i] exports = rpc.RPCProxy('ir.exports') headers = [{'string': 'Name', 'name': 'name', 'type': 'char'}] tree = treegrid.TreeGrid('export_fields', model=params.model, headers=headers, url=tools.url('/openerp/impex/get_fields'), field_parent='relation', context=ctx, views=views, import_compat=int(import_compat)) tree.show_headers = False existing_exports = exports.read( exports.search([('resource', '=', params.model)], context=ctx), [], ctx) return dict(existing_exports=existing_exports, model=params.model, ids=params.ids, ctx=ctx, search_domain=params.search_domain, source=params.source, tree=tree, import_compat=import_compat)
def save_exp(self, **kw): params, data = TinyDict.split(kw) selected_list = data.get('fields') name = data.get('savelist_name') proxy = rpc.RPCProxy('ir.exports') if selected_list and name: if isinstance(selected_list, basestring): selected_list = [selected_list] proxy.create({ 'name': name, 'resource': params.model, 'export_fields': [(0, 0, { 'name': f }) for f in selected_list] }) raise redirect('/openerp/impex/exp', **kw)
def get(self, **kw): params, data = TinyDict.split(kw) error = None error_field = None model = params.model record = kw.get('record') record = eval(record) proxy = rpc.RPCProxy(model) data = {} res = proxy.fields_get(False, rpc.session.context) all_values = {} errors = [] for k, v in record.items(): values = {} for key, val in v.items(): for field in val: fld = {'value': val[field], 'type': res[field].get('type')} if fld['type'] == 'many2many': fld['type'] = 'char' datas = {field: fld} try: TinyForm(**datas).to_python() except TinyFormError, e: errors.append({e.field: ustr(e)}) except Exception, e: errors.append({field: ustr(e)}) datas['rec'] = field datas['rec_val'] = fld['value'] datas['type'] = fld['type'] values[key] = datas
def create(self, params, tg_errors=None): params.view_mode = ['tree', 'form'] params.view_type = 'tree' params.offset = params.offset or 0 params.limit = params.limit or 50 params.count = params.count or 0 params.filter_domain = params.filter_domain or [] params.editable = 0 form = self.create_form(params, tg_errors) # don't show links in list view, except the do_select link form.screen.widget.show_links = 0 if params.get('return_to'): proxy = rpc.RPCProxy(params.model) records = proxy.read(params.ids, ['name'], rpc.session.context) params['grp_records'] = records return dict(form=form, params=params, form_name=form.screen.widget.name)
def get_groups(self, events): if not self.level: return [] obj = self.level['object'] field = self.level['link'] keys = [] groups = {} for evt in events: group_id = evt.record[field] group_title = 'None' if not group_id: # create dummy group group_id = 0 if isinstance(group_id, (list, tuple)): group_id, group_title = evt.record[field] elif group_id: group_id, group_title = rpc.RPCProxy(obj).name_get( [group_id], rpc.session.context)[0] group = groups.setdefault( group_id, { 'id': str(group_id), 'title': group_title, 'model': obj, 'items': [] }) group['items'].append(str(evt.record_id)) if group_id not in keys: keys.append(group_id) return [groups[i] for i in keys]
def menu(self, active=None, next=None): try: menu_id = int(active) except (TypeError, ValueError): menu_id = False menus = rpc.RPCProxy("ir.ui.menu") ids = menus.search([('parent_id', '=', False)]) if next or active: if not menu_id and ids: menu_id = ids[0] menu = '' if menu_id: ctx = dict( lang='NO_LANG' ) # force loading original string even if the english have been translated... menu = menus.read([menu_id], ['name'], ctx)[0]['name'] or '' general_forum = 77459 forum = { 'accounting': 87921, 'administration': 87935, 'human resources': 87923, 'knowledge': 87927, 'manufacturing': 87915, 'marketing': 87925, 'point of sale': 87929, 'project': 87919, 'purchases': 87911, 'sales': 87907, 'tools': 87933, 'warehouse': 87913, }.get(menu.lower().strip(), general_forum) cherrypy.request.uservoice_forum = forum return super(Root, self).menu(active, next)
def duplicate(self, **kw): params, data = TinyDict.split(kw) if not params.ids: params.ids = [] id = params.id ctx = params.context model = params.model proxy = rpc.RPCProxy(model) new_id = proxy.copy(id, {}, ctx) if new_id: params.id = new_id params.ids += [int(new_id)] params.count += 1 args = { 'model': params.model, 'id': params.id, 'ids': ustr(params.ids), 'view_ids': ustr(params.view_ids), 'view_mode': ustr(params.view_mode), 'domain': ustr(params.domain), 'context': ustr(params.context), 'offset': params.offset, 'limit': params.limit, 'count': params.count, 'search_domain': ustr(params.search_domain), 'filter_domain': ustr(params.filter_domain) } if new_id: raise redirect(self.path + '/edit', **args) raise redirect(self.path + '/view', **args)
def _fields_get_all(model, views, context=None): context = context or {} def parse(root, fields): for node in root.childNodes: if node.nodeName in ('form', 'notebook', 'page', 'group', 'tree', 'hpaned', 'vpaned'): parse(node, fields) elif node.nodeName == 'field': attrs = node_attributes(node) name = attrs['name'] fields[name].update(attrs) return fields def get_view_fields(view): return parse( xml.dom.minidom.parseString( view['arch'].encode('utf-8')).documentElement, view['fields']) proxy = rpc.RPCProxy(model) tree_view = proxy.fields_view_get(views.get('tree', False), 'tree', context) form_view = proxy.fields_view_get(views.get('form', False), 'form', context) fields = {} fields.update(get_view_fields(tree_view)) fields.update(get_view_fields(form_view)) return fields
def __init__(self, **attrs): super(Action, self).__init__(**attrs) self.nolabel = True self.act_id= self.name proxy = rpc.RPCProxy("ir.actions.actions") res = proxy.read([self.act_id], ['type'], rpc.session.context) if not res: raise common.message(_('Action not found')) _type=res[0]['type'] self.action = rpc.session.execute('object', 'execute', _type, 'read', [self.act_id], False, rpc.session.context)[0] if 'view_mode' in attrs: self.action['view_mode'] = attrs['view_mode'] if self.action['type']=='ir.actions.act_window': if not self.action.get('domain', False): self.action['domain']='[]' ctx = dict(rpc.session.context, active_id=False, active_ids=[]) self.context = expr_eval(self.action.get('context', '{}'), ctx) self.domain = expr_eval(self.action['domain'], ctx) views = dict(map(lambda x: (x[1], x[0]), self.action['views'])) view_mode = self.action.get('view_mode', 'tree,form').split(',') view_ids = map(lambda x: views.get(x, False), view_mode) if views.keys() != view_mode: view_mode = map(lambda x: x[1], self.action['views']) view_ids = map(lambda x: x[0], self.action['views']) if self.action['view_type'] == 'form': params = TinyDict() params.updateAttrs( model=self.action['res_model'], id=False, ids=None, view_ids=view_ids, view_mode=view_mode, context=self.context, domain=self.domain, offset = 0, limit = 50 ) # get pager vars if set if hasattr(cherrypy.request, 'terp_params'): current = cherrypy.request.terp_params current = current.chain_get(self.name or '') or current params.updateAttrs( offset=current.offset, limit=current.limit ) self.screen = screen.Screen(params, prefix=self.name, editable=True, selectable=3) elif self.action['view_type']=='tree': pass #TODO
def view_get(self, view_id=None): def _inherit_apply(src, inherit, inherited_id): def _find(node, node2): # Check if xpath query or normal inherit (with field matching) if node2.nodeType == node2.ELEMENT_NODE and node2.localName == 'xpath': res = utils.get_xpath(node2.getAttribute('expr'), node) return res and res[0] else: if node.nodeType == node.ELEMENT_NODE and node.localName == node2.localName: res = True for attr in node2.attributes.keys(): if attr == 'position': continue if node.hasAttribute(attr): if node.getAttribute( attr) == node2.getAttribute(attr): continue res = False if res: return node for child in node.childNodes: res = _find(child, node2) if res: return res return None doc_src = xml.dom.minidom.parseString(src.encode('utf-8')) doc_dest = xml.dom.minidom.parseString(inherit.encode('utf-8')) for node2 in doc_dest.childNodes: if node2.localName == 'data': continue if not node2.nodeType == node2.ELEMENT_NODE: continue node = _find(doc_src, node2) if node: vnode = doc_dest.createElement('view') vnode.setAttribute('view_id', str(inherited_id)) vnode.appendChild(node2) node.appendChild(vnode) else: attrs = ''.join([ ' %s="%s"' % (attr, node2.getAttribute(attr)) for attr in node2.attributes.keys() if attr != 'position' ]) tag = "<%s%s>" % (node2.localName, attrs) raise AttributeError, "Couldn't find tag '%s' in parent view" % tag return doc_src.toxml().replace('\t', '') views = rpc.RPCProxy('ir.ui.view') res = views.read([view_id])[0] def _inherit_apply_rec(result, inherit_id): # get all views which inherit from (ie modify) this view inherit_ids = views.search([('inherit_id', '=', inherit_id)], 0, 0, 'priority') inherit_res = views.read(inherit_ids, ['arch', 'id']) for res2 in inherit_res: result = _inherit_apply(result, res2['arch'], res2['id']) result = _inherit_apply_rec(result, res2['id']) return result doc_arch = _inherit_apply_rec(res['arch'], view_id) doc_arch = xml.dom.minidom.parseString(doc_arch.encode('utf-8')) new_doc = xml.dom.getDOMImplementation().createDocument( None, 'view', None) new_doc.documentElement.setAttribute('view_id', str(view_id)) new_doc.documentElement.appendChild(doc_arch.documentElement) return { 'model': res['model'], 'view_id': view_id, 'view_type': res['type'], 'arch': new_doc.toxml().replace('\t', '') }
def remove_log(self, log_id): error = None try: rpc.RPCProxy('publisher_warranty.contract').del_user_message(log_id) except Exception, e: error = e
def parse_groups(group_by, grp_records, headers, ids, model, offset, limit, context, data, total_fields, fields): proxy = rpc.RPCProxy(model) grouped = [] grp_ids = [] for grp in grp_records: inner = {} for key, head in headers: if not isinstance(head, int): kind = head.get('type') if kind == 'progressbar': inner[key] = CELLTYPES[kind](value=grp.get(key), **head) grouped.append(inner) child = len(group_by) == 0 digits = (16, 2) if fields: for key, val in fields.items(): if val.get('digits'): digits = val['digits'] if isinstance(digits, basestring): digits = eval(digits) integer, digit = digits if grp_records and total_fields and group_by: for sum_key, sum_val in total_fields.items(): if grp_records[0].has_key(sum_key): value = sum(map(lambda x: x[sum_key], grp_records)) if isinstance(value, float): total_fields[sum_key][1] = format.format_decimal( value or 0.0, digit) else: total_fields[sum_key][1] = value if grp_records: for rec in grp_records: for key, val in rec.items(): if isinstance(val, float): rec[key] = format.format_decimal(val or 0.0, digit) for grp_by in group_by: if fields.get(grp_by).get( 'type') == 'boolean' and grp_by in rec and rec.get( grp_by) == False: rec[grp_by] = 'False' elif not rec.get(grp_by): rec[grp_by] = '' ch_ids = [] if child: rec_dom = rec.get('__domain') dom = [('id', 'in', ids)] + rec_dom ch_ids = [ d for id in proxy.search(dom, offset, limit, 0, context) for d in data if int(str(d.get('id'))) == id ] # Need to convert in String and then Int. rec['child_rec'] = ch_ids rec['groups_id'] = 'group_' + str(random.randrange(1, 10000)) if group_by: rec['group_by_id'] = group_by[0] + '_' + str( grp_records.index(rec)) return grouped, grp_ids
def __init__(self, name, model, view, ids=[], domain=[], context={}, **kw): self.context = context or {} self.domain = copy.deepcopy(domain) or [] self.group_by_no_leaf = self.context.get('group_by_no_leaf', 0) self.selectable = kw.get('selectable', 0) self.editable = kw.get('editable', False) self.pageable = kw.get('pageable', True) self.offset = kw.get('offset', 0) self.limit = kw.get('limit', 0) self.count = kw.get('count', 0) self.link = kw.get('nolinks') proxy = rpc.RPCProxy(model) # adding the piece of code to set limit as 0 to get rid of pager's negative offset error. # Here, we don't change the self.limit as Pager needs -1 to treat Unlimited limit atribute terp_offset, terp_limit = self.offset, self.limit if self.limit < 0: terp_offset, terp_limit = 0, 0 custom_search_domain = getattr(cherrypy.request, 'custom_search_domain', []) custom_filter_domain = getattr(cherrypy.request, 'custom_filter_domain', []) if custom_search_domain: self.domain.extend(i for i in custom_search_domain if i not in domain) elif custom_filter_domain: self.domain.extend(i for i in custom_filter_domain if i not in domain) if ids is None and not self.group_by_no_leaf: ids = proxy.search(self.domain, terp_offset, terp_limit, 0, self.context) if len(ids) < self.limit: self.count = len(ids) else: self.count = proxy.search_count(domain, context) if ids and not isinstance(ids, list): ids = [ids] self.ids = ids self.concurrency_info = None self.group_by_ctx = kw.get('group_by_ctx', []) if not isinstance(self.group_by_ctx, list): self.group_by_ctx = [self.group_by_ctx] fields = view['fields'] self.grp_records = [] self.context.update(rpc.session.context.copy()) if self.group_by_no_leaf: self.limit = -1 super(ListGroup, self).__init__(name=name, model=model, view=view, ids=self.ids, domain=self.domain, context=self.context, limit=self.limit, count=self.count, offset=self.offset, editable=self.editable, selectable=self.selectable) if self.group_by_ctx: self.context['group_by'] = self.group_by_ctx else: self.group_by_ctx = self.context.get('group_by', []) self.group_by_ctx, self.hiddens, self.headers = parse( self.group_by_ctx, self.hiddens, self.headers, None, self.group_by_ctx) self.grp_records = proxy.read_group( self.context.get('__domain', []) + (self.domain or []), fields.keys(), self.group_by_ctx, 0, False, self.context) terp_params = getattr(cherrypy.request, 'terp_params', []) if terp_params.sort_key and terp_params.sort_key in self.group_by_ctx and self.group_by_ctx.index( terp_params.sort_key) == 0: if terp_params.sort_order == 'desc': rev = True else: rev = False self.grp_records = sorted(self.grp_records, key=itemgetter(terp_params.sort_key), reverse=rev) for grp_rec in self.grp_records: if not grp_rec.get('__domain'): grp_rec['__domain'] = self.context.get( '__domain', []) + (self.domain or []) if not grp_rec.get('__context'): grp_rec['__context'] = {'group_by': self.group_by_ctx} self.grouped, grp_ids = parse_groups(self.group_by_ctx, self.grp_records, self.headers, self.ids, model, terp_offset, terp_limit, self.context, self.data, self.field_total, fields) if self.pageable: self.count = len(self.grouped) self.pager = Pager(ids=self.ids, offset=self.offset, limit=self.limit, count=self.count) self.pager._name = self.name
def get_fields(self, model, prefix='', name='', field_parent=None, **kw): parent_field = kw.get('ids').split(',')[0].split('/') if len(parent_field) == 1: parent_field = parent_field[0] else: parent_field = parent_field[-2] is_importing = kw.get('is_importing', False) import_compat = bool(int(kw.get('import_compat', True))) try: ctx = ast.literal_eval(kw['context']) except: ctx = {} ctx.update(**rpc.session.context) try: views = ast.literal_eval(kw['views']) except: views = {} fields = _fields_get_all(model, views, ctx) m2ofields = cherrypy.session.get('fld') if m2ofields: for i in m2ofields: if i == parent_field: fields = {} else: m2ofields = [] fields.update({ 'id': { 'string': 'ID' }, '.id': { 'string': 'Database ID' } }) fields_order = fields.keys() fields_order.sort(lambda x, y: -cmp(fields[x].get('string', ''), fields[y].get('string', ''))) records = [] for i, field in enumerate(fields_order): value = fields[field] record = {} if import_compat and value.get('readonly', False): ok = False for sl in value.get('states', {}).values(): for s in sl: ok = ok or (s == ('readonly', False)) if not ok: continue id = prefix + (prefix and '/' or '') + field nm = name + (name and '/' or '') + value['string'] if is_importing and (value.get('type') not in ('reference',)) and (not value.get('readonly') \ or not dict(value.get('states', {}).get('draft', [('readonly', True)])).get('readonly', True)): record.update(id=id, items={'name': nm}, action='javascript: void(0)', target=None, icon=None, children=[], required=value.get('required', False)) records.append(record) elif not is_importing: record.update(id=id, items={'name': nm}, action='javascript: void(0)', target=None, icon=None, children=[]) records.append(record) if len(nm.split('/')) < 3 and value.get('relation', False): if import_compat or is_importing: ref = value.pop('relation') proxy = rpc.RPCProxy(ref) cfields = proxy.fields_get(False, rpc.session.context) if (value['type'] == 'many2many') and not is_importing: record['children'] = None record['params'] = { 'model': ref, 'prefix': id, 'name': nm } elif (value['type'] == 'many2one') or (value['type'] == 'many2many' and is_importing): m2ofields.append(field) cfields_order = cfields.keys() cfields_order.sort( lambda x, y: -cmp(cfields[x].get('string', ''), cfields[y].get('string', ''))) children = [] for j, fld in enumerate(cfields_order): cid = id + '/' + fld cid = cid.replace(' ', '_') children.append(cid) record['children'] = children or None record['params'] = { 'model': ref, 'prefix': id, 'name': nm } cherrypy.session['fld'] = m2ofields else: cfields_order = cfields.keys() cfields_order.sort( lambda x, y: -cmp(cfields[x].get('string', ''), cfields[y].get('string', ''))) children = [] for j, fld in enumerate(cfields_order): cid = id + '/' + fld cid = cid.replace(' ', '_') children.append(cid) record['children'] = children or None record['params'] = { 'model': ref, 'prefix': id, 'name': nm } else: ref = value.pop('relation') proxy = rpc.RPCProxy(ref) cfields = proxy.fields_get(False, rpc.session.context) cfields_order = cfields.keys() cfields_order.sort( lambda x, y: -cmp(cfields[x].get('string', ''), cfields[y].get('string', ''))) children = [] for j, fld in enumerate(cfields_order): cid = id + '/' + fld cid = cid.replace(' ', '_') children.append(cid) record['children'] = children or None record['params'] = {'model': ref, 'prefix': id, 'name': nm} cherrypy.session['fld'] = [] records.reverse() return dict(records=records)
def filter(self, **kw): params, data = TinyDict.split(kw) if params.get('_terp_save_current_id'): ctx = dict((params.context or {}), **rpc.session.context) if params.id: rpc.RPCProxy(params.model).write([params.id], data, ctx) else: id = rpc.RPCProxy(params.model).create(data, ctx) params.ids.append(id) params.count += 1 l = params.limit or 50 o = params.offset or 0 c = params.count or 0 id = params.id or False ids = params.ids or [] filter_action = params.filter_action if ids and filter_action == 'FIRST': o = 0 id = ids[0] if ids and filter_action == 'LAST': o = c - c % l id = ids[-1] if ids and filter_action == 'PREV': if id == ids[0]: o -= l elif id in ids: id = ids[ids.index(id) - 1] if ids and filter_action == 'NEXT': if id == ids[-1]: o += l elif id in ids: id = ids[ids.index(id) + 1] elif id is False: o = 0 id = ids[0] if filter_action: # remember the current page (tab) of notebooks cherrypy.session['remember_notebooks'] = True if params.offset != o: domain = params.domain if params.search_domain is not None: domain = params.search_domain data = params.search_data ctx = params.context or {} ctx.update(rpc.session.context.copy()) res = search(params.model, o, l, domain=domain, context=ctx, data=data) o = res['offset'] l = res['limit'] if not c: c = res['count'] params.search_domain = res['search_domain'] params.search_data = res['search_data'] ids = res['ids'] id = False if ids and filter_action in ('FIRST', 'NEXT'): id = ids[0] if ids and filter_action in ('LAST', 'PREV'): id = ids[-1] params.id = id params.ids = ids params.offset = o params.limit = l params.count = c return self.create(params)
def __init__(self, **kw): super(Logs, self).__init__() # Server log will display in flash message in form, tree view for any server action like wizard. self.logs = rpc.RPCProxy('res.log').get()
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 act_window(action, data): if not action.get('opened'): action.setdefault('target', 'current') return act_window_opener(action, data) for key in ('res_id', 'res_model', 'view_type', 'view_mode', 'limit', 'search_view'): data[key] = action.get(key, data.get(key)) if not data.get('search_view') and data.get('search_view_id'): data['search_view'] = str( rpc.session.execute('object', 'execute', data['res_model'], 'fields_view_get', data['search_view_id'], 'search', data['context'])) if data.get('limit'): data['limit'] = 20 if action.get('target') and action['target'] == 'popup' and action.get( 'res_model') and isinstance(action.get('context'), dict): search_view_id = rpc.RPCProxy('ir.ui.view').search( [('type', '=', 'search'), ('model', '=', action['res_model'])], 0, 0, 0, rpc.session.context) if search_view_id and action['context'].get('search_view'): action['context']['search_view'] = search_view_id[0] view_ids = False if action.get('views', []): if isinstance(action['views'], list): view_ids = [x[0] for x in action['views']] data['view_mode'] = ",".join([x[1] for x in action['views']]) else: if action.get('view_id'): view_ids = [action['view_id'][0]] elif action.get('view_id'): view_ids = [action['view_id'][0]] if not action.get('domain'): action['domain'] = '[]' ctx = dict(data.get('context', {}), active_id=data.get('id', False), active_ids=data.get('ids', []), active_model=data.get('model', False)) if action.get('context') and isinstance(action['context'], dict): if not action['context'].get('active_ids'): action['context']['active_ids'] = ctx['active_ids'] or [] ctx.update(expr_eval(action.get('context', '{}'), ctx)) search_view = action.get('search_view_id') if search_view: if isinstance(search_view, (list, tuple)): ctx['search_view'] = search_view[0] else: ctx['search_view'] = search_view # save active_id in session rpc.session.active_id = data.get('id') domain = expr_eval(action['domain'], ctx) if data.get('domain'): domain.append(data['domain']) if 'menu' in data['res_model'] and action.get('name') == 'Menu': return close_popup() if action.get('display_menu_tip'): display_menu_tip = action.get('help') else: display_menu_tip = None return execute_window(view_ids, data['res_model'], data['res_id'], domain, action['view_type'], ctx, data['view_mode'], name=action.get('name'), target=action.get('target'), limit=data.get('limit'), search_view=data['search_view'], context_menu=data.get('context_menu'), display_menu_tip=display_menu_tip, action_id=action.get('id'))
def index(self, translate='fields', **kw): params, data = TinyDict.split(kw) ctx = dict((params.context or {}), **rpc.session.context) params['context'] = ustr(ctx) proxy = rpc.RPCProxy('res.lang') lang_ids = proxy.search([('translatable', '=', '1')]) langs = proxy.read(lang_ids, ['code', 'name']) proxy = rpc.RPCProxy(params.model) data = [] view = [] view_view = cache.fields_view_get(params.model, False, 'form', ctx, True) view_fields = view_view['fields'] view_relates = view_view.get('toolbar') names = view_fields.keys() names.sort(lambda x, y: cmp(view_fields[x].get('string', ''), view_fields[y].get('string', ''))) if translate == 'fields' and params.id: for name in names: attrs = view_fields[name] if attrs.get('translate'): type = attrs.get('type') value = {} for lang in langs: context = copy.copy(ctx) context['lang'] = adapt_context(lang['code']) val = proxy.read([params.id], [name], context) val = val[0] if isinstance( val, list) and len(val) > 0 else None if val[name] is False: val[name] = "" value[lang['code']] = val[name] if isinstance(val,dict) \ and name in val else None data += [(name, value, None, attrs.get('string'), type)] if translate == 'labels': for name in names: attrs = view_fields[name] if attrs.get('string'): value = {} for lang in langs: code = lang['code'] val = proxy.read_string(False, [code], [name]) if name in val[code]: value[code] = val[code][name] or None if value: data += [(name, value, None, None, None)] if translate == 'relates' and view_relates: for bar, tools in view_relates.items(): for tool in tools: value = {} for lang in langs: code = lang['code'] val = rpc.session.execute('object', 'execute', tool['type'], 'read', [tool['id']], ['name'], {'lang': code}) value[code] = val[0]['name'] or None data += [(tool['id'], value, tool['type'], None, None)] if translate == 'view': for lang in langs: code = lang['code'] view_item_ids = rpc.session.execute( 'object', 'execute', 'ir.translation', 'search', [('name', '=', params.model), ('type', '=', 'view'), ('lang', '=', code)]) view_items = rpc.session.execute('object', 'execute', 'ir.translation', 'read', view_item_ids, ['src', 'value']) values = [] for val in view_items: values += [val] if values: view += [(code, values)] return dict(translate=translate, langs=langs, data=data, view=view, model=params.model, id=params.id, ctx=params.context)
def datas_read(ids, model, flds, context=None): ctx = dict((context or {}), **rpc.session.context) return rpc.RPCProxy(model).export_data(ids, flds, ctx)
def __init__(self, name, model, view, ids=[], domain=[], parent_group=None, group_level=0, groups=[], context={}, **kw): self.context = context or {} self.domain = domain or [] self.selectable = kw.get('selectable', 0) self.editable = kw.get('editable', False) self.pageable = kw.get('pageable', True) self.offset = kw.get('offset', 0) self.limit = kw.get('limit', 50) self.count = kw.get('count', 0) self.link = kw.get('nolinks') self.parent_group = parent_group or None self.group_level = group_level or 0 sort_key = kw.get('sort_key') or '' sort_order = kw.get('sort_order') or '' proxy = rpc.RPCProxy(model) if ids is None: if self.limit > 0: ids = proxy.search(self.domain, self.offset, self.limit, 0, rpc.session.context.copy()) else: ids = proxy.search(self.domain, 0, 0, 0, rpc.session.context.copy()) if len(ids) < self.limit: self.count = len(ids) else: self.count = proxy.search_count(domain, rpc.session.context.copy()) if ids and not isinstance(ids, list): ids = [ids] self.ids = ids self.concurrency_info = None self.group_by_ctx = kw.get('group_by_ctx', []) if not isinstance(self.group_by_ctx, list): self.group_by_ctx = [self.group_by_ctx] fields = view['fields'] self.grp_records = [] super(MultipleGroup, self).__init__(name=name, model=model, view=view, ids=self.ids, domain=self.domain, parent_group=parent_group, group_level=group_level, groups=groups, context=self.context, limit=self.limit, count=self.count, offset=self.offset, editable=self.editable, selectable=self.selectable, sort_order=sort_order, sort_key=sort_key) self.group_by_no_leaf = self.context.get('group_by_no_leaf', 0) self.group_by_ctx, self.hiddens, self.headers = parse( self.group_by_ctx, self.hiddens, self.headers, self.group_level, groups) if not len(self.group_by_ctx): # Display RAW records (i.e non grouped) # NOTE: fetching of ids and data are done by List.__init__() - based on # provided domain, offset, limit, ... params self.grp_childs = [{ 'child_rec': self.data, 'groups_id': 'group_' + str(random.randrange(1, 10000)), 'group_by_id': parent_group, }] return self.grp_records = proxy.read_group(self.context.get('__domain', []), fields.keys(), self.group_by_ctx, 0, False, self.context) for grp_rec in self.grp_records: grp_rec['__level'] = self.group_level if sort_key and sort_key in self.group_by_ctx and self.group_by_ctx.index( sort_key) == 0: if sort_order == 'desc': rev = True else: rev = False self.grp_records = sorted(self.grp_records, key=itemgetter(sort_key), reverse=rev) self.grouped, grp_ids = parse_groups( self.group_by_ctx, self.grp_records, self.headers, self.ids, model, self.offset, self.limit, rpc.session.context.copy(), self.data, self.field_total, fields)
def detect_data(self, csvfile, csvsep, csvdel, csvcode, csvskip, **kw): params, data = TinyDict.split(kw) _fields = {} _fields_invert = {} error = None fields = dict( rpc.RPCProxy(params.model).fields_get(False, rpc.session.context)) fields.update({ 'id': { 'string': 'ID' }, '.id': { 'string': 'Database ID' } }) def model_populate(fields, prefix_node='', prefix=None, prefix_value='', level=2): def str_comp(x, y): if x < y: return 1 elif x > y: return -1 else: return 0 fields_order = fields.keys() fields_order.sort(lambda x, y: str_comp( fields[x].get('string', ''), fields[y].get('string', ''))) for field in fields_order: if (fields[field].get('type','') not in ('reference',))\ and (not fields[field].get('readonly')\ or not dict(fields[field].get('states', {}).get( 'draft', [('readonly', True)])).get('readonly',True)): st_name = prefix_value + fields[field]['string'] or field _fields[prefix_node + field] = st_name _fields_invert[st_name] = prefix_node + field if fields[field].get('type', '') == 'one2many' and level > 0: fields2 = rpc.session.execute( 'object', 'execute', fields[field]['relation'], 'fields_get', False, rpc.session.context) model_populate(fields2, prefix_node + field + '/', None, st_name + '/', level - 1) if fields[field].get('relation', False) and level > 0: model_populate( { '/id': { 'type': 'char', 'string': 'ID' }, '.id': { 'type': 'char', 'string': 'Database ID' } }, prefix_node + field, None, st_name + '/', level - 1) fields.update({ 'id': { 'string': 'ID' }, '.id': { 'string': _('Database ID') } }) model_populate(fields) try: data = csv.reader(csvfile.file, quotechar=str(csvdel), delimiter=str(csvsep)) except: raise common.warning(_('Error opening .CSV file'), _('Input Error.')) records = [] fields = [] word = '' limit = 3 try: for i, row in enumerate(data): records.append(row) if i == limit: break for line in records: for word in line: word = ustr(word.decode(csvcode)) if word in _fields: fields.append((word, _fields[word])) elif word in _fields_invert.keys(): fields.append((_fields_invert[word], word)) else: error = { 'message': _("You cannot import the field '%s', because we cannot auto-detect it" % (word, )) } break except: error = { 'message': _('Error processing the first line of the file. Field "%s" is unknown' ) % (word, ), 'title': _('Import Error.') } kw['fields'] = fields if error: csvfile.file.seek(0) return self.imp(error=dict(error, preview=csvfile.file.read(200)), **kw) return self.imp(records=records, **kw)
def eval_domain_filter(self, **kw): all_domains = kw.get('all_domains') custom_domains = kw.get('custom_domain') all_domains = eval(all_domains) domains = all_domains.get('domains') selection_domain = all_domains.get('selection_domain') search_context = all_domains.get('search_context') group_by_ctx = kw.get('group_by_ctx', []) if isinstance(group_by_ctx, str): group_by_ctx = group_by_ctx.split(',') if domains: domains = eval(domains) c = search_context.get('context', {}) v = search_context.get('value') if v and isinstance(v, basestring) and '__' in v: value, operator = v.split('__') v = int(value) ctx = expr_eval(c, {'self':v}) context = rpc.session.context if ctx: ctx.update(context) domain = [] check_domain = all_domains.get('check_domain') if check_domain and isinstance(check_domain, basestring): domain = expr_eval(check_domain, context) or [] search_data = {} model = kw.get('model') proxy = rpc.RPCProxy(model) res = proxy.fields_get(False, context) all_error = [] fld = {} if domains: for field, value in domains.iteritems(): if '/' in field: fieldname, bound = field.split('/') else: fieldname = field bound = '' data = {} fld['type'] = res[fieldname].get('type') if fld['type'] == 'many2many': fld['type'] = 'char' fld['value'] = value data[field] = fld try: frm = TinyForm(**data).to_python() except TinyFormError, e: error_field = e.field error = ustr(e) all_error.append(dict(error=error, error_field=error_field)) continue if bound in ('from', 'to'): if bound == 'from': test = '>=' else: test = '<=' convert_format = openobject.i18n.format.convert_date_format_in_domain([(fieldname, test, value)], res, context) domain.append(convert_format[0]) search_data.setdefault(fieldname, {})[bound] = convert_format[0][2] elif isinstance(value, bool) and value: search_data[field] = 1 elif isinstance(value, int) and not isinstance(value, bool): domain.append((field, '=', value)) search_data[field] = value elif 'selection_' in value: domain.append((field, '=', value.split('selection_')[1])) search_data[field] = value.split('selection_')[1] elif fld['type'] == 'selection': domain.append((field, '=', value)) search_data[field] = value else: if not 'm2o_' in value: operator = 'ilike' if '__' in value: value, operator = value.split('__') value = int(value) domain.append((field, operator, value)) search_data[field] = value else: search_data[field] = value.split('m2o_')[1] if all_error: return dict(all_error=all_error)
def __init__(self, view, model, res_id=False, domain=[], context={}, action=None, fields=None): super(ViewTree, self).__init__(name='view_tree', action=action) self.model = view['model'] self.domain2 = domain or [] self.context = context or {} self.domain = [] fields_info = dict(fields) self.field_parent = view.get("field_parent") or None if self.field_parent: self.domain = domain self.view = view self.view_id = view['view_id'] proxy = rpc.RPCProxy(self.model) ctx = dict(self.context, **rpc.session.context) dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8')) root = dom.childNodes[0] attrs = node_attributes(root) self.string = attrs.get('string', 'Unknown') self.toolbar = attrs.get('toolbar', False) ids = [] id = res_id colors = {} for color_spec in attrs.get('colors', '').split(';'): if color_spec: colour, test = color_spec.split(':') colors[colour] = test if self.toolbar: ids = proxy.search(self.domain2, 0, 0, 0, ctx) self.toolbar = proxy.read(ids, ['name', 'icon'], ctx) if not id and ids: id = ids[0] if id: ids = proxy.read([id], [self.field_parent], ctx)[0][self.field_parent] elif not ids: ids = proxy.search(domain, 0, 0, 0, ctx) self.headers = [] self.parse(root, fields) self.tree = treegrid.TreeGrid(name="tree_%d" % (id), model=self.model, headers=self.headers, url=url("/openerp/tree/data"), ids=ids, domain=self.domain, context=self.context, field_parent=self.field_parent, onselection="onSelection", fields_info=fields_info, colors=colors) self.id = id self.ids = ids toolbar = {} for item, value in view.get('toolbar', {}).items(): if value: toolbar[item] = value if toolbar: self.sidebar = Sidebar(self.model, None, toolbar, context=self.context) # get the correct view title self.string = self.context.get('_terp_view_name', self.string) or self.string