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.
Best Answer
\Magento\Checkout\Model\Cart' class has been deprecated from
100.1.0`.Use
\Magento\Quote\Model\Quote
instead Please check https://github.com/magento/magento2/commit/e5479b4e7b87b8ad22dc1ca8e4c33556999da5f2