My requirement is that certain kind of bundle products are not allowed to be added more than once in an order. I am trying to do so by intercepting the Add To Cart API method using a Plugin.
Here's my code:
di.xml:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
<!-- Interceptor (plugin) for Add To Cart action -->
<!-- Prevent adding multiple products of the same kind to cart -->
<type name="Magento\Quote\Api\CartItemRepositoryInterface">
<plugin name="interceptAddToCart"
type="MyCompany\MyModule\Plugin\CartItemRepositoryPlugin"
sortOrder="1"
disabled="false"/>
</type>
</config>
Plugin file:
<?php
namespace MyCompany\MyModule\Plugin;
use Magento\Framework\Exception\CouldNotSaveException;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Quote\Api\CartItemRepositoryInterface;
class CartItemRepositoryPlugin
{
protected $_productRepositoryInterface;
protected $_cartItemRepositoryInterface;
/**
* Plugin constructor.
*
* @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepositoryInterface
* @param \Magento\Quote\Api\CartItemRepositoryInterface $cartItemRepositoryInterface
*/
public function __construct(
ProductRepositoryInterface $productRepositoryInterface,
CartItemRepositoryInterface $cartItemRepositoryInterface
) {
$this->_productRepositoryInterface = $productRepositoryInterface;
$this->_cartItemRepositoryInterface = $cartItemRepositoryInterface;
}
/**
* beforeSave
*
* @param $subject
* @param \Magento\Quote\Api\Data\CartItemInterface $cartItem The item.
* @return array
* @throws \Magento\Framework\Exception\NoSuchEntityException The specified cart does not exist.
* @throws \Magento\Framework\Exception\CouldNotSaveException The specified item could not be saved to the cart.
* @throws \Magento\Framework\Exception\InputException The specified item or cart is not valid.
*/
public function beforeSave($subject, $cartItem)
{
// For debugging purposes I removed the logic and simply returned the cart item.
return [$cartItem];
}
}
For adding products to cart, I am using Magento's default REST API.
[POST] {{base_url}}rest/V1/carts/mine/items
Parameters:
{
"cart_item": {
"quote_id": "73",
"sku": "product_sku",
"qty": 1,
"product_option": {
"extension_attributes": {
"bundle_options": [
{
"option_id": 30,
"option_qty": 1,
"option_selections": [41]
},
{
"option_id": 31,
"option_qty": 1,
"option_selections": [42]
},
{
"option_id": 32,
"option_qty": 1,
"option_selections": [43]
},
{
"option_id": 33,
"option_qty": 1,
"option_selections": [44]
}
]
}
}
}
}
Now when I hit the Add To Cart API, I see this message:
{
"message": "Please specify product option(s).",
"trace": "#0 {path}/vendor/magento/module-quote/Model/Quote/Item/CartItemPersister.php(84): Magento\\Quote\\Model\\Quote->addProduct(Object(Magento\\Catalog\\Model\\Product\\Interceptor), Object(Magento\\Framework\\DataObject))\n#1 {path}/vendor/magento/module-quote/Model/QuoteRepository/SaveHandler.php(69): Magento\\Quote\\Model\\Quote\\Item\\CartItemPersister->save(Object(Magento\\Quote\\Model\\Quote), Object(Magento\\Quote\\Model\\Quote\\Item))\n#2 {path}/vendor/magento/module-quote/Model/QuoteRepository.php(161): Magento\\Quote\\Model\\QuoteRepository\\SaveHandler->save(Object(Magento\\Quote\\Model\\Quote))\n#3 {path}/vendor/magento/module-quote/Model/Quote/Item/Repository.php(96): Magento\\Quote\\Model\\QuoteRepository->save(Object(Magento\\Quote\\Model\\Quote))\n#4 {path}/vendor/magento/framework/Interception/Interceptor.php(146): Magento\\Quote\\Model\\Quote\\Item\\Repository->save(Object(Magento\\Quote\\Model\\Quote\\Item))\n#5 {path}/var/generation/Magento/Quote/Model/Quote/Item/Repository/Interceptor.php(26): Magento\\Quote\\Model\\Quote\\Item\\Repository\\Interceptor->___callPlugins('save', Array, Array)\n#6 [internal function]: Magento\\Quote\\Model\\Quote\\Item\\Repository\\Interceptor->save(Object(Magento\\Quote\\Model\\Quote\\Item))\n#7 {path}/vendor/magento/module-webapi/Controller/Rest.php(307): call_user_func_array(Array, Array)\n#8 {path}/vendor/magento/module-webapi/Controller/Rest.php(216): Magento\\Webapi\\Controller\\Rest->processApiRequest()\n#9 {path}/var/generation/Magento/Webapi/Controller/Rest/Interceptor.php(24): Magento\\Webapi\\Controller\\Rest->dispatch(Object(Magento\\Framework\\App\\Request\\Http))\n#10 {path}/vendor/magento/framework/App/Http.php(135): Magento\\Webapi\\Controller\\Rest\\Interceptor->dispatch(Object(Magento\\Framework\\App\\Request\\Http))\n#11 {path}/vendor/magento/framework/App/Bootstrap.php(258): Magento\\Framework\\App\\Http->launch()\n#12 {path}/pub/index.php(37): Magento\\Framework\\App\\Bootstrap->run(Object(Magento\\Framework\\App\\Http))\n#13 {main}"
}
If I create a fresh new quote and repeat this process, the outcome is the same.
If I disable my Plugin, either by entirely removing it, or by setting disabled="true"
in di.xml
, everything works fine.
What could be going wrong?