2

I added new step on checkout page. It would be between 1st step(shipping) and 3rd step(originally, it was 2nd step - review & payment)

I'm creating a module which has a custom shipping method, called as customer pickup and a extra step, called as Detail For Pickup.

When a customer select customer pickup as shipping method, the next step would be "Detail For Pickup" and if it is noted well, it should be moved to payment step.

By the way, when a customer select "Flat Rate" as shipping method, i would like to make it that the customized step should be skipped because i already set that shipping method as not pick-up order shipping method. so the function of pick up for detail doesn't need anymore.

Let me upload the snapshot of this and my code.

  • Case 1 - When customer select "Customer Pick Up" enter image description here enter image description here

  • Case 2 - When customer select "Fixed Rage" enter image description here

My Code has these functions

  1. Added custom shipping method
  2. Added extra step on checkout page
  3. When i set payment on delivery and credit card as payment method. When customer select customer pickup as shipping method,both payment should be shown on checkout page. Otherwise, only credit card should be shown as payment method on 3rd step.
  4. When customer select customer pickup as shipping method,the 2nd step should be skipped automatically

I NEED 4TH FUNCTION ON MY MODULE SERIOUSLY.IN ORDER TO REACH MY GOAL, I THINK IT NEEDS JAVASCRIPT AND PLUGIN KNOWLEDGE TO 4TH FUNCTION AS WHAI I IMPLEMENTED ON 3RD FUNCTION. BUT I COULDN'T GET WELL ON THIS CASE

Meezin\CustomerPickup\Model\Carrier\CustomerPickup.php

<?php


namespace Meezin\CustomerPickup\Model\Carrier;

use Magento\Quote\Model\Quote\Address\RateRequest;
use Magento\Shipping\Model\Rate\Result;

class CustomerPickup
    extends \Magento\Shipping\Model\Carrier\AbstractCarrier
    implements \Magento\Shipping\Model\Carrier\CarrierInterface
{
/**
 * Constant defining shipping code for method
 */
const SHIPPING_CODE = 'customerpickup';

/**
 * @var string
 */
protected $_code = self::SHIPPING_CODE;

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

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

/**
 * @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 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,
    array $data = []
) {
    $this->rateResultFactory = $rateResultFactory;
    $this->rateMethodFactory = $rateMethodFactory;
    parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
}

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

/**
 * @param RateRequest $request
 * @return bool|Result
 */
public function collectRates(RateRequest $request)
{
    if (!$this->getActiveFlag()) {
        // This shipping method is disabled in the configuration
        return false;
    }

    // Check whether order is eligible for customer pickup
        // Add logic here to determine if this order is eligible for this shipping method
        // e.g. Is the entire order in stock? Does the customer have a local address?

    // If the order is not eligible, return false
    // Otherwise, continue to build and return $result which includes our shipping method's details

    /** @var \Magento\Shipping\Model\Rate\Result $result */
    $result = $this->rateResultFactory->create();

    /** @var \Magento\Quote\Model\Quote\Address\RateResult\Method $method */
    $method = $this->rateMethodFactory->create();

    $method->setCarrier(self::SHIPPING_CODE);
    // Get the title from the configuration, as defined in system.xml
    $method->setCarrierTitle($this->getConfigData('title'));

    $method->setMethod(self::SHIPPING_CODE);
    // Get the title from the configuration, as defined in system.xml
    $method->setMethodTitle($this->getConfigData('name'));

    // Get the price from the configuration, as defined in system.xml
    $amount = $this->getConfigData('price');

    $method->setPrice($amount);
    $method->setCost($amount);

    $result->append($method);

    return $result;
}
}

Meezin\CustomerPickup\Model\Carrier\Plugin\CashondeliveryPlug.php

<?php
namespace Meezin\CustomerPickup\Plugin;
use Magento\Payment\Model\Method\AbstractMethod;
use Magento\Quote\Model\Quote;
class CashondeliveryPlug
{

  /**
   * @var \Magento\Checkout\Model\Session
   */
   protected $_checkoutSession;

  /**
   * Constructor
   *
   * @param \Magento\Checkout\Model\Session $checkoutSession
   */
    public function __construct
    (
        \Psr\Log\LoggerInterface $logger,
        \Magento\Checkout\Model\Session $checkoutSession
     ) {
        $this->logger = $logger;
        $this->_checkoutSession = $checkoutSession;
        return;
    }

    public function aroundIsAvailable(\Magento\Payment\Model\Method\AbstractMethod $subject, callable $proceed)
    {
        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $cart = $objectManager->get('Magento\Checkout\Model\Cart');
        $shippingMethod = $cart->getQuote()->getShippingAddress()->getShippingMethod();
        #$this->logger->debug($shippingMethod);
        if ($shippingMethod == 'flatrate_flatrate') {
            return false;
        }
        $result = $proceed();
        return $result;
      }
}

Meezin\CustomerPickup\view\frontend\web\template\pickup-detail.html

<!--Use 'stepCode' as id attribute-->

<div id="pickup-step-title"
     class="step-content"
     data-role="content">
    <form data-bind="submit: navigateToNextStep" novalidate="novalidate">
        <!-- 1. Ask customer if they need for this section or not-->
        <legend class="label">Are you Non Pick-up Customer? Then, Please skip this section</legend>
        <!-- 2. If yes, choose the pick-up store -->
        <label class="label">Pick-Up Store</label>
        <div class="control">
            <select name="pickup-store" id="pickup-store">
                <option id="ny" value="newyorkcity">New York City Store</option>
                <option id="qu" value="queens">Queens Store</option>
                <option id="nj" value="newjersey">New Jersey Store</option>
                <option id="la" value="losangeles">Los Angeles Store</option>
            </select>
        </div>
        <!-- 3. choose pick up date -->
        <label class="label">Pick-Up Time</label>
        <div class="control">
            <input class="input-text" type="date" name="pickup_date" id="pickup_date" readonly="true"/>
        </div>
        <!-- 4. Comment for Pick-up -->
        <label class="label">Add Comment</label>
        <div class="control">
            <textarea name="pickup_comment" id="pickup_comment"></textarea>
        </div>
        <div class="actions-toolbar">
            <div class="primary">
                <button data-role="opc-continue" type="submit" class="button action continue primary">
                    <span><!-- ko i18n: 'Next'--><!-- /ko --></span>
                </button>
            </div>
        </div>
    </form>
</div>

Meezin\CustomerPickup\view\frontend\web\js\view\checkout-pickup-step.js

define(
[
    'ko',
    'uiComponent',
    'underscore',
    'Magento_Checkout/js/model/step-navigator',
    'Magento_Customer/js/model/customer'
],
function (
    ko,
    Component,
    _,
    stepNavigator,
    customer
) {
    'use strict';
    /**
    * check-login - is the name of the component's .html template
    */
    return Component.extend({
        defaults: {
            template: 'Meezin_CustomerPickup/pickup-detail'
        },

        //add here your logic to display step,
        isVisible: ko.observable(true),
        isLogedIn: customer.isLoggedIn(),
        //step code will be used as step content id in the component template
        stepCode: 'isPickUp',
        //step title value
        stepTitle: 'Detail For Pick-up',

        /**
        *
        * @returns {*}
        */
        initialize: function () {
            this._super();
            // register your step
            stepNavigator.registerStep(
                this.stepCode,
                //step alias
                null,
                this.stepTitle,
                //observable property with logic when display step or hide step
                this.isVisible,

                _.bind(this.navigate, this),

                /**
                * sort order value
                * 'sort order value' < 10: step displays before shipping step;
                * 10 < 'sort order value' < 20 : step displays between shipping and payment step
                * 'sort order value' > 20 : step displays after payment step
                */
                15
            );

            return this;
        },

        /**
        * The navigate() method is responsible for navigation between checkout step
        * during checkout. You can add custom logic, for example some conditions
        * for switching to your custom step
        */
        navigate: function () {

        },

        /**
        * @returns void
        */
        navigateToNextStep: function () {
            stepNavigator.next();
        }
    });
}

);

Meezin\CustomerPickup\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">
                    <!-- this is for new step -->
                    <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">
                                        <!-- The new step you add -->
                                        <item name="check-pickup-step" xsi:type="array">
                                            <item name="component" xsi:type="string">Meezin_CustomerPickup/js/view/checkout-pickup-step</item>
                                                <!--To display step content before shipping step "sortOrder" value should be < 1-->
                                                <!--To display step content between shipping step and payment step  1 < "sortOrder" < 2 -->
                                                <!--To display step content after payment step "sortOrder" > 2 -->
                                            <item name="sortOrder" xsi:type="string">2</item>
                                            <item name="children" xsi:type="array">
                                                <!--add here child component declaration for your step-->
                                                <!--<item name="children" xsi:type="array">
                                                    <item name="pickup_store" xsi:type="array">
                                                    <item name="component" xsi:type="string">uiComponent</item>
                                                    <item name="sortOrder" xsi:type="string">10</item>
                                                    <item name="children" xsi:type="array" />
                                                    </item>
                                                </item>-->
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                    <!-- this is for new step -->
                </argument>
            </arguments>
    </referenceBlock>
</body>

Any idea? Thanks a lot

Your Answer

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

Browse other questions tagged or ask your own question.