Magento – Magento 2 fieldset.xml; copy fields from quote to order

fieldsetsmagento2

I have created a custom model to create order from quote;
I am using fieldset.xml to copy quote custom codes to order. I have created custom columns in both quote and order with matching fields. When order is placed values are storing in quote custom fields but not copying to order. Below is my fieldset.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="urn:magento:framework:DataObject/etc/fieldset.xsd">
<scope id="global">
    <!--quote convert to order-->
    <fieldset id="sales_convert_quote">            
        <field name="preorder_number">
            <aspect name="to_order" />
        </field>
        <field name="purchase_order_number">
            <aspect name="to_order" />
        </field>
        <field name="reference_number">
            <aspect name="to_order" />
        </field>
    </fieldset>
    <!--quote item convert to order item-->
    <fieldset id="quote_convert_item">
        <field name="preorder_number">
            <aspect name="to_order_item" />
        </field>
        <field name="purchase_order_number">
            <aspect name="to_order_item" />
        </field>
        <field name="reference_number">
            <aspect name="to_order_item" />
        </field>
    </fieldset>
</scope>

What else I need to do?

Best Answer

If you take a look at the current magento2.1 code base you will notice that in moduleName/etc folder there is a fieldset.xml with command to copy information from one table to another. However this DO NOT work. If you take a closer look you will also notice that there is observer that does the same exact thing. Take a look at https://github.com/magento/magento2/issues/5823

To copy from quote* to order* table you will need to use an observer and/or plugin.

In your custom Module events.xml add

 <event name="sales_model_service_quote_submit_before">
    <observer name="[moduelname]_sales_model_service_quote_submit_before" instance="Company\ModuleName\Observer\SaveOrderBeforeSalesModelQuoteObserver" />
</event>

Then

<?php

namespace Company\ModuleName\Observer;

use Magento\Framework\Event\ObserverInterface;

class SaveOrderBeforeSalesModelQuoteObserver implements ObserverInterface
{

    /**
     * List of attributes that should be added to an order.
     *
     * @var array
     */
    private $attributes = [
        'field_1_name_here',
        'field_2_name_here',
        'field_...._here'
    ];


    /**

     *
     * @param \Magento\Framework\Event\Observer $observer
     * @return $this
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        /* @var Magento\Sales\Model\Order $order */
        $order = $observer->getEvent()->getData('order');
        /* @var Magento\Quote\Model\Quote $quote */
        $quote = $observer->getEvent()->getData('quote');

        foreach ($this->attributes as $attribute) {
            if ($quote->hasData($attribute)) {
                $order->setData($attribute, $quote->getData($attribute));
            }
        }

        return $this;
    }
}

To copy item from quote_item to order_item, magento seem to have removed the best observer to get the job which was sales_convert_quote_item_to_order_item. Take a look at this example that should help you copy field from quote_item to order_item table. How to "add to cart" a product with custom input field and save it to Database?