Example #1
0
def get_search_default(attrs, screen_context=None, default_domain=[]):
    screen_context = screen_context or {}

    if 'context' in attrs:
        ctx = expr_eval(attrs.get('context', "{}"), {'self':attrs.get('name', False)})
        group_by = ctx.get('group_by')
        if group_by:
            if isinstance(group_by, list):
                str_ctx = map(lambda x: 'group_' + x, group_by)
            else:
                str_ctx = 'group_' + group_by
            result = str_ctx in screen_context.get('group_by', [])
            return  result or attrs.get('name') and screen_context.get('search_default_' + attrs.get('name'))

    if cherrypy.request.path_info != '/openerp/listgrid/get' and 'name' in attrs:
        search_default = screen_context.get('search_default_' + attrs['name'])
        if search_default:
            # The value of search_default_$field can be either a literal
            # (integer, string, ...) or the name of a search_default context
            # variable. Try .get()ing the value in case it's a context object,
            # otherwise return the literal itself
            # ...
            # or so I expected, apparently somebody else already did the
            # resolution of those, so either we have a truthy value and we
            # return it, or we don't and we don't do anything
            return search_default

    return False
Example #2
0
def get_search_default(attrs, screen_context=None, default_domain=[]):
    screen_context = screen_context or {}

    if 'context' in attrs:
        ctx = expr_eval(attrs.get('context', "{}"),
                        {'self': attrs.get('name', False)})
        group_by = ctx.get('group_by')
        if group_by:
            if isinstance(group_by, list):
                str_ctx = map(lambda x: 'group_' + x, group_by)
            else:
                str_ctx = 'group_' + group_by
            result = str_ctx in screen_context.get('group_by', [])
            return result or attrs.get('name') and screen_context.get(
                'search_default_' + attrs.get('name'))

    if cherrypy.request.path_info != '/openerp/listgrid/get' and 'name' in attrs:
        search_default = screen_context.get('search_default_' + attrs['name'])
        if search_default:
            # The value of search_default_$field can be either a literal
            # (integer, string, ...) or the name of a search_default context
            # variable. Try .get()ing the value in case it's a context object,
            # otherwise return the literal itself
            # ...
            # or so I expected, apparently somebody else already did the
            # resolution of those, so either we have a truthy value and we
            # return it, or we don't and we don't do anything
            return search_default

    return False
Example #3
0
    def create_form(self, params, tg_errors=None):

        params.id = params.o2m_id
        params.model = params.o2m_model
        params.view_mode = ['form', 'tree']
        params.view_type = 'form'

        #XXX: dirty hack to fix bug #401700
        if not params.get('_terp_view_ids'):
            params['_terp_view_ids'] = []

        # to get proper view, first generate form using the view_params
        vp = params.view_params

        form = tw.form_view.ViewForm(vp, name="view_form", action="/openerp/openo2m/save")
        cherrypy.request.terp_validators = {}

        if '/' in params.o2m:
            params.o2m = '.'.join(params.o2m.split('/')[-1:])

        wid = form.screen.widget.get_widgets_by_name(params.o2m)[0]

        # save view_params for later phazes
        vp = vp.make_plain('_terp_view_params/')
        hiddens = map(lambda x: tw.form.Hidden(name=x, default=ustr(vp[x])), vp)

        params.prefix = params.o2m
        params.views = wid.view
        params.hide_new_button = False

        ctx = params.context or {}
        ctx.update(params.parent_context or {})
        ctx.update(params.o2m_context or {})
        p, ctx = TinyDict.split(ctx)
        
        if ctx.get('default_name'):
            del ctx['default_name']

        arch = params.views.get('form', {}).get('arch', False)
        if arch:
            dom = xml.dom.minidom.parseString(arch.encode('utf-8'))
            form_attribute = node_attributes(dom.childNodes[0])
            if form_attribute.get('hide_new_button'):
                params.hide_new_button = expr_eval(form_attribute.get('hide_new_button', False), {'context': ctx})

        params.context = ctx or {}
        params.hidden_fields = [tw.form.Hidden(name='_terp_parent_model', default=params.parent_model),
                                tw.form.Hidden(name='_terp_parent_id', default=params.parent_id),
                                tw.form.Hidden(name='_terp_parent_context', default=ustr(params.parent_context)),
                                tw.form.Hidden(name='_terp_o2m', default=params.o2m),
                                tw.form.Hidden(name='_terp_o2m_id', default=params.id or None),
                                tw.form.Hidden(name='_terp_o2m_model', default=params.o2m_model),
                                tw.form.Hidden(name='_terp_o2m_context', default=ustr(params.o2m_context or {})),
                                tw.form.Hidden(name=params.prefix + '/__id', default=params.id or None)] + hiddens

        form = tw.form_view.ViewForm(params, name="view_form", action="/openerp/openo2m/save")
        form.screen.string = wid.screen.string

        return form
Example #4
0
    def expr_eval(self, expr, source=None):
        if not isinstance(expr, basestring):
            return expr

        return expr_eval(
                expr, dict(self,
                           context=self.params.context or {},
                           active_id=self.get('id', False)))
    def expr_eval(self, expr, source=None):
        if not isinstance(expr, basestring):
            return expr

        return expr_eval(
            expr,
            dict(self,
                 context=self.params.context or {},
                 active_id=self.get('id', False)))
Example #6
0
    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)
Example #7
0
    def __init__(self, **attrs):
        super(Filter, self).__init__(**attrs)

        default_domain = attrs.get('default_domain')
        self.global_domain = []
        self.icon = attrs.get('icon')
        self.filter_domain = attrs.get('domain', [])
        self.help = attrs.get('help')
        self.filter_id = 'filter_%s' % (random.randint(0,10000))
        filter_context = attrs.get('context')
        screen_context = attrs.get('screen_context', {})

        self.def_checked = False
        self.groupcontext = []

        default_search = get_search_default(attrs, screen_context, default_domain)

        # context implemented only for group_by.
        self.group_context = None
        if filter_context:
            self.filter_context = eval(filter_context)
            self.group_context = self.filter_context.get('group_by', False)
            if self.group_context:
                if isinstance(self.group_context, list):
                    self.group_context = map(lambda x: 'group_' + x, self.group_context)
                else:
                    self.group_context = 'group_' + self.group_context

        if default_search:
            self.def_checked = True
            self.global_domain += (expr_eval(self.filter_domain, {'context':screen_context}))
            if self.group_context:
                self.groupcontext = self.group_context

        self.nolabel = True
        self.readonly = False
        if self.filter_context:
            if not self.filter_context.get('group_by'):
                self.filter_context = self.filter_context
            else:
                self.filter_context = {}
        self.text_val = self.string or self.help
        if self.icon:
            self.icon = icons.get_icon(self.icon)

        if self.string == self.help:
            self.help = None

        self.first_box = attrs.get('first_box')
        self.last_box = attrs.get('last_box')
        self.first_last_box = attrs.get('first_last_box')
        
        if not self.def_checked and attrs.get('group_by_ctx'):
            if self.group_context in attrs['group_by_ctx']:
                self.def_checked = True
    def 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.session.context})
            except:
                value = params['value']
            params['text'] = rpc.name_get(self.relation, value,
                                          rpc.session.context)
Example #9
0
    def action(self, **kw):
        params, data = TinyDict.split(kw)
        context_menu = kw.get('context_menu') or False

        id = params.id or False
        ids = params.selection or []

        if not ids and id:
            ids = [id]

        if not id and ids:
            id = ids[0]

        domain = params.domain or []
        context = params.context or {}
        action = {}

        if data.get('datas'):
            action = eval(data.get('datas'))
        type = action.get('type')
        act_id = params.action

        if not act_id:
            return self.do_action('client_action_multi', datas=kw)

        if type is None:
            action_type = rpc.RPCProxy('ir.actions.actions').read(
                act_id, ['type'], context)['type']
            tmp_ctx = dict(context)
            if action_type == 'ir.actions.report.xml':
                # avoid reading large binary values that we won't even care about
                tmp_ctx['bin_size'] = True
            action = rpc.session.execute('object', 'execute', action_type,
                                         'read', act_id, False, tmp_ctx)

        if domain:
            if isinstance(domain, basestring):
                domain = eval(domain)
            domain.extend(expr_eval(action.get('domain', '[]'), context))
            action['domain'] = ustr(domain)

        if context.get('search_view'):
            context.pop('search_view')
        action['form_context'] = context or {}
        import actions
        return actions.execute(action,
                               model=params.model,
                               id=id,
                               ids=ids,
                               report_type='pdf',
                               context_menu=context_menu)
Example #10
0
def execute(action, **data):
    """Execute the action with the provided data. for internal use only.

    @param action: the action
    @param data: the data

    @return: mostly XHTML code
    """
    if 'type' not in action:
        #XXX: in gtk client just returns to the caller
        #raise common.error('Error', 'Invalid action...')
        return;

    data.setdefault('context', {}).update(expr_eval(action.get('form_context', '{}') or action.get('context','{}'), data.get('context', {})))

    action_executor = ACTIONS_BY_TYPE[action['type']]
    return action_executor(action, data)
Example #11
0
    def action(self, **kw):
        params, data = TinyDict.split(kw)
        context_menu = kw.get('context_menu') or False

        id = params.id or False
        ids = params.selection or []

        if not ids and id:
            ids = [id]

        if not id and ids:
            id = ids[0]

        domain = params.domain or []
        context = params.context or {}
        action = {}

        if data.get('datas'):
            action = eval(data.get('datas'))
        type = action.get('type')
        act_id = params.action

        if not act_id:
            return self.do_action('client_action_multi', datas=kw)

        if type is None:
            action_type = rpc.RPCProxy('ir.actions.actions').read(act_id, ['type'], context)['type']
            tmp_ctx = dict(context)
            if action_type == 'ir.actions.report.xml':
                # avoid reading large binary values that we won't even care about
                tmp_ctx['bin_size'] = True
            action = rpc.session.execute('object', 'execute', action_type, 'read', act_id, False, tmp_ctx)

        if domain:
            if isinstance(domain, basestring):
                domain = eval(domain)
            domain.extend(expr_eval(action.get('domain', '[]'), context))
            action['domain'] = ustr(domain)

        if context.get('search_view'):
            context.pop('search_view')
        action['form_context'] = context or {}
        import actions
        return actions.execute(action, model=params.model, id=id, ids=ids, report_type='pdf', context_menu=context_menu)
def execute(action, **data):
    """Execute the action with the provided data. for internal use only.

    @param action: the action
    @param data: the data

    @return: mostly XHTML code
    """
    if 'type' not in action:
        #XXX: in gtk client just returns to the caller
        #raise common.error('Error', 'Invalid action...')
        return

    data.setdefault('context', {}).update(
        expr_eval(
            action.get('form_context', '{}') or action.get('context', '{}'),
            data.get('context', {})))

    action_executor = ACTIONS_BY_TYPE[action['type']]
    return action_executor(action, data)
Example #13
0
    def action(self, **kw):
        params, data = TinyDict.split(kw)
        context_menu = kw.get('context_menu')

        id = params.id or False
        ids = params.selection or []

        if not ids and id:
            ids = [id]

        if not id and ids:
            id = ids[0]

        domain = params.domain or []
        context = params.context or {}
        if not context and rpc.session.context:
            context['lang'] = rpc.session.context.get('lang')
        action = {}

        if data.get('datas'):
            action = eval(data.get('datas'))
        type = action.get('type')
        act_id = params.action

        if not act_id:
            return self.do_action('client_action_multi', datas=kw)

        if type is None:
            action_type = rpc.RPCProxy('ir.actions.actions').read(act_id, ['type'], context)['type']
            action = rpc.session.execute('object', 'execute', action_type, 'read', act_id, False, context)

        if domain:
            if isinstance(domain, basestring):
                domain = eval(domain)
            domain.extend(expr_eval(action.get('domain', '[]'), context))
            action['domain'] = ustr(domain)

        action['form_context'] = context or {}
        import actions
        return actions.execute(action, model=params.model, id=id, ids=ids, report_type='pdf', context_menu=context_menu)
Example #14
0
 def do_filter_sc(self, **kw):
     name = kw.get('name')
     model = kw.get('model')
     domain = kw.get('domain')
     group_by = kw.get('group_by', [])
     if isinstance(group_by, (str,unicode)):
         group_by = expr_eval(group_by)
     if group_by:
         context = {'group_by': group_by}
     else:
         context = {}
     if name:
         datas = {
             'name':name,
             'model_id':model,
             'domain':domain,
             'context':str(context),
             'user_id':rpc.session.uid
         }
         result = rpc.session.execute('object', 'execute', 'ir.filters', 'create_or_replace', datas, rpc.session.context)
         return {'filter': (domain, name, group_by), 'new_id':result}
     return {}
Example #15
0
    def build_row(self, row):
        row = row.copy()
        # compute color once for whole row
        rowcolor = None
        for color, expr in self.colors.items():
            try:
                if expr_eval(expr,
                    dict(row, active_id=rpc.session.active_id or False)):
                    rowcolor = color
                    break
            except Exception:
                pass

        for (name, invisible, cell) in self.build_new_fields(self.fields):
            if invisible:
                cell.set_value(row.get(name, False))
            else:
                cell.value = row.get(name, False)
                cell.text = cell.get_text()
                cell.link = cell.get_link()
            cell.color = rowcolor
            row[name] = cell
        return row
Example #16
0
    def build_row(self, row):
        row = row.copy()
        # compute color once for whole row
        rowcolor = None
        for color, expr in self.colors.items():
            try:
                if expr_eval(
                        expr,
                        dict(row, active_id=rpc.session.active_id or False)):
                    rowcolor = color
                    break
            except Exception:
                pass

        for (name, invisible, cell) in self.build_new_fields(self.fields):
            if invisible:
                cell.set_value(row.get(name, False))
            else:
                cell.value = row.get(name, False)
                cell.text = cell.get_text()
                cell.link = cell.get_link()
            cell.color = rowcolor
            row[name] = cell
        return row
 def do_filter_sc(self, **kw):
     name = kw.get('name')
     model = kw.get('model')
     domain = kw.get('domain')
     group_by = kw.get('group_by', [])
     if isinstance(group_by, (str, unicode)):
         group_by = expr_eval(group_by)
     if group_by:
         context = {'group_by': group_by}
     else:
         context = {}
     if name:
         datas = {
             'name': name,
             'model_id': model,
             'domain': domain,
             'context': str(context),
             'user_id': rpc.session.uid
         }
         result = rpc.session.execute('object', 'execute', 'ir.filters',
                                      'create_or_replace', datas,
                                      rpc.session.context)
         return {'filter': (domain, name, group_by), 'new_id': result}
     return {}
Example #18
0
    def data(self,
             ids,
             model,
             fields,
             field_parent=None,
             icon_name=None,
             domain=[],
             context={},
             sort_by=None,
             sort_order="asc",
             fields_info=None,
             colors={}):

        if ids == 'None' or ids == '':
            ids = []

        if isinstance(ids, basestring):
            ids = map(int, ids.split(','))
        elif isinstance(ids, list):
            ids = map(int, ids)

        if isinstance(fields, basestring):
            fields = eval(fields)

        if isinstance(domain, basestring):
            domain = eval(domain)

        if isinstance(context, basestring):
            context = eval(context)

        if isinstance(colors, basestring):
            colors = eval(colors)

        if isinstance(fields_info, basestring):
            fields_info = simplejson.loads(fields_info)

        if field_parent and field_parent not in fields:
            fields.append(field_parent)

        proxy = rpc.RPCProxy(model)

        ctx = dict(context, **rpc.session.context)

        if icon_name:
            fields.append(icon_name)

        if model == 'ir.ui.menu' and 'action' not in fields:
            fields.append('action')

        result = proxy.read(ids, fields, ctx)

        if sort_by:
            fields_info_type = simplejson.loads(fields_info[sort_by])
            result.sort(lambda a, b: self.sort_callback(
                a, b, sort_by, sort_order, type=fields_info_type['type']))

        for item in result:
            if colors:
                for color, expr in colors.items():
                    try:
                        if expr_eval(expr, item or False):
                            item['color'] = color
                            break
                    except:
                        pass

        # format the data
        for field in fields:
            field_info = simplejson.loads(fields_info[field])
            if field_info.get('widget', ''):
                field_info['type'] = field_info['widget']
            formatter = FORMATTERS.get(field_info['type'])
            for x in result:
                if x[field] and formatter:
                    x[field] = formatter(x[field], field_info)

        records = []
        for item in result:
            # empty string instead of False or None
            for k, v in item.items():
                if v is None or v is False:
                    item[k] = ''

            id = item.pop('id')
            record = {
                'id':
                id,
                'action':
                url('/openerp/tree/open', model=model, id=id, context=ctx),
                'target':
                None,
                'icon':
                None,
                'children': [],
                'items':
                item
            }

            if icon_name and item.get(icon_name):
                icon = item.pop(icon_name)
                record['icon'] = icons.get_icon(icon)

            if field_parent and field_parent in item:
                record['children'] = item.pop(field_parent) or None

                # For nested menu items, remove void action url
                # to suppress 'No action defined' error.
                if (model == 'ir.ui.menu' and record['children']
                        and not item['action']):
                    record['action'] = None

            records.append(record)

        return {'records': records}
Example #19
0
    def __init__(self, **attrs):

        super(Action, self).__init__(**attrs)
        self.nolabel = True

        self.act_id= self.name
        
        proxy = rpc.RPCProxy("ir.actions.actions")
        res = proxy.read([self.act_id], ['type'], rpc.session.context)
        if not res:
            raise common.message(_('Action not found'))

        _type=res[0]['type']
        self.action = rpc.session.execute('object', 'execute', _type, 'read', [self.act_id], False, rpc.session.context)[0]

        if 'view_mode' in attrs:
            self.action['view_mode'] = attrs['view_mode']

        if self.action['type']=='ir.actions.act_window':

            if not self.action.get('domain', False):
                self.action['domain']='[]'

            ctx = dict(rpc.session.context,
                       active_id=False,
                       active_ids=[])

            self.context = expr_eval(self.action.get('context', '{}'), ctx)
            self.domain = expr_eval(self.action['domain'], ctx)
            views = dict(map(lambda x: (x[1], x[0]), self.action['views']))
            view_mode = self.action.get('view_mode', 'tree,form').split(',')
            view_ids = map(lambda x: views.get(x, False), view_mode)
            
            if views.keys() != view_mode:
                view_mode = map(lambda x: x[1], self.action['views'])
                view_ids = map(lambda x: x[0], self.action['views'])
            
            if self.action['view_type'] == 'form':

                params = TinyDict()
                params.updateAttrs(
                    model=self.action['res_model'],
                    id=False,
                    ids=None,
                    view_ids=view_ids,
                    view_mode=view_mode,
                    context=self.context,
                    domain=self.domain,
                    offset = 0,
                    limit = 50
                )

                # get pager vars if set
                if hasattr(cherrypy.request, 'terp_params'):
                    current = cherrypy.request.terp_params
                    current = current.chain_get(self.name or '') or current

                    params.updateAttrs(
                        offset=current.offset,
                        limit=current.limit
                    )

                self.screen = screen.Screen(params, prefix=self.name, editable=True, selectable=3)

            elif self.action['view_type']=='tree':
                pass #TODO
Example #20
0
    def __init__(self, **attrs):
        #FIXME: validation error in `Pricelist Version`
        attrs['required'] = False

        super(O2M, self).__init__(**attrs)

        self.new_attrs = { 'text': _("New"), 'help': _('Create new record.')}
        self.default_get_ctx = attrs.get('default_get', {}) or attrs.get('context', {})

        # get top params dictionary
        params = cherrypy.request.terp_params
        self.source = params.source
        self.edition = params.o2m_edit
        pprefix = ''
        if '/' in self.name:
            pprefix = self.name[:self.name.rindex('/')]

        pparams = params.chain_get(pprefix)
        if (pparams and not pparams.id) or (not pparams and not params.id):
            self.new_attrs = { 'text': _("Save/New"), 'help': _('Save parent record.')}

        self.parent_id = params.id
        if pparams:
            self.parent_id = pparams.id

        # get params for this field
        current = params.chain_get(self.name)

        self.model = attrs['relation']
        self.link = attrs.get('link', '')
        self.onchange = None # override onchange in js code

        view = attrs.get('views', {})
        mode = str(attrs.get('mode', 'tree,form')).split(',')

        self.view = view

        view_mode = mode
        view_type = mode[0]
        self.view_type = view_type
        
        if not current:
            current = TinyDict()

        if current.view_mode: view_mode = current.view_mode
        if current.view_type: view_type = current.view_type

        self.switch_to = view_mode[-1]
        if view_type == view_mode[-1]: self.switch_to = view_mode[0]

        ids = attrs.get('value') or []
        if not isinstance(ids, list):
            ids = [ids]

        if ids:
            if isinstance(ids[0], dict):
                current.default_data = ids
                for item in current.default_data:
                    self.default_value.append(
                        OneToMany.create(item))
                    item['id'] = 0
                ids = []
            elif isinstance(ids[0], tuple):
                [current_id[1] for current_id in ids]
        
        id = (ids or None) and ids[0]
        
        if self.name == self.source or self.name == params.source:
            if params.sort_key and ids:
                domain = current.domain or []
                domain.append(('id', 'in', ids))
                ids = rpc.RPCProxy(self.model).search(domain, current.offset, current.limit, params.sort_key + ' '+params.sort_order, current.context)
                id = ids[0]
        if current and params.source and self.name in params.source.split('/'):
            id = current.id

        id = id or None
                
        current.model = self.model
        current.id = id
        current.ids = ids
        current.view_mode = view_mode
        current.view_type = view_type
        current.domain = current.domain or []
        current.context = current.context or {}

        group_by_ctx = ''
        if self.default_get_ctx:
            ctx = dict(cherrypy.request.terp_record,
                       context=current.context,
                       active_id=self.parent_id or False)
            ctx[attrs['name']] = ids
            # XXX: parent record for O2M
            #if self.parent:
            #    ctx['parent'] = EvalEnvironment(self.parent)

            try:
                context = ctx.copy()
                ctx = expr_eval("dict(%s)" % self.default_get_ctx, context)
                ctx.update(expr_eval("dict(%s)" % attrs.get('context', '{}'), context))
                current.context.update(ctx)
            except:
                pass

            if ctx and ctx.get('group_by'):
                group_by_ctx = ctx.get('group_by')

        current.offset = current.offset or 0
        current.limit = current.limit or 50
        current.count = len(ids or [])

        # Group By for one2many list.
        if group_by_ctx:
            current.group_by_ctx = group_by_ctx
            current.domain = [('id', 'in', ids)]

        if current.view_type == 'tree' and self.readonly:
            self.editable = False

        if 'default_name' in current.context:
            del current.context['default_name']

        if self.view_type == 'tree' and pparams:
            self.editable = bool(pparams.id)

        self.screen = Screen(current, prefix=self.name, views_preloaded=view,
                             editable=self.editable, readonly=self.readonly,
                             selectable=0, nolinks=self.link, _o2m=1)
        
        self.id = id
        self.ids = ids

        if view_type == 'tree':
            self.id = None

        elif view_type == 'form':
            records_count = len(self.screen.ids or [])

            current_record = 0
            if records_count and self.screen.id in self.screen.ids:
                current_record = self.screen.ids.index(self.screen.id) + 1
                self.pager_info = _('%d of %d') % (current_record, records_count)
            else:
                self.pager_info = _('- of %d') % (records_count)
Example #21
0
        parent_context.update(
            active_id=params.active_id or False,
            active_ids=params.active_ids or [])

        ctx.update(
            parent=pctx,
            context=parent_context,
            active_id=params.active_id or False,
            active_ids=params.active_ids or []
        )

        if params.active_id and not params.active_ids:
            ctx['active_ids'] = [params.active_id]

        if domain and isinstance(domain, basestring):
            domain = expr_eval(domain, ctx)

        if domain and len(domain) >= 2 and domain[-2] in ['&', '|']: # For custom domain ('AND', OR') from search view.
            dom1 = domain[-1:]
            dom2 = domain[:-2]
            domain = dom2 + dom1

        if context and isinstance(context, basestring):
            if not context.startswith('{'):
                context = "dict(%s)"%context
                ctx['dict'] = dict # required

            context = expr_eval(context, ctx)

#           Fixed many2one pop up in listgrid when value is None.
            for key, val in context.items():
def act_window(action, data):
    if not action.get('opened'):
        action.setdefault('target', 'current')
        return act_window_opener(action, data)

    for key in ('res_id', 'res_model', 'view_type', 'view_mode', 'limit',
                'search_view'):
        data[key] = action.get(key, data.get(key))
    if not data.get('search_view') and data.get('search_view_id'):
        data['search_view'] = str(
            rpc.session.execute('object', 'execute', data['res_model'],
                                'fields_view_get', data['search_view_id'],
                                'search', data['context']))
    if data.get('limit'):
        data['limit'] = 20

    if action.get('target') and action['target'] == 'popup' and action.get(
            'res_model') and isinstance(action.get('context'), dict):
        search_view_id = rpc.RPCProxy('ir.ui.view').search(
            [('type', '=', 'search'), ('model', '=', action['res_model'])], 0,
            0, 0, rpc.session.context)
        if search_view_id and action['context'].get('search_view'):
            action['context']['search_view'] = search_view_id[0]

    view_ids = False
    if action.get('views', []):
        if isinstance(action['views'], list):
            view_ids = [x[0] for x in action['views']]
            data['view_mode'] = ",".join([x[1] for x in action['views']])
        else:
            if action.get('view_id'):
                view_ids = [action['view_id'][0]]
    elif action.get('view_id'):
        view_ids = [action['view_id'][0]]
    if not action.get('domain'):
        action['domain'] = '[]'

    ctx = dict(data.get('context', {}),
               active_id=data.get('id', False),
               active_ids=data.get('ids', []),
               active_model=data.get('model', False))

    if action.get('context') and isinstance(action['context'], dict):
        if not action['context'].get('active_ids'):
            action['context']['active_ids'] = ctx['active_ids'] or []

    ctx.update(expr_eval(action.get('context', '{}'), ctx))

    search_view = action.get('search_view_id')
    if search_view:
        if isinstance(search_view, (list, tuple)):
            ctx['search_view'] = search_view[0]
        else:
            ctx['search_view'] = search_view

        # save active_id in session
    rpc.session.active_id = data.get('id')
    domain = expr_eval(action['domain'], ctx)
    if data.get('domain'):
        domain.append(data['domain'])

    if 'menu' in data['res_model'] and action.get('name') == 'Menu':
        return close_popup()

    if action.get('display_menu_tip'):
        display_menu_tip = action.get('help')
    else:
        display_menu_tip = None

    return execute_window(view_ids,
                          data['res_model'],
                          data['res_id'],
                          domain,
                          action['view_type'],
                          ctx,
                          data['view_mode'],
                          name=action.get('name'),
                          target=action.get('target'),
                          limit=data.get('limit'),
                          search_view=data['search_view'],
                          context_menu=data.get('context_menu'),
                          display_menu_tip=display_menu_tip,
                          action_id=action.get('id'))
Example #23
0
    def parse(self, model=None, root=None, fields=None, values={}):

        views = []
        search_model = model

        filters_run = []
        for node in root.childNodes:
            if not node.nodeType==node.ELEMENT_NODE:
                continue

            if filters_run and node.localName != 'filter':
                views.append(FiltersGroup(children=filters_run))
                filters_run = []

            attrs = node_attributes(node)
            attrs.update(is_search=True,
                         model=search_model)

            if 'nolabel' in attrs:
                attrs['nolabel'] = False

            if node.localName in ('form', 'tree', 'search', 'group'):
                if node.localName == 'group':
                    attrs['group_by_ctx'] = values.get('group_by_ctx')
                    attrs['expand'] = expr_eval(attrs.get('expand',False),{'context':self.context})
                    Element = Group
                else:
                    Element = Frame

                views.append(Element(children=
                                     self.parse(model=search_model, root=node,
                                                fields=fields, values=values),
                                     **attrs))

            elif node.localName=='newline':
                views.append(NewLine(**attrs))

            elif node.localName=='filter':
                attrs.update(
                    model=search_model,
                    default_domain=self.domain,
                    screen_context=self.context)
                if values and values.get('group_by_ctx'):
                    attrs['group_by_ctx'] = values['group_by_ctx']
                elif self.groupby:
                    attrs['group_by_ctx'] = self.groupby

                v = Filter(**attrs)
                if v.groupcontext and v.groupcontext not in self.groupby:
                    self.groupby.append(v.groupcontext)
                self.listof_domain.extend(i for i in v.global_domain if not i in self.listof_domain)
                filters_run.append(v)

            elif node.localName == 'field':
                val  = attrs.get('select', False) or fields[str(attrs['name'])].get('select', False) or self.view_type == 'search'
                if val:
                    name = attrs['name']
                    if name in self.fields_type:
                        continue

                    # in search view fields should be writable
                    attrs.update(readonly=False,
                                 required=False,
                                 translate=False,
                                 disabled=False,
                                 visible=True,
                                 invisible=False,
                                 editable=True,
                                 attrs=None)

                    try:
                        fields[name].update(attrs)
                    except:
                        print "-"*30,"\n malformed tag for:", attrs
                        print "-"*30
                        raise

                    if attrs.get('widget'):
                        if attrs['widget'] == 'one2many_list':
                            fields[name]['widget'] = 'one2many'

                        fields[name]['type2'] = fields[name]['type']
                        fields[name]['type'] = attrs['widget']

                    kind = fields[name]['type']

                    if kind not in WIDGETS:
                        continue

                    if kind == 'many2one':
                        attrs['relation'] = fields[name]['relation']
                        attrs['type'] = fields[name]['type']
                        if not attrs.get('string'):
                            attrs['string'] = fields[name]['string']

                    self.fields_type[name] = kind

                    field = WIDGETS[kind](**fields[name])
                    field.onchange = None
                    field.callback = None

                    if kind == 'boolean':
                        # '0' in string because 0 is considering as No Value, and we need 0 as some value.
                        field.options = [[1,_('Yes')],['0',_('No')]]
                        field.validator.if_empty = ''

                    default_search = None
                    if name:
                        default_search = get_search_default(fields[name], self.context, self.domain)
                        defval = default_search
                        if defval:
                            model = fields[name].get('relation')
                            type2 = fields[name].get('type2')

                            if kind == 'many2one' and model:
                                try:
                                    value = rpc.name_get(model, default_search, self.context)
                                except Exception,e:
                                    value = defval
                                defval = value or ''

                            if attrs.get('filter_domain'):
                                domain = expr_eval(attrs['filter_domain'], {'self': defval})
                            else:
                                if field.kind == 'selection':
                                    if type2 == 'many2one':
                                        m2nval = defval
                                        try:
                                            m2nval = int(defval)
                                        except:
                                            # you see, since defval can basically be anything, including a totally
                                            # illogic value, my only possibility is to do return another illogic value,
                                            # so it won't crash too much
                                            pass
                                        domain = [(name, '=', m2nval)]
                                    else:
                                        domain = [(name, '=', defval)]

                                elif field.kind in ('date','datetime'):
                                    domain = [(name, '>=', defval)]
                                    
                                elif field.kind == 'boolean':
                                    domain = [(name, '=', defval)]
                                               
                                else:
                                    domain = [(name,fields[name].get('comparator','ilike'), defval)]

                            field.set_value(defval)
                            self.listof_domain += [i for i in domain if not i in self.listof_domain]
                            self.context.update(expr_eval(attrs.get('context',"{}"), {'self': default_search}))

                    if (not default_search) and name in values and isinstance(field, TinyInputWidget):
                        field.set_value(values[name])

                    views.append(field)
                    for n in node.childNodes:
                        if n.localName=='filter':
                            attrs_child = dict(
                                node_attributes(n),
                                default_domain=self.domain,
                                screen_context=self.context)
                            if 'string' in attrs_child: del attrs_child['string']
                            if values and values.get('group_by_ctx'):
                                attrs['group_by_ctx'] = values['group_by_ctx']

                            filter_field = Filter(**attrs_child)
                            filter_field.onchange = None
                            filter_field.callback = None

                            if filter_field.groupcontext and filter_field.groupcontext not in self.groupby:
                                self.groupby.append(filter_field.groupcontext)
                            self.listof_domain.extend(i for i in filter_field.global_domain
                                                        if i not in self.listof_domain)
                            field.filters.append(filter_field)
Example #24
0
    def parse(self, root, fields, data=[]):
        """Parse the given node to generate valid list headers.

        @param root: the root node of the view
        @param fields: the fields

        @return: an instance of List
        """

        headers = []
        hiddens = []
        buttons = []
        field_total = {}
        values = [row.copy() for row in data]

        myfields = []  # check for duplicate fields

        for node in root.childNodes:

            if node.nodeName == "button":
                attrs = node_attributes(node)
                if attrs.get("invisible", False):
                    visible = eval(attrs["invisible"], {"context": self.context})
                    if visible:
                        continue
                buttons += [Button(**attrs)]
                headers.append(("button", len(buttons)))

            elif node.nodeName == "field":
                attrs = node_attributes(node)

                if "name" in attrs:

                    name = attrs["name"]

                    if name in myfields:
                        print "-" * 30
                        print " malformed view for:", self.model
                        print " duplicate field:", name
                        print "-" * 30
                        raise common.error(_("Application Error"), _("Invalid view, duplicate field: %s") % name)

                    myfields.append(name)

                    if attrs.get("widget"):
                        if attrs["widget"] == "one2many_list":
                            attrs["widget"] = "one2many"
                        attrs["type"] = attrs["widget"]

                    try:
                        fields[name].update(attrs)
                    except:
                        print "-" * 30, "\n malformed tag for:", attrs
                        print "-" * 30
                        raise

                    kind = fields[name]["type"]

                    if kind not in CELLTYPES:
                        kind = "char"

                    fields[name].update(attrs)

                    try:
                        visval = fields[name].get("invisible", "False")
                        invisible = eval(visval, {"context": self.context})
                    except NameError, e:
                        cherrypy.log.error(e, context="listgrid.List.parse")
                        invisible = False

                    if invisible:
                        hiddens += [(name, fields[name])]

                    if "sum" in attrs:
                        field_total[name] = [attrs["sum"], 0.0]

                    for i, row in enumerate(data):

                        row_value = values[i]
                        if invisible:
                            cell = Hidden(**fields[name])
                            cell.set_value(row_value.get(name, False))
                        else:
                            cell = CELLTYPES[kind](value=row_value.get(name, False), **fields[name])

                        for color, expr in self.colors.items():
                            try:
                                if expr_eval(expr, dict(row_value, active_id=rpc.session.active_id or False)):
                                    cell.color = color
                                    break
                            except:
                                pass

                        row[name] = cell

                    if invisible:
                        continue

                    headers += [(name, fields[name])]
Example #25
0
    def __init__(self, **attrs):
        #FIXME: validation error in `Pricelist Version`
        attrs['required'] = False

        super(O2M, self).__init__(**attrs)

        self.new_attrs = {'text': _("New"), 'help': _('Create new record.')}
        self.default_get_ctx = attrs.get('default_get', {}) or attrs.get(
            'context', {})

        # get top params dictionary
        params = cherrypy.request.terp_params
        self.source = params.source
        self.edition = params.o2m_edit
        pprefix = ''
        if '/' in self.name:
            pprefix = self.name[:self.name.rindex('/')]

        pparams = params.chain_get(pprefix)
        if (pparams and not pparams.id) or (not pparams and not params.id):
            self.new_attrs = {
                'text': _("Save/New"),
                'help': _('Save parent record.')
            }

        self.parent_id = params.id
        if pparams:
            self.parent_id = pparams.id

        # get params for this field
        current = params.chain_get(self.name)

        self.model = attrs['relation']
        self.link = attrs.get('link', '')
        self.onchange = None  # override onchange in js code

        view = attrs.get('views', {})
        mode = str(attrs.get('mode', 'tree,form')).split(',')

        self.view = view

        view_mode = mode
        view_type = mode[0]
        self.view_type = view_type

        if not current:
            current = TinyDict()

        if current.view_mode: view_mode = current.view_mode
        if current.view_type: view_type = current.view_type

        self.switch_to = view_mode[-1]
        if view_type == view_mode[-1]: self.switch_to = view_mode[0]

        ids = attrs.get('value') or []
        if not isinstance(ids, list):
            ids = [ids]

        current.offset = current.offset or 0
        current.limit = current.limit or 50
        current.count = len(ids or [])

        if current.limit != -1 and not params.sort_key:
            ids = ids[current.offset:current.offset + current.limit]

        if ids:
            if isinstance(ids[0], dict):
                current.default_data = ids
                for item in current.default_data:
                    self.default_value.append(OneToMany.create(item))
                    item['id'] = 0
                ids = []
            elif isinstance(ids[0], tuple):
                [current_id[1] for current_id in ids]

        id = (ids or None) and ids[0]

        if self.name == self.source or self.name == params.source:
            if params.sort_key and ids:
                domain = current.domain or []
                domain.append(('id', 'in', ids))
                limit = current.limit
                if current.limit == -1:
                    limit = 0
                ids = rpc.RPCProxy(self.model).search(
                    domain, current.offset, limit,
                    params.sort_key + ' ' + params.sort_order, current.context)
                id = ids[0]
        if current and params.source and isinstance(
                params.source,
                basestring) and self.name in params.source.split('/'):
            id = current.id

        id = id or None

        current.model = self.model
        current.id = id
        current.ids = ids
        current.view_mode = view_mode
        current.view_type = view_type
        current.domain = current.domain or []
        current.context = current.context or {}

        group_by_ctx = ''
        if self.default_get_ctx:
            ctx = dict(cherrypy.request.terp_record,
                       context=current.context,
                       active_id=self.parent_id or False)
            ctx[attrs['name']] = ids
            # XXX: parent record for O2M
            #if self.parent:
            #    ctx['parent'] = EvalEnvironment(self.parent)

            try:
                context = ctx.copy()
                ctx = expr_eval("dict(%s)" % self.default_get_ctx, context)
                ctx.update(
                    expr_eval("dict(%s)" % attrs.get('context', '{}'),
                              context))
                current.context.update(ctx)
            except:
                pass

            if ctx and ctx.get('group_by'):
                group_by_ctx = ctx.get('group_by')

        # Group By for one2many list.
        if group_by_ctx:
            current.group_by_ctx = group_by_ctx
            current.domain = [('id', 'in', ids)]

        if current.view_type == 'tree' and self.readonly:
            self.editable = False

        if 'default_name' in current.context:
            del current.context['default_name']

        self.screen = Screen(current,
                             prefix=self.name,
                             views_preloaded=view,
                             editable=self.editable,
                             readonly=self.readonly,
                             selectable=0,
                             nolinks=self.link,
                             _o2m=1)

        self.id = id
        self.ids = ids

        if view_type == 'tree':
            self.id = None

        elif view_type == 'form':
            records_count = len(self.screen.ids or [])

            current_record = 0
            if records_count and self.screen.id in self.screen.ids:
                current_record = self.screen.ids.index(self.screen.id) + 1
                self.pager_info = _('%d of %d') % (current_record,
                                                   records_count)
            else:
                self.pager_info = _('- of %d') % (records_count)
    def __init__(self, **attrs):
        super(M2M, self).__init__(**attrs)

        ids = None
        params = getattr(cherrypy.request, "terp_params", None)
        if not params:
            params = TinyDict()
            params.model = attrs.get("relation", "model")
            params.ids = attrs.get("value", [])
            params.name = attrs.get("name", "")

        current = params.chain_get(self.name)
        if current and params.source == self.name:
            ids = current.ids

        self.model = attrs.get("relation", "model")
        self.link = attrs.get("link", None)
        self.onchange = None  # override onchange in js code

        self.relation = attrs.get("relation", "")
        self.domain = attrs.get("domain", [])
        self.context = attrs.get("context", {}) or {}

        view = attrs.get("views", {})
        mode = str(attrs.get("mode", "tree,form")).split(",")

        self.view = view

        view_mode = mode
        view_type = mode[0]

        self.switch_to = view_mode[-1]
        if view_type == view_mode[-1]:
            self.switch_to = view_mode[0]

        if ids is None:
            ids = attrs.get("value") or []

        id = (ids or None) and ids[0]

        pprefix = ""
        if "/" in self.name:
            pprefix = self.name[: self.name.rindex("/")]

        current = params.chain_get(self.name)

        if not current:
            current = TinyDict()

        current.offset = current.offset or 0
        current.limit = current.limit or 50
        current.count = len(ids or [])

        if isinstance(ids, tuple):
            ids = list(ids)

        if self.name == params.source and params.sort_key and ids:
            # reorder ids based on supplier criteria (sort_key, sort_order)
            domain = current.domain or []
            domain.append(("id", "in", ids))
            ids = rpc.RPCProxy(self.model).search(
                domain, 0, 0, params.sort_key + " " + params.sort_order, current.context
            )
            id = ids[0]

        if current.view_mode:
            view_mode = current.view_mode
        if current.view_type:
            view_type = current.view_type

        if current and params.source == self.name:
            id = current.id

        id = id or None

        current.model = self.model
        current.id = id

        current.ids = ids or []
        current.view_mode = view_mode
        current.view_type = view_type
        current.domain = current.domain or []
        current.context = current.context or {}

        if isinstance(self.context, basestring):
            # XXX: parent record for O2M
            # if self.parent:
            #    ctx['parent'] = EvalEnvironment(self.parent)

            try:
                ctx = expr_eval(
                    self.context,
                    dict(cherrypy.request.terp_record, context=current.context, active_id=current.id or False),
                )
                current.context.update(ctx)
            except:
                pass

        if current.view_type == "tree" and self.readonly:
            self.editable = False

        if self.editable is False:
            selectable = 0
        else:
            selectable = 2

        # try to get original input values if creating validation form
        if not params.filter_action:
            try:
                current.ids = eval(cherrypy.request.terp_data.get(self.name))
            except:
                pass

        self.screen = Screen(
            current,
            prefix=self.name,
            views_preloaded=view,
            editable=self.editable,
            readonly=self.editable,
            selectable=selectable,
            nolinks=self.link,
            **{"_m2m": 1}
        )

        self.screen.widget.checkbox_name = False
        self.screen.widget.m2m = True

        self.validator = validators.many2many()
Example #27
0
def act_window(action, data):
    if not action.get('opened'):
        action.setdefault('target', 'current')
        return act_window_opener(action, data)

    for key in ('res_id', 'res_model', 'view_type',
                'view_mode', 'limit', 'search_view'):
        data[key] = action.get(key, data.get(key))
    if not data.get('search_view') and data.get('search_view_id'):
        data['search_view'] = str(rpc.session.execute(
                'object', 'execute', data['res_model'], 'fields_view_get',
                data['search_view_id'], 'search', data['context']))
    # store action limit within request and set it as None for action
    # so that view specific can differenciate between defaults (i.e this
    # act_window limit) and user's choosen value
    if data.get('limit'):
        # TODO: we're conservative here - so we set limit to 20,
        #       but we should really use act_window's limit (i.e data['limit'])
        #       once we're sure there is *no* performance impact.
        cherrypy.request.action_limit = 20
    data['limit'] = None
    
    if action.get('target') and action['target'] == 'popup' and action.get('res_model') and isinstance(action.get('context'), dict):
        search_view_id = rpc.RPCProxy('ir.ui.view').search([('type','=', 'search'), ('model','=',action['res_model'])], 0, 0, 0, rpc.session.context)
        if search_view_id and action['context'].get('search_view'):
            action['context']['search_view'] = search_view_id[0]
    
    view_ids = False
    if action.get('views', []):
        if isinstance(action['views'], list):
            view_ids = [x[0] for x in action['views']]
            data['view_mode'] = ",".join([x[1] for x in action['views']])
        else:
            if action.get('view_id'):
                view_ids = [action['view_id'][0]]
    elif action.get('view_id'):
        view_ids = [action['view_id'][0]]
    if not action.get('domain'):
        action['domain'] = '[]'

    ctx = dict(data.get('context', {}),
        active_id=data.get('id', False),
        active_ids=data.get('ids', []),
        active_model=data.get('model', False)
    )
    
    if action.get('context') and isinstance(action['context'], dict):
        if not action['context'].get('active_ids'):
            action['context']['active_ids'] = ctx['active_ids'] or []
    
    ctx.update(expr_eval(action.get('context', '{}'), ctx))

    search_view = action.get('search_view_id')
    if search_view:
        if isinstance(search_view, (list, tuple)):
            ctx['search_view'] = search_view[0]
        else:
            ctx['search_view'] = search_view

        # save active_id in session
    rpc.session.active_id = data.get('id')
    domain = expr_eval(action['domain'], ctx)
    if data.get('domain'):
        domain.append(data['domain'])

    if 'menu' in data['res_model'] and action.get('name') == 'Menu':
        return close_popup()

    if action.get('display_menu_tip'):
        display_menu_tip = action.get('help')
    else:
        display_menu_tip = None

    return execute_window(view_ids,
                          data['res_model'],
                          data['res_id'],
                          domain,
                          action['view_type'],
                          ctx, data['view_mode'],
                          name=action.get('name'),
                          target=action.get('target'),
                          limit=data.get('limit'),
                          search_view=data['search_view'],
                          context_menu=data.get('context_menu'),
                          display_menu_tip=display_menu_tip,
                          action_id=action.get('id'))
Example #28
0
    def __init__(self, **attrs):
        super(M2M, self).__init__(**attrs)

        ids = None
        params = getattr(cherrypy.request, 'terp_params', None)
        if not params:
            params = TinyDict()
            params.model = attrs.get('relation', 'model')
            params.ids = attrs.get('value', [])
            params.name = attrs.get('name', '')

        current = params.chain_get(self.name)
        if current and params.source == self.name:
            ids = current.ids

        self.model = attrs.get('relation', 'model')
        self.link = attrs.get('link', None)
        self.onchange = None  # override onchange in js code

        self.relation = attrs.get('relation', '')
        self.domain = attrs.get('domain', [])
        self.context = attrs.get('context', {}) or {}

        view = attrs.get('views', {})
        mode = str(attrs.get('mode', 'tree,form')).split(',')

        self.view = view

        view_mode = mode
        view_type = mode[0]

        self.switch_to = view_mode[-1]
        if view_type == view_mode[-1]: self.switch_to = view_mode[0]

        if ids is None:
            ids = attrs.get('value', [])

        id = (ids or None) and ids[0]

        pprefix = ''
        if '/' in self.name:
            pprefix = self.name[:self.name.rindex('/')]

        if self.name == params.source and params.sort_key and ids:
            self.domain.append(('id', 'in', ids))
            ids = rpc.RPCProxy(self.model).search(
                self.domain, 0, 0, params.sort_key + ' ' + params.sort_order,
                self.context)
            id = ids[0]
        current = params.chain_get(self.name)

        if not current:
            current = TinyDict()

        current.offset = current.offset or 0
        current.limit = current.limit or 50
        current.count = len(ids or [])

        if current.view_mode: view_mode = current.view_mode
        if current.view_type: view_type = current.view_type

        if current and params.source == self.name:
            id = current.id

        id = id or None

        current.model = self.model
        current.id = id

        if isinstance(ids, tuple):
            ids = list(ids)

        current.ids = ids or []
        current.view_mode = view_mode
        current.view_type = view_type
        current.domain = current.domain or []
        current.context = current.context or {}

        if isinstance(self.context, basestring):
            # XXX: parent record for O2M
            #if self.parent:
            #    ctx['parent'] = EvalEnvironment(self.parent)

            try:
                ctx = expr_eval(
                    self.context,
                    dict(cherrypy.request.terp_record,
                         context=current.context,
                         active_id=current.id or False))
                current.context.update(ctx)
            except:
                pass

        if current.view_type == 'tree' and self.readonly:
            self.editable = False

        if self.editable is False:
            selectable = 0
        else:
            selectable = 2

        # try to get original input values if creating validation form
        if not params.filter_action:
            try:
                current.ids = eval(cherrypy.request.terp_data.get(self.name))
            except:
                pass

        self.screen = Screen(current,
                             prefix=self.name,
                             views_preloaded=view,
                             editable=self.editable,
                             readonly=self.editable,
                             selectable=selectable,
                             nolinks=self.link,
                             **{'_m2m': 1})

        self.screen.widget.checkbox_name = False
        self.screen.widget.m2m = True

        self.validator = validators.many2many()
Example #29
0
    def __init__(self, **attrs):
        super(Filter, self).__init__(**attrs)

        default_domain = attrs.get('default_domain')
        self.global_domain = []
        self.icon = attrs.get('icon')
        self.filter_domain = attrs.get('domain', [])
        self.help = attrs.get('help')
        self.filter_id = 'filter_%s' % (random.randint(0,10000))
        self.filter_name = attrs.get('name', attrs.get('string', '')).replace('/', '-')
        self.filter_status = attrs.get('filter_status', {}).get(self.filter_name)
        filter_context = attrs.get('context')
        screen_context = attrs.get('screen_context', {})

        self.def_checked = False
        self.groupcontext = []

        default_search = get_search_default(attrs, screen_context, default_domain)

        # context implemented only for group_by.
        self.group_context = None
        if filter_context:
            self.filter_context = eval(filter_context)
            self.group_context = self.filter_context.get('group_by', False)
            if self.group_context:
                if isinstance(self.group_context, list):
                    self.group_context = map(lambda x: 'group_' + x, self.group_context)
                else:
                    self.group_context = 'group_' + self.group_context

        if default_search:
            self.def_checked = True
            self.global_domain += (expr_eval(self.filter_domain, {'context':screen_context}))
            if self.group_context:
                self.groupcontext = self.group_context

        self.nolabel = True
        self.readonly = False
        if self.filter_context:
            if not self.filter_context.get('group_by'):
                self.filter_context = self.filter_context
            else:
                self.filter_context = {}
        self.text_val = self.string or self.help
        if self.icon:
            self.icon = icons.get_icon(self.icon)

        if self.string == self.help:
            self.help = None

        self.first_box = attrs.get('first_box')
        self.last_box = attrs.get('last_box')
        self.first_last_box = attrs.get('first_last_box')
        
        if not self.def_checked and attrs.get('group_by_ctx'):
            if self.group_context in attrs['group_by_ctx']:
                self.def_checked = True

        if self.filter_status is not None:
            # if filter_status is defined that means user have manually
            # check/unchecked the filter, so we override default choice
            # by user's choice.
            self.def_checked = bool(self.filter_status)
Example #30
0
    def parse(self, root, fields, data=[]):
        """Parse the given node to generate valid list headers.

        @param root: the root node of the view
        @param fields: the fields

        @return: an instance of List
        """

        headers = []
        hiddens = []
        buttons = []

        field_total = {}
        field_real_total = {}
        values  = [row.copy() for row in data]

        myfields = [] # check for duplicate fields

        for node in root.childNodes:

            if node.nodeName == 'button':
                if self.force_readonly:
                    continue
                attrs = node_attributes(node)
                if attrs.get('invisible', False):
                    visible = eval(attrs['invisible'], {'context':self.context})
                    if visible:
                        continue
                buttons += [Button(**attrs)]
                headers.append(("button", len(buttons)))
            elif node.nodeName == 'separator':
                headers += [("separator", {'type': 'separator', 'string': '|', 'not_sortable': 1})]
            elif node.nodeName == 'field':
                attrs = node_attributes(node)

                if 'name' in attrs:

                    name = attrs['name']

                    if name in myfields:
                        print "-"*30
                        print " malformed view for:", self.model
                        print " duplicate field:", name
                        print "-"*30
                        raise common.error(_('Application Error'), _('Invalid view, duplicate field: %s') % name)

                    myfields.append(name)

                    if attrs.get('widget'):
                        if attrs['widget']=='one2many_list':
                            attrs['widget']='one2many'
                        attrs['type'] = attrs['widget']

                    try:
                        fields[name].update(attrs)
                    except:
                        print "-"*30,"\n malformed tag for:", attrs
                        print "-"*30
                        raise

                    kind = fields[name]['type']

                    if kind not in CELLTYPES:
                        kind = 'char'

                    fields[name].update(attrs)

                    try:
                        visval = fields[name].get('invisible', 'False')
                        invisible = visval if isinstance(visval, bool) \
                            else eval(visval, {'context': self.context})
                    except NameError, e:
                        cherrypy.log.error(e, context='listgrid.List.parse')
                        invisible = False

                    if invisible:
                        hiddens += [(name, fields[name])]

                    if 'sum' in attrs:
                        field_total[name] = [attrs['sum'], 0.0]
                        
                    if 'real_sum' in attrs:
                        field_real_total[name] = [attrs['real_sum'], 0.0]

                    for i, row in enumerate(data):
                        row_value = values[i]
                        if invisible:
                            cell = Hidden(**fields[name])
                            cell.set_value(row_value.get(name, False))
                        else:
                            cell = CELLTYPES[kind](value=row_value.get(name, False), **fields[name])

                        for color, expr in self.colors.items():
                            try:
                                if expr_eval(expr,
                                     dict(row_value, active_id=rpc.session.active_id or False)):
                                    cell.color = color
                                    break
                            except:
                                pass

                        row[name] = cell
                    if invisible:
                        continue

                    headers += [(name, fields[name])]
Example #31
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))]
Example #32
0
    def parse(self, root, fields, data=[]):
        """Parse the given node to generate valid list headers.

        @param root: the root node of the view
        @param fields: the fields

        @return: an instance of List
        """

        headers = []
        hiddens = []
        buttons = []
        field_total = {}
        values  = [row.copy() for row in data]

        myfields = [] # check for duplicate fields

        for node in root.childNodes:

            if node.nodeName == 'button':
                attrs = node_attributes(node)
                if attrs.get('invisible', False):
                    visible = eval(attrs['invisible'], {'context':self.context})
                    if visible:
                        continue
                buttons += [Button(**attrs)]
                headers.append(("button", len(buttons)))
                
            elif node.nodeName == 'field':
                attrs = node_attributes(node)

                if 'name' in attrs:

                    name = attrs['name']

                    if name in myfields:
                        raise common.error(
                            _('Application Error'),
                            _("Invalid view for model '%(model)s', duplicate field: %(field)s",
                              model=self.model, name=name))

                    myfields.append(name)

                    if attrs.get('widget'):
                        if attrs['widget']=='one2many_list':
                            attrs['widget']='one2many'
                        attrs['type'] = attrs['widget']

                    try:
                        fields[name].update(attrs)
                    except:
                        parse_logger.debug(
                            "Malformed tag for field %s, with %s",
                            name, attrs)
                        raise

                    kind = fields[name]['type']

                    if kind not in CELLTYPES:
                        kind = 'char'

                    fields[name].update(attrs)

                    try:
                        visval = fields[name].get('invisible', 'False')
                        invisible = eval(visval, {'context': self.context})
                    except NameError, e:
                        parse_logger.info(e)
                        invisible = False

                    if invisible:
                        hiddens += [(name, fields[name])]

                    if 'sum' in attrs:
                        field_total[name] = [attrs['sum'], 0.0]

                    for i, row in enumerate(data):

                        row_value = values[i]
                        if invisible:
                            cell = Hidden(**fields[name])
                            cell.set_value(row_value.get(name, False))
                        else:
                            cell = CELLTYPES[kind](value=row_value.get(name, False), **fields[name])

                        for color, expr in self.colors.items():
                            try:
                                if expr_eval(expr,
                                     dict(row_value, active_id=rpc.get_session().active_id or False)):
                                    cell.color = color
                                    break
                            except:
                                pass

                        row[name] = cell

                    if invisible:
                        continue

                    headers += [(name, fields[name])]
Example #33
0
    def __init__(self, **attrs):
        super(M2M, self).__init__(**attrs)

        ids = None
        params = getattr(cherrypy.request, 'terp_params', None)
        if not params:
            params = TinyDict()
            params.model = attrs.get('relation', 'model')
            params.ids = attrs.get('value', [])
            params.name = attrs.get('name', '')

        current = params.chain_get(self.name)
        if current and params.source == self.name:
            ids = current.ids

        self.model = attrs.get('relation', 'model')
        self.link = attrs.get('link', None)
        self.onchange = None # override onchange in js code

        self.relation = attrs.get('relation', '')
        self.domain = attrs.get('domain', [])
        self.context = attrs.get('context', {}) or {}        

        view = attrs.get('views', {})
        mode = str(attrs.get('mode', 'tree,form')).split(',')

        self.view = view

        view_mode = mode
        view_type = mode[0]

        self.switch_to = view_mode[-1]
        if view_type == view_mode[-1]: self.switch_to = view_mode[0]

        if ids is None:
            ids = attrs.get('value', [])

        id = (ids or None) and ids[0]
        
        pprefix = ''
        if '/' in self.name:
            pprefix = self.name[:self.name.rindex('/')]
        
        if self.name == params.source and params.sort_key and ids:
            self.domain.append(('id', 'in', ids))
            ids = rpc.RPCProxy(self.model).search(self.domain, 0, 0, params.sort_key+ ' '+params.sort_order, self.context)
            id = ids[0]
        current = params.chain_get(self.name)

        if not current:
            current = TinyDict()

        current.offset = current.offset or 0
        current.limit = current.limit or 50
        current.count = len(ids or [])

        if current.view_mode: view_mode = current.view_mode
        if current.view_type: view_type = current.view_type

        if current and params.source == self.name:
            id = current.id

        id = id or None

        current.model = self.model
        current.id = id

        if isinstance(ids, tuple):
            ids = list(ids)

        current.ids = ids or []
        current.view_mode = view_mode
        current.view_type = view_type
        current.domain = current.domain or []
        current.context = current.context or {}

        if isinstance(self.context, basestring):
            # XXX: parent record for O2M
            #if self.parent:
            #    ctx['parent'] = EvalEnvironment(self.parent)

            try:
                ctx = expr_eval(
                        self.context,
                        dict(cherrypy.request.terp_record,
                             context=current.context,
                             active_id=current.id or False))
                current.context.update(ctx)
            except:
                pass

        if current.view_type == 'tree' and self.readonly:
            self.editable = False

        if self.editable is False:
            selectable = 0
        else:
            selectable = 2

        # try to get original input values if creating validation form
        if not params.filter_action:
            try:
                current.ids = eval(cherrypy.request.terp_data.get(self.name))
            except:
                pass

        self.screen = Screen(current, prefix=self.name, views_preloaded=view,
                             editable=self.editable, readonly=self.editable,
                             selectable=selectable, nolinks=self.link, **{'_m2m': 1})

        self.screen.widget.checkbox_name = False
        self.screen.widget.m2m = True

        self.validator = validators.many2many()
Example #34
0
def act_window(action, data):
    if not action.get('opened'):
        action.setdefault('target', 'current')
        return act_window_opener(action, data)

    for key in ('res_id', 'res_model', 'view_type',
                'view_mode', 'limit', 'search_view'):
        data[key] = action.get(key, data.get(key))
    if not data.get('search_view') and data.get('search_view_id'):
        data['search_view'] = str(rpc.RPCProxy(data['res_model']).fields_view_get(
                data['search_view_id'], 'search', data['context']))
    if data.get('limit'):
        data['limit'] = 20
    
    if action.get('target') and action['target'] == 'popup' and action.get('res_model') and isinstance(action.get('context'), dict):
        search_view_id = rpc.RPCProxy('ir.ui.view').search([('type','=', 'search'), ('model','=',action['res_model'])], 0, 0, 0, rpc.get_session().context)
        if search_view_id and action['context'].get('search_view'):
            action['context']['search_view'] = search_view_id[0]
    
    view_ids = False
    if action.get('views', []):
        if isinstance(action['views'], list):
            view_ids = [x[0] for x in action['views']]
            data['view_mode'] = ",".join([x[1] for x in action['views']])
        else:
            if action.get('view_id'):
                view_ids = [action['view_id'][0]]
    elif action.get('view_id'):
        view_ids = [action['view_id'][0]]
    if not action.get('domain'):
        action['domain'] = '[]'

    ctx = dict(data.get('context', {}),
        active_id=data.get('id', False),
        active_ids=data.get('ids', []),
        active_model=data.get('model', False)
    )

    if action.get('context') and isinstance(action['context'], dict):
        if not action['context'].get('active_ids'):
            action['context']['active_ids'] = ctx['active_ids'] or []

    ctx.update(expr_eval(action.get('context', '{}'), ctx))

    search_view = action.get('search_view_id')
    if search_view:
        if isinstance(search_view, (list, tuple)):
            ctx['search_view'] = search_view[0]
        else:
            ctx['search_view'] = search_view

        # save active_id in session
    rpc.get_session().active_id = data.get('id')
    domain = expr_eval(action['domain'], ctx)
    if data.get('domain'):
        domain.append(data['domain'])

    if 'menu' in data['res_model'] and action.get('name') == 'Menu':
        return close_popup()

    if action.get('display_menu_tip'):
        display_menu_tip = action.get('help')
    else:
        display_menu_tip = None

    return execute_window(view_ids,
                          data['res_model'],
                          data['res_id'],
                          domain,
                          action['view_type'],
                          ctx, data['view_mode'],
                          name=action.get('name'),
                          target=action.get('target'),
                          limit=data.get('limit'),
                          search_view=data['search_view'],
                          context_menu=data.get('context_menu'),
                          display_menu_tip=display_menu_tip,
                          action_id=action.get('id'))
Example #35
0
    def __init__(self, **attrs):
        super(Filter, self).__init__(**attrs)

        default_domain = attrs.get('default_domain')
        self.global_domain = []
        self.icon = attrs.get('icon')
        self.filter_domain = attrs.get('domain', [])
        self.help = attrs.get('help')
        self.filter_id = 'filter_%s' % (random.randint(0, 10000))
        self.filter_name = attrs.get('name', '')
        self.filter_status = attrs.get('filter_status', {}).get(self.name)
        filter_context = attrs.get('context')
        screen_context = attrs.get('screen_context', {})

        self.def_checked = False
        self.groupcontext = []

        default_search = get_search_default(attrs, screen_context,
                                            default_domain)

        # context implemented only for group_by.
        self.group_context = None
        if filter_context:
            self.filter_context = eval(filter_context)
            self.group_context = self.filter_context.get('group_by', False)
            if self.group_context:
                if isinstance(self.group_context, list):
                    self.group_context = map(lambda x: 'group_' + x,
                                             self.group_context)
                else:
                    self.group_context = 'group_' + self.group_context

        if default_search:
            self.def_checked = True
            self.global_domain += (expr_eval(self.filter_domain,
                                             {'context': screen_context}))
            if self.group_context:
                self.groupcontext = self.group_context

        self.nolabel = True
        self.readonly = False
        if self.filter_context:
            if not self.filter_context.get('group_by'):
                self.filter_context = self.filter_context
            else:
                self.filter_context = {}
        self.text_val = self.string or self.help
        if self.icon:
            self.icon = icons.get_icon(self.icon)

        if self.string == self.help:
            self.help = None

        self.first_box = attrs.get('first_box')
        self.last_box = attrs.get('last_box')
        self.first_last_box = attrs.get('first_last_box')

        if not self.def_checked and attrs.get('group_by_ctx'):
            if self.group_context in attrs['group_by_ctx']:
                self.def_checked = True

        if self.filter_status is not None:
            # if filter_status is defined that means user have manually
            # check/unchecked the filter, so we override default choice
            # by user's choice.
            self.def_checked = bool(self.filter_status)
Example #36
0
    def parse(self, root, fields, data=[]):
        """Parse the given node to generate valid list headers.

        @param root: the root node of the view
        @param fields: the fields

        @return: an instance of List
        """

        headers = []
        hiddens = []
        buttons = []
        field_total = {}
        values = [row.copy() for row in data]

        myfields = []  # check for duplicate fields

        for node in root.childNodes:

            if node.nodeName == 'button':
                attrs = node_attributes(node)
                if attrs.get('invisible', False):
                    visible = eval(attrs['invisible'],
                                   {'context': self.context})
                    if visible:
                        continue
                buttons += [Button(**attrs)]
                headers.append(("button", len(buttons)))

            elif node.nodeName == 'field':
                attrs = node_attributes(node)

                if 'name' in attrs:

                    name = attrs['name']

                    if name in myfields:
                        print "-" * 30
                        print " malformed view for:", self.model
                        print " duplicate field:", name
                        print "-" * 30
                        raise common.error(
                            _('Application Error'),
                            _('Invalid view, duplicate field: %s') % name)

                    myfields.append(name)

                    if attrs.get('widget'):
                        if attrs['widget'] == 'one2many_list':
                            attrs['widget'] = 'one2many'
                        attrs['type'] = attrs['widget']

                    try:
                        fields[name].update(attrs)
                    except:
                        print "-" * 30, "\n malformed tag for:", attrs
                        print "-" * 30
                        raise

                    kind = fields[name]['type']

                    if kind not in CELLTYPES:
                        kind = 'char'

                    fields[name].update(attrs)

                    try:
                        visval = fields[name].get('invisible', 'False')
                        invisible = eval(visval, {'context': self.context})
                    except NameError, e:
                        cherrypy.log.error(e, context='listgrid.List.parse')
                        invisible = False

                    if invisible:
                        hiddens += [(name, fields[name])]

                    if 'sum' in attrs:
                        field_total[name] = [attrs['sum'], 0.0]

                    for i, row in enumerate(data):

                        row_value = values[i]
                        if invisible:
                            cell = Hidden(**fields[name])
                            cell.set_value(row_value.get(name, False))
                        else:
                            cell = CELLTYPES[kind](value=row_value.get(
                                name, False),
                                                   **fields[name])

                        for color, expr in self.colors.items():
                            try:
                                if expr_eval(
                                        expr,
                                        dict(row_value,
                                             active_id=rpc.session.active_id
                                             or False)):
                                    cell.color = color
                                    break
                            except:
                                pass

                        row[name] = cell

                    if invisible:
                        continue

                    headers += [(name, fields[name])]
Example #37
0
    def parse(self, model=None, root=None, fields=None, values={}):

        views = []
        search_model = model

        filters_run = []
        for node in root.childNodes:
            if not node.nodeType == node.ELEMENT_NODE:
                continue

            if filters_run and node.localName != 'filter':
                views.append(FiltersGroup(children=filters_run))
                filters_run = []

            attrs = node_attributes(node)
            attrs.update(is_search=True, model=search_model)

            if 'nolabel' in attrs:
                attrs['nolabel'] = False

            if node.localName in ('form', 'tree', 'search', 'group'):
                if node.localName == 'group':
                    attrs['group_by_ctx'] = values.get('group_by_ctx')
                    attrs['expand'] = expr_eval(attrs.get('expand', False),
                                                {'context': self.context})
                    Element = Group
                else:
                    Element = Frame

                views.append(
                    Element(children=self.parse(model=search_model,
                                                root=node,
                                                fields=fields,
                                                values=values),
                            **attrs))

            elif node.localName == 'newline':
                views.append(NewLine(**attrs))

            elif node.localName == 'filter':
                attrs.update(model=search_model,
                             default_domain=self.domain,
                             screen_context=self.context)
                if values and values.get('group_by_ctx'):
                    attrs['group_by_ctx'] = values['group_by_ctx']
                elif self.groupby:
                    attrs['group_by_ctx'] = self.groupby

                if values and values.get('filter_status'):
                    attrs['filter_status'] = values['filter_status']

                v = Filter(**attrs)
                if v.groupcontext and v.groupcontext not in self.groupby:
                    self.groupby.append(v.groupcontext)
                self.listof_domain.extend(i for i in v.global_domain
                                          if not i in self.listof_domain)
                filters_run.append(v)

            elif node.localName == 'field':
                val = attrs.get(
                    'select', False) or fields[str(attrs['name'])].get(
                        'select', False) or self.view_type == 'search'
                if val:
                    name = attrs['name']
                    if name in self.fields_type:
                        continue

                    # in search view fields should be writable
                    attrs.update(readonly=False,
                                 required=False,
                                 translate=False,
                                 disabled=False,
                                 visible=True,
                                 invisible=False,
                                 editable=True,
                                 attrs=None)

                    try:
                        fields[name].update(attrs)
                    except:
                        print "-" * 30, "\n malformed tag for:", attrs
                        print "-" * 30
                        raise

                    if attrs.get('widget'):
                        if attrs['widget'] == 'one2many_list':
                            fields[name]['widget'] = 'one2many'

                        fields[name]['type2'] = fields[name]['type']
                        fields[name]['type'] = attrs['widget']

                    kind = fields[name]['type']

                    if kind not in WIDGETS:
                        continue

                    if kind == 'many2one':
                        attrs['relation'] = fields[name]['relation']
                        attrs['type'] = fields[name]['type']
                        if not attrs.get('string'):
                            attrs['string'] = fields[name]['string']

                    self.fields_type[name] = kind

                    field = WIDGETS[kind](**fields[name])
                    field.onchange = None
                    field.callback = None

                    if kind == 'boolean':
                        # '0' in string because 0 is considering as No Value, and we need 0 as some value.
                        field.options = [[1, _('Yes')], ['0', _('No')]]
                        field.validator.if_empty = ''

                    default_search = None
                    if name:
                        default_search = get_search_default(
                            fields[name], self.context, self.domain)
                        defval = default_search
                        if defval:
                            model = fields[name].get('relation')
                            type2 = fields[name].get('type2')

                            if kind == 'many2one' and model:
                                try:
                                    value = rpc.name_get(
                                        model, default_search, self.context)
                                except Exception, e:
                                    value = defval
                                defval = value or ''

                            if attrs.get('filter_domain'):
                                domain = expr_eval(attrs['filter_domain'],
                                                   {'self': defval})
                            else:
                                if field.kind == 'selection':
                                    if type2 == 'many2one':
                                        m2nval = defval
                                        try:
                                            m2nval = int(defval)
                                        except:
                                            # you see, since defval can basically be anything, including a totally
                                            # illogic value, my only possibility is to do return another illogic value,
                                            # so it won't crash too much
                                            pass
                                        domain = [(name, '=', m2nval)]
                                    else:
                                        domain = [(name, '=', defval)]

                                elif field.kind in ('date', 'datetime'):
                                    domain = [(name, '>=', defval)]

                                elif field.kind == 'boolean':
                                    domain = [(name, '=', defval)]

                                else:
                                    domain = [(name, fields[name].get(
                                        'comparator', 'ilike'), defval)]

                            field.set_value(defval)
                            self.listof_domain += [
                                i for i in domain
                                if not i in self.listof_domain
                            ]
                            self.context.update(
                                expr_eval(attrs.get('context', "{}"),
                                          {'self': default_search}))

                    if (not default_search) and name in values and isinstance(
                            field, TinyInputWidget):
                        field.set_value(values[name])

                    views.append(field)
                    for n in node.childNodes:
                        if n.localName == 'filter':
                            attrs_child = dict(node_attributes(n),
                                               default_domain=self.domain,
                                               screen_context=self.context)
                            if 'string' in attrs_child:
                                del attrs_child['string']
                            if values and values.get('group_by_ctx'):
                                attrs['group_by_ctx'] = values['group_by_ctx']

                            filter_field = Filter(**attrs_child)
                            filter_field.onchange = None
                            filter_field.callback = None

                            if filter_field.groupcontext and filter_field.groupcontext not in self.groupby:
                                self.groupby.append(filter_field.groupcontext)
                            self.listof_domain.extend(
                                i for i in filter_field.global_domain
                                if i not in self.listof_domain)
                            field.filters.append(filter_field)
Example #38
0
    def data(self, ids, model, fields, field_parent=None, icon_name=None,
             domain=[], context={}, sort_by=None, sort_order="asc", fields_info=None, colors={}):
        
        if ids == 'None' or ids == '':
            ids = []

        if isinstance(ids, basestring):
            ids = map(int, ids.split(','))
        elif isinstance(ids, list):
            ids = map(int, ids)

        if isinstance(fields, basestring):
            fields = eval(fields)

        if isinstance(domain, basestring):
            domain = eval(domain)

        if isinstance(context, basestring):
            context = eval(context)
        
        if isinstance(colors, basestring):
            colors = eval(colors)
            
        if isinstance(fields_info, basestring):
            fields_info = simplejson.loads(fields_info)

        if field_parent and field_parent not in fields:
            fields.append(field_parent)

        proxy = rpc.RPCProxy(model)

        ctx = dict(context,
                   **rpc.session.context)

        if icon_name:
            fields.append(icon_name)

        if model == 'ir.ui.menu' and 'action' not in fields:
            fields.append('action')

        result = proxy.read(ids, fields, ctx)

        if sort_by:
            fields_info_type = simplejson.loads(fields_info[sort_by])
            result.sort(lambda a,b: self.sort_callback(a, b, sort_by, sort_order, type=fields_info_type['type']))

        for item in result:
            if colors:
                for color, expr in colors.items():
                    try:
                        if expr_eval(expr,item or False):
                            item['color'] = color
                            break
                    except:
                            pass

        # format the data
        for field in fields:
            field_info = simplejson.loads(fields_info[field])
            if field_info.get('widget',''):
                field_info['type'] = field_info['widget']
            formatter = FORMATTERS.get(field_info['type'])
            for x in result:
                if x[field] and formatter:
                    x[field] = formatter(x[field], field_info)

        records = []
        for item in result:
            # empty string instead of False or None
            for k, v in item.items():
                if v is None or v is False:
                    item[k] = ''

            id = item.pop('id')
            record = {
                'id': id,
                'action': url('/openerp/tree/open', model=model, id=id, context=ctx),
                'target': None,
                'icon': None,
                'children': [],
                'items': item
            }

            if icon_name and item.get(icon_name):
                icon = item.pop(icon_name)
                record['icon'] = icons.get_icon(icon)

            if field_parent and field_parent in item:
                record['children'] = item.pop(field_parent) or None

                # For nested menu items, remove void action url
                # to suppress 'No action defined' error.
                if (model == 'ir.ui.menu' and record['children'] and
                     not item['action']):
                    record['action'] = None

            records.append(record)

        return {'records': records}
Example #39
0
    def on_change(self, **kw):

        data = kw.copy()

        callback = data.pop('_terp_callback')
        caller = data.pop('_terp_caller')
        model = data.pop('_terp_model')
        context = data.pop('_terp_context')

        try:
            context = eval(context) # convert to python dict
        except:
            context = {}

        match = re.match('^(.*?)\((.*)\)$', callback)

        if not match:
            raise common.error(_('Application Error'), _('Wrong on_change trigger: %s') % callback)

        for k, v in data.items():
            try:
                data[k] = eval(v)
            except:
                pass

        result = {}

        prefix = ''
        if '/' in caller:
            prefix = caller.rsplit('/', 1)[0]

        ctx = TinyForm(**kw).to_python(safe=True)
        pctx = ctx

        if prefix:
            ctx = ctx.chain_get(prefix)

            if '/' in prefix:
                pprefix = prefix.rsplit('/', 1)[0]
                pctx = pctx.chain_get(pprefix)

        ctx2 = dict(rpc.get_session().context,
                    **context or {})

        ctx['parent'] = pctx
        ctx['context'] = ctx2

        func_name = match.group(1)
        arg_names = [n.strip() for n in match.group(2).split(',')]

        args = [utils.expr_eval(arg, ctx) for arg in arg_names]
        # TODO: If the eval fails in expr_eval (because `arg` does not exist in `ctx`), it returns `{}`
        # This is a value we don't want, but not sure where that behavior
        # comes from/is used so in order not to risk breakage throughout
        # patch it here
        args = [(False if arg == {} else arg)
                for arg in args]

        proxy = rpc.RPCProxy(model)

        ids = ctx.id and [ctx.id] or []

        try:
            response = getattr(proxy, func_name)(ids, *args)
        except Exception, e:
             return dict(error=_ep.render())
Example #40
0
    def eval_domain_filter(self, **kw):

        all_domains = kw.get('all_domains')
        custom_domains = kw.get('custom_domain')

        all_domains = eval(all_domains)

        domains = all_domains.get('domains')
        selection_domain = all_domains.get('selection_domain')
        search_context = all_domains.get('search_context')

        group_by_ctx = kw.get('group_by_ctx', [])
        if isinstance(group_by_ctx, str):
            group_by_ctx = group_by_ctx.split(',')

        if domains:
            domains = eval(domains)

        c = search_context.get('context', {})
        v = search_context.get('value')
        if v and isinstance(v, basestring) and '__' in v:
            value, operator = v.split('__')
            v = int(value)
        ctx = expr_eval(c, {'self':v})

        context = rpc.session.context
        if ctx:
            ctx.update(context)

        domain = []
        check_domain = all_domains.get('check_domain')

        if check_domain and isinstance(check_domain, basestring):
            domain = expr_eval(check_domain, context) or []

        search_data = {}
        model = kw.get('model')
        proxy = rpc.RPCProxy(model)
        res = proxy.fields_get(False, context)
        all_error = []
        fld = {}
        
        if domains:
            for field, value in domains.iteritems():
                
                if '/' in field:
                    fieldname, bound = field.split('/')
                else:
                    fieldname = field
                    bound = ''

                data = {}
                fld['type'] = res[fieldname].get('type')
                if fld['type'] == 'many2many':
                    fld['type'] = 'char'
                fld['value'] = value
                data[field] = fld

                try:
                    frm = TinyForm(**data).to_python()
                except TinyFormError, e:
                    error_field = e.field
                    error = ustr(e)
                    all_error.append(dict(error=error, error_field=error_field))
                    continue

                if bound in ('from', 'to'):
                    if bound == 'from': test = '>='
                    else: test = '<='

                    convert_format = openobject.i18n.format.convert_date_format_in_domain([(fieldname, test, value)], res, context)
                    domain.append(convert_format[0])
                    search_data.setdefault(fieldname, {})[bound] = convert_format[0][2]

                elif isinstance(value, bool) and value:
                    search_data[field] = 1

                elif isinstance(value, int) and not isinstance(value, bool):
                    domain.append((field, '=', value))
                    search_data[field] = value

                elif 'selection_' in value:
                    domain.append((field, '=', value.split('selection_')[1]))
                    search_data[field] = value.split('selection_')[1]

                elif fld['type'] == 'selection':
                    domain.append((field, '=', value))
                    search_data[field] = value

                else:
                    if not 'm2o_' in value:
                        operator = 'ilike'
                        if '__' in value:
                            value, operator = value.split('__')
                            value = int(value)
                        domain.append((field, operator, value))
                        search_data[field] = value
                    else:
                        search_data[field] = value.split('m2o_')[1]
            if all_error:
                return dict(all_error=all_error)
Example #41
0
    def on_change(self, **kw):

        data = kw.copy()

        callback = data.pop('_terp_callback')
        caller = data.pop('_terp_caller')
        model = data.pop('_terp_model')
        context = data.pop('_terp_context')

        change_default = False
        if '_terp_change_default' in data:
            change_default = data.pop('_terp_change_default')

        try:
            context = eval(context)  # convert to python dict
        except:
            context = {}

        match = re.match('^(.*?)\((.*)\)$', callback)

        if not match:
            raise common.error(_('Application Error'),
                               _('Wrong on_change trigger: %s') % callback)

        for k, v in data.items():
            try:
                data[k] = eval(v)
            except:
                pass

        result = {}

        prefix = ''
        if '/' in caller:
            prefix = caller.rsplit('/', 1)[0]

        ctx = TinyForm(**kw).to_python(safe=True)
        pctx = ctx

        if prefix:
            ctx = ctx.chain_get(prefix)

            if '/' in prefix:
                pprefix = prefix.rsplit('/', 1)[0]
                pctx = pctx.chain_get(pprefix)

        ctx2 = dict(rpc.session.context, **context or {})

        ctx['parent'] = pctx
        ctx['context'] = ctx2

        func_name = match.group(1)
        arg_names = [n.strip() for n in match.group(2).split(',')]

        args = [utils.expr_eval(arg, ctx) for arg in arg_names]
        # TODO: If the eval fails in expr_eval (because `arg` does not exist in `ctx`), it returns `{}`
        # This is a value we don't want, but not sure where that behavior
        # comes from/is used so in order not to risk breakage throughout
        # patch it here
        args = [(False if arg == {} else arg) for arg in args]

        proxy = rpc.RPCProxy(model)

        ids = ctx.id and [ctx.id] or []

        try:
            response = getattr(proxy, func_name)(ids, *args)
        except Exception, e:
            return dict(error=_ep.render())