I'm trying to read a record of invoice but I get a problem the next problem, bellow is my terminal log:
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'
I try to remove some fields but still get the error.
Here is my custom module:
# 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()
I expect to read the invoice to create a copy with some changed values, so i forced a raise error to make sure that is gonna be created.
First you used api.model
means you are using new API. I'm confused about this line:
for form in self.browse(self):
with api.model
self is always an empty set a never tried this I wonder why you are in the loop in the first play.
I think you need to change this to api.multi and remove the context parameter in the new api the parameter is in the self it's self.
self._context or self.env.context
try this but this a simple explanation how new API work you don't have to pass cr, ids, context each time
@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'])
you are mixing new api with old api ?!! a lot in your code you should use one of the two. you will have a lot of problem with code good luck.
like for example
inv._refund_cleanup_lines(
cr, uid, invoice_lines, context=context)
I don't see any variable or argument cr or uid you get the idea
for example instead of reading the fields and calling the method like this what you had to do is:
# no read at all you all ready have acces to fields
inv._refund_cleanup_lines(inv.invoice_line)
Hope you get the idea.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.