Impacted versions: 10.0

Steps to reproduce: Create Sale Order (line in step 1 product qty = 100, in step 2 line product qty = 1000) with two or more purchase procurements  and Cancel it.

Current behavior:

Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/odoo/http.py", line 640, in _handle_exception
    return super(JsonRequest, self)._handle_exception(exception)
  File "/usr/lib/python2.7/dist-packages/odoo/http.py", line 677, in dispatch
    result = self._call_function(**self.params)
  File "/usr/lib/python2.7/dist-packages/odoo/http.py", line 333, in _call_function
    return checked_call(self.db, *args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/odoo/service/model.py", line 101, in wrapper
    return f(dbname, *args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/odoo/http.py", line 326, in checked_call
    result = self.endpoint(*a, **kw)
  File "/usr/lib/python2.7/dist-packages/odoo/http.py", line 935, in __call__
    return self.method(*args, **kw)
  File "/usr/lib/python2.7/dist-packages/odoo/http.py", line 506, in response_wrap
    response = f(*args, **kw)
  File "/usr/lib/python2.7/dist-packages/odoo/addons/web/controllers/main.py", line 889, in call_button
    action = self._call_kw(model, method, args, {})
  File "/usr/lib/python2.7/dist-packages/odoo/addons/web/controllers/main.py", line 877, in _call_kw
    return call_kw(request.env[model], method, args, kwargs)
  File "/usr/lib/python2.7/dist-packages/odoo/api.py", line 689, in call_kw
    return call_kw_multi(method, model, args, kwargs)
  File "/usr/lib/python2.7/dist-packages/odoo/api.py", line 680, in call_kw_multi
    result = method(recs, *args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/odoo/addons/sale_stock/models/sale_order.py", line 66, in action_cancel
    self.mapped('order_line').mapped('procurement_ids').cancel()
  File "/usr/lib/python2.7/dist-packages/odoo/addons/stock/models/procurement.py", line 85, in cancel
    propagated_procurements = self.filtered(lambda order: order.state != 'done').propagate_cancels()
  File "/usr/lib/python2.7/dist-packages/odoo/addons/purchase/models/purchase.py", line 898, in propagate_cancels
    price_unit = self.env['account.tax']._fix_tax_included_price_company(seller.price, procurement.purchase_line_id.product_id.supplier_taxes_id, procurement.purchase_line_id.taxes_id, self.company_id) if seller else 0.0
  File "/usr/lib/python2.7/dist-packages/odoo/fields.py", line 904, in __get__
    record.ensure_one()
  File "/usr/lib/python2.7/dist-packages/odoo/models.py", line 4823, in ensure_one
    raise ValueError("Expected singleton: %s" % self)
ValueError: Expected singleton: procurement.order(37, 38)

Expected behavior:

Order Canceled

Comment:

Error exist in line:

 price_unit = self.env['account.tax']._fix_tax_included_price_company(seller.price, procurement.purchase_line_id.product_id.supplier_taxes_id, procurement.purchase_line_id.taxes_id, self.company_id) if seller else 0.0

the problem is with value: self.company_id

should be: procurement.company_id





msg = _("Extra line with %s ") % (line.product_id.display_name,)
            line.order_id.message_post(body=msg)
        return line
    @api.multi
    def write(self, values):
        orders = False
        if 'product_qty' in values:
            changed_lines = self.filtered(lambda x: x.order_id.state == 'purchase')
            if changed_lines:
                orders = changed_lines.mapped('order_id')
                for order in orders:
                    order_lines = changed_lines.filtered(lambda x: x.order_id == order)
                    msg = ""
                    if any([values['product_qty'] < x.product_qty for x in order_lines]):
                        msg += "<b>" + _('The ordered quantity has been decreased. Do not forget to take it into account on your bills and receipts.') + '</b><br/>'
                    msg += "<ul>"
                    for line in order_lines:
                        msg += "<li> %s:" % (line.product_id.display_name,)
                        msg += "<br/>" + _("Ordered Quantity") + ": %s -> %s <br/>" % (line.product_qty, float(values['product_qty']),)
                        if line.product_id.type in ('product', 'consu'):
                            msg += _("Received Quantity") + ": %s <br/>" % (line.qty_received,)
                        msg += _("Billed Quantity") + ": %s <br/></li>" % (line.qty_invoiced,)
                    msg += "</ul>"
                    order.message_post(body=msg)
        
        if 'date_planned' in values:
            self.env['stock.move'].search([
                ('purchase_line_id', 'in', self.ids), ('state', '!=', 'done')
            ]).write({'date_expected': values['date_planned']})
        result = super(PurchaseOrderLine, self).write(values)