cancel
Showing results for 
Search instead for 
Did you mean: 

Magento Cloud : Redeem Reward Points On Subtotal not Grandtotal.

0 Kudos

Magento Cloud : Redeem Reward Points On Subtotal not Grandtotal.

Hi Team,

I tried something as below. So I have enabled the reward points for the order placement process. Right now the reward points are redeemable on the full amount of the order (Grand Total) and I want to allow redeem reward points only on the Subtotal, not on Grand Total.

So here my goal is to customers should pay shipping charges on order time and for that, I have modified the below file.

File: vendor/magento/module-reward/Model/Total/Quote/Reward.php (File overridden in the custom plugin)

public function collect(
    \Magento\Quote\Model\Quote $quote,
    \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment,
    \Magento\Quote\Model\Quote\Address\Total $total
) {
    if (!$this->_rewardData->isEnabledOnFront($quote->getStore()->getWebsiteId())) {
        return $this;
    }
    $total->setRewardPointsBalance(0)->setRewardCurrencyAmount(0)->setBaseRewardCurrencyAmount(0);

    if ($total->getBaseSubtotal() >= 0 && $quote->getCustomer()->getId() && $quote->getUseRewardPoints()) {
        /* @var $reward \Magento\Reward\Model\Reward */
        $reward = $quote->getRewardInstance();
        if (!$reward || !$reward->getId()) {
            $customer = $quote->getCustomer();
            $reward = $this->_rewardFactory->create()->setCustomer($customer);
            $reward->setCustomerId($quote->getCustomer()->getId());
            $reward->setWebsiteId($quote->getStore()->getWebsiteId());
            $reward->loadByCustomer();
        }
        $pointsLeft = $reward->getPointsBalance() - $quote->getRewardPointsBalance();
        $rewardCurrencyAmountLeft = $this->priceCurrency->convert(
            $reward->getCurrencyAmount(),
            $quote->getStore()
        ) - $quote->getRewardCurrencyAmount();
        $baseRewardCurrencyAmountLeft = $reward->getCurrencyAmount() - $quote->getBaseRewardCurrencyAmount();
        if ($baseRewardCurrencyAmountLeft >= $total->getBaseSubtotal()) {
            $pointsBalanceUsed = $reward->getPointsEquivalent($total->getBaseSubtotal());
            $pointsCurrencyAmountUsed = $total->getSubtotal();
            $basePointsCurrencyAmountUsed = $total->getBaseSubtotal();

            $total->setGrandTotal($total->getShippingAmount());
            $total->setBaseGrandTotal($total->getBaseShippingAmount());
        } else {
            $pointsBalanceUsed = $reward->getPointsEquivalent($baseRewardCurrencyAmountLeft);
            if ($pointsBalanceUsed > $pointsLeft) {
                $pointsBalanceUsed = $pointsLeft;
            }
            $pointsCurrencyAmountUsed = $rewardCurrencyAmountLeft;
            $basePointsCurrencyAmountUsed = $baseRewardCurrencyAmountLeft;

            $subtotal = $total->getSubtotal() + $total->getShippingAmount();
            $baseSubtotal = $total->getBaseSubtotal() + $total->getBaseShippingAmount();

            $total->setGrandTotal($subtotal - $pointsCurrencyAmountUsed);
            $total->setBaseGrandTotal($baseSubtotal - $basePointsCurrencyAmountUsed);
        }
        $quote->setRewardPointsBalance(round($quote->getRewardPointsBalance() + $pointsBalanceUsed));
        $quote->setRewardCurrencyAmount($quote->getRewardCurrencyAmount() + $pointsCurrencyAmountUsed);
        $quote->setBaseRewardCurrencyAmount($quote->getBaseRewardCurrencyAmount() + $basePointsCurrencyAmountUsed);

        $total->setRewardPointsBalance(round($pointsBalanceUsed));
        $total->setRewardCurrencyAmount($pointsCurrencyAmountUsed);
        $total->setBaseRewardCurrencyAmount($basePointsCurrencyAmountUsed);
    }
    return $this;
}

In above function I have replaced $total->getBaseGrandTotal() with $total->getBaseSubtotal() and $total->getGrandTotal() with $total->getSubtotal().

So the above code worked for me on the simple checkout but when I have tried the same thing on the multi-checkout process then it's giving me an error The requested Payment Method is not available.


https://i.stack.imgur.com/tzwvv.png


Note: File override is pending and Need to add one config option for reward points redeemable or not on shipping.

Thanks