Esempio n. 1
0
    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)
Esempio n. 3
0
    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))]
Esempio n. 4
0
    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))]
Esempio n. 5
0
    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)
Esempio n. 7
0
    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))]
Esempio n. 8
0
    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
Esempio n. 9
0
    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
Esempio n. 10
0
    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