Questions
i want to add a custom shipping method with some fields.
up to creating the custom shipping method completed.it will show in the checkout and saved the custom shipping method as the shipping in order.
I want to add some field after select this shipping method and save in the orders table.
How can i do this?
hi Mujahidh Haseem,
Thanks for your question. I will try to answer you question first part.
create QaisarSatti/HelloWorld/etc/extension_attributes.xml
<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="testingfield" type="string"/>
</extension_attributes>
</config>
create QaisarSatti/HelloWorld/etc/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\ShippingInformationManagement">
<plugin name="custom_field" type="QaisarSatti\HelloWorld\Plugin\Checkout\Model\ShippingInformationManagement" sortOrder="1"/>
</type>
</config>
Create plugin QaisarSatti/HelloWorld/Plugin/Checkout/Model/ShippingInformationManagement.php
class ShippingInformationManagement
{
protected $quoteRepository;
public function __construct(
\Magento\Quote\Model\QuoteRepository $quoteRepository
) {
$this->quoteRepository = $quoteRepository;
}
/**
* @param \Magento\Checkout\Model\ShippingInformationManagement $subject
* @param $cartId
* @param \Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation
*/
public function beforeSaveAddressInformation(
\Magento\Checkout\Model\ShippingInformationManagement $subject,
$cartId,
\Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation
) {
$extAttributes = $addressInformation->getExtensionAttributes();
$customfield = $extAttributes->getCustomfield();
$quote->setCustomfield($customfield);
}
}
Render the component shippingAdditional section.
QaisarSatti/HelloWorld/view/frontend/layout/checkout_index_index.xml
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="checkout.root">
<arguments>
<argument name="jsLayout" xsi:type="array">
<item name="components" xsi:type="array">
<item name="checkout" xsi:type="array">
<item name="children" xsi:type="array">
<item name="steps" xsi:type="array">
<item name="children" xsi:type="array">
<item name="shipping-step" xsi:type="array">
<item name="children" xsi:type="array">
<item name="shippingAddress" xsi:type="array">
<item name="children" xsi:type="array">
<item name="shippingAdditional" xsi:type="array">
<item name="component" xsi:type="string">uiComponent</item>
<item name="displayArea" xsi:type="string">shippingAdditional</item>
<item name="children" xsi:type="array">
<item name="additional_block" xsi:type="array">
<item name="component" xsi:type="string">QaisarSatti_HelloWOrld/js/view/checkout/shipping/additional-fields</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>
Now create component.
QaisarSatti/HelloWorld/view/web/js/view/checkout/shipping/additional-fields.js
'uiComponent'
], function (Component) {
'use strict';
return Component.extend({
defaults: {
template: 'QaisarSatti_HelloWorld/checkout/shipping/additional-fields'
}
});
});
Now create component html file.
QaisarSatti/HelloWorld/view/web/template/checkout/shipping/additional-fields.html
Now overwrite following js
Magento/Checkout/view/frontend/web/js/model/shipping-save-processor/default.js
create QaisarSatti/HelloWorld/view/frontend/requirejs-config.js
"map": {
"*": {
'Magento_Checkout/js/model/shipping-save-processor/default': 'QaisarSatti_HelloWorld/js/model/shipping-save-processor/default'
}
}
};
Create default.js top add your field
QaisarSatti/HelloWorld/view/frontend/web/js/model/shipping-save-processor/default.js
[
'jquery',
'ko',
'Magento_Checkout/js/model/quote',
'Magento_Checkout/js/model/resource-url-manager',
'mage/storage',
'Magento_Checkout/js/model/payment-service',
'Magento_Checkout/js/model/payment/method-converter',
'Magento_Checkout/js/model/error-processor',
'Magento_Checkout/js/model/full-screen-loader',
'Magento_Checkout/js/action/select-billing-address'
],
function (
$,
ko,
quote,
resourceUrlManager,
storage,
paymentService,
methodConverter,
errorProcessor,
fullScreenLoader,
selectBillingAddressAction
) {
'use strict';
return {
saveShippingInformation: function () {
var payload;
if (!quote.billingAddress()) {
selectBillingAddressAction(quote.shippingAddress());
}
payload = {
addressInformation: {
shipping_address: quote.shippingAddress(),
billing_address: quote.billingAddress(),
shipping_method_code: quote.shippingMethod().method_code,
shipping_carrier_code: quote.shippingMethod().carrier_code,
extension_attributes:{
testingfield: $('[name="testingfield"]').val()
}
}
};
fullScreenLoader.startLoader();
return storage.post(
resourceUrlManager.getUrlForSetShippingInformation(quote),
JSON.stringify(payload)
).done(
function (response) {
quote.setTotals(response.totals);
paymentService.setPaymentMethods(methodConverter(response.payment_methods));
fullScreenLoader.stopLoader();
}
).fail(
function (response) {
errorProcessor.process(response);
fullScreenLoader.stopLoader();
}
);
}
};
}
);
Create observer to get the data.
create QaisarSatti/HelloWorld/etc/events.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="sales_model_service_quote_submit_before">
<observer name="customfield" instance="QaisarSatti\HelloWorld\Observer\SaveCustomFieldObserver"/>
</event>
</config>
create QaisarSatti/HelloWorld/Observer/SaveCustomFieldObserver.php
namespace QaisarSatti\HelloWorld\Observer;
use Magento\Framework\Event\Observer as EventObserver;
use Magento\Framework\Event\ObserverInterface;
class SaveCustomFieldObserver implements ObserverInterface
{
/**
* @var \Magento\Framework\ObjectManagerInterface
*/
protected $_objectManager;
/**
* @param \Magento\Framework\ObjectManagerInterface $objectmanager
*/
public function __construct(\Magento\Framework\ObjectManagerInterface $objectmanager)
{
$this->_objectManager = $objectmanager;
}
public function execute(EventObserver $observer)
{
$order = $observer->getOrder();
$quoteRepository = $this->_objectManager->create('Magento\Quote\Model\QuoteRepository');
/** @var \Magento\Quote\Model\Quote $quote */
$quote = $quoteRepository->get($order->getQuoteId());
echo $quote->getCustomfield();
return $this;
}
}