Thursday, 5 December 2019

Adding a new step to checkout page


Step 1: Create the .js file implementing the view model.

Create the checkout-login-step.js file under Akshweb/HelloWorld/view/frontend/web/js/view directory.
Basically, we need step_codestep_titleorder and the condition that allows to display this step.

Here is the code (Read code comment to get more info)

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: 'Akshaweb_HelloWorld/check-login'
            },

            //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: 'isLogedCheck',
            //step title value
            stepTitle: 'Logging Status',

            /**
            *
            * @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();
            }
        });
    }
);

Step 2: Create an .html template for the component.

In the above step, we use Akshaweb_HelloWorld/check-login as our template, let’s create it.

Create a new html file named check-login.html under Akshaweb/HelloWorld/view/frontend/web/template directory.

Here is the code

<!--Use 'stepCode' as id attribute-->
<li data-bind="fadeVisible: isVisible, attr: { id: stepCode }">
<div class="step-title" data-bind="i18n: stepTitle" data-role="title"></div>
    <div id="checkout-step-title"
         class="step-content"
         data-role="content">
         <p>The customer is <span data-bind="if: !isLogedIn">not</span> Logged-in</p>
        <form data-bind="submit: navigateToNextStep" novalidate="novalidate">
            <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>
</li>

Step 3: Add the new step to the Checkout page layout.

We need to extend the checkout page’s layout to be able to display the new step
Add this file in our module:

Akshaweb/HelloWorld/view/frontend/layout/checkout_index_index.xml

The content as follow:

<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">
                        <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-login-step" xsi:type="array">
                                                <item name="component" xsi:type="string">Akshaweb_HelloWorld/js/view/checkout-login-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>

That’s the steps to add a new step to checkout page.
Clean cache and refresh your browser, the result will appear like this
check login step

Thursday, 11 April 2019

Magento2 programmatically create coupon

Magento2 programmatically create coupon

In this article, i have explaining how to we can create coupon programmatically.

At Magento 2, if you wish to create a coupon problematically .

Follow below steps:

  • First, you have to create a Cart Price rule/Shopping Cart rule.
  • At, Second steps you will create coupon code.

Advanced sales promotion rules like #free-gift, discount on #first-order, #nth-order, #total-sales-amount, #total-order-number #specific-customers #subscribers etc.http://bit.ly/M2-Sales-Promotion

1.Create Cart Price rules

For a create rules, i have used repository interface classes:

Magento\SalesRule\Api\RuleRepositoryInterface
Magento\SalesRule\Api\CouponRepositoryInterface

For set the data for rules repository class, we have use the interface

Magento\SalesRule\Api\Data\RuleInterface

This interface some setter methods using this setter method, using those method you can set discount percent/amount ,rules starting & ending date ,conditions of a rules.

Here an example code of Create Cart price rule

<?php

namespace DevAmitbera\CustomModule\Model;

use Magento\SalesRule\Api\Data\RuleInterface;
use Magento\SalesRule\Api\RuleRepositoryInterface;
use Magento\SalesRule\Model\CouponFactory;
use Magento\SalesRule\Model\RuleFactory;


class Test 
{

    /**
     * @var RuleInterface
     */
    private $rule;

    /**
     * @var RuleFactory
     */
    private $ruleFactory;

    /**
     * @var RuleRepositoryInterface
     */
    private $RuleRepository;

    public function __construct(
            RuleRepositoryInterface $RuleRepository,
            RuleFactory $ruleFactory,
            RuleInterface $rule
    ) {
        $this->RuleRepository = $RuleRepository;
        $this->ruleFactory = $ruleFactory;
        $this->rule = $rule;
    }


    public function createCartRules() {

        $rule =$this->rule;
        $rule->setName('5% discount') // Rules name
                ->setDescription('5% discount on all')
                ->setIsAdvanced(true)
                ->setStopRulesProcessing(false)
                ->setDiscountQty(5)
                ->setCustomerGroupIds([0, 1])
                ->setWebsiteIds([1])
                ->setUseAutoGeneration(0)    // If want to auto generate
                ->setCouponType(RuleInterface::COUPON_TYPE_SPECIFIC_COUPON)
                ->setSimpleAction(RuleInterface::DISCOUNT_ACTION_FIXED_AMOUNT_FOR_CART)
                ->setUsesPerCoupon(100)
                ->setUsesPerCustomer(2)
                ->setDiscountAmount(10)
                ->setFromDate('2019-04-01') //Format YYYY-MM-DD
                ->setToDate('2039-04-14') //Format YYYY-MM-DD
                ->setIsActive(true);

        try {
            $resultRules = $this->RuleRepository->save($rule);
        } catch (\Magento\Framework\Exception\LocalizedException $ex) {
            var_dump($ex->getMessage());
        }
    }

} 

Parameters of Setter methods

  • setName() Method used for set  Rule Name.
  • setDescription($description) used for set for rule Description
  • setIsActive() is used for Enabled disabled Rule.Its value is true or false
  • setCustomerGroupIds($customerGroupIds) Method used for  Customer Groups field value. Parameters type Shoule Array like [0, 1]. 
  • setWebsiteIds($websiteIds) used for set Websites field.$websiteIds Type means parameters type should be Array .LIke setWebsiteIds([1]).A single website ‘s website id is 1.
  • setCouponType($couponType), Using this method you can set Coupon type .$couponType Variable type integer and It value will be 1 (No Coupon) or 2 (Specific Coupon)
  • setUseAutoGeneration($useAutoGeneration) use for create auto generate coupon.Parameter type boolean means true or false   . 
  • setSimpleAction($simpleAction) it is use for set Coupon discount type means Value of  Apply field at Action tab.It value may be by_percent (i.e Percent of product price discount),by_fixed(i.e Fixed amount discount) oR cart_fixed(i.e Fixed amount discount for whole cart)Or buy_x_get_y(i.e Buy X get Y free (discount amount is Y))
  • setDiscountAmount($discountAmount) is use for set field Discount Amount value
  • setDiscountQty($discountQty) is use for set  Maximum Qty Discount is Applied To field value. It value will be an integer.
  • setSimpleFreeShipping($simpleFreeShipping) is use for set Free Shipping field .It value should be string and value will be 0 (I.e No),1 (I.e For matching items only),2 ( I.e For shipment with matching items)

See more details about the setter function interface Magento\SalesRule\Api\Data\RuleInterface

Create Coupon of the rule

After creating Cart Price rules, you may be want to the coupon code

Use below Class

Magento\SalesRule\Api\CouponRepositoryInterface:save

Data Provider interface : Magento\SalesRule\Api\Data\CouponInterface

/*
* $this->couponFactory \Magento\SalesRule\Model\CouponFactory
* @coupon \Magento\SalesRule\Api\Data\CouponInterface
*/
$coupon = $this->couponFactory->create();

$coupon->setCode($couponCode)
        ->setIsPrimary(true)
        ->setRuleId($rulesId());
$this->couponRepository->save($coupon);

Here note that setIsPrimary() parameters should be true /false means boolean

If you want to Coupon Code at Rule Information  Section

,then you have to make setIsPrimary(true) .

Code Sample for Create Single Coupon for a rule

<?php


namespace Stackexchange\Magento\Observer;

use Magento\SalesRule\Api\CouponRepositoryInterface;
use Magento\SalesRule\Api\Data\CouponInterface;
use Magento\SalesRule\Api\Data\RuleInterface;
use Magento\SalesRule\Api\RuleRepositoryInterface;
use Magento\SalesRule\Model\CouponFactory;
use Magento\SalesRule\Model\RuleFactory;
use Magento\Framework\Math\Random;
use Magento\SalesRule\Api\Data\CouponGenerationSpecInterfaceFactory;
use Magento\SalesRule\Model\Service\CouponManagementService;

class CreateCouponCustomer {

    /**
     * @var CouponGenerationSpecInterfaceFactory
     */
    private $generationSpecFactory;

    /**
     * @var CouponManagementService
     */
    private $couponManagementService;

    /**
     * @var Random
     */
    private $random;

    /**
     * @var CouponFactory
     */
    private $couponFactory;

    /**
     * @var RuleFactory
     */
    private $ruleFactory;

    /**
     * @var CouponRepositoryInterface
     */
    private $couponRepository;

    /**
     * @var RuleRepositoryInterface
     */
    private $RuleRepository;

    public function __construct(
      CouponRepositoryInterface $couponRepository,
      RuleRepositoryInterface $RuleRepository,
      CouponFactory $couponFactory,   
      RuleFactory $ruleFactory,
      Random $random,
     CouponGenerationSpecInterfaceFactory $generationSpecFactory,
     CouponManagementService $couponManagementService       
    ) {
        
        $this->RuleRepository = $RuleRepository;
        $this->couponRepository = $couponRepository;
        $this->ruleFactory = $ruleFactory;
        $this->couponFactory = $couponFactory;
        $this->random = $random;
        $this->couponManagementService = $couponManagementService;
        $this->generationSpecFactory = $generationSpecFactory;
    }
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $customer = $observer->getEvent()->getCustomer();
        $rule =  $this->ruleFactory->create();
        $rule->setName('5% discount')
            ->setIsAdvanced(true)
            ->setStopRulesProcessing(false)
            ->setDiscountQty(10)
            ->setCustomerGroupIds([$customer->getGroupId()])
            ->setWebsiteIds([1])
            ->setCouponType(RuleInterface::COUPON_TYPE_SPECIFIC_COUPON)
            ->setSimpleAction(RuleInterface::DISCOUNT_ACTION_FIXED_AMOUNT_FOR_CART)
            ->setDiscountAmount(10)
            ->setIsActive(true);
        
        try{
            $resultRules = $this->RuleRepository->save($rule);
            $this->createCouponCode($resultRules);
        } catch (\Magento\Framework\Exception\LocalizedException $ex) {

        }
        
    }
    private function createCouponCode(RuleInterface $rule)
    {
        $couponCode = $this->random->getRandomString(8);
        $coupon = $this->couponFactory->create();
        $coupon->setCode($couponCode)
                ->setIsPrimary(1)
                ->setRuleId($rule->getRuleId());
        $this->couponRepository->save($coupon);
    }
}
 At the example, I have created a random coupon code by creating 8 lengths using Magento\Framework\Math\Random::getRandomString(8)

Create Auto generate multiple Coupon for a single rule

Want auto generate multiple Coupon codes, that you donot need to use below class

Magento\SalesRule\Api\CouponRepositoryInterface;
Magento\SalesRule\Api\Data\CouponInterface;

Used the classes:

  • Magento\SalesRule\Api\Data\CouponGenerationSpecInterfaceFactory;
  • Magento\SalesRule\Model\Service\CouponManagementService;

This is coupon does not show at Rule Information  

Auto generate Coupon

Section and it will show at Manage Coupon Codes section.

        $couponSpecData = [
            'rule_id' => $ruleId(),
            'qty' => 5, // How many coupon you want to create 
            'length' => 12, // Coupon length
            'format' => 'alphanum', // Alphanumeric = alphanum, Alphabetical = alpha ,
            'prefix' => 'A', // Can use Null 'prefix' =>  null,
            'suffix' => 'Z', // Can use Null 'prefix' =>  null,
            'dash' => 0, // Can use Null 'prefix' =>  null,
            'quantity' => 5 // How coupon you want to create 
        ];
        /**
         * @var $this->generationSpecFactory \Magento\SalesRule\Api\Data\CouponGenerationSpecInterfaceFactory
         * @var $this->couponManagementService \Magento\SalesRule\Model\Service\CouponManagementService
         */
        $couponSpec = $this->generationSpecFactory->create(['data' => $couponSpecData]);
        $this->couponManagementService->generate($couponSpec);

Here rule_id,Coupon Qty : qty,Code Length:length & quantity,Code Format: format are required fields

Simple Code for Auto generate coupon code

<?php

namespace StackExchange\Magento\Model;

use Magento\SalesRule\Api\CouponRepositoryInterface;
use Magento\SalesRule\Api\Data\CouponInterface;
use Magento\SalesRule\Api\Data\RuleInterface;
use Magento\SalesRule\Api\RuleRepositoryInterface;
use Magento\SalesRule\Model\CouponFactory;
use Magento\SalesRule\Model\RuleFactory;
use Magento\Framework\Math\Random;
use Magento\SalesRule\Api\Data\CouponGenerationSpecInterfaceFactory;
use Magento\SalesRule\Model\Service\CouponManagementService;

class AutoCoupon {

    /**
     * @var RuleInterface
     */
    private $rule;

    /**
     * @var CouponGenerationSpecInterfaceFactory
     */
    private $generationSpecFactory;

    /**
     * @var CouponManagementService
     */
    private $couponManagementService;

    /**
     * @var Random
     */
    private $random;

    /**
     * @var CouponFactory
     */
    private $couponFactory;

    /**
     * @var RuleFactory
     */
    private $ruleFactory;

    /**
     * @var CouponRepositoryInterface
     */
    private $couponRepository;

    /**
     * @var RuleRepositoryInterface
     */
    private $RuleRepository;

    public function __construct(
            CouponRepositoryInterface $couponRepository,
            RuleRepositoryInterface $RuleRepository,
            CouponFactory $couponFactory,
            RuleFactory $ruleFactory,
            RuleInterface $rule,
            Random $random,
            CouponGenerationSpecInterfaceFactory $generationSpecFactory,
            CouponManagementService $couponManagementService
    ) {
        $this->RuleRepository = $RuleRepository;
        $this->couponRepository = $couponRepository;
        $this->ruleFactory = $ruleFactory;
        $this->couponFactory = $couponFactory;
        $this->random = $random;
        $this->couponManagementService = $couponManagementService;
        $this->generationSpecFactory = $generationSpecFactory;
        $this->rule = $rule;
    }


    public function createCartRules() {

        $rule =$this->rule;
        $rule->setName('5% discount') // Rules name
                ->setDescription('5% discount on all')
                ->setIsAdvanced(true)
                ->setStopRulesProcessing(false)
                ->setDiscountQty(5)
                ->setCustomerGroupIds([0, 1])
                ->setWebsiteIds([1])
                ->setUseAutoGeneration(true)    // If want to auto generate
                ->setCouponType(RuleInterface::COUPON_TYPE_SPECIFIC_COUPON)
                ->setSimpleAction(RuleInterface::DISCOUNT_ACTION_FIXED_AMOUNT_FOR_CART)
                ->setUsesPerCoupon(100)
                ->setUsesPerCustomer(2)
             
                ->setDiscountAmount(10)
                ->setFromDate('2019-04-01') //Format YYYY-MM-DD
                ->setToDate('2039-04-14') //Format YYYY-MM-DD
                ->setIsActive(true);

        try {
            $resultRules = $this->RuleRepository->save($rule);
            $this->autoGenerateCouponOnSingleRules($resultRules);
        } catch (\Magento\Framework\Exception\LocalizedException $ex) {
            var_dump($ex->getMessage());
        }
    }
    /**
     * 
     * @param RuleInterface $rule
     */
    private function autoGenerateCouponOnSingleRules(RuleInterface $rule)
    {
        $couponSpecData = [
            'rule_id' => $rule->getRuleId(),
            'qty' => 5, // How coupon you want to create 
            'length' => 12, // Coupon length
            'format' => 'alphanum', // Alphanumeric = alphanum, Alphabetical = alpha ,
            'prefix' => 'A', // Can use Null 'prefix' =>  null,
            'suffix' => 'Z', // Can use Null 'prefix' =>  null,
            'dash' => 0, // Can use Null 'prefix' =>  null,
            'quantity' => 5 // How coupon you want to create 
        ];
        
        $couponSpec = $this->generationSpecFactory->create(['data' => $couponSpecData]);
        $this->couponManagementService->generate($couponSpec);
    }  
}

Saturday, 4 July 2015

How to change page layout in Magento

There are in few steps,you can page pay layouts.

For change the page layout,you need to change root block  template(<reference name=”root”>) using setsetTemplate() method  ,So use <action method=”setTemplate”><template>YourPageLayoutLocation/YourLayput.phtml</template></action>

and apply this template by  <action method=”setIsHandle”><applied>1</applied></action>

 

<?xml version="1.0"?>
<layout version="0.1.0">	
	.......
   <HandlerName>
     <reference name="root">
         <action method="setTemplate"><template>YourPageLayoutLocation/YourLayput.phtml</template></action>
	 <action method="setIsHandle"><applied>1</applied></action> 
     </reference>
   </HandlerName>
   [...]
</layout>

 

Suppose i am changing template   in checkout cart page

<checkout_cart_index translate="label">
 <reference name="root">
        <action method="setTemplate"><template>page/2columns-left.phtml</template></action>
         <!-- Mark root page block that template is applied -->
         <action method="setIsHandle"><applied>1</applied></action>
    </reference>
 </checkout_cart_index>

Thursday, 4 June 2015

magento2 get base url and media url and static url

magento2 get base url and media url and static url. Whenever you are working on  magento2 then a lot of times you need to get base URL and media URL and static url. From this blog, you base url, media url, static content url in Magento2.Magento2 basically, use interface

/* This is an interface Class */
Magento\Store\Model\StoreManagerInterface

And this class have a function  Store()  which is provide store data.

After that,  using getBaseUrl() over Store()  you can get base url  and also get Media URL.

/* Using Direct Object Manager */ 
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
/* Get store manager */ 
$storeManager = $objectManager->get('\Magento\Store\Model\StoreManagerInterface');
// BASE URL 
$baseUrl = $storeManager->getStore()->getBaseUrl();

// MEDIA URL 
$mediaUrl =$storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA);
// Static contnt URL 

$statiContenteUrl = $storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_STATIC);

Where $storeManager is the instance of Magento\Store\Model\StoreManagerInterface.

If you want to get Base Url without Index.php then click here.

For Getting Media Url Use Below code:

$mediaUrl =$storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA);

Get Static content Url

$statiContenteUrl =$storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_STATIC);

But I am strongly recommended to NOT use object Manager. Use Interface injection at the __construct function of your class. Like below example:

     /* @var \Magento\Store\Model\StoreManagerInterface
     */
    protected $_storeManager;
 
    public function __construct(
 	......
        \Magento\Store\Model\StoreManagerInterface $storeManager
	 .......
    ) {
	 .....
        $this->_storeManager = $storeManager;
 	.....
    }
 
    public function myStoreBaseUrls(){
 	$storeManager = $this->_storeManager;
 	$statiContenteUrl = $storeManager->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_STATIC);
	$mediaUrl = $storeManager->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA);
 	$linkUrl = $storeManager->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_LINK);
 	$baseUrlwithoutIndexPhp = $storeManager->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_WEB);
  	return $this->_storeManager->getStore()->getBaseUrl();
     }
    public function myStoreUrl(){
 	return $this->_storeManager->getStore()->getBaseUrl()
    }

Want to get  Base Url with Out Index.php then you below code:

$baseUrlWithOutIndexPhp = $storeManager->getStore()
->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_WEB);

The above code always gives the URL without Index.php either Seo rewrite enabled at the admin or not.It does not depend on that setting.

Where,

$linkUrl= $storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_LINK);

It gives Base URL with index.php http://example.com/index.php/  when SEO rewrite is not enabled.

And give Base URL without index.php http://example.com/index.php/  when SEO rewrite is enabled.


  How to Upgrade magento version from 2.3.x [EE] to 2.3.x [EE] Here are the steps I used to successfully update Magento 2.3.3 [EE] to 2.3.5 ...