e-Zest members share technology ideas to foster digital transformation.

Magento 2 - How to add product's custom attribute to checkout summary

Written by Sejal Shah | Oct 1, 2018 1:26:00 PM
Adding custom attributes to Magento 2 Checkout is a complex task since the whole checkout is built up from a series of KnockoutJS components, which are then rendered using the knockout.js templating system. Magento 2 defines these components and their mutual relationship in a large XML file. To pull the data from the server, Magento uses global Javascript variable window.checkoutConfig that is then used by Knockout.js to compute and display information on the frontend.

You will have to create a plugin for that. I wanted to add product flavor to order summary for each product.

Here are the steps and the code:

Attribute to display = Flavor
Vendor Name = Store
Module Name = Flavor

Files you need to create:

  1. Registration.php : app/code/Store/Flavor/registration.php
  2. di.xml : app/code/Store/Flavor/etc/di.xml
  3. module.xml : app/code/Store/Flavor/etc/module.xml
  4. ConfigProviderPlugin.php : app/code/Store/Flavor/Plugin/ConfigProviderPlugin.php
  5. details.js : copy of vendor/magento/module-checkout/view/frontend/web/js/view/summary/item/details.js
  6. details.html : copy of vendor/magento/module-checkout/view/frontend/web/template/summary/item/details.html
Code:

registration.php


<?php

\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Store_Flavor',
__DIR__
);

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\Checkout\Model\DefaultConfigProvider">
<plugin name="AddAttPlug" type="Store\Flavor\Plugin\ConfigProviderPlugin" />
</type>
</config>

module.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Store_Flavor" setup_version="1.0.0">
</module>
</config>

ConfigProviderPlugin.php

<?php

namespace Store\Flavor\Plugin;

use Magento\Checkout\Model\Session as CheckoutSession;
use Magento\Quote\Api\CartItemRepositoryInterface as QuoteItemRepository;

class ConfigProviderPlugin extends \Magento\Framework\Model\AbstractModel
{
private $checkoutSession;
private $quoteItemRepository;
protected $scopeConfig;

public function __construct(
CheckoutSession $checkoutSession,
QuoteItemRepository $quoteItemRepository,
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
) {
$this->_scopeConfig = $scopeConfig;
$this->checkoutSession = $checkoutSession;
$this->quoteItemRepository = $quoteItemRepository;
}

public function afterGetConfig(\Magento\Checkout\Model\DefaultConfigProvider $subject, array $result)
{
$quoteId = $this->checkoutSession->getQuote()->getId();
if ($quoteId) {
$itemOptionCount = count($result['totalsData']['items']);
$quoteItems = $this->quoteItemRepository->getList($quoteId);
$isbnOptions = array();
foreach ($quoteItems as $index => $quoteItem) {
$quoteItemId = $quoteItem['item_id'];
$isbnOptions[$quoteItemId] = $quoteItem['isbn'];
}

for ($i=0; $i < $itemOptionCount; $i++) {
$quoteParentId = $result['totalsData']['items'][$i]['item_id'];
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$productId = $result['quoteItemData'][$i]['product']['entity_id'];
$productObj = $objectManager->create('\Magento\Catalog\Model\Product')->load($productId);

$productFlavours = $productObj->getResource()->getAttribute('flavors')->getFrontend()->getValue($productObj);
if($productFlavours == 'No' || $productFlavours == 'NA'){
$productFlavours = '';
}
$result['quoteItemData'][$i]['flavor'] = $productFlavours;
json_encode($result);
}
}
return $result;
}

}

details.js

define(
[
'uiComponent'
],
function (Component) {
"use strict";
var quoteItemData = window.checkoutConfig.quoteItemData;
return Component.extend({
defaults: {
template: 'Magento_Checkout/summary/item/details'
},
quoteItemData: quoteItemData,
getValue: function(quoteItem) {
return quoteItem.name;
},
getItemFlavor: function(quoteItem) {
var itemProduct = this.getItemProduct(quoteItem.item_id);
return itemProduct.flavor;
},
getItemProduct: function(item_id) {
var itemElement = null;
_.each(this.quoteItemData, function(element, index) {
if (element.item_id == item_id) {
itemElement = element;
}
});
return itemElement;
}

});
}

);

details.html

Add this code
<span class="product-item-new" data-bind="text: getItemFlavor($parent)"></span>

If you have any further queries about the code, feel free to comment in the comment section below..