I am integrating In-store pickup in Magento 2 checkout page. I have called one ajax while check page is loaded and append all stores with the In-store shipping method.
The JS file:
require([
'jquery',
'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/shipping-rate-service'
], function($) {
url = $('.url').val();
$.ajax({
url: url+'pickupshipping/index',
}).done(function (data) {
$('#checkout-shipping-method-load').after('<div class="store_selectbox" style="display:none">'+data+'</div>');
});
$(document).on('click', '.table-checkout-shipping-method .row' ,function() {
var sel_val = $('.all_stores').val();
if ($('#s_method_freeshipping_freeshipping').is(':checked')) {
instockcheck(sel_val);
$('.store_selectbox').css('display', 'block');
} else {
$('.store_selectbox').css('display', 'none');
$('#in-store-address-display').html('');
$('#checkout-step-shipping').removeClass('sealed-content');
$('#display-error').html('');
}
});
$(document).on('click', '#shipping-method-buttons-container button', function(e){
if ($('#s_method_freeshipping_freeshipping').is(':checked')) {
var sel_val = $('.all_stores').val();
var receive_later = [];
var receive_asap = [];
var remove_p = [];
$('.remove_p').each(function(index, val){
if($(this).is(':checked')) {
remove_p.push($(this).parent().find('.each_pro').val());
}
});
$('.receive_asap').each(function(index, val){
if($(this).is(':checked')) {
receive_asap.push($(this).parent().find('.each_pro').val());
}
});
$('.receive_later').each(function(index, val){
if($(this).is(':checked')) {
receive_later.push($(this).parent().find('.each_pro').val());
}
});
$.ajax({
data: {choose_store: sel_val, remove_p: remove_p, receive_asap: receive_asap, receive_later, receive_later},
type: 'post',
url: url+'pickupshipping/index/checkoutnext',
}).done(function (data) {
});
}
});
$(document).on('change', '.all_stores', function() {
var sel_val = $('.all_stores').val();
instockcheck(sel_val);
});
function instockcheck(sel_val) {
$.ajax({
data: {choose_store: sel_val},
type: 'post',
url: url+'pickupshipping/index/checkoutinstockcheck',
}).done(function (data) {
if(data != 'success') {
url1 = window.location.href+'cart';
button_url = '<a href="'+url1+'">Goto Cart</a>';
if ($('#s_method_freeshipping_freeshipping').is(':checked')) {
$('#display-error').html(data+button_url);
instoredisplay(sel_val);
}
} else {
$('#display-error').html('');
if ($('#s_method_freeshipping_freeshipping').is(':checked')) {
instoredisplay(sel_val);
}
}
});
}
function instoredisplay(sel_val) {
$.post(url+'pickupshipping/index/getshopdetails', {choose_store: sel_val}, function(data, textStatus, xhr) {
$('#in-store-address-display').html(data);
});
}
});
This Ajax is called when choosing In-store shipping:
<?php
namespace Custom\Pickupshipping\Controller\Index;
use Magento\Framework\App\Action\Context;
//use Magento\Checkout\Model\Session as session;
class Checkoutinstockcheck extends \Magento\Framework\App\Action\Action
{
protected $_resultPageFactory;
public function __construct(Context $context, \Magento\Framework\View\Result\PageFactory $resultPageFactory)
{
$this->_resultPageFactory = $resultPageFactory;
parent::__construct($context);
}
public function execute()
{
$product_not_instock = array();
$shop_code = $this->getRequest()->getParam('choose_store');
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$cart = $objectManager->get('\Magento\Checkout\Model\Cart');
// retrieve quote items collection
$itemsCollection = $cart->getQuote()->getItemsCollection();
// get array of all items what can be display directly
$itemsVisible = $cart->getQuote()->getAllVisibleItems();
$index = 0;
if(!empty($itemsCollection)) {
foreach($itemsCollection as $each_item) {
$_product = $objectManager->create('Magento\Catalog\Model\Product')->load($each_item->getProductId());
$inStore = $_product->getResource()->getAttribute($shop_code)->getFrontend()->getValue($_product);
if($_product->getTypeId() == 'bundle') {
continue;
}
if(empty($inStore) || $inStore < 0) {
$product_not_instock[$index]['product_name'] = $_product->getName();
$product_not_instock[$index++]['id'] = $each_item->getProductId();
}
}
}
$msg = 'success';
if(!empty($product_not_instock)) {
$msg = '<div class="alert-msg-instock">Following product is not available in-store: <br/><ul>';
foreach($product_not_instock as $each_p) {
$action_html = '<div>
<div>The quantity requested for this item exceeds the selected stores inventory.</div><br/>
<div>Please select one of the following options:</div><br/>
<div class="pro_container">
Action Required: (Please check the box)<br/>
<input type="radio" name="checkout_options_'.$each_p['id'].'" class="receive_later" value="1" />Allow an additional 0-5 days to pick up my entire order<br/>
<input type="radio" name="checkout_options_'.$each_p['id'].'" class="receive_asap" value="2" />I would like to receive my items seperately as soon as the become available.<br/>
<input type="radio" name="checkout_options_'.$each_p['id'].'" class="remove_p" value="3" />Remove this item from my order<br/>
<input type="hidden" class="each_pro" value="'.$each_p['id'].'" />
</div>
</div>';
$msg .= '<li><div class="preduct_name" style="color:#000"><b>'.$each_p['product_name'].'</b></div>
<div>'.$action_html.'</div>
</li>';
}
$msg .= '</ul></div>';
}
echo $msg;
return;
}
}
But the Ajax call is giving 500 error.
Can anyone tell me what is the reason ?
Best Answer
Someone had almost the same issue on community.magento.com and I have added a solution there.
https://community.magento.com/t5/Programming-Questions/Show-custom-payment-method-error/m-p/58533#M1564