1) For customer account: /V1/carts/mine/coupons/:couponCode
I just explain how sale rules work for customer logged
a) Set coupon:
vendor/magento/module-quote/etc/webapi.xml
<route url="/V1/carts/mine/coupons/:couponCode" method="PUT">
<service class="Magento\Quote\Api\CouponManagementInterface" method="set"/>
<resources>
<resource ref="Magento_Cart::manage" />
</resources>
</route>
So, the service class interface class Magento\Quote\Api\CouponManagementInterface::set()
will be used and Magento\Quote\Model\CouponManagement::set
will be called.
$quote->setCouponCode($couponCode);
$this->quoteRepository->save($quote->collectTotals());
When quote collects totals: $quote->collectTotals()
\Magento\SalesRule\Model\Quote\Discount::collect()
will be called. It will calculate the coupon logic here.
b) Remove coupon:
vendor/magento/module-quote/etc/webapi.xml
<route url="/V1/carts/mine/coupons" method="DELETE">
<service class="Magento\Quote\Api\CouponManagementInterface" method="remove"/>
<resources>
<resource ref="self" />
</resources>
<data>
<parameter name="cartId" force="true">%cart_id%</parameter>
</data>
</route>
Magento\Quote\Model\CouponManagement::remove()
will be called.
c) Total Segment: V1/carts/mine/payment-information
vendor/magento/module-checkout/etc/webapi.xml
<route url="/V1/carts/mine/payment-information" method="GET">
<service class="Magento\Checkout\Api\PaymentInformationManagementInterface" method="getPaymentInformation"/>
<resources>
<resource ref="self" />
</resources>
<data>
<parameter name="cartId" force="true">%cart_id%</parameter>
</data>
</route>
vendor/magento/module-checkout/Model/PaymentInformationManagement.php
/**
* {@inheritDoc}
*/
public function getPaymentInformation($cartId)
{
...
$paymentDetails->setTotals($this->cartTotalsRepository->get($cartId));
...
}
\Magento\Quote\Model\Cart\CartTotalRepository::get()
if ($quote->isVirtual()) {
$addressTotalsData = $quote->getBillingAddress()->getData();
$addressTotals = $quote->getBillingAddress()->getTotals();
} else {
$addressTotalsData = $quote->getShippingAddress()->getData();
$addressTotals = $quote->getShippingAddress()->getTotals();
}
......
$calculatedTotals = $this->totalsConverter->process($addressTotals);
$quoteTotals->setTotalSegments($calculatedTotals);
This will get the totals data and set the total segments.
\Magento\Quote\Model\Quote\TotalsReader::fetch()
foreach ($this->collectorList->getCollectors($quote->getStoreId()) as $reader) {
$data = $reader->fetch($quote, $total);
2) For guest account, we can see the apis:
vendor/magento/module-quote/etc/webapi.xml
<!-- Managing Guest Cart Coupons -->
<route url="/V1/guest-carts/:cartId/coupons" method="GET">
<service class="Magento\Quote\Api\GuestCouponManagementInterface" method="get"/>
<resources>
<resource ref="anonymous" />
</resources>
</route>
<route url="/V1/guest-carts/:cartId/coupons/:couponCode" method="PUT">
<service class="Magento\Quote\Api\GuestCouponManagementInterface" method="set"/>
<resources>
<resource ref="anonymous" />
</resources>
</route>
<route url="/V1/guest-carts/:cartId/coupons" method="DELETE">
<service class="Magento\Quote\Api\GuestCouponManagementInterface" method="remove"/>
<resources>
<resource ref="anonymous" />
</resources>
</route>
Best Answer
Go to below js path :-
app\design\frontend\Vendor_Name\Theme_Name\Magento_Ui\web\js\lib\core\collection.js
Line no :- 272 (find below line)
var hasObsoleteComponents = items().length && !_.intersection(_elems, items()).length;
Just Replace function items just like below
var hasObsoleteComponents = items.length && !_.intersection(_elems, items).length;