2

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?

5
  • 1
    have you tried in php code (observer etc) $quote->getShippingAddress()->addData($addressArray); ? Jul 12, 2018 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, 2018 at 6:42
  • i think you should go with observer first Jul 12, 2018 at 9:22
  • @amitshree can you please share your module or give some hint. Dec 21, 2018 at 6:46
  • @JimitBhavsar Please check my answer. You will get lot of idea from there.
    – amitshree
    Dec 21, 2018 at 13:43

1 Answer 1

1

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.

5
  • I'm getting blank value for : $deliveryType = $quote->getDeliveryType(); Jan 12, 2019 at 12:20
  • can you tell me how can i get value as "store" in above method Jan 12, 2019 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, 2019 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? Mar 4, 2019 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, 2019 at 5:37

Your Answer

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

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