2
votes

We're trying to create odoo function field, that renders as list.

We've following model:

class sale_wizard(orm.TransientModel):
    _name = 'account.bank.statement.review.wizard'


    def _orders(self, cr, uid, ids, fields, arg, context=None):
        statement = self.env['account.bank.statement'].browse(self._context.get('active_id'))
        partner_id = statement.partner_id.id
        sale_orders = self.pool.get('sale.order').search(cr, uid, [
            ('partner_id', '=', partner_id),
        ])
        print 'hiro'
        print sale_orders
        return [(1,2,3), (1,2,3)]


    _columns = { 
        'order_ids': fields.function(_orders, string="Sale Orders", type="many2many"),
    }

We've following view:

    <?xml version="1.0" encoding="utf-8"?>
    <openerp>
        <data>
            <!-- Wizard Form -->
            <record model="ir.ui.view" id="orders_review_form">
                <field name="name">Sale Orders Review</field>
                <field name="model">account.bank.statement.review.wizard</field>
                <field name="arch" type="xml">
                    <form string="Sale Orders Test">
                        <group col="2">
                            <field name="order_ids" />
                        </group>
                    </form>
                </field>
            </record>
        </data>
    </openerp>

When I'm opening form, that contains view - it renders as empty list. And lines

print 'hiro'
print sale_orders

don't execute. So function field order_ids don't execute function orders.

Where to dig?

UPD In other module - function field works as expected and executes on model initialization.

2

2 Answers

4
votes

There are some issues in your code. 1. when you define a functional field you need to provide the relation model. here the relation is to sale.order. so

_columns = { 
        'order_ids': fields.function(_orders, string="Sale Orders", type="many2many", relation='sale.order'),
    }
  1. Functional field's method always return a dictionary. Here in your case, as 'multi' attribute is not specified the method should return a dictionary with id of record where you have added the functional field as key and the result as value. Here the value is list of sale order ids.For example.

    def _orders(self, cr, uid, ids, fields, arg, context=None):
        res = {}
        for _obj in self.browse(cr, uid, ids, context=context):
            _orders = _order_pool.search(cr, uid, [('partner_id', '=', statement.partner_id.id), ], context=context)
            res[_obj.id] =_orders
        return res
    
1
votes

In 2 words: In odoo 8 functional field is replaced by computed field.

So, changed code of model to following:

class sale_wizard(orm.TransientModel):
    _name = 'account.bank.statement.review.wizard'

    def _orders(self, cr, uid, ids, fields, arg, context=None):

        res = {}
        _statement = self.pool.get('account.bank.statement')
        statement = _statement.browse(cr, uid, context.get('active_id', False), context=context)
        _order_pool = self.pool.get('sale.order')

        if statement:
             for _obj in self.browse(cr, uid, ids, context=context):
                _orders = _order_pool.search(cr, uid, [('partner_id', '=', statement.partner_id.id), ], context=context)
                res[_obj.id] = [(6, 0, _orders)]

        return res

    _columns = { 
        'order_ids': fields.many2many('sale.order', string="Sale Orders", compute='_orders'),
    }


    _defaults = {
        #dirty trick to set values on wizard launch
        'order_ids': lambda self, cr, uid, context : self._orders(cr, uid, [0], '', '', context)[0], 
    }