Import Product custom

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="TQ_Migration" setup_version="1.1.0">
        <sequence>
            <module name="Magento_CatalogImportExport"/>
        </sequence>
    </module>
</config>
namespace TQ\Migration\Model\Import\Product;
class Product extends \Magento\CatalogImportExport\Model\Import\Product
{
    protected function _saveProducts() {
        //TODO
    }
}
namespace TTV\Migration\Model\Import\Product;

class CategoryPro cessor extends \Magento\CatalogImportExport\Model\Import\Product\CategoryProcessor
{
    protected function createCategory($name, $parentId) {
       //TODO
    }
}

Cron

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
    <group id="tq_product_import">
        <job name="tq_product_import" instance="TQ\ProductImportExport\Model\Import\Cron" method="execute">
            <config_path>tq_product_import/settings/cron_expr</config_path>
        </job>
    </group>
</config>

namespace TQ\Migration\Model\Import;

class Cron
{
    /**
     * @var \Magento\ImportExport\Model\Import
     */
    protected $import;</pre>
<pre>  /**
     * Execute the job
     *
     * @throws \Exception
  */
   public function execute() {
      //ToDo
   }</pre>
<pre>} 

or command

namespace TQ\Migration\Console\Command;
class ImportCommand extends Command
{
    /**
     * @var \Magento\Framework\ObjectManagerInterface
     */
    private $objectManager;

    /**
     * @var \Magento\Framework\App\State
     */
    private $state;

    /**
     * @param \Magento\Framework\ObjectManagerInterface $objectManager
     * @param \Magento\Framework\App\State $state
     */
    public function __construct(
        \Magento\Framework\ObjectManagerInterface $objectManager,
        \Magento\Framework\App\State $state
    ) {
        $this->objectManager = $objectManager;
        $this->state         = $state;
        parent::__construct();
    }

    /**
     * {@inheritdoc}
     */
    protected function configure()
    {
        $this->setName('data:import')
            ->setDescription('Import catalog')
            ->addArgument('filename', InputArgument::REQUIRED, "CSV file path")
            ->addOption('entity', 'e', InputOption::VALUE_OPTIONAL, 'Import entity type')
            ->addOption('images_path', "i", InputOption::VALUE_OPTIONAL, "Images path")
            ->addOption('behavior', "b", InputOption::VALUE_OPTIONAL, "Behavior");
        parent::configure();
    }

    /**
     * {@inheritdoc}
     */
    protected function execute(InputInterface $input, OutputInterface $output) {
        //TODO
    }

import.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_ImportExport:etc/import.xsd">
    <entity name="tq_customer" label="TQ Customers Import" model="TQ\Migration\Model\Import\Customer" behaviorModel="Magento\ImportExport\Model\Source\Import\Behavior\Custom" />
    <relatedIndexer entity="tq_customer" name="customer_grid" />
    <entity name="ttv_product" label="TQ Product Import" model="TQ\Migration\Model\Import\Product" behaviorModel="Magento\ImportExport\Model\Source\Import\Behavior\Custom" />
    <relatedIndexer entity="tq_product" name="product_grid" />
</config>

UI component

Vaimo/Checkout/view/frontend/requirejs-config.js

/**
 * Copyright © 2009-2017 TQ Group. All rights reserved.
 * See LICENSE.txt for license details.
 */
var config = {
    config: {
        mixins: {
            'Magento_Checkout/js/view/shipping': {
                'Vaimo_Checkout/js/view/checkout/address': true
            }
        }
    }
};

TQ/Checkout/view/frontend/layout/checkout_index_index.xml

<?xml version="1.0"?>
<!-- /**  * Copyright © 2009-2017 TQ Group. All rights reserved.  * See LICENSE.txt for license details.  **/ -->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="checkout"       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="sidebar" xsi:type="array">
                                   <item name="config" xsi:type="array">
                                        <item name="componentDisabled" xsi:type="boolean">true</item>
                                    </item>
                                </item>
                                <item name="steps" xsi:type="array">
                                    <item name="children" xsi:type="array">
                                        <item name="shipping_methods" xsi:type="array">
                                            <item name="component" xsi:type="string">Vaimo_Checkout/js/view/checkout/shipping-methods-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>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

TQ/Checkout/view/frontend/web/js/view/checkout/address.js

/**
 * Copyright © 2009-2017 TQ Group. All rights reserved.
 * See LICENSE.txt for license details.
 */
define(
    [
        'Magento_Customer/js/model/customer',
        'Magento_Checkout/js/model/quote',
        'Magento_Checkout/js/model/step-navigator',
        'mage/translate',
    ],
    function (
        customer,
        quote,
        stepNavigator,
        $t
    ) {
        'use strict';

        return function (shipping) {
            return shipping.extend({
                defaults: {
                    template: 'Vaimo_Checkout/checkout/address'
                },

                /**
                 * @return {exports}
                 */
                initialize: function () {
                    this._super();
                    stepNavigator.steps.sort(stepNavigator.sortItems).forEach(function(element) {
                        if (element.code == 'shipping') {
                            element.title = $t('Shipping Address');
                        }
                    });
                },

                validateShippingInformation: function(){
                    var shippingAddress,
                        addressData,
                        loginFormSelector = 'form[data-role=email-with-possible-login]',
                        emailValidationResult = customer.isLoggedIn();

                    if (!quote.shippingMethod()) {
                        this.selectShippingMethod(this.rates()[0]);
                    }

                    if (!customer.isLoggedIn()) {
                        $(loginFormSelector).validation();
                        emailValidationResult = Boolean($(loginFormSelector + ' input[name=username]').valid());
                    }

                    if (this.isFormInline) {
                        this.source.set('params.invalid', false);
                        this.source.trigger('shippingAddress.data.validate');

                        if (this.source.get('shippingAddress.custom_attributes')) {
                            this.source.trigger('shippingAddress.custom_attributes.data.validate');
                        }

                        if (this.source.get('params.invalid') || !emailValidationResult) {
                            return false;
                        }

                        shippingAddress = quote.shippingAddress();
                        addressData = addressConverter.formAddressDataToQuoteAddress(
                            this.source.get('shippingAddress')
                        );

                        //Copy form data to quote shipping address object
                        for (var field in addressData) {

                            if (addressData.hasOwnProperty(field) &&
                                shippingAddress.hasOwnProperty(field) &&
                                typeof addressData[field] != 'function' &&
                                _.isEqual(shippingAddress[field], addressData[field])
                            ) {
                                shippingAddress[field] = addressData[field];
                            } else if (typeof addressData[field] != 'function' &&
                                !_.isEqual(shippingAddress[field], addressData[field])) {
                                shippingAddress = addressData;
                                break;
                            }
                        }

                        if (customer.isLoggedIn()) {
                            shippingAddress.save_in_address_book = 1;
                        }
                        selectShippingAddress(shippingAddress);
                    }

                    if (!emailValidationResult) {
                        $(loginFormSelector + ' input[name=username]').focus();

                        return false;
                    }

                    return true;
                }
            });
        };
    }
);

TQ/Checkout/view/frontend/web/js/view/checkout/shipping-methods-step.js

/**
 * Copyright © 2009-2017 TQ Group. All rights reserved.
 * See LICENSE.txt for license details.
 **/

define(
    [
        'ko',
        'uiComponent',
        'underscore',
        'Magento_Checkout/js/model/step-navigator',
        'Magento_Checkout/js/model/shipping-service',
        'Magento_Checkout/js/action/set-shipping-information'
    ],
    function (
        ko,
        Component,
        _,
        stepNavigator,
        shippingService,
        setShippingInformationAction
    ) {
        'use strict';
        return Component.extend({
            defaults: {
                template: 'Vaimo_Checkout/checkout/shipping-methods'
            },
            //add here your logic to display step,
            isVisible: ko.observable(true),
            errorValidationMessage: ko.observable(false),

            /**
             *
             * @returns {*}
             */
            initialize: function () {
                this._super();
                // register your step
                stepNavigator.registerStep(
                    //step code will be used as step content id in the component template
                    'shipping_methods',
                    //step alias
                    null,
                    //step title value
                    'Shipping Methods',
                    //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;
            },

            rates: shippingService.getShippingRates(),

            /**
             * Set shipping information handler
             */
            setShippingInformation: function () {
                if (this.validateShippingInformation()) {
                    setShippingInformationAction().done(
                        function () {
                            stepNavigator.next();
                        }
                    );
                }
            },

            validateShippingInformation: function () {
                /**
                 * @see Add the logic here @see vendor/magento/module-checkout/view/frontend/web/js/view/shipping.js
                 */
                return true;
            },
            /**
             * 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();
            }
        });
    }
);

TQ/Checkout/view/frontend/web/template/checkout/address.html

<!-- /**  * Copyright © 2009-2017 TQ Group. All rights reserved.  * See LICENSE.txt for license details.  */ -->
	<li id="shipping" class="checkout-shipping-method" data-bind="fadeVisible: visible()">
<div class="step-title" data-bind="i18n: 'Shipping Address'" data-role="title"></div>
<div id="checkout-step-shipping"          class="step-content"          data-role="content">
<form class="form methods-shipping" data-bind="submit: setShippingInformation" novalidate="novalidate">
            <!-- ko if: (!quoteIsVirtual) -->
            <!-- ko foreach: getRegion('customer-email') -->
            <!-- ko template: getTemplate() --><!-- /ko -->
            <!--/ko-->
            <!--/ko-->

            <!-- ko foreach: getRegion('address-list') -->
            <!-- ko template: getTemplate() --><!-- /ko -->
            <!--/ko-->

            <!-- ko foreach: getRegion('address-list-additional-addresses') -->
            <!-- ko template: getTemplate() --><!-- /ko -->
            <!--/ko-->

            <!-- Address form pop up -->
            <!-- ko if: (!isFormInline) -->
            <button type="button"                     data-bind="click: showFormPopUp, visible: !isNewAddressAdded()"                     class="action action-show-popup">
                <span data-bind="i18n: 'New Address'"></span></button>
<div id="opc-new-shipping-address" data-bind="visible: isFormPopUpVisible()">
                <!-- ko template: 'Magento_Checkout/shipping-address/form' --><!-- /ko --></div>
<!-- /ko -->

            <!-- ko foreach: getRegion('before-form') -->
            <!-- ko template: getTemplate() --><!-- /ko -->
            <!--/ko-->

            <!-- Inline address form -->
            <!-- ko if: (isFormInline) -->
            <!-- ko template: 'Magento_Checkout/shipping-address/form' --><!-- /ko -->
            <!-- /ko -->
<div class="actions-toolbar" id="shipping-method-buttons-container">
<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></li>

view/frontend/web/template/checkout/shipping-methods.html

<!-- /**  * Copyright © 2009-2017 Vaimo Group. All rights reserved.  * See LICENSE.txt for license details.  **/ -->
	<li id="shipping_methods" data-bind="fadeVisible: isVisible">
<div class="step-title" data-bind="i18n: 'Shipping Methods'" data-role="title"></div>
<div id="checkout-step-title"          class="step-content"          data-role="content">
        <!-- ko if: rates().length  -->
<form class="form methods-shipping" id="co-shipping-method-form" data-bind="submit: setShippingInformation" novalidate="novalidate">
<div id="checkout-shipping-method-load">
<table class="table-checkout-shipping-method">
<thead>
<tr class="row">
<th class="col col-method" data-bind="i18n: 'Select Method'"></th>
<th class="col col-price" data-bind="i18n: 'Price'"></th>
<th class="col col-method" data-bind="i18n: 'Method Title'"></th>
<th class="col col-carrier" data-bind="i18n: 'Carrier Title'"></th>
</tr>
</thead>
<tbody>

                    <!--ko foreach: { data: rates(), as: 'method'}-->
<tr class="row" data-bind="click: $parent.selectShippingMethod">
<td class="col col-method">
                            <!-- ko ifnot: method.error_message -->
                            <!-- ko if: $parent.rates().length == 1 -->
                            <input class="radio"                                    type="radio"                                    data-bind="attr: {                                             checked: $parent.rates().length == 1,                                             'value' : method.carrier_code + '_' + method.method_code,                                             'id': 's_method_' + method.method_code,                                             'aria-labelledby': 'label_method_' + method.method_code + '_' + method.carrier_code + ' ' + 'label_carrier_' + method.method_code + '_' + method.carrier_code                                          }" />
                            <!-- /ko -->
                            <!--ko ifnot: ($parent.rates().length == 1)-->
                            <input type="radio"                                    data-bind="                                         value: method.carrier_code + '_' + method.method_code,                                         checked: $parent.isSelected,                                         attr: {                                             'id': 's_method_' + method.carrier_code + '_' + method.method_code,                                             'aria-labelledby': 'label_method_' + method.method_code + '_' + method.carrier_code + ' ' + 'label_carrier_' + method.method_code + '_' + method.carrier_code                                         },                                         click: $parent.selectShippingMethod"                                    class="radio"/>
                            <!--/ko-->
                            <!-- /ko --></td>
<td class="col col-price">
                            <!-- ko foreach: $parent.getRegion('price') -->
                            <!-- ko template: getTemplate() --><!-- /ko -->
                            <!-- /ko --></td>
<td class="col col-method"                             data-bind="text: method.method_title, attr: {'id': 'label_method_' + method.method_code + '_' + method.carrier_code}"></td>
<td class="col col-carrier"                             data-bind="text: method.carrier_title, attr: {'id': 'label_carrier_' + method.method_code + '_' + method.carrier_code}"></td>
</tr>
<!-- ko if:  method.error_message -->
<tr class="row row-error">
<td class="col col-error" colspan="4">
<div class="message error">
<div data-bind="text: method.error_message"></div>
</div>
<span class="no-display">
                            <input type="radio" data-bind="attr: {'value' : method.method_code, 'id': 's_method_' + method.method_code}"/>
                        </span></td>
</tr>
<!-- /ko -->

                    <!-- /ko --></tbody>
</table>
</div>
<div id="onepage-checkout-shipping-method-additional-load">
                <!-- ko foreach: getRegion('shippingAdditional') -->
                <!-- ko template: getTemplate() --><!-- /ko -->
                <!-- /ko --></div>
<!-- ko if: errorValidationMessage().length > 0 -->
<div class="message notice">
                <span><!-- ko text: errorValidationMessage()--><!-- /ko --></span></div>
<!-- /ko -->
<div class="actions-toolbar" id="shipping-method-buttons-container">
<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>

        <!-- /ko -->
        <!-- ko ifnot: rates().length > 0 -->
<div class="no-quotes-block"><!-- ko i18n: 'Sorry, no quotes are available for this order at this time'--><!-- /ko --></div>
<!-- /ko --></div></li>