TypeError: list indices must be integers, not str - Odoo v8 to Odoo v10 community

TypeError: list indices must be integers, not str - Odoo v8 to Odoo v10 community

我有这两个方法:

@api.multi
def new_open_window(self, list_ids, xml_id, module): 
    """ Generate new window at view form or tree
    """
    mod_obj = self.env['ir.model.data']
    act_obj = self.env['ir.actions.act_window']
    result = mod_obj._get_id(module, xml_id) 
    imd_id = mod_obj.browse(result, ['res_id'])
    result = act_obj.browse(imd_id) 
    result['res_id'] = list_ids
    return result

@api.multi
def create_invoice(self): 
    """ Create a invoice refund
    """
    #context = context or {}
    wizard_brw = self.browse() 
    inv_id = self._context.get('active_id')
    for wizard in wizard_brw:
        if not wizard.sure:
            raise UserError(
                _("Validation error!"),
                _("Please confirm that you know what you're doing by"
                  " checking the option bellow!"))
        if (wizard.invoice_id and wizard.invoice_id.company_id.jour_id and
                wizard.invoice_id and wizard.invoice_id.company_id.acc_id):
            inv_id = self.action_invoice_create(wizard,
                                                wizard.invoice_id) 
        else:
            raise UserError(
                _('Validation error!'),
                _("You must go to the company form and configure a journal"
                  " and an account for damaged invoices"))
    return self.new_open_window([inv_id],
                                'action_invoice_tree1', 'account') 

这些方法最初是这样的(在 v8 上):

    def new_open_window(self, cr, uid, ids, list_ids, xml_id, module,
                    context=None):
    """ Generate new window at view form or tree
    """
    mod_obj = self.pool.get('ir.model.data')
    act_obj = self.pool.get('ir.actions.act_window')
    result = mod_obj._get_id(cr, uid, module, xml_id)
    imd_id = mod_obj.read(cr, uid, result, ['res_id'])['res_id']
    result = act_obj.read(cr, uid, imd_id)
    result['res_id'] = list_ids
    return result

def create_invoice(self, cr, uid, ids, context=None):
    """ Create a invoice refund
    """
    context = context or {}
    wizard_brw = self.browse(cr, uid, ids, context=context)
    inv_id = context.get('active_id')
    for wizard in wizard_brw:
        if not wizard.sure:
            raise osv.except_osv(
                _("Validation error!"),
                _("Please confirm that you know what you're doing by"
                  " checking the option bellow!"))
        if (wizard.invoice_id and wizard.invoice_id.company_id.jour_id and
                wizard.invoice_id and wizard.invoice_id.company_id.acc_id):
            inv_id = self.action_invoice_create(cr, uid, ids, wizard,
                                                wizard.invoice_id, context)
        else:
            raise osv.except_osv(
                _('Validation error!'),
                _("You must go to the company form and configure a journal"
                  " and an account for damaged invoices"))
    return self.new_open_window(cr, uid, ids, [inv_id],
                                'action_invoice_tree1', 'account')

这些方法应该读取发票(之前在弹出窗口中选择 window),然后在单击按钮时,将此发票重写为已取消的发票,发票名称上带有 "PAPEL ANULADO"。方法 create_invoice 调用另一个方法 action_invoice_create.

这是迁移后的方法:

@api.multi
def action_invoice_create(self, wizard_brw, inv_brw): #cr, uid, ids, wizard_brw, inv_brw, context=None
    """
    If the invoice has control number, this function is responsible for
    passing the bill to damaged paper
    @param wizard_brw: nothing for now
    @param inv_brw: damaged paper
    """
    invoice_line_obj = self.env['account.invoice.line']
    invoice_obj = self.env['account.invoice']
    acc_mv_obj = self.env['account.move']
    acc_mv_l_obj = self.env['account.move.line']
    tax_obj = self.env['account.invoice.tax']
    invoice = {}
    if inv_brw.nro_ctrl:
        invoice.update({
            'name': 'PAPELANULADO_NRO_CTRL_%s' % (
                inv_brw.nro_ctrl and inv_brw.nro_ctrl or ''),
            'state': 'paid',
            'tax_line': [],
        })
    else:
        raise UserError(
            _('Validation error!'),
            _("You can run this process just if the invoice have Control"
              " Number, please verify the invoice and try again."))
    invoice_obj.write([inv_brw.id], invoice) #cr, uid, [inv_brw.id], invoice, context=context
    for line in inv_brw.invoice_line:
        invoice_line_obj.write(
            [line.id],
            {'quantity': 0.0, 'invoice_line_tax_id': [],
             'price_unit': 0.0}) #cr, uid, context=context

    tax_ids = self.env['account.tax'].search([]) # cr, uid, [], context=context
    tax = tax_obj.search([('invoice_id', '=', inv_brw and inv_brw.id)]) # cr, uid, contet=context
    if tax:
        tax_obj.write(tax[0], {'invoice_id': []}) #cr, uid, tax[0], {'invoice_id': []}, context=context
    tax_obj.create({
        'name': 'SDCF',
        'tax_id': tax_ids and tax_ids[0],
        'amount': 0.00,
        'tax_amount': 0.00,
        'base': 0.00,
        'account_id': inv_brw.company_id.acc_id.id,
        'invoice_id': inv_brw and inv_brw.id}, {}) #cr ,uid, was first
    move_id = inv_brw.move_id and inv_brw.move_id.id

    if move_id:
        acc_mv_obj.button_cancel([inv_brw.move_id.id]) #cr, uid, [inv_brw.move_id.id], context=context
        acc_mv_obj.write([inv_brw.move_id.id],{'ref': 'Damanged Paper'}) #cr, uid, [inv_brw.move_id.id],{'ref': 'Damanged Paper'}, context=context
        acc_mv_l_obj.unlink([i.id for i in inv_brw.move_id.line_id]) #cr, uid was first
    return inv_brw.id

其实我不太确定这是否应该 @api.multi 我认为应该是 @api.model 虽然我不太确定。

无论如何,当我点击 create_invoice 方法时,它会抛出这个:

Traceback (most recent call last):
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/http.py", line 638, in _handle_exception
return super(JsonRequest, self)._handle_exception(exception)
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/http.py", line 675, in dispatch
result = self._call_function(**self.params)
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/http.py", line 331, in _call_function
return checked_call(self.db, *args, **kwargs)
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/service/model.py", line 119, in wrapper
return f(dbname, *args, **kwargs)
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/http.py", line 324, in checked_call
result = self.endpoint(*a, **kw)
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/http.py", line 933, in __call__
return self.method(*args, **kw)
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/http.py", line 504, in response_wrap
response = f(*args, **kw)
File "/home/kristian/odoov10/odoo-10.0rc1c-20161005/odoo/addons/web/controllers/main.py", line 866, in call_button
action = self._call_kw(model, method, args, {})
File "/home/kristian/odoov10/odoo-10.0rc1c-20161005/odoo/addons/web/controllers/main.py", line 854, in _call_kw
return call_kw(request.env[model], method, args, kwargs)
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/api.py", line 681, in call_kw
return call_kw_multi(method, model, args, kwargs)
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/api.py", line 672, in call_kw_multi
result = method(recs, *args, **kwargs)
File "/home/kristian/odoov10/gilda/l10n_ve_fiscal_requirements/wizard/wizard_invoice_nro_ctrl.py", line 134, in create_invoice
'action_invoice_tree1', 'account') 
File "/home/kristian/odoov10/gilda/l10n_ve_fiscal_requirements/wizard/wizard_invoice_nro_ctrl.py", line 106, in new_open_window
imd_id = mod_obj.browse(result, ['res_id'])
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/models.py", line 4755, in browse
return self._browse(ids, self.env, prefetch)
File "/home/kristian/.virtualenvs/odoov10/lib/python2.7/site-packages/odoo-10.0rc1c_20161005-py2.7.egg/odoo/models.py", line 4742, in _browse
prefetch[cls._name].update(ids)
TypeError: list indices must be integers, not str

错误在这一行 imd_id = mod_obj.browse(result, ['res_id']) 和这一行 return self.new_open_window([inv_id], 'action_invoice_tree1', 'account')

之前,imd_id 使用的是 read() 我已将其更改为 browse(),但仍然出现同样的错误。

希望我已经解释清楚了。

如果您需要更多信息,请告诉我。

有什么想法吗?

当您使用浏览记录时,您不会传递您希望获得的字段。

ids = [6]
rec = self.env['your.model'].browse(ids)['field_name']

这里有很多事情要做,我会从上到下的方法:

错误

invoice_obj.write([inv_brw.id], invoice)

对,可以直接在RecordSets

上使用ORM方法
inv_brw.write(invoice)  # maybe rename invoice to invoice_values

错误

for line in inv_brw.invoice_line:
    invoice_line_obj.write(
        [line.id],
        {'quantity': 0.0, 'invoice_line_tax_id': [],
         'price_unit': 0.0}) #cr, uid, context=context

对,你可以直接在RecordSets上使用ORM方法,如果有多个记录但所有要写入的值都相同,一次写入所有记录:

inv_brw.invoice_line_ids.write({  # lines field was renamed
    'quantity': 0.0,
    'invoice_line_tax_id': [],
    'price_unit': 0.0
})

错误

tax_ids = self.env['account.tax'].search([]) # cr, uid, [], context=context
tax = tax_obj.search([('invoice_id', '=', inv_brw and inv_brw.id)]) # cr, uid, contet=context
if tax:
    tax_obj.write(tax[0], {'invoice_id': []}) #cr, uid, tax[0], {'invoice_id': []}, context=context
tax_obj.create(values)  # shortened

我认为在系统中使用 "first" 税是危险的。但是,是的,这不是您的模块。但为什么不直接删除旧的发票税务条目呢?如果发票行不再设置税金,为什么还要有发票税金条目?更好:

taxes = self.env['account.tax'].search([])  # RecordSets!
invoice_taxes = tax_obj.search(
    [('invoice_id', '=', inv_brw and inv_brw.id)]).unlink()
# tax_obj.create(values)  # not necessary

错误

move_id = inv_brw.move_id and inv_brw.move_id.id

if move_id:
    acc_mv_obj.button_cancel([inv_brw.move_id.id]) #cr, uid, [inv_brw.move_id.id], context=context
    acc_mv_obj.write([inv_brw.move_id.id],{'ref': 'Damanged Paper'}) #cr, uid, [inv_brw.move_id.id],{'ref': 'Damanged Paper'}, context=context
    acc_mv_l_obj.unlink([i.id for i in inv_brw.move_id.line_id]) #cr, uid was first

对,就用新的API可能性:

move = inv_brw.move_id
if move:
    move.button_cancel()
    move.ref = 'Damanged Paper'
    move.line_ids.unlink()  # field for the move lines was renamed