def __init__(self, prefix, model, view, ids=[], domain=[], context=None, editable=True, readonly=False, nodefault=False, nolinks=1): super(Form, self).__init__(prefix=prefix, model=model, editable=editable, readonly=readonly, nodefault=nodefault) dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8')) root = dom.childNodes[0] attrs = node_attributes(root) fields = view['fields'] self.string = attrs.get('string', '') self.link = attrs.get('link', nolinks) self.model = model self.id = None proxy = rpc.RPCProxy(model) self.context = dict(rpc.get_session().context, **(context or {})) self.context['bin_size'] = True values = {} defaults = {} try: if ids: lval = proxy.read(ids[:1], fields.keys() + ['__last_update'], self.context) if lval: values = lval[0] self.id = ids[0] for f in fields: if fields[f]['type'] == 'many2one' and isinstance(values[f], tuple): values[f] = values[f][0] ConcurrencyInfo.update(self.model, [values]) elif 'datas' in view: # wizard data for f in fields: if 'value' in fields[f]: values[f] = fields[f]['value'] values.update(view['datas']) elif not self.nodefault: # default defaults = self.get_defaults(fields, domain, self.context) elif 'state' in fields: # if nodefault and state get state only defaults = proxy.default_get(['state'], self.context) elif 'x_state' in fields: # if nodefault and x_state get x_state only (for custom objects) defaults = proxy.default_get(['x_state'], self.context) except Exception,e: raise common.warning(e)
def __init__(self, prefix, model, view, ids=[], domain=[], context=None, editable=True, readonly=False, nodefault=False, nolinks=1): super(Form, self).__init__(prefix=prefix, model=model, editable=editable, readonly=readonly, nodefault=nodefault) dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8')) root = dom.childNodes[0] attrs = node_attributes(root) fields = view['fields'] self.string = attrs.get('string', '') self.link = attrs.get('link', nolinks) self.model = model self.id = None proxy = rpc.RPCProxy(model) self.context = dict(rpc.session.context, **(context or {})) self.context['bin_size'] = True values = {} defaults = {} try: if ids: lval = proxy.read(ids[:1], fields.keys() + ['__last_update'], self.context) if lval: values = lval[0] self.id = ids[0] ConcurrencyInfo.update(self.model, [values]) elif 'datas' in view: # wizard data for f in fields: if 'value' in fields[f]: values[f] = fields[f]['value'] values.update(view['datas']) elif not self.nodefault: # default defaults = self.get_defaults(fields, domain, self.context) elif 'state' in fields: # if nodefault and state get state only defaults = proxy.default_get(['state'], self.context) elif 'x_state' in fields: # if nodefault and x_state get x_state only (for custom objects) defaults = proxy.default_get(['x_state'], self.context) except Exception,e: raise common.warning(e)
def __init__(self, name, model, view, ids=[], domain=[], context={}, **kw): super(List, self).__init__(name=name, model=model, ids=ids) self.context = context or {} self.domain = domain or [] custom_search_domain = getattr(cherrypy.request, 'custom_search_domain', []) custom_filter_domain = getattr(cherrypy.request, 'custom_filter_domain', []) if name.endswith('/'): self._name = name[:-1] if name != '_terp_list': self.source = self.name.replace('/', '/') or None self.sort_order = '' self.sort_key = '' #this Condition is for Dashboard to avoid new, edit, delete operation self.dashboard = 0 self.selectable = kw.get('selectable', 0) self.editable = kw.get('editable', False) self.pageable = kw.get('pageable', True) self.view_mode = kw.get('view_mode', []) self.offset = kw.get('offset', 0) self.limit = kw.get('limit', 0) self.count = kw.get('count', 0) self.link = kw.get('nolinks') self.m2m = kw.get('m2m', 0) self.o2m = kw.get('o2m', 0) self.concurrency_info = None self.selector = None terp_params = getattr(cherrypy.request, 'terp_params', {}) if terp_params: if terp_params.get('_terp_model'): if terp_params['_terp_model'] == 'board.board' and terp_params.view_type == 'form': self.dashboard = 1 if terp_params.get('_terp_source'): if (str(terp_params.source) == self.source) or (terp_params.source == '_terp_list' and terp_params.sort_key): self.sort_key = terp_params.sort_key self.sort_order = terp_params.sort_order if self.selectable == 1: self.selector = 'radio' if self.selectable == 2: self.selector = 'checkbox' fields = view['fields'] dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8')) root = dom.childNodes[0] attrs = node_attributes(root) self.string = attrs.get('string','') search_param = copy.deepcopy(domain) or [] if custom_search_domain: for elem in custom_search_domain: if elem not in self.domain: search_param.append(elem) for elem in custom_filter_domain: if elem not in self.domain: search_param.append(elem) try: self.limit = int(attrs.get('limit')) except: pass self.colors = {} for color_spec in attrs.get('colors', '').split(';'): if color_spec: colour, test = color_spec.split(':') self.colors[colour] = test proxy = rpc.RPCProxy(model) default_data = kw.get('default_data', []) search_text = terp_params.get('_terp_search_text', False) if not self.source: self.source = terp_params.get('_terp_source', None) if not default_data and not self.o2m and not self.m2m: if self.limit > 0: if self.sort_key: ids = proxy.search(search_param, self.offset, self.limit, self.sort_key + ' ' +self.sort_order, context) else: if search_text: if self.source == '_terp_list': ids = proxy.search(search_param, self.offset, self.limit, False, context) else: ids = proxy.search(search_param, self.offset, self.limit, False, context) else: ids = proxy.search(search_param, 0, 0, 0, context) if len(ids) < self.limit: if self.offset > 0: self.count = len(ids) + self.offset else: self.count = len(ids) else: self.count = proxy.search_count(search_param, context) self.data_dict = {} data = [] if ids and not isinstance(ids, list): ids = [ids] if ids and len(ids) > 0: ctx = rpc.get_session().context.copy() ctx.update(context) try: data = proxy.read(ids, fields.keys() + ['__last_update'], ctx) except: pass ConcurrencyInfo.update(self.model, data) cherrypy.response.headers.pop('X-Concurrency-Info', None) self.concurrency_info = ConcurrencyInfo(self.model, ids) order_data = [(d['id'], d) for d in data] orderer = dict(zip(ids, count())) ordering = sorted(order_data, key=lambda object: orderer[object[0]]) data = [i[1] for i in ordering] for item in data: self.data_dict[item['id']] = item.copy() self.ids = ids elif kw.get('default_data', []): data = kw['default_data'] self.values = copy.deepcopy(data) self.headers, self.hiddens, self.data, self.field_total, self.buttons = self.parse(root, fields, data) for k, v in self.field_total.items(): if(len([test[0] for test in self.hiddens if test[0] == k])) <= 0: self.field_total[k][1] = self.do_sum(self.data, k) self.columns = len(self.headers) self.columns += (self.selectable or 0) and 1 self.columns += (self.editable or 0) and 2 self.columns += (self.buttons or 0) and 1 if self.pageable: self.pager = Pager(ids=self.ids, offset=self.offset, limit=self.limit, count=self.count) self.pager._name = self.name if self.editable and context.get('set_editable'):#Treeview editable by default or set_editable in context attrs['editable'] = "bottom" # make editors if self.editable and attrs.get('editable') in ('top', 'bottom'): for f, fa in self.headers: if not isinstance(fa, int): fa['prefix'] = '_terp_listfields' + ((self.name != '_terp_list' or '') and '/' + self.name) fa['inline'] = True if fa.get('type') == 'one2many': self.edit_inline = False self.editors = {} break Widget = get_widget(fa.get('type', 'char')) or get_widget('char') self.editors[f] = Widget(**fa) # generate hidden fields if self.editors: for f, fa in self.hiddens: fa['prefix'] = '_terp_listfields' + ((self.name != '_terp_list' or '') and '/' + self.name) self.editors[f] = form.Hidden(**fa) # limit the data if self.pageable and len(self.data) > self.limit and self.limit != -1: self.data = self.data[self.offset:] self.data = self.data[:min(self.limit, len(self.data))]
def __init__(self, name, model, view, ids=[], domain=[], context={}, **kw): super(List, self).__init__(name=name, model=model, ids=ids) self.context = context or {} self.domain = domain or [] custom_search_domain = getattr(cherrypy.request, 'custom_search_domain', []) custom_filter_domain = getattr(cherrypy.request, 'custom_filter_domain', []) if name.endswith('/'): self._name = name[:-1] if name != '_terp_list': self.source = self.name.replace('/', '/') or None self.sort_order = kw.get('sort_order', '') self.sort_key = kw.get('sort_key', '') #this Condition is for Dashboard to avoid new, edit, delete operation self.dashboard = 0 self.noteditable = [] self.notselectable = [] self.selectable = kw.get('selectable', 0) self.editable = kw.get('editable', False) self.pageable = kw.get('pageable', True) self.view_mode = kw.get('view_mode', []) self.offset = kw.get('offset', 0) self.limit = None self.count = kw.get('count', 0) self.link = kw.get('nolinks') self.m2m = kw.get('m2m', 0) self.o2m = kw.get('o2m', 0) self.concurrency_info = None self.selector = None self.force_readonly = kw.get('force_readonly', False) terp_params = getattr(cherrypy.request, 'terp_params', {}) if terp_params: if terp_params.get('_terp_model'): if terp_params['_terp_model'] == 'board.board' and terp_params.view_type == 'form': self.dashboard = 1 if terp_params.get('_terp_source'): if (str(terp_params.source) == self.source) or (terp_params.source == '_terp_list' and terp_params.sort_key): self.sort_key = terp_params.sort_key self.sort_order = terp_params.sort_order if self.selectable == 1: self.selector = 'radio' if self.selectable == 2: self.selector = 'checkbox' fields = view['fields'] dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8')) root = dom.childNodes[0] attrs = node_attributes(root) # Get the hide status of some buttons - by default buttons are shown self.hide_new_button = False self.hide_delete_button = False self.hide_edit_button = False try: self.hide_new_button = expr_eval(attrs.get('hide_new_button', False), {'context': context}) self.hide_delete_button = expr_eval(attrs.get('hide_delete_button', False), {'context': context}) self.hide_edit_button = expr_eval(attrs.get('hide_edit_button', False), {'context': context}) except: pass self.string = attrs.get('string','') search_param = copy.deepcopy(domain) or [] if custom_search_domain: for elem in custom_search_domain: if elem not in self.domain: search_param.append(elem) for elem in custom_filter_domain: if elem not in self.domain: search_param.append(elem) # -- Limits -- # 1. use action limit or default global listview limit: 20 # 2. apply tree view limit if defined in attrs: <tree limit='..'>...</tree> # 3. apply user limit if changed self.limit = getattr(cherrypy.request, 'action_limit', 20) if attrs.get('limit'): try: self.limit = int(attrs.get('limit')) except Exception: pass if kw.get('limit') is not None: self.limit = int(kw.get('limit')) self.colors = {} for color_spec in attrs.get('colors', '').split(';'): if color_spec: colour, test = color_spec.split(':') self.colors[colour] = test proxy = rpc.RPCProxy(model) default_data = kw.get('default_data', []) search_text = terp_params.get('_terp_search_text', False) approximation = False if not self.source: self.source = terp_params.get('_terp_source', None) if not default_data and not self.o2m and not self.m2m: if self.limit > 0: if self.sort_key: ids = proxy.search(search_param, self.offset, self.limit, self.sort_key + ' ' +self.sort_order + ',id', context) else: if search_text: if self.source == '_terp_list': ids = proxy.search(search_param, self.offset, self.limit, False, context) else: ids = proxy.search(search_param, self.offset, self.limit, False, context) else: ids = proxy.search(search_param, 0, 0, 0, context) if len(ids) < self.limit: if self.offset > 0: self.count = len(ids) + self.offset else: self.count = len(ids) else: self.count, approximation = proxy.approximate_search_count(search_param, context) if not default_data and self.m2m: # prefilter datas for m2m # XXX: make it explicit about how 'sum' are computed as this is going to change default behaviour if ids and self.limit not in (0, -1): ids = self.ids[self.offset:self.offset+self.limit] self.data_dict = {} data = [] if ids and not isinstance(ids, list): ids = [ids] if ids and len(ids) > 0: ctx = rpc.session.context.copy() ctx.update(context) try: data = proxy.read(ids, fields.keys() + ['__last_update'], ctx) except: pass ConcurrencyInfo.update(self.model, data) cherrypy.response.headers.pop('X-Concurrency-Info', None) self.concurrency_info = ConcurrencyInfo(self.model, ids) order_data = [(d['id'], d) for d in data] orderer = dict(zip(ids, count())) ordering = sorted(order_data, key=lambda object: orderer[object[0]]) data = [i[1] for i in ordering] for item in data: self.data_dict[item['id']] = item.copy() if not self.m2m: self.ids = ids elif kw.get('default_data', []): data = kw['default_data'] self.values = copy.deepcopy(data) self.headers, self.hiddens, self.data, self.field_total, self.field_real_total, self.buttons = self.parse(root, fields, data) for k, v in self.field_total.items(): if(len([test[0] for test in self.hiddens if test[0] == k])) <= 0: self.field_total[k][1] = self.do_sum(self.data, k) for k, v in self.field_real_total.items(): if(len([test[0] for test in self.hiddens if test[0] == k])) <= 0: self.field_real_total[k][1] = self.do_real_sum(self.data, k) self.columns = len(self.headers) self.columns += (self.selectable or 0) and 1 self.columns += (self.editable or 0) and 2 self.columns += (self.buttons or 0) and 1 if self.pageable: self.pager = Pager(ids=self.ids, offset=self.offset, limit=self.limit, count=self.count, approximation=approximation) self.pager._name = self.name if self.editable and context.get('set_editable'):#Treeview editable by default or set_editable in context attrs['editable'] = "bottom" if self.selectable and attrs.get('notselectable'): for x in self.values: try: if expr_eval(attrs.get('notselectable'), x): self.notselectable.append(x['id']) except: pass self.resequencable = expr_eval(attrs.get('resequencable') or '1') # self.resequencable = True # uncomment this if you want to disable this globally # make editors if self.editable and attrs.get('noteditable'): for x in self.values: try: if expr_eval(attrs.get('noteditable'), x): self.noteditable.append(x['id']) except: pass if self.editable and attrs.get('editable') in ('top', 'bottom'): for f, fa in self.headers: if not isinstance(fa, int): fa['prefix'] = '_terp_listfields' + ((self.name != '_terp_list' or '') and '/' + self.name) fa['inline'] = True if fa.get('type') == 'one2many': self.edit_inline = False self.editors = {} break Widget = get_widget(fa.get('type', 'char')) or get_widget('char') self.editors[f] = Widget(**fa) # generate hidden fields if self.editors: for f, fa in self.hiddens: fa['prefix'] = '_terp_listfields' + ((self.name != '_terp_list' or '') and '/' + self.name) self.editors[f] = form.Hidden(**fa) # limit the data if self.pageable and len(self.data) > self.limit and self.limit != -1: self.data = self.data[self.offset:] self.data = self.data[:min(self.limit, len(self.data))]
def __init__(self, name, model, view, ids=[], domain=[], context={}, **kw): super(List, self).__init__(name=name, model=model, ids=ids) self.context = context or {} self.domain = domain or [] custom_search_domain = getattr(cherrypy.request, 'custom_search_domain', []) custom_filter_domain = getattr(cherrypy.request, 'custom_filter_domain', []) if name.endswith('/'): self._name = name[:-1] if name != '_terp_list': self.source = self.name.replace('/', '/') or None self.sort_order = kw.get('sort_order', '') self.sort_key = kw.get('sort_key', '') #this Condition is for Dashboard to avoid new, edit, delete operation self.dashboard = 0 self.selectable = kw.get('selectable', 0) self.editable = kw.get('editable', False) self.pageable = kw.get('pageable', True) self.view_mode = kw.get('view_mode', []) self.offset = kw.get('offset', 0) self.limit = kw.get('limit', 0) self.count = kw.get('count', 0) self.link = kw.get('nolinks') self.m2m = kw.get('m2m', 0) self.o2m = kw.get('o2m', 0) self.concurrency_info = None self.selector = None terp_params = getattr(cherrypy.request, 'terp_params', {}) if terp_params: if terp_params.get('_terp_model'): if terp_params[ '_terp_model'] == 'board.board' and terp_params.view_type == 'form': self.dashboard = 1 if terp_params.get('_terp_source'): if (str(terp_params.source) == self.source) or (terp_params.source == '_terp_list' and terp_params.sort_key): self.sort_key = terp_params.sort_key self.sort_order = terp_params.sort_order if self.selectable == 1: self.selector = 'radio' if self.selectable == 2: self.selector = 'checkbox' fields = view['fields'] dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8')) root = dom.childNodes[0] attrs = node_attributes(root) self.string = attrs.get('string', '') search_param = copy.deepcopy(domain) or [] if custom_search_domain: for elem in custom_search_domain: if elem not in self.domain: search_param.append(elem) for elem in custom_filter_domain: if elem not in self.domain: search_param.append(elem) try: self.limit = int(attrs.get('limit')) except: pass self.colors = {} for color_spec in attrs.get('colors', '').split(';'): if color_spec: colour, test = color_spec.split(':') self.colors[colour] = test proxy = rpc.RPCProxy(model) default_data = kw.get('default_data', []) search_text = terp_params.get('_terp_search_text', False) if not self.source: self.source = terp_params.get('_terp_source', None) if not default_data and not self.o2m and not self.m2m: if self.limit > 0: if self.sort_key: ids = proxy.search(search_param, self.offset, self.limit, self.sort_key + ' ' + self.sort_order, context) else: if search_text: if self.source == '_terp_list': ids = proxy.search(search_param, self.offset, self.limit, False, context) else: ids = proxy.search(search_param, self.offset, self.limit, False, context) else: if self.sort_key: ids = proxy.search(search_param, 0, 0, self.sort_key + ' ' + self.sort_order, context) else: ids = proxy.search(search_param, 0, 0, 0, context) if len(ids) < self.limit: if self.offset > 0: self.count = len(ids) + self.offset else: self.count = len(ids) else: self.count = proxy.search_count(search_param, context) if not default_data and self.m2m and not self.view_using_sum_attrs( root): # for many2many we limits 'ids' to be readed only when view is not # using sum, otherwise we need to get all 'ids' to compute sums correctly if ids and self.limit not in (0, -1): ids = self.ids[self.offset:self.offset + self.limit] self.data_dict = {} data = [] if ids and not isinstance(ids, (list, tuple)): ids = [ids] if ids and len(ids) > 0: ctx = rpc.session.context.copy() ctx.update(context) try: data = proxy.read(ids, fields.keys() + ['__last_update'], ctx) except: pass ConcurrencyInfo.update(self.model, data) cherrypy.response.headers.pop('X-Concurrency-Info', None) self.concurrency_info = ConcurrencyInfo(self.model, ids) order_data = [(d['id'], d) for d in data] orderer = dict(zip(ids, count())) ordering = sorted(order_data, key=lambda object: orderer[object[0]]) data = [i[1] for i in ordering] for item in data: self.data_dict[item['id']] = item.copy() if not self.m2m: # update active 'ids' except for many2many which need to get # all known ids for update to work correctly self.ids = ids elif kw.get('default_data', []): data = kw['default_data'] self.values = copy.deepcopy(data) self.headers, self.hiddens, self.data, self.field_total, self.buttons = self.parse( root, fields, data) for k, v in self.field_total.items(): if (len([test[0] for test in self.hiddens if test[0] == k])) <= 0: self.field_total[k][1] = self.do_sum(self.data, k) self.columns = len(self.headers) self.columns += (self.selectable or 0) and 1 self.columns += (self.editable or 0) and 2 self.columns += (self.buttons or 0) and 1 if self.pageable: self.pager = Pager(ids=self.ids, offset=self.offset, limit=self.limit, count=self.count) self.pager._name = self.name # when view is editable, make sure all fields are correctly prefixed # otherwise they may conflict with parent view fields if self.editable: for f, fa in self.headers + self.hiddens: if not isinstance(fa, int): fa['prefix'] = '_terp_listfields' + ( (self.name != '_terp_list' or '') and '/' + self.name) if self.editable and context.get( 'set_editable' ): #Treeview editable by default or set_editable in context attrs['editable'] = "bottom" # make editors if self.editable and attrs.get('editable') in ('top', 'bottom'): for f, fa in self.headers: if not isinstance(fa, int): fa['prefix'] = '_terp_listfields' + ( (self.name != '_terp_list' or '') and '/' + self.name) fa['inline'] = True if fa.get('type') == 'one2many': self.edit_inline = False self.editors = {} break Widget = get_widget(fa.get('type', 'char')) or get_widget('char') self.editors[f] = Widget(**fa) # generate hidden fields if self.editors: for f, fa in self.hiddens: fa['prefix'] = '_terp_listfields' + ( (self.name != '_terp_list' or '') and '/' + self.name) self.editors[f] = form.Hidden(**fa) # limit the data if self.pageable and len(self.data) > self.limit and self.limit != -1: self.data = self.data[self.offset:] self.data = self.data[:min(self.limit, len(self.data))]
class Form(TinyInputWidget): """A generic form widget """ template = "/openerp/widgets/form/templates/form.mako" params = ['id'] member_widgets = ['frame', 'concurrency_info'] def __init__(self, prefix, model, view, ids=[], domain=[], context=None, editable=True, readonly=False, nodefault=False, nolinks=1): super(Form, self).__init__(prefix=prefix, model=model, editable=editable, readonly=readonly, nodefault=nodefault) dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8')) root = dom.childNodes[0] attrs = node_attributes(root) fields = view['fields'] self.string = attrs.get('string', '') self.link = attrs.get('link', nolinks) self.model = model self.id = None proxy = rpc.RPCProxy(model) self.context = dict(rpc.session.context, **(context or {})) self.context['bin_size'] = True values = {} defaults = {} try: if ids: lval = proxy.read(ids[:1], fields.keys() + ['__last_update'], self.context) if lval: values = lval[0] self.id = ids[0] ConcurrencyInfo.update(self.model, [values]) elif 'datas' in view: # wizard data for f in fields: if 'value' in fields[f]: values[f] = fields[f]['value'] values.update(view['datas']) elif not self.nodefault: # default defaults = self.get_defaults(fields, domain, self.context) elif 'state' in fields: # if nodefault and state get state only defaults = proxy.default_get(['state'], self.context) elif 'x_state' in fields: # if nodefault and x_state get x_state only (for custom objects) defaults = proxy.default_get(['x_state'], self.context) except Exception,e: raise common.warning(e) if defaults: for k, v in defaults.items(): values.setdefault(k, v) self.state = values.get('state', values.get('x_state')) # store current record values in request object (see, self.parse & O2M default_get_ctx) if not hasattr(cherrypy.request, 'terp_record'): cherrypy.request.terp_record = TinyDict() self.view_fields = [] self.nb_couter = 0 self.frame = self.parse(prefix, dom, fields, values)[0] self.values = [values] self.concurrency_info = ConcurrencyInfo(self.model, [self.id]) # We should generate hidden fields for fields which are not in view, as # the values of such fields might be used during `onchange` for name, attrs in fields.items(): if name not in self.view_fields: kind = attrs.get('type', 'char') if not get_widget(kind): continue attrs['prefix'] = prefix attrs['name'] = name attrs['readonly'] = True # always make them readonly field = self._make_field_widget(attrs, values.get(name)) self.frame.add_hidden(field)
def __init__(self, name, model, view, ids=[], domain=[], context={}, **kw): super(List, self).__init__(name=name, model=model, ids=ids) self.context = context or {} self.domain = domain or [] custom_search_domain = getattr(cherrypy.request, "custom_search_domain", []) custom_filter_domain = getattr(cherrypy.request, "custom_filter_domain", []) if name.endswith("/"): self._name = name[:-1] if name != "_terp_list": self.source = self.name.replace("/", "/") or None self.sort_order = "" self.sort_key = "" # this Condition is for Dashboard to avoid new, edit, delete operation self.dashboard = 0 self.selectable = kw.get("selectable", 0) self.editable = kw.get("editable", False) self.pageable = kw.get("pageable", True) self.view_mode = kw.get("view_mode", []) self.offset = kw.get("offset", 0) self.limit = kw.get("limit", 0) self.count = kw.get("count", 0) self.link = kw.get("nolinks") self.m2m = kw.get("m2m", 0) self.o2m = kw.get("o2m", 0) self.concurrency_info = None self.selector = None terp_params = getattr(cherrypy.request, "terp_params", {}) if terp_params: if terp_params.get("_terp_model"): if terp_params["_terp_model"] == "board.board" and terp_params.view_type == "form": self.dashboard = 1 if terp_params.get("_terp_source"): if (str(terp_params.source) == self.source) or ( terp_params.source == "_terp_list" and terp_params.sort_key ): self.sort_key = terp_params.sort_key self.sort_order = terp_params.sort_order if self.selectable == 1: self.selector = "radio" if self.selectable == 2: self.selector = "checkbox" fields = view["fields"] dom = xml.dom.minidom.parseString(view["arch"].encode("utf-8")) root = dom.childNodes[0] attrs = node_attributes(root) self.string = attrs.get("string", "") search_param = copy.deepcopy(domain) or [] if custom_search_domain: for elem in custom_search_domain: if elem not in self.domain: search_param.append(elem) for elem in custom_filter_domain: if elem not in self.domain: search_param.append(elem) try: self.limit = int(attrs.get("limit")) except: pass self.colors = {} for color_spec in attrs.get("colors", "").split(";"): if color_spec: colour, test = color_spec.split(":") self.colors[colour] = test proxy = rpc.RPCProxy(model) default_data = kw.get("default_data", []) search_text = terp_params.get("_terp_search_text", False) if not self.source: self.source = terp_params.get("_terp_source", None) if not default_data and not self.o2m and not self.m2m: if self.limit > 0: if self.sort_key: ids = proxy.search( search_param, self.offset, self.limit, self.sort_key + " " + self.sort_order, context ) else: if search_text: if self.source == "_terp_list": ids = proxy.search(search_param, self.offset, self.limit, False, context) else: ids = proxy.search(search_param, self.offset, self.limit, False, context) else: ids = proxy.search(search_param, 0, 0, 0, context) if len(ids) < self.limit: if self.offset > 0: self.count = len(ids) + self.offset else: self.count = len(ids) else: self.count = proxy.search_count(search_param, context) self.data_dict = {} data = [] if ids and not isinstance(ids, list): ids = [ids] if ids and len(ids) > 0: ctx = rpc.session.context.copy() ctx.update(context) try: data = proxy.read(ids, fields.keys() + ["__last_update"], ctx) except: pass ConcurrencyInfo.update(self.model, data) cherrypy.response.headers.pop("X-Concurrency-Info", None) self.concurrency_info = ConcurrencyInfo(self.model, ids) order_data = [(d["id"], d) for d in data] orderer = dict(zip(ids, count())) ordering = sorted(order_data, key=lambda object: orderer[object[0]]) data = [i[1] for i in ordering] for item in data: self.data_dict[item["id"]] = item.copy() self.ids = ids elif kw.get("default_data", []): data = kw["default_data"] self.values = copy.deepcopy(data) self.headers, self.hiddens, self.data, self.field_total, self.buttons = self.parse(root, fields, data) for k, v in self.field_total.items(): if (len([test[0] for test in self.hiddens if test[0] == k])) <= 0: self.field_total[k][1] = self.do_sum(self.data, k) self.columns = len(self.headers) self.columns += (self.selectable or 0) and 1 self.columns += (self.editable or 0) and 2 self.columns += (self.buttons or 0) and 1 if self.pageable: self.pager = Pager(ids=self.ids, offset=self.offset, limit=self.limit, count=self.count) self.pager._name = self.name if self.editable and context.get("set_editable"): # Treeview editable by default or set_editable in context attrs["editable"] = "bottom" # make editors if self.editable and attrs.get("editable") in ("top", "bottom"): for f, fa in self.headers: if not isinstance(fa, int): fa["prefix"] = "_terp_listfields" + ((self.name != "_terp_list" or "") and "/" + self.name) fa["inline"] = True if fa.get("type") == "one2many": self.edit_inline = False self.editors = {} break Widget = get_widget(fa.get("type", "char")) or get_widget("char") self.editors[f] = Widget(**fa) # generate hidden fields if self.editors: for f, fa in self.hiddens: fa["prefix"] = "_terp_listfields" + ((self.name != "_terp_list" or "") and "/" + self.name) self.editors[f] = form.Hidden(**fa) # limit the data if self.pageable and len(self.data) > self.limit and self.limit != -1: self.data = self.data[self.offset :] self.data = self.data[: min(self.limit, len(self.data))]
def get_events(self, days): proxy = rpc.RPCProxy(self.model) if self.date_stop: # use the correct algorithm: domain = self.domain + [ (self.date_stop, '<=', days[-1].isoformat() + ' 23:59:59'), (self.date_start, '>=', days[0].isoformat() + ' 00:00:00') ] else: # cannot use the correct algorithm, use the old one: first = days[0].month2.prev()[0] #HACK: add prev month domain = self.domain + [ (self.date_start, '>', first.isoformat()), (self.date_start, '<', days[-1].next().isoformat()) ] # convert color values from string to python values if self.color_values and self.color_field in self.fields: try: atr = self.fields[self.color_field] atr['required'] = False wid = get_widget(atr['type'])(**atr) vals = self.color_values[:] for i, v in enumerate(vals): try: vals[i] = wid.validator.to_python(v) except: pass domain.append((self.color_field, "in", vals)) except Exception: pass if self.options and self.options.use_search: domain += self.options.search_domain ctx = rpc.session.context.copy() ctx.update(self.context) order_by = ('sequence' in self.fields or 0) and 'sequence' if self.color_field and self.fields[self.color_field].get( 'relation') and self.color_field not in [ item[0] for item in domain ]: if self.options and self.options.get('_terp_color_filters'): clr_field = self.options['_terp_color_filters'] else: search_limit = 10 need_to_add_the_user_to_the_list_of_users = False if self.context and self.color_field and \ self.context.get('search_default_user_id') and \ self.color_field == 'user_id' and \ self.fields[self.color_field].get('relation') == 'res.users': need_to_add_the_user_to_the_list_of_users = True clr_field = rpc.RPCProxy( self.fields[self.color_field]['relation']).search([], 0, 0, 0, ctx) if need_to_add_the_user_to_the_list_of_users and self.context.get( 'search_default_user_id') not in clr_field: clr_field[search_limit - 1] = self.context.get('search_default_user_id') domain.append((self.color_field, 'in', clr_field)) ids = proxy.search(domain, 0, 0, order_by, ctx) splitIds = [tuple(x.split('-')) for x in ids if isinstance(x, str)] splitIds.sort(key=lambda x: int(x[0])) if splitIds: ids = ["-".join(i) for i in splitIds] result = proxy.read(ids, self.fields.keys() + ['__last_update'], ctx) ConcurrencyInfo.update(self.model, result) self.concurrency_info = ConcurrencyInfo(self.model, ids) colorCount = 1 if self.color_field: for evt in result: key = evt[self.color_field] name = key value = key if isinstance( key, list): # M2O, XMLRPC returns List instead of Tuple evt[self.color_field] = key = tuple(key) if isinstance(key, tuple): # M2O value, name = key if key not in self.colors: colors = choice_colors(colorCount) self.colors[key] = (name, value, colors[-1]) colorCount += 1 events = [] for evt in result: self.convert(evt) events.append(self.get_event_widget(evt)) if self.date_stop: result = events else: # filter out the events which are not in the range result = [] for e in events: if e.dayspan > 0 and days[0] - e.dayspan < e.starts: result.append(e) if e.dayspan == 0 and days[0] <= e.starts: result.append(e) return result
def get_events(self, days): proxy = rpc.RPCProxy(self.model) if self.date_stop: # use the correct algorithm: domain = self.domain + [ (self.date_stop, "<=", days[-1].isoformat() + " 23:59:59"), (self.date_start, ">=", days[0].isoformat() + " 00:00:00"), ] else: # cannot use the correct algorithm, use the old one: first = days[0].month2.prev()[0] # HACK: add prev month domain = self.domain + [ (self.date_start, ">", first.isoformat()), (self.date_start, "<", days[-1].next().isoformat()), ] # convert color values from string to python values if self.color_values and self.color_field in self.fields: try: atr = self.fields[self.color_field] atr["required"] = False wid = get_widget(atr["type"])(**atr) vals = self.color_values[:] for i, v in enumerate(vals): try: vals[i] = wid.validator.to_python(v) except: pass domain.append((self.color_field, "in", vals)) except Exception: pass if self.options and self.options.use_search: domain += self.options.search_domain ctx = rpc.get_session().context.copy() ctx.update(self.context) order_by = ("sequence" in self.fields or 0) and "sequence" if ( self.color_field and self.fields[self.color_field].get("relation") and self.color_field not in [item[0] for item in domain] ): if self.options and self.options.get("_terp_color_filters"): clr_field = self.options["_terp_color_filters"] else: search_limit = 10 need_to_add_the_user_to_the_list_of_users = False if ( self.context and self.color_field and self.context.get("search_default_user_id") and self.color_field == "user_id" and self.fields[self.color_field].get("relation") == "res.users" ): need_to_add_the_user_to_the_list_of_users = True clr_field = rpc.RPCProxy(self.fields[self.color_field]["relation"]).search([], 0, 0, 0, ctx) if ( need_to_add_the_user_to_the_list_of_users and self.context.get("search_default_user_id") not in clr_field ): clr_field[search_limit - 1] = self.context.get("search_default_user_id") domain.append((self.color_field, "in", clr_field)) ids = proxy.search(domain, 0, 0, order_by, ctx) result = proxy.read(ids, self.fields.keys() + ["__last_update"], ctx) ConcurrencyInfo.update(self.model, result) self.concurrency_info = ConcurrencyInfo(self.model, ids) if self.color_field: for evt in result: key = evt[self.color_field] name = key value = key if isinstance(key, list): # M2O, XMLRPC returns List instead of Tuple evt[self.color_field] = key = tuple(key) if isinstance(key, tuple): # M2O value, name = key self.colors[key] = (name, value, None) colors = choice_colors(len(self.colors)) for i, (key, value) in enumerate(self.colors.items()): self.colors[key] = (value[0], value[1], colors[i]) events = [] for evt in result: self.convert(evt) events.append(self.get_event_widget(evt)) if self.date_stop: result = events else: # filter out the events which are not in the range result = [] for e in events: if e.dayspan > 0 and days[0] - e.dayspan < e.starts: result.append(e) if e.dayspan == 0 and days[0] <= e.starts: result.append(e) return result
def get_events(self, days): proxy = rpc.RPCProxy(self.model) if self.date_stop: # use the correct algorithm: domain = self.domain + [(self.date_stop, '<=', days[-1].isoformat() + ' 23:59:59'), (self.date_start, '>=', days[0].isoformat() + ' 00:00:00')] else: # cannot use the correct algorithm, use the old one: first = days[0].month2.prev()[0] #HACK: add prev month domain = self.domain + [(self.date_start, '>', first.isoformat()), (self.date_start, '<', days[-1].next().isoformat())] # convert color values from string to python values if self.color_values and self.color_field in self.fields: try: atr = self.fields[self.color_field] atr['required'] = False wid = get_widget(atr['type'])(**atr) vals = self.color_values[:] for i, v in enumerate(vals): try: vals[i] = wid.validator.to_python(v) except: pass domain.append((self.color_field, "in", vals)) except Exception: pass if self.options and self.options.use_search: domain += self.options.search_domain ctx = rpc.session.context.copy() ctx.update(self.context) order_by = ('sequence' in self.fields or 0) and 'sequence' if self.color_field and self.fields[self.color_field].get('relation') and self.color_field not in [item[0] for item in domain]: if self.options and self.options.get('_terp_color_filters'): clr_field = self.options['_terp_color_filters'] else: search_limit = 10 need_to_add_the_user_to_the_list_of_users = False if self.context and self.color_field and \ self.context.get('search_default_user_id') and \ self.color_field == 'user_id' and \ self.fields[self.color_field].get('relation') == 'res.users': need_to_add_the_user_to_the_list_of_users = True clr_field = rpc.RPCProxy(self.fields[self.color_field]['relation']).search([], 0, 0, 0, ctx) if need_to_add_the_user_to_the_list_of_users and self.context.get('search_default_user_id') not in clr_field: clr_field[search_limit-1] = self.context.get('search_default_user_id') domain.append((self.color_field, 'in', clr_field)) ids = proxy.search(domain, 0, 0, order_by, ctx) splitIds = [tuple(x.split('-')) for x in ids if isinstance(x, str)] splitIds.sort(key = lambda x: int(x[0])) if splitIds: ids = ["-".join(i) for i in splitIds] result = proxy.read(ids, self.fields.keys()+['__last_update'], ctx) ConcurrencyInfo.update(self.model, result) self.concurrency_info = ConcurrencyInfo(self.model, ids) colorCount = 1 if self.color_field: for evt in result: key = evt[self.color_field] name = key value = key if isinstance(key, list): # M2O, XMLRPC returns List instead of Tuple evt[self.color_field] = key = tuple(key) if isinstance(key, tuple): # M2O value, name = key if key not in self.colors: colors = choice_colors(colorCount) self.colors[key] = (name, value, colors[-1]) colorCount += 1 events = [] for evt in result: self.convert(evt) events.append(self.get_event_widget(evt)) if self.date_stop: result = events else: # filter out the events which are not in the range result = [] for e in events: if e.dayspan > 0 and days[0] - e.dayspan < e.starts: result.append(e) if e.dayspan == 0 and days[0] <= e.starts: result.append(e) return result