2

In Magento 2 I try to customize checkout Items summary. I then created a module with :

  • Vendor/Module/Plugin/Checkout/Summary/ItemPlugin.php

namespace Vendor\Module\Plugin\Checkout\Summary;

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\Product;
use Magento\Quote\Model\Quote\Item;

class ItemPlugin
{   
    protected $productRepo;

    public function __construct(
            ProductRepositoryInterface $productRepository
            ) 
    {
        $this->productRepo = $productRepository;
    }

    public function afterGetConfig(\Magento\Checkout\Model\DefaultConfigProvider $subject, array $result)
    {
        $TDitems = $result['totalsData']['items'];

        foreach ($TDitems as $key=>$item)
        {
            $result['totalsData']['items'][$key]['custinfo']='foo;  
        }

        return $result;
    }   
}

which adds custom parameters to items.

  • Vendor/Module/etc/di.xml

  • Vendor/Module/view/frontend/web/js/view/summary/item/details.js

    define(
    [
        'uiComponent'
    ],
    function (Component) {
        "use strict";
    
        return Component.extend({
            defaults: {
                template: 'Vendor_Module/checkout/summary/item/details'
            },
            getValue: function(quoteItem) {
                return quoteItem.name;
            }
        });
    }
    );
    
  • Vendor/Module/view/frontend/web/template/checkout/summary/item/details.html

    <!-- ko foreach: getRegion('before_details') -->
    <!-- ko template: getTemplate() --><!-- /ko -->
    <!-- /ko -->
    <div class="product-item-details">
    <div class="product-item-inner">
        <div class="product-item-name-block">
            <strong class="product-item-name" data-bind="text: $parent.name"></strong>
            <div class="details-qty">
                <span class="label"><!-- ko i18n: 'Qty' --><!-- /ko --></span>
                <span class="value" data-bind="text: $parent.qty"></span>
            </div>
        </div>
        <!-- ko foreach: getRegion('after_details') -->
            <!-- ko template: getTemplate() --><!-- /ko -->
        <!-- /ko -->
    </div>
    
    <h1>toto</h1>
    <!-- ko if: ($parent.custinf)-->
    <strong class="product-item-name" data-bind="text: $parent.custinfo"></strong>
    <!-- /ko -->
    
    <!-- ko if: (JSON.parse($parent.options).length > 0)-->
    <div class="product options" data-bind="mageInit: {'collapsible':{'openedState': 'active'}}">
    ...
    </div>
    <!-- /ko -->
    

Issues :

When I go from cart to checkout page, plugin is called, custinfo parapeter is added and displayed correctly.

When I go to next checkout step, the custom template is called (I can see the toto h1), but custinfo parameter is not displayed. NB: I have a breakpoint on the plugin, and going from first checkout step to second checkout step does not call the plugin.

When I reload the second checkout step page, plugin is called, but parameter custinfo is still not displayed

When i go back from second step to first checkout page by clicking the "Shipping" step link, plugin is not called and custinfo param is not diplayed. I need to reload the page to make it appears.

Any idea of what is happening?

Thank you for your help,

EDIT1 :

I added in the details.html a Knockout command to log to console the $parent Object. On first checkout step I get :

Object { item_id: "92", name: "Blah", qty: 4, price: "18.0700", base_price: "18.0700", discount_percent: "0.0000", discount_amount: "0.0000", base_discount_amount: "0.0000", tax_percent: "0.0000", tax_amount: "0.0000", 14 more… }

On the second step I get :

Object { item_id: 92, price: 18.07, base_price: 18.07, qty: 4, row_total: 72.28, base_row_total: 72.28, row_total_with_discount: 0, tax_amount: 0, base_tax_amount: 0, tax_percent: 0, 11 more… }

clearly not the same object, but can not find where the second one is comming from (internal, session, cache, ...??)

4 Answers 4

4

On the second step of the checkout the checkout summary is updated via ajax and the totalsData array is populated again with the default quote total values as it implements the following interface Magento\Quote\Api\Data\TotalsInterface, that means your custom data is gone. A solution will be to save your custom data in the quoteItemData array and get it from there. This nice tutorial can help you on that https://www.magevision.com/blog/post/get-a-product-attribute-in-checkout-summary-magento-2/

1

quoteItem object in checkout item summary is coming from:

Magento\Quote\Api\Data\TotalsItemInterface

You need to extend it using extension attribues and a plugin if you want to access custom values in checkout summary javascript templates. Here is example of such operation:

extension_attributes.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
    <extension_attributes for="Magento\Quote\Api\Data\TotalsItemInterface">
      <attribute code="sku" type="string" />
    </extension_attributes>
</config>

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\Api\CartTotalRepositoryInterface">
        <plugin name="total_cart_repository_plugin" type="Vendor\Module\Plugin\TotalRepositoryPlugin"/>
    </type>
</config>

TotalRepositoryPlugin.php

<?php

namespace Vendor\Module\Plugin;

class TotalRepositoryPlugin
{

    /**
     * @param \Magento\Authorization\Model\UserContextInterface $userContext
     * @param \Magento\Quote\Api\Data\TotalsItemExtensionFactory $totalItemExtensionFactory
     */
    public function __construct(
        \Magento\Quote\Model\Quote\ItemFactory $itemFactory,
        \Magento\Quote\Api\Data\TotalsItemExtensionFactory $totalItemExtensionFactory    
    ) {
        $this->itemFactory = $itemFactory;
        $this->totalItemExtension = $totalItemExtensionFactory;
    }

    /**
     * add sku in total cart items
     *
     * @param  \Magento\Quote\Api\CartTotalRepositoryInterface $subject
     * @param  \Magento\Quote\Api\Data\TotalsInterface $totals
     * @return \Magento\Quote\Api\Data\TotalsInterface $totals
     */
    public function afterGet(
        \Magento\Quote\Api\CartTotalRepositoryInterface $subject,
        \Magento\Quote\Api\Data\TotalsInterface $totals
    ) {
        foreach($totals->getItems() as $item)
        {
            $quoteItem = $this->itemFactory->create()->load($item->getItemId());
            $extensionAttributes = $item->getExtensionAttributes();
            if ($extensionAttributes === null) {
                $extensionAttributes = $this->totalItemExtension->create();
            }

            $extensionAttributes->setSku($quoteItem->getSku());
            $item->setExtensionAttributes($extensionAttributes);
        }

        return $totals;
    }
}

Code was copied from this answer but I`ve tested it and it works.

1

None of the solutions above mentioned worked for me, at the end I found a not so called solution by removing a KO subscriber in vendor/magento/module-checkout/view/frontend/web/js/model/totals.js

    quote.totals.subscribe(function (newValue) {
        quoteItems(newValue.items);
    });

After removing the subscriber the payment page worked again, showing my custom attribute as intended.

0

There is a solution to save your custom data in the quoteItemData array and get it from there on details.html

You can found solution here i have described with multiple attribute options.

Magento 2 : Show Custom Option value inside summary block sidebar checkout page

Thank You!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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