cancel
Showing results for 
Search instead for 
Did you mean: 

Add product custom attribute to order export

Add product custom attribute to order export

Hi,

 

How can I add custom attribute (lets say its called 'dimensions') of each product in order, to order export?

 

Im relatively new to magento, and have no clue on how to do this.

 

Any help is more than appreciated,

Have a nice day

2 REPLIES 2

Re: Add product custom attribute to order export

Hi @blaz_p 

 

You can use plugin to add custom attribute to sales_order_item when order is placed. create a di.xml on under etc/di.xml.

 

<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='AddOrderItemPlugin' type='Vendorname\Module\Plugin\Model\Quote\Item\ToOrderItem' sortOrder='10'/>
    </type>
</config>

Then add below code in your plugin.php

 

<?php 
namespace Vendorname\Modulename\Plugin\Model\Quote\Item;

    class ToOrderItem {

        /**
         *
         * @var type \Magento\Catalog\Model\Product
         */
        protected $productRepository;

        /**
         * @param \Magento\Catalog\Model\Product $productRepository 
         */
        public function __construct(
        \Magento\Catalog\Model\Product $productRepository 
        ) {
            $this->productRepository = $productRepository;
        }

        /**
         * 
         * @param \Magento\Quote\Model\Quote\Item\ToOrderItem $subject
         * @param \Vendorname\Modulename\Plugin\Model\Quote\Item\callable $proceed
         * @param \Magento\Quote\Model\Quote\Item\AbstractItem $item
         * @param type $additional
         * @return type
         */
        public function aroundConvert(
        \Magento\Quote\Model\Quote\Item\ToOrderItem $subject, callable $proceed, \Magento\Quote\Model\Quote\Item\AbstractItem $item, $additional = []
        ) {

            $orderItem = $proceed($item, $additional);
            $productId = $item->getProduct()->getId();
            $product = $this->productRepository->load($productId);
            $dimensionsValue = $product->getDimensions();//your custom product attribute(dimensions)
            $orderItem->setDimensions($dimensionsValue);//saving into ordr item in `dimensions` column
            return $orderItem;
        }

    }

It will store your data in to the order so after that you will require to fetch that data into the order grid , so that you can able to export the extra attribute with order !

 

Fore more details refer this link - https://www.siphor.com/adding-custom-attributes-to-magento-2-quotes-and-orders/

 

Hope it helps !

if issue solved,Click Kudos & Accept as Solution

Re: Add product custom attribute to order export

To achecive this you have toModify or override :-
 
Mage230/vendor/magento/module-ui/Model/Export/MetadataProvider
File of Core Magento in the following way 

enter code here namespace Magento\Ui\Model\Export;

use Emipro\AdminSalesOrderGrid\Ui\Component\Listing\Column\Attribute;
use Magento\Framework\Api\Search\DocumentInterface;
use Magento\Framework\Locale\ResolverInterface;
use Magento\Framework\Stdlib\DateTime\TimezoneInterface;
use Magento\Framework\View\Element\UiComponentInterface;
use Magento\Sales\Api\Data\OrderInterface;
use Magento\Ui\Component\Filters;
use Magento\Ui\Component\Filters\Type\Select;
use Magento\Ui\Component\Listing\Columns;
use Magento\Ui\Component\MassAction\Filter;

/** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class MetadataProvider { /** * @var Filter */ protected $filter;

/**
 * @var array
 */
protected $columns;

/**
 * @var TimezoneInterface
 */
protected $localeDate;

/**
 * @var string
 */
protected $locale;

/**
 * @var string
 */
protected $dateFormat;

/**
 * @var array
 */
protected $data;

/**
 * @param Filter $filter
 * @param TimezoneInterface $localeDate
 * @param ResolverInterface $localeResolver
 * @param string $dateFormat
 * @param array $data
 */
public function __construct(    Filter $filter,
    TimezoneInterface $localeDate,
    ResolverInterface $localeResolver,
    OrderInterface $order,
    Attribute $attribute,
    $dateFormat = 'M j, Y h:i:s A',
    array $data = []) {
    $this->attribute = $attribute;
    $this->filter = $filter;
    $this->order = $order;
    $this->localeDate = $localeDate;
    $this->locale = $localeResolver->getLocale();
    $this->dateFormat = $dateFormat;
    $this->data = $data;
}

/**
 * Returns Columns component
 *
 * @param UiComponentInterface $component
 * @return UiComponentInterface
 * @throws \Exception
 */
protected function getColumnsComponent(UiComponentInterface $component) {
    foreach ($component->getChildComponents() as $childComponent) {
        if ($childComponent instanceof Columns) {
            return $childComponent;
        }
    }
    throw new \Exception('No columns found');
}

/**
 * Returns columns list
 *
 * @param UiComponentInterface $component
 * @return UiComponentInterface[]
 */
protected function getColumns(UiComponentInterface $component) {
    if (!isset($this->columns[$component->getName()])) {
        $columns = $this->getColumnsComponent($component);
        foreach ($columns->getChildComponents() as $column) {
            if ($column->getData('config/label') && $column->getData('config/dataType') !== 'actions') {
                $this->columns[$component->getName()][$column->getName()] = $column;
            }
        }
    }
    return $this->columns[$component->getName()];
}

/**
 * Retrieve Headers row array for Export
 *
 * @param UiComponentInterface $component
 * @return string[]
 */
public function getHeaders(UiComponentInterface $component) {
    $row = [];
    foreach ($this->getColumns($component) as $column) {
        $row[] = $column->getData('config/label');
    }

    array_walk($row, function (&$header) {
        if (mb_strpos($header, 'ID') === 0) {
            $header = '"' . $header . '"';
        }
    });

    return $row;
}

/**
 * Returns DB fields list
 *
 * @param UiComponentInterface $component
 * @return array
 */
public function getFields(UiComponentInterface $component) {
    $row = [];
    foreach ($this->getColumns($component) as $column) {
        $row[] = $column->getName();
        $row[] = $column->getTitle();
    }
    return $row;
}

/**
 * Returns row data
 *
 * @param DocumentInterface $document
 * @param array $fields
 * @param array $options
 * @return array
 */
public function getRowData(DocumentInterface $document, $fields, $options) {
    $row = [];
    foreach ($fields as $column) {
        if (isset($options[$column])) {
            $key = $document->getCustomAttribute($column)->getValue();
            if (isset($options[$column][$key])) {
                $row[0] = $this->attribute->getOrderDetails($row[2]);
                $row[] = $options[$column][$key];
            } else {
                $row[] = '';
            }
        } else {
            $row[] = $document->getCustomAttribute($column)->getValue();
        }
    }
    return $row;
}

/**
 * Returns complex option
 *
 * @param array $list
 * @param string $label
 * @param array $output
 * @return void
 */
protected function getComplexLabel($list, $label, &$output) {
    foreach ($list as $item) {
        if (!is_array($item['value'])) {
            $output[$item['value']] = $label . $item['label'];
        } else {
            $this->getComplexLabel($item['value'], $label . $item['label'], $output);
        }
    }
}

/**
 * Returns array of Select options
 *
 * @param Select $filter
 * @return array
 */
protected function getFilterOptions(Select $filter) {
    $options = [];
    foreach ($filter->getData('config/options') as $option) {
        if (!is_array($option['value'])) {
            $options[$option['value']] = $option['label'];
        } else {
            $this->getComplexLabel(
                $option['value'],
                $option['label'],
                $options
            );
        }
    }
    return $options;
}

/**
 * Returns Filters with options
 *
 * @return array
 */
public function getOptions() {
    $options = [];
    $component = $this->filter->getComponent();
    $childComponents = $component->getChildComponents();
    $listingTop = $childComponents['listing_top'];
    foreach ($listingTop->getChildComponents() as $child) {
        if ($child instanceof Filters) {
            foreach ($child->getChildComponents() as $filter) {
                if ($filter instanceof Select) {
                    $options[$filter->getName()] = $this->getFilterOptions($filter);
                }
            }
        }
    }
    return $options;
}

/**
 * Convert document date(UTC) fields to default scope specified
 *
 * @param \Magento\Framework\Api\Search\DocumentInterface $document
 * @param string $componentName
 * @return void
 */
public function convertDate($document, $componentName) {
    if (!isset($this->data[$componentName])) {
        return;
    }
    foreach ($this->data[$componentName] as $field) {
        $fieldValue = $document->getData($field);
        if (!$fieldValue) {
            continue;
        }
        $convertedDate = $this->localeDate->date(
            new \DateTime($fieldValue, new \DateTimeZone('UTC')),
            $this->locale,
            true
        );
        $document->setData($field, $convertedDate->format($this->dateFormat));
    }
}

Hope this helps you!

Problem Solved! Click Kudos & Accept as Solution!