簡體   English   中英

TypeError:不可散列的類型:'列表'| 將Odoo v8移植到Odoo 12

[英]TypeError: unhashable type: 'list' | Porting Odoo v8 to Odoo 12

我正在嘗試讀取發票記錄,但是下一個問題出了問題,以下是我的終端日志:

Odoo Server Error

Traceback (most recent call last):
  File "/home/desarrollo/Documentos/odoo-12/odoo-12.0/odoo/http.py", line 654, in _handle_exception
    return super(JsonRequest, self)._handle_exception(exception)
  File "/home/desarrollo/Documentos/odoo-12/odoo-12.0/odoo/http.py", line 312, in _handle_exception
    raise pycompat.reraise(type(exception), exception, sys.exc_info()[2])
  File "/home/desarrollo/Documentos/odoo-12/odoo-12.0/odoo/tools/pycompat.py", line 87, in reraise
    raise value
  File "/home/desarrollo/Documentos/odoo-12/odoo-12.0/odoo/http.py", line 696, in dispatch
    result = self._call_function(**self.params)
  File "/home/desarrollo/Documentos/odoo-12/odoo-12.0/odoo/http.py", line 344, in _call_function
    return checked_call(self.db, *args, **kwargs)
  File "/home/desarrollo/Documentos/odoo-12/odoo-12.0/odoo/service/model.py", line 97, in wrapper
    return f(dbname, *args, **kwargs)
  File "/home/desarrollo/Documentos/odoo-12/odoo-12.0/odoo/http.py", line 337, in checked_call
    result = self.endpoint(*a, **kw)
  File "/home/desarrollo/Documentos/odoo-12/odoo-12.0/odoo/http.py", line 939, in __call__
    return self.method(*args, **kw)
  File "/home/desarrollo/Documentos/odoo-12/odoo-12.0/odoo/http.py", line 517, in response_wrap
    response = f(*args, **kw)
  File "/home/desarrollo/Documentos/odoo-12/odoo-12.0/addons/web/controllers/main.py", line 966, in call_button
    action = self._call_kw(model, method, args, {})
  File "/home/desarrollo/Documentos/odoo-12/odoo-12.0/addons/web/controllers/main.py", line 954, in _call_kw
    return call_kw(request.env[model], method, args, kwargs)
  File "/home/desarrollo/Documentos/odoo-12/odoo-12.0/odoo/api.py", line 749, in call_kw
    return _call_kw_multi(method, model, args, kwargs)
  File "/home/desarrollo/Documentos/odoo-12/odoo-12.0/odoo/api.py", line 736, in _call_kw_multi
    result = method(recs, *args, **kwargs)
  File "/home/desarrollo/Documentos/odoo-12/custom/l10n-ve/l10n_vzla_dcnote/wizard/account_invoice_debit.py", line 178, in invoice_debit
    return self.compute_debit()
  File "/home/desarrollo/Documentos/odoo-12/custom/l10n-ve/l10n_vzla_dcnote/wizard/account_invoice_debit.py", line 111, in compute_debit
    'journal_id', 'period_id'])
  File "/home/desarrollo/Documentos/odoo-12/odoo-12.0/odoo/models.py", line 2747, in read
    fields = self.check_field_access_rights('read', fields)
  File "/home/desarrollo/Documentos/odoo-12/odoo-12.0/odoo/models.py", line 2722, in check_field_access_rights
    invalid_fields = {name for name in fields if not valid(name)}
  File "/home/desarrollo/Documentos/odoo-12/odoo-12.0/odoo/models.py", line 2722, in <setcomp>
    invalid_fields = {name for name in fields if not valid(name)}
  File "/home/desarrollo/Documentos/odoo-12/odoo-12.0/odoo/models.py", line 2713, in valid
    field = self._fields.get(fname)
TypeError: unhashable type: 'list'

我嘗試刪除一些字段,但仍然收到錯誤。

這是我的自定義模塊:

# coding: utf-8
import time

from odoo import api, fields, models, _
from odoo.tools.translate import _
from odoo.osv import osv

class AccountInvoiceDebit(models.TransientModel):

    """Debits Note from Invoice"""

    _name = "account.invoice.debit"
    _description = "Invoice Debit Note"

    date = fields.Date('Operation date',
                        help='This date will be used as the invoice date '
                                'for Refund Invoice and Period will be '
                                'chosen accordingly!')
    period = fields.Many2one('account.period', 'Force period')
    journal_id = fields.Many2one('account.journal',
                                    'Refund Journal',
                                    help='You can select here the journal '
                                        'to use for the refund invoice '
                                        'that will be created. If you '
                                        'leave that field empty, it will '
                                        'use the same journal as the '
                                        'current invoice.')
    description = fields.Char('Description', size=128, required=True)
    comment = fields.Text('Comment', required=True)

    def _get_journal(self, cr, uid, context=None):
        obj_journal = self.pool.get('account.journal')
        user_obj = self.pool.get('res.users')
        if context is None:
            context = {}
        inv_type = context.get('type', 'out_invoice')
        company_id = user_obj.browse(
            cr, uid, uid, context=context).company_id.id
        type = (inv_type == 'out_invoice') and 'sale_refund' or \
               (inv_type == 'out_refund') and 'sale' or \
               (inv_type == 'in_invoice') and 'purchase_refund' or \
               (inv_type == 'in_refund') and 'purchase'
        journal = obj_journal.search(cr, uid, [('type', '=', type), (
            'company_id', '=', company_id)], limit=1, context=context)
        return journal and journal[0] or False

    _defaults = {
        'date': lambda *a: time.strftime('%Y-%m-%d'),
        'journal_id': _get_journal,
    }

    def _get_period(self, cr, uid, context={}):
        """
        Return  default account period value
        """
        account_period_obj = self.pool.get('account.period')
        ids = account_period_obj.find(cr, uid, context=context)
        period_id = False
        if ids:
            period_id = ids[0]
        return period_id

    def _get_orig(self, cr, uid, inv, ref, context={}):
        """
        Return  default origin value
        """
        nro_ref = ref
        if inv.type == 'out_invoice':
            nro_ref = inv.number
        orig = _('INV:') + (nro_ref or '') + _('- DATE:') + (
            inv.date_invoice or '') + (' TOTAL:' + str(inv.amount_total) or '')
        return orig

    @api.model
    def compute_debit(self, context=None):
        """
        @param cr: the current row, from the database cursor,
        @param uid: the current user’s ID for security checks,
        @param ids: the account invoice refund’s ID or list of IDs

        """
        inv_obj = self.env['account.invoice']
        mod_obj = self.env['ir.model.data']
        act_obj = self.env['ir.actions.act_window']
        inv_tax_obj = self.env['account.invoice.tax']
        inv_line_obj = self.env['account.invoice.line']
        res_users_obj = self.env['res.users']
        record = self._context.get('active_ids')
        if context is None:
            context = {}

        for form in self.browse(self):
            created_inv = []
            date = False
            period = False
            description = False
            company = res_users_obj.company_id
            journal_id = self.journal_id
            for inv in inv_obj.browse(record):


                # we get original data of invoice to create a new invoice that
                # is the copy of the original
                invoice = inv.read([record],
                                       ['name', 'type', 'number', 'reference',
                                        'comment', 'date_due', 'partner_id',
                                        'partner_insite', 'partner_contact',
                                        'partner_ref', 'payment_term',
                                        'account_id', 'currency_id',
                                        'invoice_line', 'tax_line',
                                        'journal_id', 'period_id'])
                invoice = invoice[0]
                del invoice['id']
                invoice_lines = inv_line_obj.browse(
                    cr, uid, invoice['invoice_line'], context=context)
                invoice_lines = inv._refund_cleanup_lines(
                    cr, uid, invoice_lines, context=context)
                tax_lines = inv_tax_obj.browse(
                    cr, uid, invoice['tax_line'], context=context)
                tax_lines = inv_obj._refund_cleanup_lines(
                    cr, uid, tax_lines, context=context)
                # Add origin, parent and comment values
                orig = self._get_orig(cr, uid, inv, invoice[
                                      'reference'], context)
                invoice.update({
                    'type': inv.type == 'in_invoice' and 'in_refund' or
                    inv.type == 'out_invoice' and 'out_refund',
                    'date_invoice': date,
                    'state': 'draft',
                    'number': False,
                    'invoice_line': invoice_lines,
                    'tax_line': tax_lines,
                    'period_id': period,
                    'parent_id': inv.id,
                    'name': description,
                    'origin': orig,
                    'comment': form['comment']
                })
                # take the id part of the tuple returned for many2one fields
                for field in ('partner_id', 'account_id', 'currency_id',
                              'payment_term', 'journal_id'):
                    invoice[field] = invoice[field] and invoice[field][0]
                # create the new invoice
                inv_id = inv_obj.create(self, invoice, {})
                # we compute due date
                if inv.payment_term.id:
                    data = inv_obj.onchange_payment_term_date_invoice(
                        cr, uid, [inv_id], inv.payment_term.id, date)
                    if 'value' in data and data['value']:
                        inv_obj.write(cr, uid, [inv_id], data['value'])
                created_inv.append(inv_id)
            # we get the view id
            """
            xml_id = (inv_obj.type == 'out_refund') and 'action_invoice_tree1' or \
                     (inv_obj.type == 'in_refund') and 'invoice_supplier_form' or \
                     (inv_obj.type == 'out_invoice') and 'action_invoice_out_refund' or \
                     (inv_obj.type == 'in_invoice') and 'action_invoice_in_refund'
            """

            raise osv.except_osv(created_inv)
            # we get the model
            """
            result = mod_obj.get_object_reference('account.invoice', xml_id)
            id = result and result[1] or False
            # we read the act window
            result = act_obj.read(cr, uid, id, context=context)
            # we add the new invoices into domain list
            invoice_domain = eval(result['domain'])
            invoice_domain.append(('id', 'in', created_inv))
            result['domain'] = invoice_domain
            """
            return True

    @api.multi
    def invoice_debit(self):
        #ids = self._context('active_ids')
        #id_inv = self._context.get('active_ids')
        return self.compute_debit()

我希望閱讀發票以創建具有某些更改值的副本,因此我強制執行加薪錯誤以確保將其創建。

首先,您使用api.model意味着您正在使用新的API。 我對這條線感到困惑:

 for form in self.browse(self):

使用api.model self總是一個空集,從來沒有嘗試過,我想知道為什么您在第一局中就處於循環中。

我認為您需要將其更改為api.multi並刪除新api中的context參數,該參數位於self本身。

    self._context  or self.env.context

試試看,但這是一個簡單的解釋,新的API如何工作,您不必每次都傳遞cr,id,上下文

@api.multi
def compute_debit(self):


     for form in self: # you don't have to browse self it's all read a Recordset
         .....
         .....
         .....

         for inv in inv_obj.browse(record): # this is okay because it's a list of ids you should browse to convert to recrodset
             # here you don't have to pass the id in the new api 
             invoice = inv.read(['name', 'type', 'number', 'reference',
                                    'comment', 'date_due', 'partner_id',
                                    'partner_insite', 'partner_contact',
                                    'partner_ref', 'payment_term',
                                    'account_id', 'currency_id',
                                    'invoice_line', 'tax_line',
                                    'journal_id', 'period_id'])

您正在將新api與舊api混合在一起! 在您的代碼中,您應該使用兩者之一。 代碼運氣會帶來很多問題。

例如

   inv._refund_cleanup_lines(
                cr, uid, invoice_lines, context=context)

我看不到任何變量或參數cr或uid

例如,而不是讀取字段並像這樣調用方法,您要做的是:

       # no read at all you all ready have acces to fields
       inv._refund_cleanup_lines(inv.invoice_line)

希望你能明白。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM