Our Work
200+ Enterprises across globally trust KTree for their Web & Mobile application Development needs.See What We Do
Updated today
Concepts we are using: mixins(for overriding js components ),plugins(for overriding public methods)
This article will explain how to show customer previous order data in checkout and how to override core javascript files in magento
Flow Diagram
Create module which is extended from magento_checkout module.Please refer this article for Module Creation.
https://ktree.com/create-magento-2-module-custom.html
By using InitCheckout() method magento will assign customer default shipping and billing addresses to quote.
We need to modify InitCheckout() method to assign previous order data to quote so, Instead of overriding InitCheckout() method created after plugin method to InitCheckout() method.
A plugin is a great way to expand or edit a public method’s behavior by using code before, after or around method.
By using this Magento 2 Plugin Interception, you can modify the behavior of a class while there is no need to change the class directly.
In our example we are using after plugin interceptor to modify InitCheckout() method
Magento runs all after methods following the completion of the observed method. Magento requires these methods have a return value and they must have the same name as the observed method with ‘after’ as the prefix.
Below after method will copy the customer previous order data to quote
Note: after* methods will also supports parameters of observed methods (if magento version >2.2)
To create after plugin to method to InitCheckout() we need to follow following steps.
Create di.xml file in etc/frontend folder
<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="KTree\Custom\Model\Type\OnepagePlugin" />
</type>
</config>
Here: we are modifying ”initCheckout” in “Magento\Checkout\Model\Type\Onepage”
and updating customer last order data to Quote Addresses.
Create plug-in for modify after method in OnepagePlugin.php file under KTree/Custom/Model/Type/OnepagePlugin folder.
File: app/code/KTree/Custom/Model/Type/OnepagePlugin.php
<?php
namespace KTree\Custom\Model\Type;
use KTree\Custom\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;
}
}
?>
File: app/code/KTree/Custom/Helper/Data.php
<?php
namespace KTree\Custom\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;
}
}
?>
<type name="Magento\Checkout\Model\DefaultConfigProvider">
<plugin name="add_new_attribute_to_quote_data" type="KTree\Custom\Model\DefaultConfigProviderPlugin" /> </type>
The final app/code/KTree/Custom/etc/frontend/di.xml file will be like below
File: app/code/KTree/Custom/etc/frontend/di.xml
<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="KTree\Custom\Model\Type\OnepagePlugin" />
</type>
<type name="Magento\Checkout\Model\DefaultConfigProvider">
<plugin name="add_new_attribute_to_quote_data" type="KTree\Custom\Model\DefaultConfigProviderPlugin" />
</type>
</config>
File: app/code/KTree/Custom/Model/DefaultConfigProviderPlugin.php
<?php
namespace KTree\Custom\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());
$output['quoteData']['quote_shipping_address'] = $quote->getShippingAddress()->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 run “php bin/magento cache:clean” command to clear cache and refresh page ,
press F12 and run the window.checkoutConfig.quoteData.quote_shipping_address. You see,
We need to override core js files to select shipping billing addresses and payment method in frontend.
In order to override js files we need to create requirejs-config.js in app/code/KTree/Custom/view/frontend folder.
var config = {
config: {
'mixins': {
'Magento_Checkout/js/model/checkout-data-resolver': {
'KTree_Custom/js/model/checkout-data-resolver-mixin': true
},
'Magento_Checkout/js/model/quote' : {
'KTree_Custom/js/model/quote-mixin': true
}
}
}
};
In our example, we are creating requirejs-config.js file in app/code/KTree/Custom/view/frontend folder
File: app/code/KTree/Custom/view/frontend/requirejs-config.js
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;
};
});
Override checkout-data-resolver js component functions in checkout-data-resolver-mixin.js file and create the file under KTree/Custom/view/frontend/web/js/model folder to preselect customer previous order data instead of customer default data.
File: app/code/KTree/Custom/view/frontend/web/js/model/checkout-data-resolver-mixin.js
/*magento getconfig() method will create config object with current customer and get that config data using below js code*/
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) {
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) {
//addressList will return all addresses of customer
isShippingAddressInitialized = addressList.some(function (addressFromList) {
//get shipping and billing address from cookies and compare with customer address
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;
}
}
//if customer did not have order history show customer default address
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) {
//get customer previous payment method from last order
if (payment.method == quote.quoteOrderPaymentMethod()) { dat
selectPaymentMethodAction(payment);
}
});
}
}
};
checkoutDataResolver.applyShippingAddress = applyShippingAddress;
checkoutDataResolver.resolveBillingAddress = resolveBillingAddress;
checkoutDataResolver.resolvePaymentMethod = resolvePaymentMethod;
//});
return checkoutDataResolver;
}
});
Please Contact us if you have any Magento Implementation requirements. Hire dedicated Magento developers or Magento Development services from KTree. KTree is Best offshore Magento E-commerce development company with extensive experience in E-commerce development and Magento Plugins.
Request For Quote