Odoo - 在另一个模型中调用方法

时间:2017-05-16 16:14:03

标签: python openerp odoo-8 openerp-8

我想通过点击销售订单中的确认按钮来调用方法,以更新相应合作伙伴的帐户。

因此我在合作伙伴模型中定义了工作方法:

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)

我想通过点击conformation按钮调用该方法,所以我这样做:

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)

但我一直都会收到此错误:

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)

那么什么是metter? 我没有通过9个论点...... 出了什么问题?

5 个答案:

答案 0 :(得分:1)

使用新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()

答案 1 :(得分:0)

你没有传递9个参数,框架确实如此。

调用这样的方法:

partner.update_account(partner.id, 'receivable', context)

如果您检查堆栈跟踪,您将看到:

  File "/usr/lib/python2.7/dist-packages/openerp/api.py", line 508, in new_api
    result = method(self._model, cr, uid, *args, **old_kwargs)

框架已经为你传递了cr和uid参数。

答案 2 :(得分:0)

如果您使用的是Odoo的新API,则不必通过标准变量self,cr,uid,context,odoo默认为您执行此操作,

答案 3 :(得分:0)

我太懒了所有你的代码,但是因为我猜你是在使用表单上的按钮调用方法而且你收到错误:update_account() takes at most 7 arguments (9 given)

所以有问题为什么?!也许它对我很粗鲁,但你应该在开始处理odoo之前阅读官方文档。答案是你没有使用任何函数装饰器。要了解有关装饰器的更多信息,请按以下link

因此,如果您需要使用旧的api,则应使用@api.model,在任何其他情况下,您应使用@api.one@api.multi。这两者之间的差异是ids。在@api.multi中,它也会传递ids,因此您有recorset,如果@api.one您有一条记录。

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

我无法修复你的所有代码,但例如它足以修复我的代码。

答案 4 :(得分:0)

对于那些寻找通用答案的人来说,这就是我在odoo 10中调用另一种模型方法的方法:

self.env['my.model'].some_method()
相关问题