Search code examples
pythonodooodoo-8openerp-8

Odoo - Call method in another model


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?


Solution

  • 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()