0

I have followed this:

https://www.siphor.com/adding-custom-attributes-to-magento-2-quotes-and-orders/

It works well when creating custom attributes and adding data quote but after checkout, quote is not saved in table sales_orders_item.

Please help me ! I have been thinking a lot but the problem is still not resolved.

Thanks very much

  • Can you confirm in which table (quote or quote-item) you want to save custom attribute? – Pritam Info 24 Jun 4 at 14:50
  • yes, i can. data saved in table quote and quote-item but not save in table sales_orders_item after checkout success – TN98 Jun 5 at 2:11
2

You can follow the steps below to save the quote-item custom field to sales_orders_item custom fields

** Note:**

1) Assume custom field data is successfully saved in quote_item table. So the steps only describe how to save quote-item custom field value to sales_orders_item

2) Assume your custom filed name is my_custom_attribute in both quote_item and sales_orders_item table

2) Assume you are using a custom module names "Company_MyModule"

step 1)

Create a di.xml under MAGENTO-ROOT/app/code/Company/MyModule/etc/di.xml

File: MAGENTO-ROOT/app/code/Company/MyModule/etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Quote\Model\Quote\Item\ToOrderItem">
        <plugin name="company_mymodule\Sales_Quote_Item_ToOrderItem" type="Company\MyModule\Plugin\QuoteItemToOrderItemPlugin" />
    </type>    
</config>

step 2)

Create the plugin class QuoteItemToOrderItemPlugin.php under MAGENTO-ROOT/app/code/Company/MyModule/Plugin

File: MAGENTO-ROOT/app/code/Company/MyModule/Plugin/QuoteItemToOrderItemPlugin.php

<?php

namespace Company\MyModule\Plugin;

use Magento\Framework\Serialize\SerializerInterface;


class QuoteItemToOrderItemPlugin
{



    public function aroundConvert(\Magento\Quote\Model\Quote\Item\ToOrderItem $subject, callable $proceed, $quoteItem, $data)
    {

        // get order item
        $orderItem = $proceed($quoteItem, $data);

        // get your custom attribute from quote_item . 
        $quoteItemMycustomAttribValue = $quoteItem->getMyCustomAttribite();

        //set custom attribute to sales_order_item
        $orderItem->setMyCustomAttribite($quoteItemMycustomAttribValue);

        return $orderItem;
    }
}

step 3)

Run Di compile commands

php bin/magento setup:di:compile
0

app/code/Vendor/Module/etc/catalog_attributes.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Catalog:etc/catalog_attributes.xsd">
    <group name="quote_item">
        <attribute name="custom_attribute"/>
    </group>
</config>

app/code/Vendor/Module/Setup/InstallData.php

<?php
namespace [Vendor]\[Module]\Setup;

use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\DB\Ddl\Table;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Sales\Setup\SalesSetupFactory;
use Magento\Quote\Setup\QuoteSetupFactory;

/**
 * @codeCoverageIgnore
 */
class InstallData implements InstallDataInterface
{
    /**
     * EAV setup factory
     *
     * @var EavSetupFactory
     */
    private $eavSetupFactory;

    /**
     * @var QuoteSetupFactory
     */
    private $quoteSetupFactory;

    /**
     * @var SalesSetup
     */
    private $salesSetupFactory;

    /**
     * InstallData constructor.
     * @param EavSetupFactory $eavSetupFactory
     * @param QuoteSetupFactory $quoteSetupFactory
     */
    public function __construct(
        EavSetupFactory $eavSetupFactory,
        QuoteSetupFactory $quoteSetupFactory,
        SalesSetupFactory $salesSetupFactory
    )
    {
        $this->eavSetupFactory = $eavSetupFactory;
        $this->quoteSetupFactory = $quoteSetupFactory;
        $this->salesSetupFactory = $salesSetupFactory;
    }

    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        /** @var EavSetup $eavSetup */
        $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);

        /** @var QuoteSetup $quoteSetup */
        $quoteSetup = $this->quoteSetupFactory->create(['setup' => $setup]);

        /** @var SalesSetup $salesSetup */
        $salesSetup = $this->salesSetupFactory->create(['setup' => $setup]);

        /**
         * Add attributes to the eav/attribute
         */
        $eavSetup->addAttribute(
            \Magento\Catalog\Model\Product::ENTITY,
            'custom_attribute',
            [
                'type'                    => 'int',
                'label'                   => 'Custom Attribute',
                'input'                   => 'select',
                'global'                  => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL,
                'visible'                 => true,
                'required'                => false,
                'user_defined'            => true,
                'default'                 => '',
                'searchable'              => false,
                'filterable'              => false,
                'comparable'              => false,
                'visible_on_front'        => false,
                'used_in_product_listing' => false,
                'unique'                  => false,
                'option'                  => [
                    'values' => [
                        'Option 1',
                        'Option 2',
                        'Option 3'
                    ],
                ]
            ]
        );

        $attributeSetId = $eavSetup->getDefaultAttributeSetId('catalog_product');
        $eavSetup->addAttributeToSet(
            'catalog_product',
            $attributeSetId,
            'General',
            'custom_attribute'
        );

        $attributeOptions = [
            'type'     => Table::TYPE_TEXT,
            'visible'  => true,
            'required' => false
        ];
        $quoteSetup->addAttribute('quote_item', 'custom_attribute', $attributeOptions);
        $salesSetup->addAttribute('order_item', 'custom_attribute', $attributeOptions);
    }
}

app/code/Vendor/Module/etc/events.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="sales_quote_item_set_product">
        <observer name="set_item_custom_attribute" instance="[Vendor]\[Module]\Observer\SetItemCustomAttribute" />
    </event>
</config>

app/code/Vendor/Module/Observer/SetItemCustomAttribute.php

<?php
namespace [Vendor]\[Module]\Observer;

use Magento\Framework\Event\ObserverInterface;

class SetItemCustomAttribute implements ObserverInterface
{
    /**
     * @param \Magento\Framework\Event\Observer $observer
     * @return void
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $quoteItem = $observer->getQuoteItem();
        $product = $observer->getProduct();
        $quoteItem->setCustomAttribute($product->getAttributeText('custom_attribute'));
    }
}

app/code/Vendor/Module/etc/fieldset.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="lib/internal/Magento/Framework/Object/etc/fieldset.xsd">
    <scope id="global">
        <fieldset id="quote_convert_item">
            <field name="custom_attribute">
                <aspect name="to_order_item" />
            </field>
        </fieldset>
    </scope>
</config>

app/code/Vendor/Module/etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Quote\Model\Quote\Item\ToOrderItem">
        <plugin name="custom_attribute_quote_to_order_item" type="[Vendor]\[Module]\Plugin\CustomAttributeQuoteToOrderItem"/>
    </type>
</config>

app/code/Vendor/Module/Plugin/CustomAttributeQuoteToOrderItem.php

<?php
namespace [Vendor]\[Module]\Plugin;

class CustomAttributeQuoteToOrderItem
{
    public function aroundConvert(
        \Magento\Quote\Model\Quote\Item\ToOrderItem $subject,
        \Closure $proceed,
        \Magento\Quote\Model\Quote\Item\AbstractItem $item,
        $additional = []
    ) {
        /** @var $orderItem \Magento\Sales\Model\Order\Item */
        $orderItem = $proceed($item, $additional);
        $orderItem->setCustomAttribute($item->getCustomAttribute());
        return $orderItem;
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.