def get_o2m_defaults(self, o2m_values, model, o2m_model, name, view_type, view_id, o2m_view_type, o2m_view_id, editable, limit, offset, o2m_context, o2m_domain): view_id = view_id or False o2m_view_id = ast.literal_eval(o2m_view_id) or False o2m_view_type = o2m_view_type or 'form' context = dict(ast.literal_eval(o2m_context), **rpc.get_session().context) o2m_values = simplejson.loads(o2m_values) for o2m in o2m_values: o2m['id'] = 0 if o2m_view_id: view = cache.fields_view_get(o2m_model, o2m_view_id, o2m_view_type, context) else: view = cache.fields_view_get(model, view_id, view_type, rpc.get_session().context) view = view['fields'][name]['views'][o2m_view_type] list_view = listgrid.List(name, model, view, ids=None, domain=o2m_domain, context=context, default_data=copy.deepcopy(o2m_values), limit=20, editable= editable,o2m=1) view=ustr(list_view.render()) formated_o2m_values = [] for o2m in o2m_values: o2m.pop('id', None) formated_o2m_values.append((0, 0, o2m)) return dict(view=view, formated_o2m_values=ustr(formated_o2m_values))
def do_drop(self, dbname, password, **kw): self.msg = {} try: rpc.get_session().execute_db('drop', password, dbname) except openobject.errors.AccessDenied, e: self.msg = {'message': _('Bad super admin password'), 'title' : e.title}
def custom_action(self, action): menu_ids = rpc.RPCProxy('ir.ui.menu').search( [('id', '=', int(action))], 0, 0, 0, rpc.get_session().context) return actions.execute_by_keyword( 'tree_but_open', model='ir.ui.menu', id=menu_ids[0], ids=menu_ids, context=rpc.get_session().context, report_type='pdf')
def create(self, saved=False): tg_errors = None proxy = rpc.RPCProxy('res.users') action_id = proxy.action_get({}) action = rpc.RPCProxy('ir.actions.act_window').read([action_id], False, rpc.get_session().context)[0] view_ids=[] if action.get('views', []): view_ids=[x[0] for x in action['views']] elif action.get('view_id', False): view_ids=[action['view_id'][0]] params = TinyDict() params.id = rpc.get_session().uid params.ids = [params.id] params.model = 'res.users' params.view_type = 'form' params.view_mode = ['form'] params.view_ids = view_ids params.string = _('Preferences') params.editable = True form = self.create_form(params, tg_errors) return dict(form=form, params=params, editable=True, saved=saved)
def do_create(self, password, dbname, admin_password, confirm_password, demo_data=False, language=None, **kw): self.msg = {} if not re.match('^[a-zA-Z][a-zA-Z0-9_]+$', dbname): self.msg = {'message': ustr(_("You must avoid all accents, space or special characters.")), 'title': ustr(_('Bad database name'))} return self.create() ok = False try: res = rpc.get_session().execute_db('create', password, dbname, demo_data, language, admin_password) while True: try: progress, users = rpc.get_session().execute_db('get_progress', password, res) if progress == 1.0: for x in users: if x['login'] == 'admin': rpc.get_session().login(dbname, 'admin', x['password']) ok = True break else: time.sleep(1) except: raise DatabaseCreationCrash() except DatabaseCreationCrash: self.msg = {'message': (_("The server crashed during installation.\nWe suggest you to drop this database.")), 'title': (_('Error during database creation'))} return self.create() except openobject.errors.AccessDenied, e: self.msg = {'message': _('Bad super admin password'), 'title' : e.title} return self.create()
def button_action(self, **kw): params, data = TinyDict.split(kw) error = None reload = (params.context or {}).get('reload', False) result = {} name = params.button_name btype = params.button_type ctx = dict((params.context or {}), **rpc.get_session().context) id = params.id model = params.model id = (id or False) and int(id) ids = (id or []) and [id] list_grid = params.list_grid or '_terp_list' try: if btype == 'workflow': res = rpc.Workflow(model)[name](id) if isinstance(res, dict): import actions return actions.execute(res, ids=[id]) else: return dict(reload=True, list_grid=list_grid) elif btype == 'object': ctx = params.context or {} ctx.update(rpc.get_session().context.copy()) res = rpc.RPCProxy(model)[name](ids, ctx) if isinstance(res, dict): import actions return actions.execute(res, ids=[id]) else: return dict(reload=True, list_grid=list_grid) elif btype == 'action': import actions action_id = int(name) action_type = actions.get_action_type(action_id) if action_type == 'ir.actions.wizard': cherrypy.session['wizard_parent_form'] = '/form' cherrypy.session['wizard_parent_params'] = params res = actions.execute_by_id(action_id, type=action_type, model=model, id=id, ids=ids, context=ctx or {}) if res: return res else: return dict(reload=True, list_grid=list_grid) else: return dict(error = "Unallowed button type") except Exception, e: return dict(error = ustr(e))
def do_password(self, old_password, new_password, confirm_password, **kw): self.msg = {} try: rpc.get_session().execute_db('change_admin_password', old_password, new_password) except openobject.errors.AccessDenied, e: self.msg = {'message': _('Bad super admin password'), 'title' : e.title} return self.password()
def do_restore(self, filename, password, dbname, **kw): self.msg = {} try: data = base64.encodestring(filename.file.read()) rpc.get_session().execute_db('restore', password, dbname, data) except openobject.errors.AccessDenied, e: self.msg = {'message': _('Bad super admin password'), 'title' : e.title} return self.restore()
def update_params(self, params): super(M2O, self).update_params(params) if params['value'] and not params['text']: try: value = expr_eval(params['value'], {'context':rpc.get_session().context}) except: value = params['value'] params['text'] = rpc.name_get(self.relation, value, rpc.get_session().context)
def add(self, id): id = int(id) if not self.by_res_id().get(id): name = rpc.RPCProxy('ir.ui.menu').name_get([id], rpc.get_session().context)[0][1] rpc.RPCProxy('ir.ui.view_sc').create({'user_id': rpc.get_session().uid, 'res_id': id, 'resource': 'ir.ui.menu', 'name': name}) self.refresh_session() raise redirect('/openerp/tree/open', id=id, model='ir.ui.menu')
def menu(self, active=None, next=None): from openerp.widgets import tree_view try: id = int(active) except: id = False form.Form().reset_notebooks() ctx = rpc.get_session().context.copy() menus = rpc.RPCProxy("ir.ui.menu") domain = [('parent_id', '=', False)] user_menu_action_id = rpc.RPCProxy("res.users").read([rpc.session.uid], ['menu_id'], ctx)[0]['menu_id'] if user_menu_action_id: act = rpc.RPCProxy('ir.actions.act_window').read([user_menu_action_id[0]], ['res_model', 'domain'], ctx)[0] if act['res_model'] == 'ir.ui.menu' and act['domain']: domain = literal_eval(act['domain']) ids = menus.search(domain, 0, 0, 0, ctx) parents = menus.read(ids, ['name', 'action', 'web_icon_data', 'web_icon_hover_data'], ctx) for parent in parents: if parent['id'] == id: parent['active'] = 'active' if parent.get('action') and not next: next = url('/openerp/custom_action', action=id) # If only the hover image exists, use it as regular image as well if parent['web_icon_hover_data'] and not parent['web_icon_data']: parent['web_icon_data'] = parent['web_icon_hover_data'] if next or active: if not id and ids: id = ids[0] ids = menus.search([('parent_id', '=', id)], 0, 0, 0, ctx) tools = menus.read(ids, ['name', 'action'], ctx) view = cache.fields_view_get('ir.ui.menu', 1, 'tree', {}) fields = cache.fields_get(view['model'], False, ctx) for tool in tools: tid = tool['id'] tool['tree'] = tree = tree_view.ViewTree(view, 'ir.ui.menu', tid, domain=[('parent_id', '=', tid)], context=ctx, action="/openerp/tree/action", fields=fields) tree._name = "tree_%s" %(tid) tree.tree.onselection = None tree.tree.onheaderclick = None tree.tree.showheaders = 0 else: # display home action tools = None return dict(parents=parents, tools=tools, load_content=(next and next or ''), welcome_messages=rpc.RPCProxy('publisher_warranty.contract').get_last_user_messages(_MAXIMUM_NUMBER_WELCOME_MESSAGES), show_close_btn=rpc.get_session().uid == 1, widgets=openobject.pooler.get_pool()\ .get_controller('/openerp/widgets')\ .user_home_widgets(ctx))
def ok(self, **kw): params, data = TinyDict.split(kw) proxy = rpc.RPCProxy('res.users') # validators generally do that... for key in data.keys(): if not data[key]: data[key] = False elif int_pattern.match(data[key]): data[key] = int(data[key]) proxy.write([rpc.get_session().uid], data) rpc.get_session().context_reload() raise redirect('/openerp/pref/create', saved=True)
def can_shortcut_create(self): """ We only handle creating shortcuts to menu actions (for now anyway), and those go through the execute routine, so only match execute()d actions concerning ir.ui.menu. And trees, just because """ action_data = cherrypy.request.params.get('data', {}) return (rpc.get_session().is_logged() and rpc.get_session().active_id and ((cherrypy.request.path_info == '/openerp/execute' and action_data.get('model') == 'ir.ui.menu') # FIXME: hack hack hack or cherrypy.request.params.get('_terp_source_view_type') == 'tree'))
def search(model, offset=0, limit=50, domain=[], context={}, data={}): """A helper function to search for data by given criteria. @param model: the resource on which to make search @param offset: offset from when to start search @param limit: limit of the search result @param domain: the domain (search criteria) @param context: the context @param data: the form data @returns dict with list of ids count of records etc. """ domain = domain or [] context = context or {} data = data or {} proxy = rpc.RPCProxy(model) fields = proxy.fields_get([], rpc.get_session().context) search_domain = domain[:] search_data = {} for k, v in data.items(): t = fields.get(k, {}).get('type', 'char') t = make_domain(k, v, t) if t: search_domain += t search_data[k] = v l = limit o = offset if l < 1: l = 50 if o < 0: o = 0 ctx = rpc.get_session().context.copy() ctx.update(context) ids = proxy.search(search_domain, o, l, 0, ctx) if len(ids) < l: count = len(ids) else: count = proxy.search_count(search_domain, ctx) if isinstance(ids, list): count = len(ids) return dict(model=model, ids=ids, count=count, offset=o, limit=l, search_domain=search_domain, search_data=search_data)
def button_action_object(self, name, params): model, id, ids, ctx = self._get_button_infos(params) res = rpc.RPCProxy(model)[name](ids, ctx) # after installation of modules (esp. initial) we may # need values from the global context for some contexts & domains (e.g. # leads) => installer wizards are generally postfixed by '.installer' # so use this characteristic to setup context reloads if model.endswith('.installer'): rpc.get_session().context_reload() if isinstance(res, dict): import actions return actions.execute(res, ids=[id], context=ctx) params.button = None
def __init__(self, **attrs): super(Selection, self).__init__(**attrs) self.options = attrs.get('selection', []) self.type2 = attrs.get('type2') self.operator = attrs.get('operator', '=') self.search_context = attrs.get('context', {}) #Below mentioned process should be followed for m2o as selection and for boolean field on search panel if (attrs.get('relation') and attrs.get('widget') == 'selection') or (not self.options and attrs.get('type','') != 'boolean'): proxy = rpc.RPCProxy(attrs['relation']) try: domain = attrs.get('domain', []) if isinstance(domain, (str, unicode)): try: domain = eval(domain) except: domain = [] ids = proxy.search(domain) ctx = rpc.get_session().context.copy() # ctx.update(attrs.get('context', {})) # In search view this will create problem for m2o field having widget='selection' and context as attr. self.options = proxy.name_get(ids, ctx) except: self.options = [] if self.options and self.options[0][0] == '' and isinstance(self.options[0][0], unicode): self.validator = validators.Selection() # determine the actual type elif self.options and isinstance(self.options[0][0], basestring): self.kind = 'char' self.validator = validators.String() else: self.validator = validators.Selection()
def export_data(self, fname, fields, import_compat=False, export_format='csv', **kw): params, data_index = TinyDict.split(kw) proxy = rpc.RPCProxy(params.model) flds = [] for item in fields: fld = item.replace('/.id','.id') flds.append(fld) if isinstance(fields, basestring): fields = fields.replace('/.id','.id') flds = [fields] ctx = dict((params.context or {}), **rpc.get_session().context) ctx['import_comp'] = bool(int(import_compat)) domain = params.seach_domain or [] ids = params.ids or proxy.search(domain, 0, 0, 0, ctx) result = datas_read(ids, params.model, flds, context=ctx) if result.get('warning'): common.warning(unicode(result.get('warning', False)), _('Export Error')) return False result = result.get('datas',[]) if import_compat: params.fields2 = flds if export_format == 'xls': return export_xls(params.fields2, result) else: return export_csv(params.fields2, result)
def exp(self, import_compat="1", **kw): params, data = TinyDict.split(kw) ctx = dict((params.context or {}), **rpc.get_session().context) 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 refresh_session(self): ''' refresh_session() -> [{id, name, res_id}] Fetches the list of ir.ui.menu shortcuts from the server, stores them in session and returns the list. Returns only the id of the resource, not the retrieved (id, name_get()) ''' shortcuts = rpc.RPCProxy('ir.ui.view_sc')\ .get_sc(rpc.get_session().uid, 'ir.ui.menu', rpc.get_session().context) or [] for shortcut in shortcuts: # if res_id is (id, name), only keep id if isinstance(shortcut['res_id'], (list, tuple)): shortcut['res_id'] = shortcut['res_id'][0] cherrypy.session['terp_shortcuts'] = shortcuts return shortcuts
def __init__(self, model, view=False, view_id=False, ids=[], domain=[], context={},view_mode=[], group_by=[], width=360, height=300): name = 'graph_%s' % (random.randint(0,10000)) super(Graph, self).__init__(name=name, model=model, width=width, height=height) ctx = rpc.get_session().context.copy() ctx.update(context or {}) view = view or cache.fields_view_get(model, view_id, 'graph', ctx) dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8')) root = dom.childNodes[0] attrs = node_attributes(root) self.string = attrs.get('string') self.group_by = group_by chart_type = attrs.get('type', 'pie') self.ids = ids if chart_type == "bar": self.data = BarChart(model, view, view_id, ids, domain, view_mode, context, group_by) else: self.data = PieChart(model, view, view_id, ids, domain, view_mode, context, group_by) self.data = simplejson.dumps(self.data.get_data())
def remove(self, id=False, **kw): proxy = rpc.RPCProxy('ir.attachment') try: proxy.unlink([int(id)], rpc.get_session().context) return {} except Exception, e: return {'error': ustr(e)}
def previous_o2m(self, **kw): params, data = TinyDict.split(kw) if params.get('_terp_save_current_id'): ctx = dict((params.context or {}), **rpc.get_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 current = params.chain_get(params.source or '') or params idx = -1 if current.id: # save current record if params.editable: self.save(terp_save_only=True, **kw) idx = current.ids.index(current.id) idx = idx-1 if idx == len(current.ids): idx = len(current.ids) -1 if current.ids: current.id = current.ids[idx] return self.create(params)
def auto_create(self, conn_obj, src, des, act_from, act_to, **kw): conn_flds = eval(kw.get('conn_flds', '[]')) conn_flds_string = eval(kw.get('conn_flds_string', '[]')) proxy_tr = rpc.RPCProxy(conn_obj) if not(kw.get('id', False)): id = proxy_tr.create({src: act_from, des: act_to}) else: id = int(kw['id']) if src not in conn_flds: conn_flds.append(src) if des not in conn_flds: conn_flds.append(des) result = proxy_tr.read(id, conn_flds, rpc.get_session().context) data = { 'id': result['id'], 's_id': result[src][0], 'd_id': result[des][0], 'source': result[src][1], 'destination': result[des][1], 'options': {} } for i, fld in enumerate(conn_flds): data['options'][conn_flds_string[i]] = result[fld] if id > 0: return {'flag': True, 'data': data} else: return {'flag': False}
def _get_model(node, parent_model): parents = [] pnode = node.parentNode while pnode: if pnode.localName == 'field': ch = utils.xml_locate('./form[1]', pnode) \ + utils.xml_locate('./tree[1]', pnode) \ + utils.xml_locate('./graph[1]', pnode) \ + utils.xml_locate('./calendar[1]', pnode) if ch: parents.append(pnode.getAttribute('name')) pnode = pnode.parentNode parents.reverse() for parent in parents: field = rpc.RPCProxy(parent_model).fields_get([parent], rpc.get_session().context) if field: if field[parent].get('relation'): parent_model = field[parent]['relation'] return parent_model
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.get_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 _get_gantt_records(self, model, ids=None, group=None): if group: return [{ 'id': group['id'], 'items': {'name': group['title']}, 'action': None, 'target': None, 'icon': None, 'children': self._get_gantt_records(model, group['items']) }] proxy = rpc.RPCProxy(model) ctx = dict(rpc.get_session().context) records = [] for id in ids: records.append({ 'id': id, 'items': {'name': proxy.name_get([id], ctx)[0][-1]}, 'action': 'javascript: void(0)', 'target': None, 'icon': None, 'children': None }) return records
def create(self, params, tg_errors=None): params.path = self.path params.function = 'create_state' if params.id and cherrypy.request.path_info == self.path + '/view': params.load_counter = 2 elif not params.context: params.context = {'o2m_model': params.o2m_model, 'o2m_id': params.o2m_id} proxy_field = rpc.RPCProxy('ir.model.fields') field_ids = proxy_field.search([('model', '=', params.o2m_model or params.context.get('o2m_model')), ('relation', '=', params.model)], 0, 0, 0, rpc.get_session().context) m2o_field = proxy_field.read(field_ids, ['relation_field'], rpc.get_session().context)[0]['relation_field'] params.hidden_fields = [ tw.form.Hidden(name=m2o_field, default=params.o2m_id or params.context.get('o2m_id', False)), tw.form.Hidden(name='_terp_o2m_model', default=params.o2m_model)] form = self.create_form(params, tg_errors) field = form.screen.widget.get_widgets_by_name(m2o_field) if field: field[0].set_value(params.o2m_id or params.context.get('o2m_id', False)) field[0].readonly = True vals = getattr(cherrypy.request, 'terp_validators', {}) vals[m2o_field] = validators.Int() hide = [] for w in hide: w.visible = False return dict(form=form, params=params)
def moveDown(self, **kw): params, data = TinyDict.split(kw) id = params.id ids = params.ids or [] if id not in ids or ids.index(id) == len(ids) - 1: return dict() proxy = rpc.RPCProxy(params.model) ctx = rpc.get_session().context.copy() next_id = ids[ids.index(id)+1] try: res = proxy.read([id, next_id], ['sequence'], ctx) records = dict([(r['id'], r['sequence']) for r in res]) cur_seq = records[id] next_seq = records[next_id] if cur_seq == next_seq: proxy.write([next_id], {'sequence': cur_seq + 1}, ctx) proxy.write([id], {'sequence': next_seq}, ctx) else: proxy.write([id], {'sequence': next_seq}, ctx) proxy.write([next_id], {'sequence': cur_seq}, ctx) return dict() except Exception, e: return dict(error=str(e))
def add(self, view_id, xpath_expr): view_id = int(view_id) res = rpc.RPCProxy('ir.ui.view').read([view_id], ['model', 'arch'])[0] doc = xml.dom.minidom.parseString(res['arch'].encode('utf-8')) model = res['model'] field_node = utils.xml_locate(xpath_expr, doc)[0] model = _get_model(field_node, parent_model=model) # get the fields fields = rpc.RPCProxy(model).fields_get(False, rpc.get_session().context).keys() nodes = _CHILDREN.keys() nodes.remove('view') nodes.sort() fields.sort() positions = [('inside', 'Inside'), ('after', 'After'), ('before', 'Before')] if field_node.localName in [k for k,v in _CHILDREN.items() if not v] + ['field']: positions = [('after', 'After'), ('before', 'Before'), ('inside', 'Inside')] return dict(view_id=view_id, xpath_expr=xpath_expr, nodes=nodes, fields=fields, model=model, positions=positions)
def get_m2m(self, name, model, view_id, view_type, ids): view_id = ast.literal_eval(view_id) or False ids = ast.literal_eval(ids) or [] view = cache.fields_view_get(model, view_id, view_type, rpc.get_session().context) m2m_view = listgrid.List(name, model, view, ids,limit=20, editable=True, m2m=1) m2m_view = ustr(m2m_view.render()) return dict(m2m_view = m2m_view)