Odoo Help


_default value depending on relation?

Matias Garcia Isaia
on 5/8/13, 12:08 PM 3,555 views

I'm trying to make a field's default value the result of computing some of it's related objects' fields. How can I achieve that?

In this case, I have an Item that has multiple Payments (one2many). The item has its total cost as a field, and every Payment has it's amount (i.e., it can be a partial Payment). I want the default value of a new Payment's amount to be the balance of the item (say, the total cost of the Item, minus the sum of all current Payments' amount for that Item).

How can I get this done?

My current classes:

from osv import fields, osv

class item_payment(osv.osv):
    def _item_balance(self, cr, uid, ids, context):
        for id in ids:
            this_payment = self.browse(cr, uid, id)
            item_payments = self.search(cr, uid, [('project_item_id', '=', this_payment.project_item_id)])
            total_payed = item_payments.reduce((lambda acum, payment: acum + payment.amount), 0)
            this_item = self.pool.get('sade.project.item').browse(cr, uid, this_payment.project_item_id)
            res[id] = this_item.amount - total_payed
        return res

    _name = "item.payment"
    _columns = { 'amount' : fields.float('Amount', digits = (16,2)),
                'project_item_id' : fields.many2one('item', 'Item', ondelete = 'set null')
    _defaults = { 'amount' : _item_balance }

class item(osv.osv):
    _name = "item"
    _columns = { 'amount' : fields.float('Importe', digits = (16, 2)),
                'payments' : fields.one2many('item.payment', 'project_item_id', 'Pagos')


I'm getting this error:

Traceback (most recent call last):
  File "/usr/share/pyshared/openerp-server/osv/osv.py", line 122, in wrapper
    return f(self, dbname, *args, **kwargs)
  File "/usr/share/pyshared/openerp-server/osv/osv.py", line 176, in execute
    res = self.execute_cr(cr, uid, obj, method, *args, **kw)
  File "/usr/share/pyshared/openerp-server/osv/osv.py", line 167, in execute_cr
    return getattr(object, method)(cr, uid, *args, **kw)
  File "/usr/share/pyshared/openerp-server/osv/orm.py", line 985, in default_get
    defaults[f] = self._defaults[f](self, cr, uid, context)
TypeError: _item_balance() takes exactly 5 arguments (4 given)

I'm currently using OpenERP v6.1, if that matters.


Francesco OpenCode

--Francesco OpenCode--

| 6 8 9
Grottaglie, Italy
--Francesco OpenCode--

Italian Odoo (OpenERP) Modules Developer LINKEDIN: http://www.linkedin.com/in/francescoapruzzese

Francesco OpenCode
On 5/8/13, 12:10 PM

A solution is to use a function as default value for your field:

def _your_function(self, cr, uid, context=None):
    your code here
    return field_value

_defaults = {
    'your_field' : _your_function,

Thanks for the quick reply, but _defaults' functions seem to not receive an ids parameter (has sense, as the new instance still doesn't exist - it has no id). I'm updating the question now with further detail I could add after your advice.

Matias Garcia Isaia
on 5/8/13, 12:56 PM

I'm sorry, the correct function is _your_function(self, cr, uid, context=None):

Francesco OpenCode
on 5/8/13, 1:07 PM

But, how could I grab the project_item_id value for the new Payment I'm creating now that I don't have an id? I'm lost with this, though I'm pretty sure this has to be extremely trivial.

Matias Garcia Isaia
on 5/8/13, 1:25 PM

You can't use a browse in a record that noe exist, yet. I think you need to change amount as function fiueld and calculate it whee the user save the page.

Francesco OpenCode
on 5/8/13, 1:29 PM

About This Community

This platform is for beginners and experts willing to share their Odoo knowledge. It's not a forum to discuss ideas, but a knowledge base of questions and their answers.


Odoo Training Center

Access to our E-learning platform and experience all Odoo Apps through learning videos, exercises and Quizz.

Test it now

Question tools

0 follower(s)


Asked: 5/8/13, 12:08 PM
Seen: 3555 times
Last updated: 3/16/15, 8:10 AM