Reputation: 33
I want to call a method by clicking on the confirmation button in sale orders to update the account of the corresponding partner.
Therefor I have defined the working method in the partner model:
class res_partner(orm.Model):
_inherit = 'res.partner'
def update_account(self, cr, uid, partner_id, account_type, context, force_checked=None):
if account_type not in ('receivable', 'payable'):
return
company = self.pool.get('res.users').browse(cr, uid, uid, context).company_id
parent_account = getattr(company, 'parent_%s_account_id' % account_type)
if not parent_account:
return
partner = self.browse(cr, uid, partner_id, context)
if account_type == 'receivable':
checked = partner.customer
else:
checked = partner.supplier
partner_account = getattr(partner, 'property_account_%s' % account_type)
if not force_checked is None:
checked = force_checked
if partner_account:
if checked:
# If account already exists, just check if we need to update account name.
if partner_account.name != partner.name:
# We will only update account name if no other partner is using the same account.
value = 'account.account,%d' % partner_account.id
partners = self.pool.get('ir.property').search(
cr, uid, [('res_id', '!=', False),
('value_reference', '=', value)],
context=context)
if len(partners) == 1:
self.pool.get('account.account').write(
cr, uid, [partner_account.id], {
'name': partner.name,
}, context)
return
# If it's not possible to unlink the account we will rollback this change
# so the property remains the same. Note that we cannot try to unlink first,
# because in this case it would always fail because of the fact that it's set
# as the account in the partner.
cr.execute('SAVEPOINT remove_account')
self.write(cr, uid, [partner_id], {
'property_account_%s' % account_type: False,
}, context)
try:
# Unlink may raise an exception if the account is already set in another partner
# or if it has account moves.
if partner_account.name == partner.name:
self.pool.get('account.account').unlink(cr, uid, [partner_account.id], context)
except orm.except_orm:
cr.execute('ROLLBACK TO SAVEPOINT remove_account')
cr.execute('RELEASE SAVEPOINT remove_account')
if not checked:
return
sequence_obj = self.pool.get('ir.sequence')
sequence_id = sequence_obj.search(cr, uid, [('code', '=', 'res.partner')],
context=context)
sequence = sequence_obj.browse(cr, uid, sequence_id,
context=context)[0]
code = partner.ref
account_id = self.pool.get('account.account').search(cr, uid, [('code', '=', code)], context=context)
if account_id:
account_id = account_id[0]
else:
account_id = self.pool.get('account.account').create(cr, uid, {
'name': partner.name,
'code': code,
'parent_id': parent_account.id,
'user_type': 2,
'reconcile': True,
'type': account_type,
}, context)
self.write(cr, uid, [partner_id], {
'property_account_%s' % account_type: account_id,
}, context)
I want to call the method by clicking on the conformation button, so I do it like this:
class SaleOrder(models.Model):
_inherit = 'sale.order'
def action_button_confirm(self, cr, uid, ids, context=None):
sale_order = self.pool.get('sale.order').browse(cr, uid, ids)
partner = self.pool.get('res.partner').browse(cr, uid, sale_order.partner_id, context=context)
partner.update_account(cr, uid, partner.id, 'receivable', context)
return super(SaleOrder, self).action_button_confirm(cr, uid, ids, context=None)
But I get this error all the time:
Odoo Server Error
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/openerp/http.py", line 544, in _handle_exception
return super(JsonRequest, self)._handle_exception(exception)
File "/usr/lib/python2.7/dist-packages/openerp/http.py", line 581, in dispatch
result = self._call_function(**self.params)
File "/usr/lib/python2.7/dist-packages/openerp/http.py", line 317, in _call_function
return checked_call(self.db, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/openerp/service/model.py", line 118, in wrapper
return f(dbname, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/openerp/http.py", line 314, in checked_call
return self.endpoint(*a, **kw)
File "/usr/lib/python2.7/dist-packages/openerp/http.py", line 810, in __call__
return self.method(*args, **kw)
File "/usr/lib/python2.7/dist-packages/openerp/http.py", line 410, in response_wrap
response = f(*args, **kw)
File "/usr/lib/python2.7/dist-packages/openerp/addons/web/controllers/main.py", line 948, in call_button
action = self._call_kw(model, method, args, {})
File "/usr/lib/python2.7/dist-packages/openerp/addons/web/controllers/main.py", line 936, in _call_kw
return getattr(request.registry.get(model), method)(request.cr, request.uid, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/openerp/api.py", line 268, in wrapper
return old_api(self, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/openerp/addons/portal_sale/portal_sale.py", line 67, in action_button_confirm
return super(sale_order, self).action_button_confirm(cr, uid, ids, context=context)
File "/usr/lib/python2.7/dist-packages/openerp/api.py", line 268, in wrapper
return old_api(self, *args, **kwargs)
File "/Odoo/OdooV8/partner_auto_account/sale_order.py", line 15, in action_button_confirm
partner.update_account(cr, uid, partner.id, 'receivable', context)
File "/usr/lib/python2.7/dist-packages/openerp/api.py", line 266, in wrapper
return new_api(self, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/openerp/api.py", line 508, in new_api
result = method(self._model, cr, uid, *args, **old_kwargs)
TypeError: update_account() takes at most 7 arguments (9 given)
So what's the metter? I do not pass over 9 arguments... What went wrong?
Upvotes: 1
Views: 10420
Reputation: 769
I'm too lazy to read all your code, but I guess you are calling method using a button on the form and you are getting error: update_account() takes at most 7 arguments (9 given)
.
So, there is the question why? Maybe it's rude of me, but you should read official documentation before starting working on odoo. The answer is you are not using any function decorators. To learn more about decorators follow this link.
So if you need to use old API, you should use @api.model
and in any other case you should use @api.one
or @api.multi
. The difference between this two is ids
. In @api.multi
it passes ids
too so you have a recordset and in case of @api.one
you have a single record.
class SaleOrder(models.Model):
_inherit = 'sale.order'
@api.multi #because you were passing ids too
def action_button_confirm(self):
# self is here recordset of ids already and besides
# self.pool.get is an old api you shouldn't use it,
# use self.env instead
for sale_order in self:
partner = sale_order.partner_id
# you don't need to pass partner id
partner.update_account('receivable')
return super(SaleOrder, self).action_button_confirm()
I can't fix all your code, but for example it's enough what I fixed.
Upvotes: 1
Reputation: 5319
For anyone looking for a generic answer this is how I call another models method in odoo 10:
self.env['my.model'].some_method()
Upvotes: 3
Reputation: 26678
Use new API
class SaleOrder(models.Model):
_inherit = 'sale.order'
@api.multi
def action_button_confirm(self):
assert len(self) == 1, 'This option should only be used for a single id at a time.'
partner.update_account(partner_id=self.partner_id.id, account_type='receivable')
return super(SaleOrder, self).action_button_confirm()
Upvotes: 2
Reputation: 93
If you are using the new API of Odoo, you don't have to pass standard variables self, cr,uid,context, odoo do it for your by default,
Upvotes: 0
Reputation: 3747
You do not pass 9 argument, the framework does.
Call the method like this:
partner.update_account(partner.id, 'receivable', context)
If you check on the stack trace you will see that:
File "/usr/lib/python2.7/dist-packages/openerp/api.py", line 508, in new_api
result = method(self._model, cr, uid, *args, **old_kwargs)
The framework already passes the cr and uid parameters for you.
Upvotes: 0