2015-09-10 2 views
1

После некоторых операций над моделью res.partner я получаю это исключение во второй раз, когда вызывается метод make_po. Если я остановить сервер и перезапустить его, операция продолжается правильно следующий мой переопределение метода make_po и StackTrace:Невозможно использовать закрытый курсор

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 

StackTrace:

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. 

ответ

2

Я предполагаю, что это потому, что вы злоупотребляя Odoo ORM. Во-первых, в Odoo вы никогда не объявлять свойства на уровне класса, как это ...

counter = 0 
global_po_id = None 
line_counter = 0 
first_line = None 

И тогда вы обращаетесь к нему здесь:

if procurement_order.first_line 

Проблема заключается в том procurement_order имеет тип osv.osv, но эта линия код должен использовать запись обзора. Поскольку он пытается следить за трейлом и лениво загружать элементы данных из того, что, по его мнению, является записью обзора, он достигает точки, когда ему нужно использовать курсор, и у него его нет, следовательно, ошибка.

Лучше всего думать о классе osv.osv как мета-классе только для чтения, который описывает вашу таблицу в базе данных, но также позволяет вам определять некоторые статические или классные методы.

Приобретение_обслуживания должно быть результатом просмотра.

my_procurement_order = self.browse(cr, uid, ids[0], context=context) 

Следующая проблема, вы не можете присвоить значения как first_line к записи обзора во время выполнения, они предназначены только для чтения (NB это изменения в Odoo 8 новых API, но это другая история).

Обычной практикой здесь является сохранение что-то вроде локального словаря, который Вы можете обратиться:

first_lines = {my_procurement_order.id: a_line}

Смежные вопросы