Reputation: 127
Here is mycode. I want to get id_employee of current record before define its model class:
def _get_state(self, cr, uid, context=None):
idemployee = ""
for adv in self.browse(cr, uid, ids, context):
id_employee = adv.id_employee
if id_employee is None:
idemployee = _default_employee(self, cr, uid, context=None)
else:
idemployee = id_employee
sql = " SELECT C.id AS id, C.sequence, C.name \
FROM wf_group_member A \
LEFT JOIN wf_group B ON B.id = A.group_id \
LEFT JOIN wf_process BB ON BB.id = B.process_id \
LEFT JOIN wf_state C ON C.group_id = B.id \
LEFT JOIN hr_employee D ON D.id = A.member_id \
WHERE LOWER(code) = 'ca' AND member_id = %s ORDER BY sequence "
res = []
cr.execute(sql, [(idemployee)])
ardata = cr.fetchall()
for data in ardata:
res.append((data[1], data[2]))
return res
and this is my model class that I put it after _get_state function
class cashadvance(osv.osv):
_name = 'ga.cashadvance'
_columns = {
'id_user' : fields.many2one('res.users', string='User', required=True, readonly=True),
'state' : fields.selection(_get_state, 'Status', readonly=True),
'id_employee' : fields.many2one('hr.employee', string='Employee', required=True, readonly=True),
}
When I call _get_state function, it raised error :
Error details:
global name 'ids' is not defined
None" while parsing /opt/custom-addons/comben/views/cashadvance_view.xml:4, near
<record id="cashadvance_list" model="ir.ui.view">
<field name="name">cashadvance_list</field>
<field name="model">ga.cashadvance</field>
<field name="arch" type="xml">
<tree string="Cashadvance List">
<field name="id_employee"/>
<field name="category_id"/>
<field name="est_date_from" string="Est Date From"/>
<field name="est_date_to" string="Est Date To"/>
<field name="description"/>
<field name="state"/>
</tree>
</field>
</record>
can somebady help me please, thanks
Upvotes: 2
Views: 3245
Reputation: 9624
_get_state
has to be part of the class for you to use it not outside the class, the self you're passing in there is not seen as the python self
i.e the current instance, it's seen as a normal argument of the function.
Python isn't passing in self for you, let me deviate a little and reproduce the error you're getting. look at this code
def func(self,cr, uid, ids, context=None):
pass
class func_test:
def __init__(self):
func(1, 1, 1, context=1)
a = func_test()
This is the Error raised (make sure you run this with python2)
Traceback (most recent call last):
File "script.py", line 8, in <module>
a = func_test()
File "script.py", line 6, in __init__
func(1, 1, 1, context=1)
TypeError: func() takes at least 4 arguments (4 given)
python is actually correct even though it's misleading, the function expects at least four arguments because context is a keyword argument and has been filled in at the time of the function definition, but it's still missing one parameter, because the function is outside a class so the first argument which is usually called self
is taken as a normal parameter (since it's a function) not a method (function in a class). so starting from left to right self
, cr
, uid
would be filled in as 1
1
1
leaving ids
and at this point python would cry out for help because no value was found for that argument, if we move that function into the class and call it with self.func
, the current instance automatically gets passed for us.
class func_test:
def func(self,cr, uid, ids, context=None):
pass
def __init__(self):
self.func(1, 1, 1, context=1)
a = func_test()
Of course you could still have func(self, 1, 1, 1, context=1)
but that would be defeating the purpose of methods
But note that python3 is smarter and handles this scenario better than python2, this is a python3 traceback
Traceback (most recent call last):
File "script.py", line 8, in <module>
a = func_test()
File "script.py", line 6, in __init__
func(1, 1, 1, context=1)
TypeError: func() missing 1 required positional argument: 'ids'
It plainly tells us that no value was provided for ids
in the function call
so going back to Odoo your code should look like this
from openerp.osv import osv, fields
class cashadvance(osv.osv):
_name='comben.cashadvance'
def _get_state(self, cr, uid, context=None):
idemployee = ""
ids = self.search(cr, uid, [], context=context) # you probably want to search for all the records
for adv in self.browse(cr, uid, ids, context=context):
id_employee = adv.id_employee
if id_employee is None:
idemployee = self._default_employee(cr, uid, ids, context=None) # might raise singleton error if more than one record is returned
else:
idemployee = id_employee.id
sql = " SELECT C.id AS id, C.sequence, C.name \
FROM wf_group_member A \
LEFT JOIN wf_group B ON B.id = A.group_id \
LEFT JOIN wf_process BB ON BB.id = B.process_id \
LEFT JOIN wf_state C ON C.group_id = B.id \
LEFT JOIN hr_employee D ON D.id = A.member_id \
WHERE LOWER(code) = 'ca' AND member_id = %s ORDER BY sequence "
res = []
cr.execute(sql, [(idemployee)])
ardata = cr.fetchall()
for data in ardata:
res.append((data[1], data[2]))
return res
_columns = {
'id_user': fields.many2one('res.users', string='User', required=True, readonly=True),
'state': fields.selection(_get_state, string='Status', readonly=True),
'id_employee': fields.many2one('hr.employee', string='Employee', required=True, readonly=True),
}
and also move _default_employee
into the class body, so you can call it like this
self._default_employee(cr, uid, context=None) # python implicitly passes self for you
xml view
<record id="cashadvance_list" model="ir.ui.view">
<field name="name">cashadvance list</field>
<field name="model">comben.cashadvance</field>
<field name="arch" type="xml">
<tree string="Cashadvance List">
<field name="id_employee"/>
<field name="id_user"/>
<field name="state"/>
</tree>
</field>
</record>
Upvotes: 1
Reputation: 3822
In this case, you want this :
def _get_state(self, cr, uid, ids, context=None):
current_record=self.browse(cr, uid, ids)
idemployee = current_record[0].id_employee
sql = " SELECT C.id AS id, C.sequence, C.name \
FROM wf_group_member A \
LEFT JOIN wf_group B ON B.id = A.group_id \
LEFT JOIN wf_process BB ON BB.id = B.process_id \
LEFT JOIN wf_state C ON C.group_id = B.id \
LEFT JOIN hr_employee D ON D.id = A.member_id \
WHERE LOWER(code) = 'ca' AND member_id = %s ORDER BY sequence "
res = []
cr.execute(sql, [(idemployee)])
ardata = cr.fetchall()
for data in ardata:
res.append((data[1], data[2]))
return res
Upvotes: 0