Prevent Shipping Methods Based on Conditions

Let’s Begin with the new thing today. The most common or I would say, one of the most important too topic of Magento 2. Every Store flow in Magento has to go through this. so we can say it’s a common path for all.

Well Before proceeding with this topic Preventing Shipping. Let discuss the shipping page(Checkout Step 1) first.

Let’s not go into that deep. Just an overview that why we require the Shipping methods. As we all know on the Ecommerce store each product requires a shipping method to make the order successfully delivered to one’s Address.

So, the shipping methods comes many with challenges. Here are few Examples:

Shipping Method customization depends upon factors like Price, weight, products, country, etc.
Show custom message as per conditions and many more.

Here we will apply the condition to prevent Shipping methods depending upon conditions like products, price, weight, for all shipping methods, etc.

Let’s begin with this Step by step.

Let’s start with the Basic Module Structure First. Here I assume one should already Have Basic knowledge about Module and its structure, if not please refer to this link first.

I have created an Excellence_Preventshipping Module.

So, we first have to take an excess of the method which is responsible for filtering and shows valid shipping methods on checkout. Magento uses Shipping.php to validate all shipping methods

Magento/Shipping/Model/Shipping.php

Here in this we have to use collectCarrierRates($carrierCode, $request) function.

For this we can either override this model file or use plugin for this around/after/before to validate our conditions.

For now, I am overriding this model.

Let’s create di.xml file to override this class.

Now, as we have overridden the shipping.php class to our vendor files which are at Excellence\Preventshipping\Model\Rewrite\Shipping. So create a file at this path with the same name Shipping.php as we have given in di.xml.

Here in the above section, we have added the condition in collectCarrierRates() function for validation in which we are passing the method name.

Similarly, we can add a condition for price and weight too, depending upon our requirement.

We can also use a plugin in collectCarrierRates() function to do this and return false if our condition gets true.

Magento 2 – How to Get Base URL, Media URL, Current URL, Base Path, Media Path

In this blog, both methods are demonstrated, using Dependency Injection and using ObjectManager

Using Dependency Injection

Here is the sample code. It has been used in a block class but you may use it in any class you want. We will be using three classes:

\Magento\Store\Model\StoreManagerInterface\Magento\Framework\Filesystem\DirectoryList and \Magento\Framework\UrlInterface  
as follows:

You can see more functions in following classes:
/var/www/html/myproject/vendor/magento/module-store/Model/Store.php
/var/www/html/myproject/vendor/magento/framework/Url.php

Using ObjectManager

Well, this approach is never recommended as you know that using ObjectManager is never recommended in Magento 2. Find more about this here.

Though, we will see some of the methods to get work done:

How to create admin user using Command Line Interface | Magento 2

As you know a Magento Administrator can create a new user of any role from admin panel, but in some cases, one might need to create it from some other means rather than the conventional method (i.e. using Magento Admin Panel). E.g. if you forget admin login credentials, and you are unable to reset it by normal methods, then you will need some alternate way. This blog explains how you can add a new admin user using command line interface.

This is the command for adding new admin user:

php bin/magento admin:user:create --admin-user="username" --admin-password="password" --admin-email="[email protected]" --admin-firstname="First Name" --admin-lastname="Last Name"

You need to put proper information for username, password and email id and make sure neither username or email should be attached with existing admin users.

That’s all folks. You are all set to create new admin user using CLI.

Creating Customer Attribute Programmatically in Magento 2

As we know, in Enterprise edition of Magneto, a customer attribute can be created from Admin Panel itself. But, no such option is available for Community Edition.

But no worries, a customer attribute can be created programmatically in both of the editions. A custom module needs to be created for this one. The setup script of the module (InstallData.php) will be used to perform this task. Follow these steps:

1. Create setup script (InstallData.php)

Create file app/code/Excellence/Hello/Setup/InstallData.php

Add following code to the file:

<?php

namespace Excellence\Hello\Setup;

use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Eav\Model\Config;
use Magento\Customer\Model\Customer;

class InstallData implements InstallDataInterface
{
    private $eavSetupFactory;
    
    public function __construct(EavSetupFactory $eavSetupFactory, Config $eavConfig)
    {
        $this->eavSetupFactory = $eavSetupFactory;
        $this->eavConfig       = $eavConfig;
    }
}

In this class, we define the EAV setup model which will be used to interact with Magento 2 attribute.

2. Defining The Install() method

In this step, we will be creating Install() method and create EAV setup model which we will do the job

public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
    $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
    $eavSetup->addAttribute(
        \Magento\Customer\Model\Customer::ENTITY,
        'sample_attribute',
        [
            'type'         => 'varchar',
            'label'        => 'Sample Attribute',
            'input'        => 'text',
            'required'     => false,
            'visible'      => true,
            'user_defined' => true,
            'position'     => 999,
            'system'       => 0,
        ]
    );
    $sampleAttribute = $this->eavConfig->getAttribute(Customer::ENTITY, 'sample_attribute');

    // more used_in_forms ['adminhtml_checkout','adminhtml_customer','adminhtml_customer_address','customer_account_edit','customer_address_edit','customer_register_address']
    $sampleAttribute->setData(
        'used_in_forms',
        ['adminhtml_customer']

    );
    $sampleAttribute->save();
}

Here, the used_in_forms is used to show the attribute in different kind of forms such as customer registration page, account information page etc.

Complete Install Script:

Here is the complete Install script which is to be used in InstallData.php:

<?php

namespace Excellence\Hello\Setup;

use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Eav\Model\Config;
use Magento\Customer\Model\Customer;

class InstallData implements InstallDataInterface
{
    private $eavSetupFactory;
    
    public function __construct(EavSetupFactory $eavSetupFactory, Config $eavConfig)
    {
        $this->eavSetupFactory = $eavSetupFactory;
        $this->eavConfig       = $eavConfig;
    }

    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
        $eavSetup->addAttribute(
            \Magento\Customer\Model\Customer::ENTITY,
            'sample_attribute',
            [
                'type'         => 'varchar',
                'label'        => 'Sample Attribute',
                'input'        => 'text',
                'required'     => false,
                'visible'      => true,
                'user_defined' => true,
                'position'     => 999,
                'system'       => 0,
            ]
        );
        $sampleAttribute = $this->eavConfig->getAttribute(Customer::ENTITY, 'sample_attribute');

        // more used_in_forms ['adminhtml_checkout','adminhtml_customer','adminhtml_customer_address','customer_account_edit','customer_address_edit','customer_register_address']
        $sampleAttribute->setData(
            'used_in_forms',
            ['adminhtml_customer']

        );
        $sampleAttribute->save();
    }
}

After that run setup:upgrade and setup:static-content:deploy to see the changes. Also, you might need to set permissions of directories like pub, vargenerated etc.