1

On checkout page by default my saved addresses are rendered. How I'll set a custom address as shipping address instead of addresses shown from my account?

I've added an event to observe checkout page load

<?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="controller_action_predispatch_checkout_index_index">
        <observer name="vendorcheckout_before_dispatch" instance="Vendor\Module\Observer\Dispatch" />
    </event>
</config>

and here is my observer code

<?php

namespace Vendor\Module\Observer;
use Magento\Framework\Event\ObserverInterface;

class Dispatch implements ObserverInterface
{

    public function __construct(
        \Magento\Checkout\Model\Session $session,
        \Magento\Quote\Api\Data\AddressInterface $address,
        \Magento\Checkout\Api\ShippingInformationManagementInterface $shippingInformationManagement,
        \Magento\Checkout\Api\Data\ShippingInformationInterface $shippingInformation
    )
    {
        $this->session = $session;
        $this->address = $address;
        $this->shippingInformationManagement = $shippingInformationManagement;
        $this->shippingInformation = $shippingInformation;
    }

    /**
     * @param \Magento\Framework\Event\Observer $observer
     * @return void
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $address = $this->address
                    ->setFirstname('john')
                    ->setLastname('cena')
                    ->setStreet('xxxx')
                    ->setCity('Delhi')
                    ->setCountryId('US')
                    ->setRegionId(26)
                    ->setRegion('Kansas')
                    ->setPostcode('6666')
                    ->setTelephone('444')
                    ->setFax('3333')
                    ->setSaveInAddressBook(0)
                    ->setSameAsBilling(0);
        if ($this->session->getQuote()) {
            $cartId = $this->session->getQuote()->getId();
            if ($cartId) {
                $add = $this->shippingInformation->setShippingAddress($address);
                $this->shippingInformationManagement->saveAddressInformation($cartId, $add);
            }
        }
    }
}

Above code is throwing

Exception #0 (Magento\Framework\Exception\NoSuchEntityException): Carrier with such method not found: ,

Just to test manually I've added $carrierCode and $methodCode as flatrate in class module-checkout/Model/ShippingInformationManagement

This is adding shipping address properly to quote_address table. Though on checkout still my account addresses are shown instead of this custom shipping address from quote_address table.

Can someone guide me with following:
1. How to fix exception Carrier with such method not found ?
2. Do I need to update this address somewhere else also to render it on checkout page and save as shipping address with order?

  • 1
    have you tried in php code (observer etc) $quote->getShippingAddress()->addData($addressArray); ? – Idham Choudry Jul 12 '18 at 6:21
  • Not yet. I'll try to set shipping address from observer. Setting it from observer or knockout is recommended? – amitshree Jul 12 '18 at 6:42
  • i think you should go with observer first – Idham Choudry Jul 12 '18 at 9:22
  • @amitshree can you please share your module or give some hint. – Jimit Bhavsar Dec 21 '18 at 6:46
  • @JimitBhavsar Please check my answer. You will get lot of idea from there. – amitshree Dec 21 '18 at 13:43
0

This is how I have achieved it through my module:

etc/frontend/events.xml

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="controller_action_predispatch_checkout_index_index">
        <observer name="customcheckout_before_dispatch" instance="Vendor\Module\Observer\Dispatch" />
    </event>
</config>

Observer/Dispatch.php

<?php

namespace Vendor\Module\Observer;
use Magento\Framework\Event\ObserverInterface;

class Dispatch implements ObserverInterface
{

    public function __construct(
        \Magento\Checkout\Model\Session $session,
        \Magento\Quote\Api\Data\AddressInterface $address,
        \Magento\Checkout\Api\ShippingInformationManagementInterface $shippingInformationManagement,
        \Magento\Checkout\Api\Data\ShippingInformationInterface $shippingInformation,
        \Magento\Quote\Model\QuoteRepository $quoteRepository,
        \Vendor\Module\Helper\Data $helperData,
        \Magento\Framework\Url $url,
        \Magento\Framework\Message\ManagerInterface $messageManager,
        \Magento\Framework\App\ResponseFactory $responseFactory,
        \Magento\Framework\App\Response\Http $http
    )
    {
        $this->session = $session;
        $this->address = $address;
        $this->shippingInformationManagement = $shippingInformationManagement;
        $this->shippingInformation = $shippingInformation;
        $this->quoteRepository = $quoteRepository;
        $this->helperData = $helperData;
        $this->url = $url;
        $this->messageManager = $messageManager;
        $this->http = $http;
    }

    /**
     * @param \Magento\Framework\Event\Observer $observer
     * @return void
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {

        if ($this->session->getQuote()) {
            $cartId = $this->session->getQuote()->getId();
            if ($cartId) {
                $quote = $this->quoteRepository->getActive($cartId);
                $deliveryType = $quote->getDeliveryType();
                if ($deliveryType === 'store') {
                    $this->helperData->saveShippingInformation();
                }
            }

        }
    }

}

Helper/Data.php

<?php
namespace Vendor\Module\Helper;

use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Store\Model\ScopeInterface;

class Data extends AbstractHelper
{

    public function __construct(
        \Magento\Checkout\Model\Session $session,
        \Magento\Quote\Api\Data\AddressInterface $address,
        \Magento\Checkout\Api\ShippingInformationManagementInterface $shippingInformationManagement,
        \Magento\Checkout\Api\Data\ShippingInformationInterface $shippingInformation,
        \Magento\Framework\Message\ManagerInterface $messageManager,
        \Magento\Directory\Model\RegionFactory $regionFactory,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
    )
    {
        $this->session = $session;
        $this->address = $address;
        $this->shippingInformationManagement = $shippingInformationManagement;
        $this->shippingInformation = $shippingInformation;
        $this->messageManager = $messageManager;
        $this->regionFactory = $regionFactory;
        $this->scopeConfig = $scopeConfig;

    }

    public function saveShippingInformation()
    {
        if ($this->session->getQuote()) {
            $cartId = $this->session->getQuote()->getId();
            $cartSkuArray = $this->getCartItemsSkus();
            if ($cartSkuArray) {
                $shippingAddress = $this->getShippingAddressInformation();
         $this->shippingInformationManagement->saveAddressInformation($cartId, $shippingAddress);
            }
        }
    }
    public function getShippingAddressInformation() {
        $cartSkuArray = $this->getCartItemsSkus();
        $collectionPointResponse = $this->getCollectionPointAddress($cartSkuArray);
        $shippingAddress = $this->prepareShippingAddress($collectionPointResponse);
        $address = $this->shippingInformation->setShippingAddress($shippingAddress)
            ->setShippingCarrierCode('freeshipping')
            ->setShippingMethodCode('freeshipping');
        return $address;
    }

    /* prepare shipping address from your custom shipping address */
    protected function prepareShippingAddress($collectionPointResponse) {
        $collectionMessage = $collectionPointResponse['message'][0];
        $firstName = $collectionMessage['firstname'];
        $lastName = $collectionMessage['lastname'];
        $countryId = $collectionMessage['country_id'];
        $pincode = $collectionMessage['c_pincode'];
        $region = $collectionMessage['region'];;
        $street = $collectionMessage['c_address'];
        $city = $collectionMessage['c_city'];
        $telephone = $collectionMessage['telephone'];
        $regionId = $this->getRegionByName($region, $countryId);
        $address = $this->address
            ->setFirstname($firstName)
            ->setLastname($lastName)
            ->setStreet($street)
            ->setCity($city)
            ->setCountryId($countryId)
            ->setRegionId($regionId)
            ->setRegion($region)
            ->setPostcode($pincode)
            ->setTelephone($telephone)
            //->setFax('3333')
            ->setSaveInAddressBook(0)
            ->setSameAsBilling(0);
        return $address;
    }

    public function getCartItemsSkus() {
        $cartSkuArray = [];
        $cartItems = $this->session->getQuote()->getAllVisibleItems();
        foreach ($cartItems as $product) {
            $cartSkuArray[] = $product->getSku();
        }
        return $cartSkuArray;
    }

    public function getRegionByName($region, $countryId) {
        return $this->regionFactory->create()->loadByName($region, $countryId)->getRegionId();
    }

    protected function getCollectionPointAddress($cartSkuArray) {
      $customShipping = // write your logic here to gets your custom shipping
    return $customShipping;
    }
}

Note: This code saves shipping information every time you load the checkout page. You need to change it and add it to your specific scenario like I have modified it to save shipping information only when customer selects delivery type in delivery option module which is a different discussion.

  • I'm getting blank value for : $deliveryType = $quote->getDeliveryType(); – Jimit Bhavsar Jan 12 at 12:20
  • can you tell me how can i get value as "store" in above method – Jimit Bhavsar Jan 12 at 12:20
  • Seems your data is not inserted in quote table. Check quote table if you have data against field delivery_type . – amitshree Jan 14 at 6:05
  • @amitshree using this code address is saved but not render in the checkout page. is there need any changes for render custom quote address? – Emipro Technologies Pvt. Ltd. Mar 4 at 5:29
  • Checkout page address is shown from your my addresses section or local storage(if added a new address on checkout) and not from quote_address table. You need to customize their to show this address. – amitshree Mar 4 at 5:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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