Magento – Magento 2 How to add custom attribute to Quote Item Rest API

apimagento2rest api

I want to add custom attribute to >http://{{magento2}}/rest/V1/carts/mine/totals

API response.

I have done follwing way but it not working.

>extension_attributes.xml

<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\CartItemInterface">
        <attribute code="product_option" type="float" />
    </extension_attributes>
</config>

>di.xml

<type name="Magento\Quote\Model\Quote\Item">
    <plugin name="cs_product_opt" type="Namespace\Product\Plugin\Model\Cart\CartTotalRepositoryPlugin" />
</type>

>Plugin file 

<?php
/**
* Copyright 2016 aheadWorks. All rights reserved.
* See LICENSE.txt for license details.
*/

namespace Namespace\Product\Plugin\Model\Cart;

use Magento\Quote\Api\Data\TotalsExtensionInterface;
use Magento\Quote\Api\Data\TotalsExtensionFactory;
use Magento\Quote\Api\Data\CartItemExtensionFactory;
use Magento\Quote\Api\Data\TotalsInterface;
use Magento\Quote\Api\CartRepositoryInterface;
use Magento\Quote\Model\Cart\CartTotalRepository as TotalRepository;
use Magento\Quote\Model\Quote;

/**
 * Class Aheadworks\StoreCredit\Plugin\Model\Cart\CartTotalRepositoryPlugin
 */
class CartTotalRepositoryPlugin
{
    /**
     * @var CartRepositoryInterface
     */
    private $quoteRepository;

    /**
     * @var CartItemExtensionFactory
     */
    private $totalsExtensionFactory;

    /**
     * @param CartRepositoryInterface $quoteRepository
     * @param CartItemExtensionFactory $totalsExtensionFactory
     */
    public function __construct(
        CartRepositoryInterface $quoteRepository,
        CartItemExtensionFactory $totalsExtensionFactory
    ) {
        $this->quoteRepository = $quoteRepository;
        $this->totalsExtensionFactory = $totalsExtensionFactory;
    }

    /**
     * Apply extension attributes to totals
     *
     * @param TotalRepository $subject
     * @param \Closure $proceed
     * @param int $cartId
     * @return TotalsInterface
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function aroundGet(TotalRepository $subject, \Closure $proceed, $cartId)
    {
         /** @var TotalsInterface $totals */
        $totals = $proceed($cartId);

        /** @var \Magento\Quote\Api\Data\TotalsExtensionInterface $extensionAttributes */
        $extensionAttributes = $totals->getExtensionAttributes()
            ? $totals->getExtensionAttributes()
            : $this->totalsExtensionFactory->create();

        /** @var Quote $quote */
        $quote = $this->quoteRepository->getActive($cartId);

        $extensionAttributes->setProductOption(1.11);
        $totals->setExtensionAttributes($extensionAttributes);
        return $totals;
    }
}

anyone have idea how to add custom attribute to Quote Item Rest API.

Best Answer

To add new attribute on cart item. you need to consume V1/carts/mine service.

CartRepositoryPlugin.php

<?php
/**
* Copyright 2016 aheadWorks. All rights reserved.
* See LICENSE.txt for license details.
*/

namespace Namespace\Product\Plugin\Model\Cart;

use Magento\Quote\Api;
use Magento\Quote\Api\CartRepositoryInterface;
use Magento\Quote\Api\CartTotalRepositoryInterface;
use Magento\Catalog\Helper\Product\ConfigurationPool;
use Magento\Framework\Api\DataObjectHelper;
use Magento\Framework\Api\ExtensibleDataInterface;
use Magento\Quote\Model\Cart\Totals\ItemConverter;
use Magento\Quote\Api\CouponManagementInterface;
use Magento\Quote\Model\Cart\TotalsConverter;
use Magento\Quote\Api\Data\CartItemExtensionFactory;
use Magento\Quote\Model\Cart\CartTotalRepository as TotalRepository;

/**
 * Class Aheadworks\StoreCredit\Plugin\Model\Cart\CartTotalRepositoryPlugin
 */
class CartRepositoryPlugin
{
/**
 * Cart totals factory.
 *
 * @var Api\Data\TotalsInterfaceFactory
 */
private $totalsFactory;

/**
 * Quote repository.
 *
 * @var \Magento\Quote\Api\CartRepositoryInterface
 */
private $quoteRepository;

/**
 * @var \Magento\Framework\Api\DataObjectHelper
 */
private $dataObjectHelper;

/**
 * @var ConfigurationPool
 */
private $itemConverter;

/**
 * @var CouponManagementInterface
 */
protected $couponService;

/**
 * @var TotalsConverter
 */
protected $totalsConverter;

/**
 * @param Api\Data\TotalsInterfaceFactory $totalsFactory
 * @param CartRepositoryInterface $quoteRepository
 * @param DataObjectHelper $dataObjectHelper
 * @param CouponManagementInterface $couponService
 * @param TotalsConverter $totalsConverter
 * @param ItemConverter $converter
 */
public function __construct(
    Api\Data\TotalsInterfaceFactory $totalsFactory,
    CartRepositoryInterface $quoteRepository,
    DataObjectHelper $dataObjectHelper,
    CouponManagementInterface $couponService,
    TotalsConverter $totalsConverter,
    CartItemExtensionFactory $cartItemInterfaceFactory,
    ItemConverter $converter
) {
    $this->totalsFactory = $totalsFactory;
    $this->quoteRepository = $quoteRepository;
    $this->dataObjectHelper = $dataObjectHelper;
    $this->couponService = $couponService;
    $this->totalsConverter = $totalsConverter;
    $this->cartItemInterfaceFactory = $cartItemInterfaceFactory;
    $this->itemConverter = $converter;
}

/**
 * Apply extension attributes to totals
 *
 * @param TotalRepository $subject
 * @param \Closure $proceed
 * @param int $cartId
 * @return TotalsInterface
 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 */

public function aroundGet(TotalRepository $subject, \Closure $proceed, $cartId)
{
    /** @var \Magento\Quote\Model\Quote $quote */
    $quote = $this->quoteRepository->getActive($cartId);
    if ($quote->isVirtual()) {
        $addressTotalsData = $quote->getBillingAddress()->getData();
        $addressTotals = $quote->getBillingAddress()->getTotals();
    } else {
        $addressTotalsData = $quote->getShippingAddress()->getData();
        $addressTotals = $quote->getShippingAddress()->getTotals();
    }
    unset($addressTotalsData[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]);

    /** @var \Magento\Quote\Api\Data\TotalsInterface $quoteTotals */
    $quoteTotals = $this->totalsFactory->create();
    $this->dataObjectHelper->populateWithArray(
        $quoteTotals,
        $addressTotalsData,
        \Magento\Quote\Api\Data\TotalsInterface::class
    );
    $items = [];
    foreach ($quote->getAllVisibleItems() as $index => $item) {
        $cartItemExtensionAttributes = $item->getExtensionAttributes();
        if($cartItemExtensionAttributes == null){
            $cartItemExtensionAttributes = $this->cartItemInterfaceFactory->create();
            $cartItemExtensionAttributes->setProductOption('Product Option Check');
            $item->setExtensionAttributes($cartItemExtensionAttributes);       
            $item->save();
        }
        $items[$index] = $this->itemConverter->modelToDataObject($item);
    }

    $calculatedTotals = $this->totalsConverter->process($addressTotals);
    $quoteTotals->setTotalSegments($calculatedTotals);
    $amount = $quoteTotals->getGrandTotal() - $quoteTotals->getTaxAmount();
    $amount = $amount > 0 ? $amount : 0;
    $quoteTotals->setCouponCode($this->couponService->get($cartId));
    $quoteTotals->setGrandTotal($amount);
    $quoteTotals->setItems($items);
    $quoteTotals->setItemsQty($quote->getItemsQty());
    $quoteTotals->setBaseCurrencyCode($quote->getBaseCurrencyCode());
    $quoteTotals->setQuoteCurrencyCode($quote->getQuoteCurrencyCode());
    return $quoteTotals;
 }
}

extension_attributes.xml

    <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\CartItemInterface">
    <attribute code="product_option" type="string" />
</extension_attributes>

di.xml

 <type name="Magento\Quote\Model\Cart\CartTotalRepository">
  <plugin name="cp_product_opt" type="Commercepundit\Product\Plugin\Model\Cart\CartRepositoryPlugin" />
</type>

I hope it'll work for you. Let me know if you need further help.

Related Topic