0

I am trying to fetch the values from a custom attribute (multiselect attribute) of the ordered products, and display them in the order view in a new section.

In order to do that, my plan was to create a method that fetches the SKUs of the ordered products, and then another method that gets the attribute values from the product with the fetched SKU.
So I tried the following, but it didn't work:

app/code/Vendor/Module/Block/Adminhtml/Order/View/Additional.php


namespace Vendor\Module\Block\Adminhtml\Order\View;

class Attribute extends \Magento\Backend\Block\Template
{
    private $orderItem;

    /**
     * @param \Magento\Backend\Block\Template\Context $context
     * @param \Magento\Sales\Model\Order\Item $orderItem
     * @param array $data
     */
    public function __construct(
        \Magento\Backend\Block\Template\Context $context,
        \Magento\Sales\Model\Order\Item $orderItem,
        array $data = []
    ) {
        parent::__construct($context, $data);
        $this->orderItem = $orderItem;
    }

    public function getProductSku()
    {
        return $this->orderItem->getProduct()->getSku();
    }

    public function getAttributeValue()
    {
        return $this->getProductSku()->getData('bundled_products');
    }
}

My custom template should be something like (only a mockup example, not final template):

app/code/Vendor/Module/view/adminhtml/templates/order/view/additional.phtml

<?php

/** @var \Vendor\Module\Block\Adminhtml\Order\View\Additional $block */

?>

<section class="admin__page-section">
    <div class="admin__page-section-title">
        <span class="title"><?= "Bundled Products" ?></span>
    </div>
    <table class="data-table admin__table-secondary">
        <tbody>
            <tr class="col-0">
                <td class="label"><?= $block->getAttributeValue ?></td>
                <td></td>
            </tr>
        </tbody>
    </table>
</section>

The result should look something like this in Sales > Orders > Order view:

The result should look something like this

I have a theory myself why it doesn't work, but I also don't know how to fix it.
First of all, I guess the getProductSku() method should (actually be called getProductSkus() and) return an array of all the ordered SKUs. Then, for each SKU, the getAttributeValue() method should return the multiselect values selected for those SKUs.
Finally, I need to implement this in the template, which also needs to include if statements, but that is rather easy, and not what this question is about. This question is really mostly about getting product attributes of ordered products in the order view.

Maybe there is a much easier method to do all of this? Maybe with product IDs?

0

You can use the below code to get attribute value in order view the page.

namespace NameSpace\HelloWorld\Block;

use Magento\Framework\App\RequestInterface;


class HelloWorld extends \Magento\Framework\View\Element\Template
{    
    protected $_productRepository;

    public function __construct(
        \Magento\Backend\Block\Template\Context $context,
        RequestInterface $request,        
        \Magento\Catalog\Model\ProductFactory $productFactory,
        \Magento\Sales\Model\OrderFactory $orderData,
        array $data = []
    )
    {
        $this->productFactory = $productFactory;
        $this->_request = $request;
        $this->orderData = $orderData;
        parent::__construct($context, $data);
    }

    public function getProductCustomAttribute()
    {
        $orderId = $this->_request->getParam('order_id');
        $order = $this->orderData->create()->load($orderId);
        $html = '';
        foreach ($order->getAllItems() as $item) {
            $product = $this->productFactory->create()->load($item->getProductId());
            $value = $product->getResource()->getAttribute('attribute_code')->getFrontend()->getValue($product);
            if ($value) {
                $html .= '<p><strong>'.$value.'</strong></p>';
            } 
        }

        return $html;
    }

}

In Phtml file

You can call the below function:

$block->getProductCustomAttribute();

I hope this will help.

4
  • I saw a similar solution in another answer, and I guess it will work, but is there any way I can avoid using ObjectManager and use DI instead? – Audio-Engineer Nov 11 '20 at 17:14
  • Updated my answer. Please update the code based on your requirement. – Nits Nov 11 '20 at 17:46
  • It works! You are amazing! I will update the code based on my requirements and then post it as an update for others to enjoy too. Thank you a lot, Nits. – Audio-Engineer Nov 11 '20 at 18:40
  • Please accept this as an answer, so it will help others as well. – Nits Nov 12 '20 at 5:05

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.