3

I'trying to set custom attribute to quote item by method setCustomAttribute from Magento\Quote\Model\Quote\Item. Below is my code

events.xml

<?xml version="1.0" encoding="UTF-8"?>
<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="product_point_quote" instance="Vendor\Producer\Model\Observer\Sales\Quote\Item\SetCustomAttribute"/>
    </event>
</config>

SetCustomAttribute.php

<?php
namespace Vendor\Producer\Model\Observer\Sales\Quote\Item;

use Magento\Framework\Event\ObserverInterface;


class SetCustomAttribute implements ObserverInterface
{

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $product = $observer->getProduct();
        $quoteItem = $observer->getQuoteItem();
        $quoteItem->setCustomAttribute('producer', $product->getProducer());
    }
}

But it doesn't work. Below is code of setCustomAttribute from Magento\Quote\Model\Quote\Item

public function setCustomAttribute($attributeCode, $attributeValue)
{
    $customAttributesCodes = $this->getCustomAttributesCodes();
    /* If key corresponds to custom attribute code, populate custom attributes */
    if (in_array($attributeCode, $customAttributesCodes)) {
        $attribute = $this->customAttributeFactory->create();
        $attribute->setAttributeCode($attributeCode)
            ->setValue($attributeValue);
        $this->_data[self::CUSTOM_ATTRIBUTES][$attributeCode] = $attribute;
    }
    return $this;
}

It doesn't work because the method getCustomAttributesCodes() returns an empty array. The question is how to use method setCustomAttribute() in the proper way? How to populate array with custom attributes codes from getCustomAttributesCodes()?

3

I'm not entirely sure what version you are using, but looking at the current version of Magento\Quote\Model\Quote\Item there is no function setCustomAttribute. https://github.com/magento/magento2/blob/develop/app/code/Magento/Quote/Model/Quote/Item.php

I've done this in the past by adding an additional column to the quote item table for my custom data.

First add the column to you the quote item table and and any additional tables you'll want the field mapped to upon conversion. The example below assigns data to the quote item and transfers it to the sales order item upon conversion.

Setup/InstallSchema.php

<?php

namespace Vendor\Module\Setup;

use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\DB\Ddl\Table;

class InstallSchema implements InstallSchemaInterface
{
  public function install(SchemaSetupInterface $setup, ModuleContextInterface $context) {
    $setup->startSetup();

    $setup->getConnection()->addColumn(
      $setup->getTable('sales_order_item'),
      'producer',
      [
        'type' => Table::TYPE_TEXT,
        'comment' => 'Producer'
      ]
    );

    $setup->getConnection()->addColumn(
      $setup->getTable('quote_item'),
      'producer',
      [
        'type' => Table::TYPE_TEXT,
        'comment' => 'Producer'
      ]
    );

    $setup->endSetup();
  }
}

SetCustomAttribute.php needs a minor modification to set the producer property

<?php
namespace Vendor\Producer\Model\Observer\Sales\Quote\Item;

use Magento\Framework\Event\ObserverInterface;


class SetCustomAttribute implements ObserverInterface
{

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $product = $observer->getProduct();
        $quoteItem = $observer->getQuoteItem();
        $quoteItem->setProducer($product->getProducer());
    }
}

There is a bug, https://github.com/magento/magento2/issues/5823, that prevents custom fields from mapping properly on quote conversion. When this is resolved you can use fieldset.xml for moving the field data upon conversion like this:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:noNamespaceSchemaLocation="urn:magento:framework:DataObject/etc/fieldset.xsd">
    <scope id="global">
        <fieldset id="quote_convert_item">
            <field name="producer">
                <aspect name="to_order_item" />
            </field>
        </fieldset>
    </scope>
</config>

To workaround the bug I used a plugin.
etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
  <type name="Magento\Quote\Model\Quote\Item\ToOrderItem">
    <plugin name="vendor_producer_quote_to_order_item" type="Vendor\Producer\Plugin\Quote\QuoteToOrderItem"/>
  </type>
</config>

Plugin/Quote/QuoteToOrderItem.php

<?php

namespace Vendor\Producer\Plugin\Quote;

class QuoteToOrderItem
{
  public function aroundConvert(
    \Magento\Quote\Model\Quote\Item\ToOrderItem $subject,
    $proceed,
    \Magento\Quote\Model\Quote\Item\AbstractItem $item,
    $additional = []
  ) {
    $orderItem = $proceed($item, $additional);
    $orderItem->setProducer($item->getProducer());

    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.