0

I am trying to update Total amount if any user select "flat rate" shipping method. To achieve this, I've created a custom module using 'sales_quote_save_after' event observer. And getting user selected shipping method on checkout first step.

Here is my observer event which I've created.

Although I'm getting selected shipping method but cart total not updating. And I'm not getting what should I do to update Total.

public function execute(Observer $observer)
    {
        $quote= $observer->getEvent()->getQuote();
        $id = $quote->getId();
        $method = $observer->getEvent()->getQuote()->getShippingAddress()->getShippingMethod();
        if($method == 'flatrate_flatrate'){
            $charge = 10;
            $fee = $quote->getFee();
            $total = $objectManager->get('Magento\Quote\Model\Quote\Address\Total');
            $total->setTotalAmount('fee', $charge);
            $total->setBaseTotalAmount('fee', $charge);
            $total->setFee($charge);
            $quote->setFee($charge);
            $total->setGrandTotal($total->getGrandTotal() + $charge);
            $total->setBaseGrandTotal($total->getBaseGrandTotal() + $charge);
        }
        return $this;
    }

1 Answer 1

0

A better way to approach this is creating an item in quote section which allow you to set fee during you are in Cart or Checkout

app/code/Vendor/Module/etc/sales.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Sales:etc/sales.xsd">
    <section name="quote">
        <group name="totals">
            <item name="voucher" instance="Vendor\Module\Model\Quote\Discount" sort_order="450">
                <renderer name="adminhtml" instance="Vendor\Module\Block\Adminhtml\Order\Create\Totals\Fee"/>
                <renderer name="frontend" instance="Vendor\Module\Block\Checkout\Fee"/>
            </item>
        </group>
    </section>
</config>

app/code/Vendor/Module/Model/Quote/Discount.php

<?php

namespace Vendor\Module\Model\Quote;

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\Request\Http as Request;

class Discount extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
{
    /**
     * Discount calculation object
     *
     * @var \Magento\SalesRule\Model\Validator
     */
    protected $calculator;

    /**
     * Core event manager proxy
     *
     * @var \Magento\Framework\Event\ManagerInterface
     */
    protected $eventManager = null;

    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    protected $storeManager;

    /**
     * @var \Magento\Framework\Pricing\PriceCurrencyInterface
     */
    protected $priceCurrency;

    protected $shippingDiscountAdditional;
    protected $baseShippingDiscountAdditional;
    protected $shippingDiscount;
    protected $baseShippingDiscount;
    protected $logger;
    protected $request;


    public function __construct(
        \Magento\Framework\Event\ManagerInterface $eventManager,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
        \Magento\Framework\App\Request\Http $request,
        \Psr\Log\LoggerInterface $logger
    ) {
        $this->eventManager = $eventManager;
        $this->storeManager = $storeManager;
        $this->priceCurrency = $priceCurrency;
        $this->logger = $logger;
        $this->request  = $request;
    }

    /**
     * Collect address discount amount
     *
     * @param \Magento\Quote\Model\Quote $quote
     * @param \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment
     * @param \Magento\Quote\Model\Quote\Address\Total $total
     * @return $this
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     */
    public function collect(
        \Magento\Quote\Model\Quote $quote,
        \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment,
        \Magento\Quote\Model\Quote\Address\Total $total
    ) {
        parent::collect($quote, $shippingAssignment, $total);

        $store = $this->storeManager->getStore($quote->getStoreId());
        /** @var $address \Magento\Quote\Model\Shipping */
        $address = $shippingAssignment->getShipping()->getAddress();

        $items = $shippingAssignment->getItems();

        if (!count($items)) {
            return $this;
        }

        try {

        $method = $quote->getShippingAddress()->getShippingMethod();

        if ($method == 'flatrate_flatrate') {
            $charge = 10;
            $total->setTotalAmount('fee', $charge);
            $total->setBaseTotalAmount('fee', $charge);
            $total->setFee($charge);
            $quote->setFee($charge);
            $total->setGrandTotal($total->getGrandTotal() + $charge);
            $total->setBaseGrandTotal($total->getBaseGrandTotal() + $charge);
            $quote->save();
        }

        } catch (\Exception $e) {
            $this->logger->critical($e->getMessage());
        }
        return $this;
    }

    /**
     * Add discount total information to address
     *
     * @param \Magento\Quote\Model\Quote $quote
     * @param \Magento\Quote\Model\Quote\Address\Total $total
     * @return array|null
     */
    public function fetch(\Magento\Quote\Model\Quote $quote, \Magento\Quote\Model\Quote\Address\Total $total)
    {
        $result = null;
        $amount = $total->getFee();

        if ($amount != 0) {
            $description = $total->getDiscountDescription();
            $result = [
                'code' => 'fee',
                'title' => __('Fee'),
                'value' => $amount,
            ];
        }
        return $result;
    }
}

app/code/Vendor/Module/Block/Checkout/Fee.php

<?php

namespace Vendor\Module\Block\Checkout;

class Fee extends \Magento\Checkout\Block\Total\DefaultTotal
{

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.