I had similar function like you required but it's auto adding product to quote.
Instead of quote load, I add a observer that is watching the quote save.
Here is some code:
events.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="sales_quote_save_before">
<observer name="vendor_module_quote_save_before" instance="Vendor\Module\Observer\BeforeQuoteSave" />
</event>
</config>
In the observer loops through all items to find you target item:
foreach($quote->getAllItems() as $_item){
$stockItem = $this->stockItem->load($_item->getProductId(),'product_id');
if(!$stockItem->getIsInStock() || !$_item->getProduct()->isInStock()){
$quote->deleteItem($_item);
}
}
$quote->setTotalsCollectedFlag(false)->collectTotals();
It should work, remember not to save the quote in before_quote_save, it will cause an infinity loop.
Just update the code, it should target your question now.
For Guest:
POST: Create a Guest Cart
http://test.com/rest/V1/guest-carts/
POST: Add multiple products to the cart
http://test.com/rest/V1/guest-carts/94b93061280ddc2e050e196203ba598b/
In Postman, Body=>Raw=>json add bellow code
{ "products": [
{ "quote_id": "94b93061280ddc2e050e196203ba598b","pid": "2354", "qty":1 },
{ "quote_id": "94b93061280ddc2e050e196203ba598b","pid": "2353", "qty":1 },
{ "quote_id": "94b93061280ddc2e050e196203ba598b","pid": "2352", "qty":1 }
]
}
GET: Cart items
http://test.com/rest/V1/guest-multicart/
For Registered Customer:
POST: Customer login
http://test.com/rest/V1/integration/customer/token?username=nagendra.k@test.com&password=rest@123
POST: Add multiple products to the cart
http://test.com/rest/V1/carts/mine
In Postman, Body=>Raw=>json add bellow code
{ "products": [
{ "quote_id": "6","pid": "2354", "qty":1 },
{ "quote_id": "6","pid": "2353", "qty":1 },
{ "quote_id": "6","pid": "2352", "qty":1 }
]
}
GET: Cart items
http://test.com/rest/V1/cart/mine-multicart
Sky\Mobileshop\etc\webapi.xml
<route url="/V1/guest-multicart" method="POST">
<service class="Sky\Mobileshop\Api\GuestmulticartInterface" method="guestmulticart"/>
<resources>
<resource ref="anonymous"/>
</resources>
Sky\Mobileshop\etc\di.xml
<preference for="Sky\Mobileshop\Api\GuestmulticartInterface" type="Sky\Mobileshop\Model\Guestmulticart" />
<preference for="Sky\Mobileshop\Api\MinemulticartInte" type="Sky\Mobileshop\Model\Minemulticart" />
Sky\Mobileshop\Api\GuestmulticartInterface.php
<?php
namespace Sky\Mobileshop\Api;
interface GuestmulticartInterface
{
/**
* Returns greeting message to user
*
* @api
* @param mixed $id
* @return mixed
*/
public function guestmulticart($products);
}
?>
Sky\Mobileshop\Model\Guestmulticart.php
<?php
namespace Sky\Mobileshop\Model;
use Sky\Mobileshop\Api\GuestmulticartInterface;
use Magento\Quote\Api\CartRepositoryInterface;
use Magento\Quote\Model\QuoteIdMaskFactory;
class Guestmulticart implements GuestmulticartInterface
{
/**
* @var \Magento\Framework\App\State
* @var \Magento\Framework\App\Request\Http
* @var \Magento\Checkout\Helper\Cart
* @var \Magento\Catalog\Model\Product
* @var \Magento\Customer\Model\Session
* @var \Magento\Quote\Model\QuoteFactory
* @var QuoteIdMaskFactory
* @var CartRepositoryInterface
*/
protected $obj;
protected $request;
protected $cart;
protected $product;
protected $customerSession;
protected $quoteFactory;
protected $quoteRepository;
protected $quoteIdMaskFactory;
/**
* @param \Magento\Framework\App\State $obj
* @param \Magento\Framework\App\Request\Http $request
* @param \Magento\Checkout\Helper\Cart $cart
* @param \Magento\Catalog\Model\Product $product
* @param \Magento\Customer\Model\Session $customerSession
* @param \Magento\Quote\Model\QuoteFactory $quoteFactory
* @param \CartRepositoryInterface $quoteRepository
* @param \QuoteIdMaskFactory $quoteIdMaskFactory
*/
public function __construct(
\Magento\Framework\App\State $obj,
\Magento\Framework\App\Request\Http $request,
\Magento\Checkout\Helper\Cart $cart,
\Magento\Catalog\Model\Product $product,
\Magento\Customer\Model\Session $customerSession,
\Magento\Quote\Model\QuoteFactory $quoteFactory,
CartRepositoryInterface $quoteRepository,
QuoteIdMaskFactory $quoteIdMaskFactory
)
{
$this->obj = $obj;
$this->request = $request;
$this->cart = $cart;
$this->_product = $product;
$this->customerSession = $customerSession;
$this->quoteFactory = $quoteFactory;
$this->quoteIdMaskFactory = $quoteIdMaskFactory;
$this->quoteRepository = $quoteRepository;
}
public function guestmulticart($products)
{
try
{
$pid = array();
$pids = array();
$itemids = array();
$cart = $this
->cart
->getCart();
foreach ($products as $name => $value)
{
$pid = $value['pid'];
$qty = $value['qty'];
$quote_id = $value['quote_id'];
$quoteIdMask = $this
->quoteIdMaskFactory
->create()
->load($quote_id, 'masked_id');
$quote = $this
->quoteFactory
->create()
->load($quoteIdMask->getQuoteId());
array_push($pids, $pid, $qty);
$product = $this
->_product
->load($pid);
$quoteItems = $quote->addProduct($product, $qty);
$quote->save();
$quote->collectTotals()
->save();
}
return "Guest Quote Id: " . $quoteIdMask->getQuoteId();
}
catch(Exception $e)
{
return $e;
}
}
}
?>
Sky\Mobileshop\Api\MinemulticartInterface.php
<?php
namespace Sky\Mobileshop\Api;
interface MinemulticartInterface
{
/**
* Returns greeting message to user
*
* @api
* @param mixed $id
* @return mixed
*/
public function minemulticart($products);
}
?>
Sky\Mobileshop\Model\Minemulticart.php
<?php
namespace Sky\Mobileshop\Model;
use Sky\Mobileshop\Api\MinemulticartInterface;
use Magento\Quote\Api\CartRepositoryInterface;
use Magento\Quote\Model\QuoteIdMaskFactory;
class Minemulticart implements MinemulticartInterface
{
/**
* @var \Magento\Framework\App\State
* @var \Magento\Framework\App\Request\Http
* @var \Magento\Checkout\Helper\Cart
* @var \Magento\Catalog\Model\Product
* @var \Magento\Customer\Model\Session
* @var \Magento\Quote\Model\QuoteFactory
* @var QuoteIdMaskFactory
* @var CartRepositoryInterface
*/
protected $obj;
protected $request;
protected $cart;
protected $product;
protected $customerSession;
protected $quoteFactory;
protected $quoteRepository;
protected $quoteIdMaskFactory;
/**
* @param \Magento\Framework\App\State $obj
* @param \Magento\Framework\App\Request\Http $request
* @param \Magento\Checkout\Helper\Cart $cart
* @param \Magento\Catalog\Model\Product $product
* @param \Magento\Customer\Model\Session $customerSession
* @param \Magento\Quote\Model\QuoteFactory $quoteFactory
* @param \CartRepositoryInterface $quoteRepository
* @param \QuoteIdMaskFactory $quoteIdMaskFactory
*/
public function __construct(
\Magento\Framework\App\State $obj,
\Magento\Framework\App\Request\Http $request,
\Magento\Checkout\Helper\Cart $cart,
\Magento\Catalog\Model\Product $product,
\Magento\Customer\Model\Session $customerSession,
\Magento\Quote\Model\QuoteFactory $quoteFactory,
CartRepositoryInterface $quoteRepository,
QuoteIdMaskFactory $quoteIdMaskFactory
)
{
$this->obj = $obj;
$this->request = $request;
$this->cart = $cart;
$this->_product = $product;
$this->customerSession = $customerSession;
$this->quoteFactory = $quoteFactory;
$this->quoteIdMaskFactory = $quoteIdMaskFactory;
$this->quoteRepository = $quoteRepository;
}
public function minemulticart($products)
{
try
{
$cart = $this
->cart
->getCart();
foreach ($products as $name => $value)
{
$pid = $value['pid'];
$qty = $value['qty'];
$quote_id = $value['quote_id'];
$quote = $this
->quoteFactory
->create()
->load($quote_id);
$product = $this
->_product
->load($pid);
$quoteItems = $quote->addProduct($product, $qty);
$quote->save();
$quote->collectTotals()
->save();
}
return "Customer Quote Id: " . $quote_id;
}
catch(Exception $e)
{
return $e;
}
}
}
?>
Best Answer
By default, Magento doesn't have UI for multiple quotes. Also, Magento relies on is_active quote field in order to bind the consumer to exactly one quote. However, you can use
\Magento\Quote\Api\CartRepositoryInterface
to introduce more active quotes per consumer. You also need to create custom UI for your custom quotes.