I want to display my custom extension attributes that are saved in quote on the ShippingInformation sidebar (underneath shipping method).
I have been able to successfully save my extension attributes to my quote, but unable to get them in Shipping Method Title() or Quote JS objects. How can I retrieve the extension attributes for display in the shipping method section.
etc/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Checkout\Block\Checkout\LayoutProcessor">
<plugin name="checkout_customshipping_fields" type="VendorName\ModuleName\Plugin\Checkout\LayoutProcessorPlugin" sortOrder="10"/>
</type>
<type name="Magento\Checkout\Model\ShippingInformationManagement">
<plugin name="save_customshipping_to_quote" type="VendorName\ModuleName\Plugin\Quote\SaveToQuote" sortOrder="10"/>
</type>
</config>
etc/extensions_attributes.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
<extension_attributes for="Magento\Checkout\Api\Data\ShippingInformationInterface">
<attribute code="customfield1" type="string" />
<attribute code="customfield2" type="string" />
</extension_attributes>
</config>
Plugin/SaveToQuote.php
<?php
namespace VendorName\ModuleName\Plugin\Quote;
use Magento\Quote\Model\QuoteRepository;
class SaveToQuote
{
protected $quoteRepository;
protected $logger;
public function __construct(
QuoteRepository $quoteRepository,
\Psr\Log\LoggerInterface $logger
) {
$this->quoteRepository = $quoteRepository;
$this->logger = $logger;
}
public function beforeSaveAddressInformation(
\Magento\Checkout\Model\ShippingInformationManagement $subject,
$cartId,
\Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation
) {
if(!$extAttributes = $addressInformation->getExtensionAttributes())
return;
$quote = $this->quoteRepository->getActive($cartId);
$quote->setCustomfield1($extAttributes->getCustomfield1());
$quote->setCustomfield2($extAttributes->getCustomfield2());
}
}
view/frontend/requirejs-config.js
var config = {
config: {
mixins: {
'Magento_Checkout/js/view/shipping': {
'VendorName_ModuleName/js/view/shipping': true
},
'Magento_Checkout/js/view/shipping-information': {
'VendorName_ModuleName/js/view/shipping-information': true
}
}
},
"map": {
"*": {
'Magento_Checkout/js/model/shipping-save-processor/payload-extender': 'VendorName_ModuleName/js/model/shipping-save-processor/payload-extender-override'
}
}
};
view/frontend/web/js/view/shipping.js
define(
[
'jquery',
'underscore',
'Magento_Ui/js/form/form',
'ko',
'Magento_Customer/js/model/customer',
'Magento_Customer/js/model/address-list',
'Magento_Checkout/js/model/address-converter',
'Magento_Checkout/js/model/quote',
'Magento_Checkout/js/action/create-shipping-address',
'Magento_Checkout/js/action/select-shipping-address',
'Magento_Checkout/js/model/shipping-rates-validator',
'Magento_Checkout/js/model/shipping-address/form-popup-state',
'Magento_Checkout/js/model/shipping-service',
'Magento_Checkout/js/action/select-shipping-method',
'Magento_Checkout/js/model/shipping-rate-registry',
'Magento_Checkout/js/action/set-shipping-information',
'Magento_Checkout/js/model/step-navigator',
'Magento_Ui/js/modal/modal',
'Magento_Checkout/js/model/checkout-data-resolver',
'Magento_Checkout/js/checkout-data',
'uiRegistry',
'mage/translate',
'Magento_Checkout/js/model/shipping-rate-service'
],function (
$,
_,
Component,
ko,
customer,
addressList,
addressConverter,
quote,
createShippingAddress,
selectShippingAddress,
shippingRatesValidator,
formPopUpState,
shippingService,
selectShippingMethodAction,
rateRegistry,
setShippingInformationAction,
stepNavigator,
modal,
checkoutDataResolver,
checkoutData,
registry,
$t
) {
'use strict';
var mixin = {
initObservable: function () {
this._super();
this.selectedMethod = ko.computed(function() {
var method = quote.shippingMethod();
var selectedMethod = method != null ? method.carrier_code + '_' + method.method_code : null;
return selectedMethod;
}, this);
return this;
},
/**
* Set shipping information handler
*/
setShippingInformation: function () {
if (this.validateMyShipping() && this.validateShippingInformation()) {
setShippingInformationAction().done(
function () {
stepNavigator.next();
}
);
}
},
validateMyShipping: function () {
var shippingMethod = quote.shippingMethod().method_code+'_'+quote.shippingMethod().carrier_code;
if (this.source.get('customfields') && shippingMethod == "customshipping_customshipping") {
this.source.set('params.invalid', false);
this.source.trigger('customfields.data.validate');
if(this.source.get('params.invalid')) {
return false;
}
}
return true;
}
};
return function (target) {
return target.extend(mixin);
};
});
view/frontend/web/js/model/shipping-save-processor/payload-extender-override.js
define([
'jquery',
], function ($) {
'use strict';
return function (payloadExtender) {
payloadExtender.addressInformation['extension_attributes'] = {
customfield1: $('[name="customfields[customfield1]"]').val(),
customfield2: $('[name="customfields[customfield2]"]').val()
};
console.log('payloadExtender:', payloadExtender.addressInformation); // working, shows extensionattributes
return payloadExtender;
};
});
view/frontend/web/js/view/shipping-information.js
define([
'jquery',
'uiComponent',
'Magento_Checkout/js/model/quote',
'Magento_Checkout/js/model/step-navigator',
'Magento_Checkout/js/model/sidebar'
], function ($, Component, quote, stepNavigator, sidebarModel) {
'use strict';
var mixin = {
/**
* @return {String}
*/
getShippingMethodTitle: function () {
var shippingMethod = quote.shippingMethod();
if(shippingMethod) {
var shippingMethodContent = shippingMethod['carrier_title'] + ' - ' + shippingMethod['method_title'];
var shippingMethodCode = shippingMethod['carrier_code'] + '_' + shippingMethod['method_code'];
if(shippingMethodCode === 'customshipping_customshipping') {
console.log("SHIPPING METHOD", shippingMethod, quote);
// EXTENSION ATTRIBUTES NOT AVAILABLE HERE, I want to change shipping method content
}
return shippingMethodContent;
}
return '';
}
};
return function (target) {
return target.extend(mixin);
};
});
Inside shipping-information.js getShippingMethodTitle() mixin, I expected to see quote['extensionattributes']['customfield1'] quote['extensionattributes']['customfield2']
I can't find where I can access the custom extension attributes from within this function. As you can see, I used console.log to print the object of quote, but these attributes do not exist anywhere.
The attributes have been successfully saved to my database table 'quote'.
What do I need to do to access these new extension attributes within the mixin for getShippingMethodTitle?