无法使用关闭的游标
Unable to use a closed cursor
在对 res.partner
模型进行一些操作后,我在第二次调用 make_po 方法时遇到此异常。如果我停止服务器并重新启动它,操作将继续正确执行以下是我对 make_po 方法和堆栈跟踪的覆盖:
class procurement_order(osv.osv):
_inherit = 'procurement.order'
counter = 0
global_po_id = None
line_counter = 0
first_line = None
def make_po(self, cr, uid, ids, context=None):
_logger = logging.getLogger(__name__)
""" Resolve the purchase from procurement, which may result in a new PO creation, a new PO line creation or a quantity change on existing PO line.
Note that some operations (as the PO creation) are made as SUPERUSER because the current user may not have rights to do it (mto product launched by a sale for example)
@return: dictionary giving for each procurement its related resolving PO line.
OVERRIDE: If we already have a purchase order on a draft state with the same product, do not append the lines.
Instead create a new Purchase Order
"""
company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id
po_obj = self.pool.get('purchase.order')
seq_obj = self.pool.get('ir.sequence')
sales_orders = self.pool.get('sale.order')
po_line = self.pool.get('purchase.order.line')
# Get the procurement ID ("key" == Procurement ID, "value" == PO line)
procurement_purchase_order = super(procurement_order, self).make_po(cr, uid, ids, context=context)
key, value = procurement_purchase_order.popitem()
procurement_purchase_order[key] = value
# Search for the equivalent purchase.order.line
p_o_line_returned_id = po_line.search(cr, uid, [('id', '=', value)])
p_o_line_returned = po_line.browse(cr, uid, p_o_line_returned_id, context=context)
# get purchase order from its line
purchase_order_from_line_ID = po_obj.search(cr, uid, [('id', '=', p_o_line_returned.order_id.id)])
purchase_order_from_line = po_obj.browse(cr, uid, purchase_order_from_line_ID, context=context)
# Get me the current procurement
current_procurement_ID = self.search(cr, uid, [('id', '=', key)])
current_procurement = self.browse(cr, uid, current_procurement_ID, context=context)
# Get me the line ids of the lines that are related to purchase_order_from_line_ID
lines_IDS = po_line.search(cr, uid, [('order_id', '=', purchase_order_from_line_ID[0])])
_logger.warning('lines_IDS' + str(lines_IDS))
# Check the source of all the lines in thelines_IDS
for line in po_line.browse(cr, uid, lines_IDS, context=context):
_logger.warning('First line value ' + str(procurement_order.first_line))
_logger.warning('')
if line.procurement_ids != 0:
if procurement_order.line_counter == 0:
procurement_order.first_line = line
procurement_order.line_counter += 1
# Compare the first line procurement.group_id with the current procurement.group_id
if procurement_order.first_line.procurement_ids and procurement_order.first_line.procurement_ids[0].group_id == current_procurement[0].group_id:
_logger.warning('GROUP IDS ARE EQUAL')
else:
_logger.warning('GROUP IDS ARE NOT EQUAL')
# if we have inequality between the group ids then that means that the current "line" was created by a different SO
to_remove = []
to_remove.append(line.id)
# from the current_procurement.group_id get the PO.line and remove it
temp_group_id = current_procurement[0].group_id.id
_logger.warning(str(temp_group_id))
temp_line_for_removal_ID = po_line.search(cr, uid, [('id', '=', temp_group_id)])
po_line.unlink(cr, uid, temp_line_for_removal_ID, context=context)
_logger.warning('Removed from Purchase Order ' + str(purchase_order_from_line_ID[0]) + ' Lines ' + str(to_remove))
pass_ids = []
# for all the procrements that belong to my SO
# for procurement in self.browse(cr, uid, ids, context=context):
partner = self._get_product_supplier(cr, uid, current_procurement, context=context)
if not partner:
self.message_post(cr, uid, [current_procurement.id], _('There is no supplier associated to product %s') % (current_procurement.product_id.name))
procurement_purchase_order[current_procurement.id] = False
else:
schedule_date = self._get_purchase_schedule_date(cr, uid, current_procurement, company, context=context)
purchase_date = self._get_purchase_order_date(cr, uid, current_procurement, company, schedule_date, context=context)
line_vals = self._get_po_line_values_from_proc(cr, uid, current_procurement, partner, company, schedule_date, context=context) # get the lines from here
name = seq_obj.get(cr, uid, 'purchase.order') or _('PO: %s') % current_procurement.name
po_vals = {
'name': name,
'origin': current_procurement.origin,
'partner_id': partner.id,
'location_id': current_procurement.location_id.id,
'picking_type_id': current_procurement.rule_id.picking_type_id.id,
'pricelist_id': partner.property_product_pricelist_purchase.id,
'currency_id': partner.property_product_pricelist_purchase and partner.property_product_pricelist_purchase.currency_id.id or current_procurement.company_id.currency_id.id,
'date_order': purchase_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
'company_id': current_procurement.company_id.id,
'fiscal_position': po_obj.onchange_partner_id(cr, uid, None, partner.id, context=context)['value']['fiscal_position'],
'payment_term_id': partner.property_supplier_payment_term.id or False,
'dest_address_id': current_procurement.partner_dest_id.id,
}
# The first time create the PO and add a line to it
if procurement_order.counter == 0:
po_id = self.create_procurement_purchase_order(cr, uid, current_procurement, po_vals, line_vals, context=context)
procurement_order.global_po_id = po_id
po_line_id = po_obj.browse(cr, uid, po_id, context=context).order_line[0].id
pass_ids.append(current_procurement.id)
procurement_purchase_order[current_procurement.id] = po_line_id
self.write(cr, uid, [current_procurement.id], {'purchase_line_id': po_line_id}, context=context)
_logger.warning('New Purchase order created ' + str(po_id))
else:
# All the other lines from the procurements will be appended here
proc_order = self.pool.get('procurement.order')
purchase_order_created = po_obj.browse(cr, uid, procurement_order.global_po_id, context=context) # get the Purchase Order
line_vals = proc_order._get_po_line_values_from_proc(cr, uid, current_procurement, partner, company, schedule_date, context=context) # Get the line from the procurement
po_line_obj = self.pool.get('purchase.order.line')
line_vals['order_id'] = purchase_order_created[0].id
# if there exists a line with the same id, do not add it
if len(po_line_obj.search(cr, uid, [('order_id', '=', purchase_order_created[0].id)])) == 0:
po_line_id = po_line_obj.create(cr, uid, line_vals, context=context)
_logger.warning('Appending line ' + str(line_vals) + 'to existing Purchase order ' + str(purchase_order_created))
else:
_logger.warning('Line has already been appended, dismissed')
if pass_ids:
self.message_post(cr, uid, pass_ids, body=_("Draft Purchase Order created"), context=context)
procurement_order.counter += 1
self.pool.get('purchase.order.line').split_lines(cr, uid, [procurement_purchase_order[ids[0]]], context=context)
return procurement_purchase_order
堆栈跟踪:
2015-09-10 13:15:11,752 1167 ERROR odoov8 openerp.http: Exception during JSON request handling.
Traceback (most recent call last):
File "/home/odoo/odoo/openerp/http.py", line 537, in _handle_exception
return super(JsonRequest, self)._handle_exception(exception)
File "/home/odoo/odoo/openerp/http.py", line 574, in dispatch
result = self._call_function(**self.params)
File "/home/odoo/odoo/openerp/http.py", line 310, in _call_function
return checked_call(self.db, *args, **kwargs)
File "/home/odoo/odoo/openerp/service/model.py", line 113, in wrapper
return f(dbname, *args, **kwargs)
File "/home/odoo/odoo/openerp/http.py", line 307, in checked_call
return self.endpoint(*a, **kw)
File "/home/odoo/odoo/openerp/http.py", line 803, in __call__
return self.method(*args, **kw)
File "/home/odoo/odoo/openerp/http.py", line 403, in response_wrap
response = f(*args, **kw)
File "/home/odoo/odoo/addons/web/controllers/main.py", line 948, in call_button
action = self._call_kw(model, method, args, {})
File "/home/odoo/odoo/addons/web/controllers/main.py", line 936, in _call_kw
return getattr(request.registry.get(model), method)(request.cr, request.uid, *args, **kwargs)
File "/home/odoo/odoo/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/odoo/odoo/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 "/home/odoo/odoo/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/odoo/odoo/addons/sale/sale.py", line 605, in action_button_confirm
self.signal_workflow(cr, uid, ids, 'order_confirm')
File "/home/odoo/odoo/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/odoo/odoo/openerp/models.py", line 3560, in signal_workflow
result[res_id] = workflow.trg_validate(uid, self._name, res_id, signal, cr)
File "/home/odoo/odoo/openerp/workflow/__init__.py", line 85, in trg_validate
return WorkflowService.new(cr, uid, res_type, res_id).validate(signal)
File "/home/odoo/odoo/openerp/workflow/service.py", line 91, in validate
res2 = wi.validate(signal)
File "/home/odoo/odoo/openerp/workflow/instance.py", line 75, in validate
wi.process(signal=signal, force_running=force_running, stack=stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 120, in process
ok = self._split_test(activity['split_mode'], signal, stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 248, in _split_test
self._join_test(t[0], t[1], stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 257, in _join_test
WorkflowItem.create(self.session, self.record, activity, inst_id, stack=stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 95, in create
workflow_item.process(stack=stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 120, in process
ok = self._split_test(activity['split_mode'], signal, stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 248, in _split_test
self._join_test(t[0], t[1], stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 257, in _join_test
WorkflowItem.create(self.session, self.record, activity, inst_id, stack=stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 95, in create
workflow_item.process(stack=stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 120, in process
ok = self._split_test(activity['split_mode'], signal, stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 248, in _split_test
self._join_test(t[0], t[1], stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 257, in _join_test
WorkflowItem.create(self.session, self.record, activity, inst_id, stack=stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 95, in create
workflow_item.process(stack=stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 116, in process
if not self._execute(activity, stack):
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 162, in _execute
returned_action = self.wkf_expr_execute(activity)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 313, in wkf_expr_execute
return self.wkf_expr_eval_expr(activity['action'])
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 291, in wkf_expr_eval_expr
result = eval(line, env, nocopy=True)
File "/home/odoo/odoo/openerp/tools/safe_eval.py", line 314, in safe_eval
return eval(c, globals_dict, locals_dict)
File "", line 1, in <module>
File "/home/odoo/odoo/openerp/api.py", line 239, in wrapper
return new_api(self, *args, **kwargs)
File "/home/odoo/odoo/openerp/api.py", line 547, in new_api
result = method(self._model, cr, uid, self.ids, *args, **kwargs)
File "/home/odoo/odoo/addons/sale/sale.py", line 765, in action_ship_create
procurement_obj.run(cr, uid, proc_ids, context=context)
File "/home/odoo/odoo/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/odoo/odoo/addons/procurement_jit_stock/procurement_jit_stock.py", line 30, in run
res = super(procurement_order, self).run(cr, uid, ids, autocommit=autocommit, context=context)
File "/home/odoo/odoo/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/odoo/odoo/addons/stock/procurement.py", line 219, in run
self.pool.get('stock.move').action_confirm(cr, uid, move_to_confirm_ids, context=context)
File "/home/odoo/odoo/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/odoo/odoo/addons/stock/stock.py", line 2214, in action_confirm
self._create_procurements(cr, uid, moves, context=context)
File "/home/odoo/odoo/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/odoo/odoo/addons/procurement_jit_stock/procurement_jit_stock.py", line 43, in _create_procurements
self.pool['procurement.order'].run(cr, uid, res, context=context)
File "/home/odoo/odoo/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/odoo/odoo/addons/procurement_jit_stock/procurement_jit_stock.py", line 30, in run
res = super(procurement_order, self).run(cr, uid, ids, autocommit=autocommit, context=context)
File "/home/odoo/odoo/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/odoo/odoo/addons/stock/procurement.py", line 210, in run
res = super(procurement_order, self).run(cr, uid, new_ids, autocommit=autocommit, context=context)
File "/home/odoo/odoo/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/odoo/odoo/addons/procurement/procurement.py", line 206, in run
res = self._run(cr, uid, procurement, context=context or {})
File "/home/odoo/odoo/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/odoo/odoo/addons/purchase/purchase.py", line 1267, in _run
return self.make_po(cr, uid, [procurement.id], context=context)[procurement.id]
File "/home/odoo/odoo/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/odoo/odoo/addons/glints/models/purchase.py", line 154, in make_po
if procurement_order.first_line.procurement_ids and procurement_order.first_line.procurement_ids[0].group_id == current_procurement[0].group_id:
File "/home/odoo/odoo/openerp/fields.py", line 817, in __get__
self.determine_value(record)
File "/home/odoo/odoo/openerp/fields.py", line 910, in determine_value
record._prefetch_field(self)
File "/home/odoo/odoo/openerp/api.py", line 239, in wrapper
return new_api(self, *args, **kwargs)
File "/home/odoo/odoo/openerp/models.py", line 3231, in _prefetch_field
result = records.read(list(fnames), load='_classic_write')
File "/home/odoo/odoo/openerp/api.py", line 239, in wrapper
return new_api(self, *args, **kwargs)
File "/home/odoo/odoo/openerp/models.py", line 3176, in read
self._read_from_database(stored, inherited)
File "/home/odoo/odoo/openerp/api.py", line 239, in wrapper
return new_api(self, *args, **kwargs)
File "/home/odoo/odoo/openerp/models.py", line 3300, in _read_from_database
cr.execute(query_str, [tuple(sub_ids)] + where_params)
File "/home/odoo/odoo/openerp/sql_db.py", line 157, in wrapper
raise psycopg2.OperationalError(msg)
OperationalError: Unable to use a closed cursor.
我认为这是因为您滥用了 Odoo ORM。首先,在 Odoo 中,您永远不会像这样声明 class 级别的属性...
counter = 0
global_po_id = None
line_counter = 0
first_line = None
然后你在这里引用它:
if procurement_order.first_line
问题是 procurement_order 的类型是 osv.osv 但这行代码应该使用浏览记录。当它试图追踪并从它认为是浏览记录的内容中懒惰地加载数据项时,它会到达需要使用游标但没有游标可供使用的地步,因此出现错误。
最好将 osv.osv class 视为只读元数据 class,它在数据库中描述了您的 table,但也让您有一些已定义静态或 class 方法。
您使用的procurement_order应该是浏览的结果
my_procurement_order = self.browse(cr, uid, ids[0], context=context)
下一个问题是您不能在 运行 时将 first_line 之类的值分配给浏览记录,它们是只读的(注意这在 Odoo 8 new API 但那是另一回事了)。
这里的一个常见做法是维护一个类似本地字典的东西,你可以参考:
first_lines = {my_procurement_order.id: a_line}
在对 res.partner
模型进行一些操作后,我在第二次调用 make_po 方法时遇到此异常。如果我停止服务器并重新启动它,操作将继续正确执行以下是我对 make_po 方法和堆栈跟踪的覆盖:
class procurement_order(osv.osv):
_inherit = 'procurement.order'
counter = 0
global_po_id = None
line_counter = 0
first_line = None
def make_po(self, cr, uid, ids, context=None):
_logger = logging.getLogger(__name__)
""" Resolve the purchase from procurement, which may result in a new PO creation, a new PO line creation or a quantity change on existing PO line.
Note that some operations (as the PO creation) are made as SUPERUSER because the current user may not have rights to do it (mto product launched by a sale for example)
@return: dictionary giving for each procurement its related resolving PO line.
OVERRIDE: If we already have a purchase order on a draft state with the same product, do not append the lines.
Instead create a new Purchase Order
"""
company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id
po_obj = self.pool.get('purchase.order')
seq_obj = self.pool.get('ir.sequence')
sales_orders = self.pool.get('sale.order')
po_line = self.pool.get('purchase.order.line')
# Get the procurement ID ("key" == Procurement ID, "value" == PO line)
procurement_purchase_order = super(procurement_order, self).make_po(cr, uid, ids, context=context)
key, value = procurement_purchase_order.popitem()
procurement_purchase_order[key] = value
# Search for the equivalent purchase.order.line
p_o_line_returned_id = po_line.search(cr, uid, [('id', '=', value)])
p_o_line_returned = po_line.browse(cr, uid, p_o_line_returned_id, context=context)
# get purchase order from its line
purchase_order_from_line_ID = po_obj.search(cr, uid, [('id', '=', p_o_line_returned.order_id.id)])
purchase_order_from_line = po_obj.browse(cr, uid, purchase_order_from_line_ID, context=context)
# Get me the current procurement
current_procurement_ID = self.search(cr, uid, [('id', '=', key)])
current_procurement = self.browse(cr, uid, current_procurement_ID, context=context)
# Get me the line ids of the lines that are related to purchase_order_from_line_ID
lines_IDS = po_line.search(cr, uid, [('order_id', '=', purchase_order_from_line_ID[0])])
_logger.warning('lines_IDS' + str(lines_IDS))
# Check the source of all the lines in thelines_IDS
for line in po_line.browse(cr, uid, lines_IDS, context=context):
_logger.warning('First line value ' + str(procurement_order.first_line))
_logger.warning('')
if line.procurement_ids != 0:
if procurement_order.line_counter == 0:
procurement_order.first_line = line
procurement_order.line_counter += 1
# Compare the first line procurement.group_id with the current procurement.group_id
if procurement_order.first_line.procurement_ids and procurement_order.first_line.procurement_ids[0].group_id == current_procurement[0].group_id:
_logger.warning('GROUP IDS ARE EQUAL')
else:
_logger.warning('GROUP IDS ARE NOT EQUAL')
# if we have inequality between the group ids then that means that the current "line" was created by a different SO
to_remove = []
to_remove.append(line.id)
# from the current_procurement.group_id get the PO.line and remove it
temp_group_id = current_procurement[0].group_id.id
_logger.warning(str(temp_group_id))
temp_line_for_removal_ID = po_line.search(cr, uid, [('id', '=', temp_group_id)])
po_line.unlink(cr, uid, temp_line_for_removal_ID, context=context)
_logger.warning('Removed from Purchase Order ' + str(purchase_order_from_line_ID[0]) + ' Lines ' + str(to_remove))
pass_ids = []
# for all the procrements that belong to my SO
# for procurement in self.browse(cr, uid, ids, context=context):
partner = self._get_product_supplier(cr, uid, current_procurement, context=context)
if not partner:
self.message_post(cr, uid, [current_procurement.id], _('There is no supplier associated to product %s') % (current_procurement.product_id.name))
procurement_purchase_order[current_procurement.id] = False
else:
schedule_date = self._get_purchase_schedule_date(cr, uid, current_procurement, company, context=context)
purchase_date = self._get_purchase_order_date(cr, uid, current_procurement, company, schedule_date, context=context)
line_vals = self._get_po_line_values_from_proc(cr, uid, current_procurement, partner, company, schedule_date, context=context) # get the lines from here
name = seq_obj.get(cr, uid, 'purchase.order') or _('PO: %s') % current_procurement.name
po_vals = {
'name': name,
'origin': current_procurement.origin,
'partner_id': partner.id,
'location_id': current_procurement.location_id.id,
'picking_type_id': current_procurement.rule_id.picking_type_id.id,
'pricelist_id': partner.property_product_pricelist_purchase.id,
'currency_id': partner.property_product_pricelist_purchase and partner.property_product_pricelist_purchase.currency_id.id or current_procurement.company_id.currency_id.id,
'date_order': purchase_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
'company_id': current_procurement.company_id.id,
'fiscal_position': po_obj.onchange_partner_id(cr, uid, None, partner.id, context=context)['value']['fiscal_position'],
'payment_term_id': partner.property_supplier_payment_term.id or False,
'dest_address_id': current_procurement.partner_dest_id.id,
}
# The first time create the PO and add a line to it
if procurement_order.counter == 0:
po_id = self.create_procurement_purchase_order(cr, uid, current_procurement, po_vals, line_vals, context=context)
procurement_order.global_po_id = po_id
po_line_id = po_obj.browse(cr, uid, po_id, context=context).order_line[0].id
pass_ids.append(current_procurement.id)
procurement_purchase_order[current_procurement.id] = po_line_id
self.write(cr, uid, [current_procurement.id], {'purchase_line_id': po_line_id}, context=context)
_logger.warning('New Purchase order created ' + str(po_id))
else:
# All the other lines from the procurements will be appended here
proc_order = self.pool.get('procurement.order')
purchase_order_created = po_obj.browse(cr, uid, procurement_order.global_po_id, context=context) # get the Purchase Order
line_vals = proc_order._get_po_line_values_from_proc(cr, uid, current_procurement, partner, company, schedule_date, context=context) # Get the line from the procurement
po_line_obj = self.pool.get('purchase.order.line')
line_vals['order_id'] = purchase_order_created[0].id
# if there exists a line with the same id, do not add it
if len(po_line_obj.search(cr, uid, [('order_id', '=', purchase_order_created[0].id)])) == 0:
po_line_id = po_line_obj.create(cr, uid, line_vals, context=context)
_logger.warning('Appending line ' + str(line_vals) + 'to existing Purchase order ' + str(purchase_order_created))
else:
_logger.warning('Line has already been appended, dismissed')
if pass_ids:
self.message_post(cr, uid, pass_ids, body=_("Draft Purchase Order created"), context=context)
procurement_order.counter += 1
self.pool.get('purchase.order.line').split_lines(cr, uid, [procurement_purchase_order[ids[0]]], context=context)
return procurement_purchase_order
堆栈跟踪:
2015-09-10 13:15:11,752 1167 ERROR odoov8 openerp.http: Exception during JSON request handling.
Traceback (most recent call last):
File "/home/odoo/odoo/openerp/http.py", line 537, in _handle_exception
return super(JsonRequest, self)._handle_exception(exception)
File "/home/odoo/odoo/openerp/http.py", line 574, in dispatch
result = self._call_function(**self.params)
File "/home/odoo/odoo/openerp/http.py", line 310, in _call_function
return checked_call(self.db, *args, **kwargs)
File "/home/odoo/odoo/openerp/service/model.py", line 113, in wrapper
return f(dbname, *args, **kwargs)
File "/home/odoo/odoo/openerp/http.py", line 307, in checked_call
return self.endpoint(*a, **kw)
File "/home/odoo/odoo/openerp/http.py", line 803, in __call__
return self.method(*args, **kw)
File "/home/odoo/odoo/openerp/http.py", line 403, in response_wrap
response = f(*args, **kw)
File "/home/odoo/odoo/addons/web/controllers/main.py", line 948, in call_button
action = self._call_kw(model, method, args, {})
File "/home/odoo/odoo/addons/web/controllers/main.py", line 936, in _call_kw
return getattr(request.registry.get(model), method)(request.cr, request.uid, *args, **kwargs)
File "/home/odoo/odoo/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/odoo/odoo/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 "/home/odoo/odoo/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/odoo/odoo/addons/sale/sale.py", line 605, in action_button_confirm
self.signal_workflow(cr, uid, ids, 'order_confirm')
File "/home/odoo/odoo/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/odoo/odoo/openerp/models.py", line 3560, in signal_workflow
result[res_id] = workflow.trg_validate(uid, self._name, res_id, signal, cr)
File "/home/odoo/odoo/openerp/workflow/__init__.py", line 85, in trg_validate
return WorkflowService.new(cr, uid, res_type, res_id).validate(signal)
File "/home/odoo/odoo/openerp/workflow/service.py", line 91, in validate
res2 = wi.validate(signal)
File "/home/odoo/odoo/openerp/workflow/instance.py", line 75, in validate
wi.process(signal=signal, force_running=force_running, stack=stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 120, in process
ok = self._split_test(activity['split_mode'], signal, stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 248, in _split_test
self._join_test(t[0], t[1], stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 257, in _join_test
WorkflowItem.create(self.session, self.record, activity, inst_id, stack=stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 95, in create
workflow_item.process(stack=stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 120, in process
ok = self._split_test(activity['split_mode'], signal, stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 248, in _split_test
self._join_test(t[0], t[1], stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 257, in _join_test
WorkflowItem.create(self.session, self.record, activity, inst_id, stack=stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 95, in create
workflow_item.process(stack=stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 120, in process
ok = self._split_test(activity['split_mode'], signal, stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 248, in _split_test
self._join_test(t[0], t[1], stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 257, in _join_test
WorkflowItem.create(self.session, self.record, activity, inst_id, stack=stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 95, in create
workflow_item.process(stack=stack)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 116, in process
if not self._execute(activity, stack):
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 162, in _execute
returned_action = self.wkf_expr_execute(activity)
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 313, in wkf_expr_execute
return self.wkf_expr_eval_expr(activity['action'])
File "/home/odoo/odoo/openerp/workflow/workitem.py", line 291, in wkf_expr_eval_expr
result = eval(line, env, nocopy=True)
File "/home/odoo/odoo/openerp/tools/safe_eval.py", line 314, in safe_eval
return eval(c, globals_dict, locals_dict)
File "", line 1, in <module>
File "/home/odoo/odoo/openerp/api.py", line 239, in wrapper
return new_api(self, *args, **kwargs)
File "/home/odoo/odoo/openerp/api.py", line 547, in new_api
result = method(self._model, cr, uid, self.ids, *args, **kwargs)
File "/home/odoo/odoo/addons/sale/sale.py", line 765, in action_ship_create
procurement_obj.run(cr, uid, proc_ids, context=context)
File "/home/odoo/odoo/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/odoo/odoo/addons/procurement_jit_stock/procurement_jit_stock.py", line 30, in run
res = super(procurement_order, self).run(cr, uid, ids, autocommit=autocommit, context=context)
File "/home/odoo/odoo/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/odoo/odoo/addons/stock/procurement.py", line 219, in run
self.pool.get('stock.move').action_confirm(cr, uid, move_to_confirm_ids, context=context)
File "/home/odoo/odoo/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/odoo/odoo/addons/stock/stock.py", line 2214, in action_confirm
self._create_procurements(cr, uid, moves, context=context)
File "/home/odoo/odoo/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/odoo/odoo/addons/procurement_jit_stock/procurement_jit_stock.py", line 43, in _create_procurements
self.pool['procurement.order'].run(cr, uid, res, context=context)
File "/home/odoo/odoo/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/odoo/odoo/addons/procurement_jit_stock/procurement_jit_stock.py", line 30, in run
res = super(procurement_order, self).run(cr, uid, ids, autocommit=autocommit, context=context)
File "/home/odoo/odoo/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/odoo/odoo/addons/stock/procurement.py", line 210, in run
res = super(procurement_order, self).run(cr, uid, new_ids, autocommit=autocommit, context=context)
File "/home/odoo/odoo/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/odoo/odoo/addons/procurement/procurement.py", line 206, in run
res = self._run(cr, uid, procurement, context=context or {})
File "/home/odoo/odoo/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/odoo/odoo/addons/purchase/purchase.py", line 1267, in _run
return self.make_po(cr, uid, [procurement.id], context=context)[procurement.id]
File "/home/odoo/odoo/openerp/api.py", line 241, in wrapper
return old_api(self, *args, **kwargs)
File "/home/odoo/odoo/addons/glints/models/purchase.py", line 154, in make_po
if procurement_order.first_line.procurement_ids and procurement_order.first_line.procurement_ids[0].group_id == current_procurement[0].group_id:
File "/home/odoo/odoo/openerp/fields.py", line 817, in __get__
self.determine_value(record)
File "/home/odoo/odoo/openerp/fields.py", line 910, in determine_value
record._prefetch_field(self)
File "/home/odoo/odoo/openerp/api.py", line 239, in wrapper
return new_api(self, *args, **kwargs)
File "/home/odoo/odoo/openerp/models.py", line 3231, in _prefetch_field
result = records.read(list(fnames), load='_classic_write')
File "/home/odoo/odoo/openerp/api.py", line 239, in wrapper
return new_api(self, *args, **kwargs)
File "/home/odoo/odoo/openerp/models.py", line 3176, in read
self._read_from_database(stored, inherited)
File "/home/odoo/odoo/openerp/api.py", line 239, in wrapper
return new_api(self, *args, **kwargs)
File "/home/odoo/odoo/openerp/models.py", line 3300, in _read_from_database
cr.execute(query_str, [tuple(sub_ids)] + where_params)
File "/home/odoo/odoo/openerp/sql_db.py", line 157, in wrapper
raise psycopg2.OperationalError(msg)
OperationalError: Unable to use a closed cursor.
我认为这是因为您滥用了 Odoo ORM。首先,在 Odoo 中,您永远不会像这样声明 class 级别的属性...
counter = 0
global_po_id = None
line_counter = 0
first_line = None
然后你在这里引用它:
if procurement_order.first_line
问题是 procurement_order 的类型是 osv.osv 但这行代码应该使用浏览记录。当它试图追踪并从它认为是浏览记录的内容中懒惰地加载数据项时,它会到达需要使用游标但没有游标可供使用的地步,因此出现错误。
最好将 osv.osv class 视为只读元数据 class,它在数据库中描述了您的 table,但也让您有一些已定义静态或 class 方法。
您使用的procurement_order应该是浏览的结果
my_procurement_order = self.browse(cr, uid, ids[0], context=context)
下一个问题是您不能在 运行 时将 first_line 之类的值分配给浏览记录,它们是只读的(注意这在 Odoo 8 new API 但那是另一回事了)。
这里的一个常见做法是维护一个类似本地字典的东西,你可以参考:
first_lines = {my_procurement_order.id: a_line}