3a2roub
3a2roub

Reputation: 573

openerp sum function for relational fields

In Openerp, we have object_A with one one2many field belonging to object_B. Object_B has a float field. In object_A we have a one2many_list widget for the corresponding object_B so naturally we'd have multiple rows for each new record.
I know it's trivial but I'm having a hard time writing a function in object_A to sum up the total value of Object_B float column. What i have so far is something like that:

def get_result(self, cr, uid, ids):
   total = {}
   for obj in self.browse(cr, uid, ids):
      result=0.0
      total[result]+= obj.o2m_field.float_field
   return total

Upvotes: 4

Views: 1901

Answers (3)

Daniel Reis
Daniel Reis

Reputation: 13352

Just for kicks, doing it the functional way:

def get_result(self, cr, uid, ids, context=None):
   return {obj.id: sum(o2m.float_field for o2m in obj.o2m_field)
           for obj in self.browse(cr, uid, ids, context=context)}

Upvotes: 2

gurney alex
gurney alex

Reputation: 13645

The code provided by @DReispt should work, and if you approve an answer, please approve his, and not mine.

The important thing to understand is that a function field in OpenERP returns a dictionary with the object ids for the key and the value of the field for the given object as the associated value.

In your orginal code:

result = 0.0
total[result] += anything

would result in a KeyError since the dictionary is empty originally (total = {} at the beginning of your code).

A shorter version of DReispt code would be

def get_result(self, cr, uid, ids, context=None):
   total = {}
   for obj in self.browse(cr, uid, ids, context=context):
      total[obj.id] = sum(o2m.float_field for o2m in obj.o2m_field)
   return total 

This version takes advantage of Python's generator expression which can be passed to the sum() built in function. It is also slightly faster, because you avoid accessing the total dictionary multiple times for each object.

Upvotes: 6

Daniel Reis
Daniel Reis

Reputation: 13352

You need to loop the o2m:

def get_result(self, cr, uid, ids, context=None):
   total = {}
   for obj in self.browse(cr, uid, ids, context=context):
      total[obj.id] = 0
      for o2m in obj.o2m_field:
          total[obj.id] += o2m.float_field
   return total 
   #example: {56: 12.34, 57: 56.78}

Upvotes: 5

Related Questions