Description
Preconditions
- Magento 2.2.6
- Multiple address checkout enabled
- quote_item.item_id and quote_address_item.address_item_id auto increments are different. (If they are the same, the values are correct on order placement due to sheer luck)
Steps to reproduce
- Add an item to cart, log in (or create an account), and proceed to multiple address checkout.
- Complete all steps of checkout and place order
Expected result
- All resulting order_item records in the database have a quote_item_id value that matches the item_id value of the original quote_item record. In other words, the order_item should point at the quote_item.
Actual result
- All resulting order_item records in the database have a quote_item_id value that matches the address_item_id value of the original quote_address_item record. In other words, the order item points at the quote_address_item instead of the quote_item.
Additional Information
Magento\Multishipping\Model\Checkout\Type\Multishipping::_prepareOrder calls \Magento\Quote\Model\Quote\Item\ToOrderItem::convert for each quote address item. The convert method relies on mapping from fieldset.xml to determine which values to copy from the quote item. This is the relevant id field:
<fieldset id="quote_convert_item"> ... <field name="id"> <aspect name="to_order_item" targetField="quote_item_id" /> </field>
Because the field name is "id", the object copy service (utilized in the convert method) calls getId() on $item. This is fine during a regular checkout when $item is an instance of quote item, but it's a problem during multiple address checkout when $item is an instance of quote address item. In that case, it returns the primary key from the quote_address_item table instead of the quote_item table, and ultimately produces an order item where quote_item_id points at the quote address item id. That will mean one of the following:
- The referenced quote_item record will be from an unrelated quote.
- The referenced quote_item record will not exist.
- The referenced quote_item record will be correct by sheer luck because the quote_item and quote_item_address auto increments happened to be the same during the checkout process. This is unlikely with anything other than a fresh Magento installation.
The solution would be to handle quote address item instances differently and ensure that the quote_address_item.quote_item_id is mapped to sales_order_item.quote_item_id.