Magento2 | PWA | GraphQL

Show customer previous order data in checkout and auto select previous shipping address Magento2


In this post we will check how to show customer previous order data in checkout and auto select previous shipping address on checkout page Magento2. 



You can find complete module on Github at Magelearn_CustomerAddress

Let's start it by creating custom module.

Create folder inside app/code/Magelearn/CustomerAddress

Add registration.php file in it:

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
	\Magento\Framework\Component\ComponentRegistrar::MODULE,
	'Magelearn_CustomerAddress',
	__DIR__
);

Add composer.json file in it:

{
    "name": "magelearn/customer-address",
    "description": "Magento2 module which assign previous order data to quote",
    "type": "magento2-module",
    "license": "proprietary",
    "authors": [
        {
            "name": "vijay rami",
            "email": "vijaymrami@gmail.com"
        }
    ],
    "minimum-stability": "dev",
    "require": {},
    "autoload": {
        "files": [ "registration.php" ],
        "psr-4": {
            "Magelearn\\CustomerAddress\\": ""
        }
    }
}

Add etc/module.xml file in it:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Magelearn_CustomerAddress" setup_version="1.0.0">
  <sequence>
      <module name="Magento_Checkout"/>
  </sequence>
</module>
</config>

here first we will modifying ”initCheckout” in “Magento\Checkout\Model\Type\Onepage” with plugin and updating customer last order data to Quote Addresses.

For that Add etc/frontend/di.xml file.

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
  <type name="Magento\Checkout\Model\Type\Onepage">
       <plugin name="assign_address_to_quote" type="Magelearn\CustomerAddress\Model\Type\OnepagePlugin" />
   </type>
   <type name="Magento\Checkout\Model\DefaultConfigProvider">
        <plugin name="add_new_attribute_to_quote_data" type="Magelearn\CustomerAddress\Model\DefaultConfigProviderPlugin" />
    </type>
</config>
As per highlighted code above add Plugin file at Magelearn/CustomerAddress/Model/Type/OnepagePlugin.php
<?php
namespace Magelearn\CustomerAddress\Model\Type;

use Magelearn\CustomerAddress\Helper\Data;

class OnepagePlugin
{

    protected $_localHelper;

    public function __construct(
            Data $localhelper
    )
    {
        $this->_localHelper = $localhelper;
    }

    public function afterInitCheckout(
            \Magento\Checkout\Model\Type\Onepage $checkout,
            $result
    )
    {
        $customerSession = $checkout->getCustomerSession();

        /*
         * want to load the correct customer information by assigning to address
         * instead of just loading from sales/quote_address
         */
        $customer = $customerSession->getCustomerDataObject();
        if ($customer) {

            $order = $this->_localHelper->getLastOrder();
            if ($order && $order->getId()) {
                $this->_localHelper->saveCustomerAddressFromOrder($order);
            }
        }

        return $result;
    }
}

Now we will add our helper file at Magelearn/CustomerAddress/Helper/Data.php

<?php
namespace Magelearn\CustomerAddress\Helper;

use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Checkout\Model\Session;
use Magento\Customer\Api\AddressRepositoryInterface;

class Data extends AbstractHelper
{

    protected $_ordersFactory;

    protected $_session;

    protected $_checkoutSession;

    /**
     *
     * @var AddressRepositoryInterface
     */
    protected $addressRepository;

    protected $_lastOrder;

    public function __construct(
        \Magento\Customer\Model\Session $session,
        Session $checkoutSession,
        \Magento\Sales\Model\ResourceModel\Order\CollectionFactory $ordersFactory,
        AddressRepositoryInterface $addressRepository
    )
    {
        $this->_session = $session;
        $this->_ordersFactory = $ordersFactory;
        $this->_checkoutSession = $checkoutSession;
        $this->addressRepository = $addressRepository;
    }

    public function saveCustomerAddressFromOrder($order)
    {
        if ($this->_checkoutSession->getQuote() && $order->getId()) {
            $shippingAddressObj = $billingAddressObj = $order->getBillingAddress()->getData();
            $paymentDetails = $order->getPayment()->getData();

            if (! $order->getIsVirtual()) {
                $shippingAddressObj = $order->getShippingAddress()->getData();
            }
            $quote = $this->_checkoutSession->getQuote();
            $quote->getBillingAddress()->addData($billingAddressObj);
            $quote->getShippingAddress()->addData($shippingAddressObj);
            $quote->getPayment()->addData($paymentDetails);
            $quote->save();
            return;
        }
    }

    public function getLastOrder()
    {
        if (! $this->_lastOrder) {
            $customerId = $this->_session->getCustomer()->getId();
            $collection = $this->_ordersFactory->create()
                ->addFieldToFilter('customer_id', $customerId)
                ->setOrder('created_at', 'desc')
                ->setPageSize(1)
                ->load();
            foreach ($collection as $order) {
                $this->_lastOrder = $order;
                break;
            }
        }
        return $this->_lastOrder;
    }
}

Now as per highlighted in etc/frontend/di.xml file, to display previous order data in frontend we also need to save data in window.CheckoutConfig provider . In order to achieve this we need to add one more after plugin to GetConfig() method.

In this example we are adding 3 more attributes ('quote_shipping_address', 'quote_billing_address' and 'quote_paymentmethod') to window.CheckoutConfig.

Add Model/DefaultConfigProviderPlugin.php file.

<?php
namespace Magelearn\CustomerAddress\Model;

use Magento\Checkout\Model\Session as CheckoutSession;

class DefaultConfigProviderPlugin
{

    /**
     *
     * @var CheckoutSession
     */
    private $checkoutSession;

    /**
     *
     * @var \Magento\Quote\Api\CartRepositoryInterface
     */
    private $quoteRepository;

    public function __construct(
        CheckoutSession $checkoutSession,
        \Magento\Quote\Api\CartRepositoryInterface $quoteRepository)
    {
        $this->checkoutSession = $checkoutSession;
        $this->quoteRepository = $quoteRepository;
    }

    public function afterGetConfig(
        \Magento\Checkout\Model\DefaultConfigProvider $config,
        $output
    )
    {
        $output = $this->getCustomQuoteData($output);
        return $output;
    }

    private function getCustomQuoteData($output)
    {
        if ($this->checkoutSession->getQuote()->getId()) {
            $quote = $this->quoteRepository->get($this->checkoutSession->getQuote()
                ->getId());
            if (! $this->checkoutSession->getQuote()->isVirtual()) {
                if (isset($quote->getShippingAddress()->getData()['customer_address_id'])) {
                    $output['quoteData']['quote_shipping_address'] = $quote->getShippingAddress()->getData()['customer_address_id'];
                }
            }
            if (isset($quote->getBillingAddress()->getData()['customer_address_id'])) {
                $output['quoteData']['quote_billing_address'] = $quote->getBillingAddress()->getData()['customer_address_id'];
            }
            $output['quoteData']['quote_paymentmethod'] = $quote->getPayment()->getMethod();
        }
        return $output;
    }
}

Now at the time of checkout we will modify js models to load previous order's billing, shipping and Payment data properly.

For that first add view/frontend/requirejs-config.js file.

var config = {
    config: {
        'mixins': {
            'Magento_Checkout/js/model/checkout-data-resolver': {
                'Magelearn_CustomerAddress/js/model/checkout-data-resolver-mixin': true
            },
            "Magento_Checkout/js/model/quote" : {
              "Magelearn_CustomerAddress/js/model/quote-mixin": true
            }
        }
    }
};

Now as per highlighted in above file, we will add view/frontend/web/js/model/quote-mixin.js file.

define([
    'ko',
    'underscore'
], function (ko, _) {
    'use strict';
  
    return function (quote) {

      /**
       * @return {quote shipping address_id or null}
       */
      var quoteShippingAddress = function () {

          return (window.checkoutConfig.quoteData['quote_shipping_address']);
      };
      /**
       * @return {quote billing address_id or null}
       */
      var quoteBillingAddress = function () {
          return (window.checkoutConfig.quoteData['quote_billing_address']);
      };
      /**
       * @return {previous order payment method or null}
       */
      var quoteOrderPaymentMethod = function () {
          return (window.checkoutConfig.quoteData['quote_paymentmethod']);
      };
      quote.quoteShippingAddress = quoteShippingAddress;
      quote.quoteBillingAddress = quoteBillingAddress;
      quote.quoteOrderPaymentMethod = quoteOrderPaymentMethod;
      return quote;
    };
  });

Also Add view/frontend/web/js/model/checkout-data-resolver-mixin.js

define([
  'Magento_Customer/js/model/address-list',
  'Magento_Checkout/js/model/quote',
  'Magento_Checkout/js/checkout-data',
  'Magento_Checkout/js/action/create-shipping-address',
  'Magento_Checkout/js/action/select-shipping-address',
  'Magento_Checkout/js/action/select-shipping-method',
  'Magento_Checkout/js/model/payment-service',
  'Magento_Checkout/js/action/select-payment-method',
  'Magento_Checkout/js/model/address-converter',
  'Magento_Checkout/js/action/select-billing-address',
  'Magento_Checkout/js/action/create-billing-address',
  'underscore'],
function (
  addressList,
  quote,
  checkoutData,
  createShippingAddress,
  selectShippingAddress,
  selectShippingMethodAction,
  paymentService,
  selectPaymentMethodAction,
  addressConverter,
  selectBillingAddress,
  createBillingAddress,
  _){
    'use strict';

    return function (checkoutDataResolver) {
      //  return checkoutDataResolver.extend({

          var applyShippingAddress =  function(isEstimatedAddress){
              var address,
                  shippingAddress,
                  isConvertAddress,
                  addressData,
                  isShippingAddressInitialized;

              if (addressList().length === 0) {
                  address = addressConverter.formAddressDataToQuoteAddress(
                      checkoutData.getShippingAddressFromData()
                  );
                  selectShippingAddress(address);
              }
              shippingAddress = quote.shippingAddress();
              isConvertAddress = isEstimatedAddress || false;

              if (!shippingAddress) {
                  isShippingAddressInitialized = addressList.some(function (addressFromList) {
                      if (checkoutData.getSelectedShippingAddress() == addressFromList.getKey()) { //eslint-disable-line
                          addressData = isConvertAddress ?
                              addressConverter.addressToEstimationAddress(addressFromList)
                              : addressFromList;
                          selectShippingAddress(addressData);

                          return true;
                      }

                      return false;
                  });

                  if (!isShippingAddressInitialized) {
                      isShippingAddressInitialized = addressList.some(function (addrs) {
                        /*edit shipping*/
                        if (quote.quoteShippingAddress()){
                          if(addrs.customerAddressId == quote.quoteShippingAddress()) {
                              addressData = isConvertAddress ?
                                  addressConverter.addressToEstimationAddress(addrs)
                                  : addrs;
                              selectShippingAddress(addressData);

                              return true;
                          }
                        }
                        else if(addrs.isDefaultShipping()){
                           addressData = isConvertAddress ?
                              addressConverter.addressToEstimationAddress(addrs)
                              : addrs;
                            selectShippingAddress(addressData);

                             return true;
                           }
                      });
                  }

                  if (!isShippingAddressInitialized && addressList().length === 1) {
                      addressData = isConvertAddress ?
                          addressConverter.addressToEstimationAddress(addressList()[0])
                          : addressList()[0];
                      selectShippingAddress(addressData);
                  }
              }
          };
        var resolveBillingAddress = function(){
          var selectedBillingAddress = checkoutData.getSelectedBillingAddress(),
              newCustomerBillingAddressData = checkoutData.getNewCustomerBillingAddress();

          if (selectedBillingAddress) {
              if (selectedBillingAddress == 'new-customer-address' && newCustomerBillingAddressData) { //eslint-disable-line
                  selectBillingAddress(createBillingAddress(newCustomerBillingAddressData));
              } else {
                  addressList.some(function (address) {
                      if (selectedBillingAddress == address.getKey()) { //eslint-disable-line eqeqeq
                          selectBillingAddress(address);
                      }
                  });
              }
          } else {
            /*assign billing address*/
            if(quote.quoteBillingAddress()){
              addressList.some(function (addrs) {
                if (addrs.customerAddressId == quote.quoteBillingAddress()) {
                      selectBillingAddress(addrs);
                  }
              });
            }
            this.applyBillingAddress();
          }
        };
        var resolvePaymentMethod = function(){
          var availablePaymentMethods = paymentService.getAvailablePaymentMethods(),
              selectedPaymentMethod = checkoutData.getSelectedPaymentMethod();

          if (selectedPaymentMethod) {
              availablePaymentMethods.some(function (payment) {
                  if (payment.method == selectedPaymentMethod) { //eslint-disable-line eqeqeq
                      selectPaymentMethodAction(payment);
                  }
              });
          }
          else{
              if(quote.quoteOrderPaymentMethod()){
                availablePaymentMethods.some(function (payment) {
                  if (payment.method == quote.quoteOrderPaymentMethod()) { //previous order dat
                      selectPaymentMethodAction(payment);
                  }
                });
            }
          }
        };
      checkoutDataResolver.applyShippingAddress = applyShippingAddress;
      checkoutDataResolver.resolveBillingAddress = resolveBillingAddress;
      checkoutDataResolver.resolvePaymentMethod = resolvePaymentMethod;
        //});
        return checkoutDataResolver;
    }
});

After adding above files, Please place any order and add new shipping address.
So when next time when you Place order at that time previous order's Shipping address will be selected not default one 😋

0 Comments On "Show customer previous order data in checkout and auto select previous shipping address Magento2"

Back To Top