This question has been flagged
3 Replies
9126 Views

I have a function field. The function of the field is

def _wage(self, cr, uid, ids, fieldnames, args, context=None):

res = {}

for obj in self.browse(cr, uid, ids, context=context):

s = (

"""select sum(wage) from hr_attendance where employee_id=%s and name >= date_trunc('month', current_date - interval '1' month)and name < date_trunc('month', current_date)""" % ( obj.employee_id.id))

cr.execute(s)

l = cr.fetchone()

value = l[0]

res[obj.id] = value

return res

This field calculate the wage using the query. Sometime I need to type and save the wage not based on the calculation. So I want that filed as editable.

I tried inverse function.

This the field

'wage': fields.function( string='Per Month Salary', fnct=_wage, fnct_inv=_set_wage, store=True, type='float'),


I give the inverse function as 


def _set_wage(self, cr, uid, id, field_name, field_value, args=None, context=None):

obj = self.browse(cr, uid, id)

for record in obj:

if record.wage != field_value:

cr.execute(

'UPDATE hr_contract '

'SET wage=%s '

'WHERE id=%s', (field_value, id)

)

return True

When I give this function the field becomes editable but when I type and save the value it again changes to the computed value.

I also tried another method

def _set_wage(self, cr, uid, id, field_name, field_value, args=None, context=None):

obj = self.browse(cr, uid, id)

for record in obj:

if record.wage != field_value:

record.wage=self.write(cr, uid, id, {'wage': field_value})

return True


It shows error as

RuntimeError: maximum recursion depth exceeded in cmp


How can I store the value of the function field after it is edited?

Help me with an example.

Thanks...

Avatar
Discard
Best Answer

Computational/Functional Fields, as the name indicates that the values will be computed either while saving the record or while accessing the record depending on the store attribute , so ideally one should not enter any data to it, and let the system to evaluate value for the same.

Well accordingly to your requirement, i.e sometimes you want the system to compute while other cases you would like to manually enter the data into it.

If that is the case then instead of creating it as a functional/computational fields, create it as a normal physical field, & write Onchange method to calculate the value, upon calculation either you can retain or change the value and save the record.

By this way it will satisfy both computation & manual data-entry.

Avatar
Discard
Best Answer

change self to record in your code,

def _set_wage(self, cr, uid, id, field_name, field_value, args=None, context=None):

    obj = self.browse(cr, uid, id)

    for record in obj:

        if record.wage != field_value:

                record.wage=record.write( {'wage': field_value})

        return True

Avatar
Discard
Author

Thanks for your answer.

I tried this code but it shows error as

TypeError: write() takes exactly 2 arguments (5 given)

@Uppili, I might be a tad late, but this TypeError means you did a write on odoo7 code. The answer provided by kirubanidhi is written in odoo8. If you are still in odoo7 use: self.write(cr, uid, id, {'wage': field_value}), but do not assign it to the record's attribute.

The max recursion you are getting is because 'record.wage= ' calls a write on the object, but your assignment record.write() also calls a write on the object. Meaning you are in an endless loop of writing your field, thus resulting in a max recursion depth error.