Magento 2 Trashcan extension

It might have happened with each of the Magento 2 store owners out there that you deleted any product by mistakes. This extension might come in handy at that time to recovers those deleted products from the trashcan. A must have extension for all Magento 2 stores.

Feature:

      Simple and quick installation
      Restore of products, including metadata and images
      100% open source
      No limitations, no extra costs
      Restore easily from the trashcan (Trashcan > Manage Trashcan)

Download TrashCan for Magento 2 from here

Enjoy!

How to add custom field to Shipping Address form in Magento 2 Onepage Checkout

Magento2 checkout is much improvement than magento 1. It’s complex too. So adding new field is not same as magento 1, but in magento 2 it’s simple. So we go with much explanation for adding custom input field.

Suppose vendor name SR and Module name is CheckoutAdditionalField

Step 1: Create module.xml

app/code/SR/CheckoutAdditionalField/etc/module.xml
<?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="SR_CheckoutAdditionalField" setup_version="2.0.0">
        <sequence>
            <module name="Magento_Checkout"/>
        </sequence>
    </module>
</config>

Step 2: Create composer.json

app/code/SR/CheckoutAdditionalField/composer.json
{
    "name": "sr/module-checkoutadditionalfield",
    "description": "Checkout Additional Field",
    "require": {
        "php": "~5.5.0|~5.6.0|~7.0.0",
        "magento/framework": "100.0.*",
        "magento/module-ui": "100.0.*",
        "magento/module-config": "100.0.*",
        "magento/module-checkout": "100.0.*"
    },
    "type": "magento2-module",
    "version": "100.0.0",
    "license": [
        "OSL-3.0",
        "AFL-3.0"
    ],
    "autoload": {
        "files": [ "registration.php" ],
        "psr-4": {
            "SR\\CheckoutAdditionalField\\": ""
        }
    }
}

Step 3: Create registration.php

app/code/SR/CheckoutAdditionalField/registration.php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'SR_CheckoutAdditionalField',
    __DIR__
);

Step 4: Now need to overwrite Magento\Checkout\Block\Checkout\LayoutProcessor process method. So create a plugin,

SR/CheckoutAdditionalField/Plugin/Checkout/Model/Checkout/LayoutProcessor.php
namespace SR\CheckoutAdditionalField\Plugin\Checkout\Model\Checkout;


class LayoutProcessor
{
    /**
     * @param \Magento\Checkout\Block\Checkout\LayoutProcessor $subject
     * @param array $jsLayout
     * @return array
     */
    public function afterProcess(
        \Magento\Checkout\Block\Checkout\LayoutProcessor $subject,
        array  $jsLayout
    ) {
        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
        ['shippingAddress']['children']['shipping-address-fieldset']['children']['delivery_date'] = [
            'component' => 'Magento_Ui/js/form/element/abstract',
            'config' => [
                'customScope' => 'shippingAddress',
                'template' => 'ui/form/field',
                'elementTmpl' => 'ui/form/element/date',
                'options' => [],
                'id' => 'delivery-date'
            ],
            'dataScope' => 'shippingAddress.delivery_date',
            'label' => 'Delivery Date',
            'provider' => 'checkoutProvider',
            'visible' => true,
            'validation' => [],
            'sortOrder' => 250,
            'id' => 'delivery-date'
        ];

        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
        ['shippingAddress']['children']['shipping-address-fieldset']['children']['drop_down'] = [
            'component' => 'Magento_Ui/js/form/element/select',
            'config' => [
                'customScope' => 'shippingAddress',
                'template' => 'ui/form/field',
                'elementTmpl' => 'ui/form/element/select',
                'id' => 'drop-down',
            ],
            'dataScope' => 'shippingAddress.drop_down',
            'label' => 'Drop Down',
            'provider' => 'checkoutProvider',
            'visible' => true,
            'validation' => [],
            'sortOrder' => 251,
            'id' => 'drop-down',
            'options' => [
                [
                    'value' => '',
                    'label' => 'Please Select',
                ],
                [
                    'value' => '1',
                    'label' => 'First Option',
                ]
            ]
        ];

        return $jsLayout;
    }
}

You can download this sample module from here

How to add custom button in admin order detail page in magento 2

Suppose vendor name ‘SR‘ and Module name ‘RewriteSales

Create a plugin in SR/RewriteSales/etc/adminhtml/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Backend\Block\Widget\Context">
        <plugin name="add_custom_button_sales_veiw" type="SR\RewriteSales\Plugin\Widget\Context" sortOrder="1"/>
    </type>
</config>

Then create in SR/RewriteSales/Plugin/Widget/Context.php

namespace SR\RewriteSales\Plugin\Widget;


class Context
{
    public function afterGetButtonList(
        \Magento\Backend\Block\Widget\Context $subject,
        $buttonList
    )
    {
        if($subject->getRequest()->getFullActionName() == 'sales_order_view'){
            $buttonList->add(
                'custom_button',
                [
                    'label' => __('Custom Button'),
                    'onclick' => "setLocation('window.location.href')",
                    'class' => 'ship'
                ]
            );
        }

        return $buttonList;
    }
}

Enjoy!

Magento Trashcan extension

It might have happened with each of the Magento store owners out there that you deleted any product by mistakes. This extension might come in handy at that time to recovers those deleted products from the trashcan. A must have extension for all Magento stores.

Feature:

      Simple and quick installation
      Restore of products, including metadata and images
      100% open source
      No limitations, no extra costs
      Restore easily from the trashcan (Trashcan > Manage Trashcan)

Quick steps to get it working
1. Download TrashCan from here
2. Copy all file to your site
3. Clear cache.

Done!

View and Filter Product sku and name in Magento sales order grid

This feature is really very important, but by default this feature is missing. So lets do it.
NameSpace : MyPackage and Module: MyModule

Module configuration

<!-- app/etc/modules/MyPackage_MyModule.xml -->
<config>
    <modules>
        <MyPackage_MyModule>
            <active>true</active>
            <codePool>local</codePool>
        </MyPackage_MyModule>
    </modules>
</config>

Create config file for this module

<!-- app/code/local/MyPackage/MyModule/etc/config.xml -->
<?xml version="1.0"?>
<config>
    <modules>
        <MyPackage_MyModule>
            <version>0.0.0.1</version>
        </MyPackage_MyModule>
    </modules>
    <global>
        <blocks>
            <mymodule>
                <class>MyPackage_MyModule_Block</class>
            </mymodule>
            <adminhtml>
                <rewrite>
                    <sales_order_grid>MyPackage_MyModule_Block_Adminhtml_Sales_Order_Grid</sales_order_grid>
                </rewrite>
            </adminhtml>
        </blocks>
    </global>
</config>

Create a Grid.php file in the following location.

<?php
// app/code/local/MyPackage/MyModule/Block/Adminhtml/Sales/Order/Grid.php
class MyPackage_MyModule_Block_Adminhtml_Sales_Order_Grid extends Mage_Adminhtml_Block_Widget_Grid
{
    
}

Copy all content from /app/code/core/Mage/Adminhtml/Block/Sales/Order/grid.php into app/code/local/MyPackage/MyModule/Block/Adminhtml/Sales/Order/Grid.php.

<?php
// app/code/local/MyPackage/MyModule/Block/Adminhtml/Sales/Order/Grid.php
class MyPackage_MyModule_Block_Adminhtml_Sales_Order_Grid extends Mage_Adminhtml_Block_Widget_Grid
{
    public function __construct()
    {
        parent::__construct();
        $this->setId('sales_order_grid');
        $this->setUseAjax(true);
        $this->setDefaultSort('created_at');
        $this->setDefaultDir('DESC');
        $this->setSaveParametersInSession(true);
    }

    /**
     * Retrieve collection class
     *
     * @return string
     */
    protected function _getCollectionClass()
    {
        return 'sales/order_grid_collection';
    }
---------------
--------
----------
    public function getGridUrl()
    {
        return $this->getUrl('*/*/grid', array('_current'=>true));
    }
}

Now replace _prepareCollection() function to the following code,

protected function _prepareCollection()
    {
        $collection = Mage::getResourceModel($this->_getCollectionClass())
            ->join(
                'sales/order_item',
                '`sales/order_item`.order_id=`main_table`.entity_id',
                array(
                    'sku'  => new Zend_Db_Expr('group_concat(`sales/order_item`.sku SEPARATOR ",")'),
                    'name' => new Zend_Db_Expr('group_concat(`sales/order_item`.name SEPARATOR ",")'),
                )
            );
        $collection->getSelect()->group('entity_id');
        $this->setCollection($collection);
        return parent::_prepareCollection();
    }

After adding this function lets add the columns in grid for sku and product name inside _prepareColumns() function.

$this->addColumn('sku', array(
            'header'    => Mage::helper('Sales')->__('Skus'),
            'width'     => '100px',
            'index'     => 'sku',
            'type'        => 'text',
        ));

        $this->addColumn('name', array(
            'header'    => Mage::helper('Sales')->__('Product Names'),
            'width'     => '100px',
            'index'     => 'name',
            'type'        => 'text',
        ));

Enjoy!

How to set error layout in Zend Framework 2 application

Here today, I will discuss possible two way to set error layout. Lets start.

Way 1:
Put this code inside onBootstap method in Module.php.

$eventManager = $e->getApplication()->getEventManager();
$eventManager->attach(MvcEvent::EVENT_DISPATCH_ERROR, function(MvcEvent $event) {
    $viewModel = $event->getViewModel();
    $viewModel->setTemplate('layout/error-layout');
}, -200);


Way 2:

In your 404.phtml and/or error.phtml views, just simply put this code

<?php $this->layout('layout/error-layout'); ?>