1
votes

I am trying to filter purchase orders based on a property of its line items. So, for example, I would like to see all purchase orders who have any line item with product_type = 'X'.

<record id="po_x" model="ir.actions.act_window">
        <field name="name">X Purchase Orders</field>
        <field name="type">ir.actions.act_window</field>
        <field name="res_model">purchase.order</field>
        <field name="view_type">form</field>
        <field name="view_mode">tree,form,calendar,graph,gantt</field>
        <field name="domain">[('has_x_line','=',True)]</field>
        <field name="context">{}</field>
    </record>

product_type is a custom field that I added to an inherited version of order line.

class purchase_order_custom(osv.osv):
    _name = 'purchase.order'
    _inherit = 'purchase.order'

    def linehasproducttype(self, cr, uid, ids, name, arg, context=None):
        cur_obj={}
        cur_obj=self.browse(cr, uid, ids, context=context)
        for line in cur_obj.order_line:
            if line.product_type == 'X':
                return True
        return False

    _columns={
          'has_x_line': fields.function(linehasproducttype, string="Has X Line", type='boolean', context={'pt':'X'})
              }
purchase_order_custom() 

2 questions:

Q1. The above code is not working. That is, it is not really filtering as desired. What could be wrong?

Q2. I have many product types and I am not inclined to make a function for each type. Can I pass an argument somehow or use the context for this purpose as I am trying to do? If so, how do I use it in the code?

Thanks

EDIT: I have also tried the following code with no luck:

def linehasproducttype(self, cr, uid, ids, name, arg, context=None):
    res = dict.fromkeys(ids, False)
    for cur_obj in self.browse(cr, uid, ids, context=context):
        res[cur_obj.id] = False
        for line in cur_obj.order_line:
            if line.product_type == 'X':
                res[cur_obj.id] = True
    return res
1

1 Answers

2
votes

You have one possibly two problems in your code:

If this code is intended to run on OpenERP 6.1 or prior, you need to provide the argument "method" in your field definition and set it to true, else your method won't be found.

Your function is not generic. It needs to return a dictionary, with the ids given to your function in the "ids" param as keys. You have to remember that almost every function you pass to the OpenERP core needs to work on a set of records and not a single record. Look at the core code for examples.

Regarding your second question, you can always add data to the context in your view XML which should then be available in the code handling these views. This will only work if you have distinct views for every product type.

Another possibility would be to define a generic tree view for all products and define a filter, which will only show the desired products. The developer book describes how to do that.

Edit: You should be able to just use a domain expression like the following in your action or filter:

<field name="domain">[('order_line.product_type','=','X')]</field>