0
votes

In Odoo/OpenERP I want to make a filter to compare field1 and field2 of the same object like below.

Plz let me know how to make this filter work, adding filter on partners search form:

                <field name="credit_limit"/>
                <field name="credit"/>

               <filter name="credit limit" domain="[('credit','>',credit_limit)]"/>

Applying this filter gives below error:

Uncaught Error: Failed to evaluate search criterions:
{"code":400,"message":"Evaluation Error","data":{"type":"local_exception","debug":"Local evaluation failure\nNameError: name 'credit_limit' is not defined\n\n{\"domains\":[[],\"[('customer','=',1)]\",\"[('credit','=',credit_limit)]\"],\"contexts\":[{\"lang\":\"en_US\",\"tz\":\"Africa/Cairo\",\"uid\":1,\"search_default_customer\":1}],\"group_by_seq\":[]}"}}

I googled many times to find a solution without finding anyone .

the simple form [('credit_limit','<',credit)] always returns the error "can not convert string to float" where string is credit and float is credit_limit.

is there any way to say [('credit_limit','<',valueof(credit))] or [('field1','=',valueof(field2))] ??

Regards,

2
If credit is meant to hold a number why the field is of a string type? - Ludwik Trammer

2 Answers

0
votes

You need to create a function field with a search function to do that.

Here is an example, using the 'old api' syntax:

class SomeModel(orm.Model):
    _name = 'some.model'

    def _func_credit_limit_exceeded(self, cr, uid, ids, 
                                    field_name, arg, context):
        """compute the value of the function field"""
        res = {}
        for record in self.browse(cr, uid, ids, context=context):
            res[record.id] = record.credit > record.credit_limit
        return res

    def _func_search_credit_limit_exceeded(self, cr, uid, obj, 
                                           name, criterion, context):
        """we only support a search on the form
        ('column_name', '=', boolean) or ('column_name', '!=', boolean)
        """
        match_ids = []
        field, op, value = criterion
        # argument processing
        if op == '!=':
            value = not value
        elif op != '=':
            raise ValueError('Unsupported operator')
        # build the search query
        if value = True:
            comparison = '>'
        else:
            comparison = '<='
        query = 'SELECT id FROM some_model ' \
                'WHERE credit %s credit_limit' % comparison
        # get the ids matching the search 
        # and return the corresponding domain
        cr.execute(query)
        for row in cr.fetchall():
            match_ids.append(row[0])
        if match_ids:
            # return domain matching the selected ids
            return [('id', 'in', match_ids)]
        else:
            # return a domain which will never yield a result
            return [('id', '=', 0)]

    _columns = {'credit': fields.float('Credit'),
                'credit_limit': fields.float('Credit Limit'),
                'credit_limit_exceeded':
                    fields.function(_func_credit_limit_exceeded,
                                    fnct_search=_func_search_credit_limit_exceeded,
                                    string='Credit Limit Exceeded',
                                    type='boolean'),
                 }
0
votes

For numeric fields, you can create a computed field which counts the difference of the two field. if the result is 0 they are equal, if negative the 2nd is greater if positive the first is greater.