0

I am working on https://www.depoto.com/.

Right now, we are having two delivery options for product availability like Product is available and Product is not available.

For this, we used https://www.magearray.com/check-delivery-availability-extension-for-magento-2.html Extension. In this extension, they provided the fields to add the pin codes. If the user entered pin code, Then available or not available message will display.

And, We provide two shipping methods like Free shipping and Flat rate shipping method

Flat rate shipping method should come to the product not available locations.

Note: Flat Rate method for Delivery available pin codes

My flatrate.php code is as follows:

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Magento\OfflineShipping\Model\Carrier;

use Magento\OfflineShipping\Model\Carrier\Flatrate\ItemPriceCalculator;
use Magento\Quote\Model\Quote\Address\RateRequest;
use Magento\Shipping\Model\Carrier\AbstractCarrier;
use Magento\Shipping\Model\Carrier\CarrierInterface;
use Magento\Shipping\Model\Rate\Result;

/**
 * Flat rate shipping model
 *
 * @api
 * @since 100.0.2
 */
class Flatrate extends AbstractCarrier implements CarrierInterface
{
    /**
     * @var string
     */
    protected $_code = 'flatrate';

    /**
     * @var bool
     */
    protected $_isFixed = true;

    /**
     * @var \Magento\Shipping\Model\Rate\ResultFactory
     */
    protected $_rateResultFactory;

    /**
     * @var \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory
     */
    protected $_rateMethodFactory;

    /**
     * @var ItemPriceCalculator
     */
    private $itemPriceCalculator;

    /**
     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
     * @param \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
     * @param \Psr\Log\LoggerInterface $logger
     * @param \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory
     * @param \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
     * @param ItemPriceCalculator $itemPriceCalculator
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
        \Psr\Log\LoggerInterface $logger,
        \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory,
        \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
        \Magento\OfflineShipping\Model\Carrier\Flatrate\ItemPriceCalculator $itemPriceCalculator,
        array $data = []
    ) {
        $this->_rateResultFactory = $rateResultFactory;
        $this->_rateMethodFactory = $rateMethodFactory;
        $this->itemPriceCalculator = $itemPriceCalculator;
        parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
    }

    /**
     * @param RateRequest $request
     * @return Result|bool
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     * @SuppressWarnings(PHPMD.NPathComplexity)
     */
    public function collectRates(RateRequest $request)
    {
        if (!$this->getConfigFlag('active')) {
            return false;
        }

        $freeBoxes = $this->getFreeBoxesCount($request);
        $this->setFreeBoxes($freeBoxes);

        /** @var Result $result */
        $result = $this->_rateResultFactory->create();

        $shippingPrice = $this->getShippingPrice($request, $freeBoxes);

        if ($shippingPrice !== false) {
            $method = $this->createResultMethod($shippingPrice);
            $result->append($method);
        }

        return $result;
    }

    /**
     * @param RateRequest $request
     * @return int
     */
    private function getFreeBoxesCount(RateRequest $request)
    {
        $freeBoxes = 0;
        if ($request->getAllItems()) {
            foreach ($request->getAllItems() as $item) {
                if ($item->getProduct()->isVirtual() || $item->getParentItem()) {
                    continue;
                }

                if ($item->getHasChildren() && $item->isShipSeparately()) {
                    $freeBoxes += $this->getFreeBoxesCountFromChildren($item);
                } elseif ($item->getFreeShipping()) {
                    $freeBoxes += $item->getQty();
                }
            }
        }
        return $freeBoxes;
    }

    /**
     * @return array
     */
    public function getAllowedMethods()
    {
        return ['flatrate' => $this->getConfigData('name')];
    }

    /**
     * @param RateRequest $request
     * @param int $freeBoxes
     * @return bool|float
     */
    private function getShippingPrice(RateRequest $request, $freeBoxes)
    {
        $shippingPrice = false;

        $configPrice = $this->getConfigData('price');
        if ($this->getConfigData('type') === 'O') {
            // per order
            $shippingPrice = $this->itemPriceCalculator->getShippingPricePerOrder($request, $configPrice, $freeBoxes);
        } elseif ($this->getConfigData('type') === 'I') {
            // per item
            $shippingPrice = $this->itemPriceCalculator->getShippingPricePerItem($request, $configPrice, $freeBoxes);
        }

        $shippingPrice = $this->getFinalPriceWithHandlingFee($shippingPrice);

        if ($shippingPrice !== false && $request->getPackageQty() == $freeBoxes) {
            $shippingPrice = '0.00';
        }
        return $shippingPrice;
    }

    /**
     * @param int|float $shippingPrice
     * @return \Magento\Quote\Model\Quote\Address\RateResult\Method
     */
    private function createResultMethod($shippingPrice)
    {
        /** @var \Magento\Quote\Model\Quote\Address\RateResult\Method $method */
        $method = $this->_rateMethodFactory->create();

        $method->setCarrier('flatrate');
        $method->setCarrierTitle($this->getConfigData('title'));

        $method->setMethod('flatrate');
        $method->setMethodTitle($this->getConfigData('name'));

        $method->setPrice($shippingPrice);
        $method->setCost($shippingPrice);
        return $method;
    }

    /**
     * @param mixed $item
     * @return mixed
     */
    private function getFreeBoxesCountFromChildren($item)
    {
        $freeBoxes = 0;
        foreach ($item->getChildren() as $child) {
            if ($child->getFreeShipping() && !$child->getProduct()->isVirtual()) {
                $freeBoxes += $item->getQty() * $child->getQty();
            }
        }
        return $freeBoxes;
    }
}

My check_availability.phtml file is as follows:

Path for this file: /app/code/MageArray/CheckDelivery/view/frontend/templates/product/view

<?php $product = $this->getCurrentProduct() ?>
<?php $helper=$this->helper("MageArray\CheckDelivery\Helper\Data");?>
<?php if($product && $product->getCheckDeliveryEnable() != 2 && $helper->getIsActive() == 1): ?>
    <form class="form" id="check-delivery-form" method="post">
       <fieldset class="fieldset">
           <legend class="legend"><span><?php echo __('Check Product Availability') ?></span></legend><br>
            <div class="row">
                <div class="field required col-sm-6">
                    <label for="delivery_postcode" class="label"><span><?php echo __('Pincode') ?></span></label>
                    <div class="control">
                        <input type="text" name="postcode" id="delivery_postcode" value="" title="<?php echo __('Postcode') ?>" class="input-text" data-validate="{required:true, 'validate-digits':true}">

                    </div>
                </div>
                <div class="actions-toolbar col-sm-6">
                    <div class="primary">
                        <button type="submit" class="action submit primary action-check-delivery" title="<?php  echo __('Check') ?>"><span><?php echo __('Check') ?></span></button>

                    </div>
                </div>
            </div>
            <div class="break"></div>
            <div class="message"></div>
       </fieldset>
     </form>
<script>
require([
    'jquery',
    'mage/mage'
], function ($) {
    var dataForm = $('#check-delivery-form');
    dataForm.mage('validation', {});
    var dataFormMessage = $('#check-delivery-form .message');
    dataFormMessage.removeClass('success').removeClass('error').hide();
    $('.action-check-delivery').on('click',function () {
            var formData = new FormData();
            formData.append('postcode', $('#check-delivery-form input[name="postcode"]').val());
            $.ajax({
                url: '<?php echo $this->getUrl('checkDelivery/postcode/check',['id'=> $product->getId()]) ?>',
                data: formData,
                processData: false,
                contentType: false,
                showLoader: true,
                type: 'POST',
                dataType: 'json',
                success: function (response) {
                    dataFormMessage.removeClass('success').removeClass('error').hide();
                    dataFormMessage.addClass(response.type).html(response.message).show();
                }
            });
            return false;
    });
});
</script>
<?php endif; ?>

Brief explanation:

We have two shipping methods, 1. Store pickup (customer will come to store and collect his items) 2. free shipping method.

We will provide the shipping items to some list of pincodes only. If any customer enter his area zip code for delivery, that entered zip code exists from our providing zipcodes, the free shipping and store pickup methods shold be same.

But if entered zipcode not available from our list, the store pickup only has to be one. For store pickup, we use flat rate method (Renamed from flat rate to Store pickup)

  • You are going to have to add a product attribute for product shipping method and create a new shipping method that looks for items with this attribute set in the quote. – Dominic Xigen Jul 8 at 20:31
1

You can enable or disable any shipping method by overriding core magento modules.

1 . Free shipping:

=> override collectRates method from

vendor/magento/module-offline-shipping/Model/Carrier/Freeshipping.php

class. Check the product availability by getting the items from request arguments.

=> $request->getAllItems() this way you can get all items from current quote. Add your conditions to check the availabilty.

=> If want disable the shipping method just return false in
collectRates method. When we return false in this method, shipping method will be disabled.

2 . FlatRate Shipping:

=> override collectRates method from

 vendor/magento/module-offline-shipping/Model/Carrier/Flatrate.php

class. Check the product availability by getting the items from request arguments.

=> $request->getAllItems() this way you can get all items from current quote. Add your conditions to check the availabilty.

=> If want disable the shipping method just return false in
collectRates method. When we return false in this method, shipping method will be disabled.

  • Yeah, it seems good. I am completely about the flat rate method only. And, I have used one extension for product availability. In this extension, they provided the fields to add the pin codes. If the user entered pin code, Then available or not available message will display. What should I do? – Teja Bhagavan Kollepara Jul 9 at 7:12
  • make a call to the function to check delivery status with the pincode. pincode can fetched from request argument, $request->getData('dest_postcode'). Based on the response from the function, you can enable/disable the shipping method. – Venugopal Chikkegowda Jul 9 at 7:16
  • Without looking at custom extension, it is very difficult to explain @TejaBhagavanKollepara – Venugopal Chikkegowda Jul 17 at 3:06
  • Please share your skype id and we will discuss. And please let me know which files should i share here – Teja Bhagavan Kollepara Jul 17 at 6:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.