The First PWA POS App for Magento 2 by Magestore: Our Review

One of the hottest web development trends to hit the world of eCommerce is PWA. Magento® is currently developing a PWA studio to enhance their features. Other companies as Vue Storefront and Magento development agencies are looking to expand PWA’s presence. Progressive Web Apps give your customers greater access to your product and makes it easier than ever to get conversions. Magestore is developing a new POS solution that revolutionizes customer experience with a PWA app-like experience. Magento’s PWA studio and PWA POS will fit your website with cutting-edge eCommerce solutions.

What is PWA?

A PWA is a new way of accessing websites. Basically, it takes all the best features of a website and combines them with all the best features of an app. The user is given an option to add the site to their home screen. If they accept, an icon appears on the home screen and a user can return to the site with a single click. Users aren’t required to download anything, and the PWA loads more quickly than other sites, even on the first visit. Once it’s added to the home screen, it smart caches data for near-instant load times.

What is POS?

POS is an acronym for “point of sale.” It’s an essential element of any eCommerce business. Traditionally, the cash register has performed the role of receiving money and counting orders. In the digital age, even the point of sale has been upgraded to fit new technology and customer expectations. Now, the POS is a blend of software and hardware. It processes credit cards, handles cash payments, tracks and manages transactions, and coordinates post-transaction services. Put simply, the modern POS streamlines business operations while providing customers with a user-friendly experience.

PWA POS by Magestore for Magento

Now you know what the PWA is and what the POS system is. What has connected them? That is the case we want to talk about. The Magestore team has created a new PWA POS product. Basically, it is a fully-fledged POS system that works across multiple devices with super fast and stable performance.

As any business owner knows, handling the paperwork can be a major headache. Going around and around to get all the information you need, from end-of-day totals to customer information. Add in inventory, shipping, and peak hour sales, and you’re looking at the biggest challenges faced by any type of business. This is the beauty of Magestore’s PWA POS. Now that Magento business owners have all information including sales, customers, and inventories within just ONE place – your POS. In real-time. With instant access.

Less paperwork, less chance of deadly errors.

Customers get a full range of options to pay for their purchased products. No need to wait in long lines for the clerks to process one sale at a time. Also, it is easier for the staff to work with PWA POS as it loads quicker and you get the same functionality as in web version. They also receive full customer and inventory details to make sales.

The result? For the customer: a faster and smoother checkout experience. For the business owner: streamlined business operations with built-in coordination of all information necessary for customer fulfillment. To break it down further, this means that you have a successful, and efficient business with lower overhead. Magestore’s PWA POS handles a wide range of different payment styles and processes them at high speed. Plus, it provides easy access allows offline viewing with no lag time. Finally, customers are able to easily view current stock availability as part of the POS.

Now let’s move on to more features of PWA POS and what it will give your business. Most certainly that you’ve heard about Omnichannel businesses. Accessibility is the feature that makes them successful and PWA POS certainly help to create the omnichannel experience.

PWA POS Benefits

In addition to the potential for expansion, the PWA POS has several other benefits. First, it can be accessed quickly, even on the first visit. Many users will bounce from the site if it takes more than three seconds to load. PWAs have been designed with this in mind, guaranteeing instant load time and letting customers surf without interruption even when the connection is bad or when offline. Web pages are updated silently in the background, and information from previous visits is pre-cached to tailor customer experience. Plus, since the same app runs on both mobile and desktop, PWAs lower your maintenance costs and requirements. Let’s take a look at the key advantages in order to understand how it works.

More & Faster Sales

Let’s face it – customers have plenty of options these days. And, attention spans are becoming shorter and shorter. So, if a customer has to wait for a page to load before making a purchase, odds are they’ll find another source. The Point of Sale is the last place you want to lose a sale, so it’s vital that your POS will process product search, checkout, and report quickly. With PWA, you get lightning-fast load times and tailored customer experience.

Time & Cost Saving

We’ve touched a scenario upon how the customer can save time in the sales process. What about the business itself? A great bulk of business overhead is the admin. You have to pay employees to manage the paperwork. You have to spend the budget and man-hours for post-transaction fulfillment. And this is vital for the success of the company. A few unsatisfied customers can lead to poor reviews and fewer visits to your site. Keep your customers happy, and your conversion rates will soar. So, by streamlining your business operations, you actually improve the success of your business.

Ease of Expansion

One of the greatest details of the Magestore PWA POS is that it can be changed and upgraded from the backend. It’s the core Magento system that you’ve already been familiar with. You can manage or add locations for your products or physical sites. It also lets you determine roles and set permission for them. Staff can be assigned directly through the POS, and staff statistics can be easily monitored by the business owner. Finally, when it comes time to expand, there are no extra fees. In fact, this product is a one-time payment with no recurring fees. After purchase, your business can be expanded indefinitely without additional expenditure.

Control All Over the Stores

Another challenge faced by business owners is to coordinate the activity of all stores. Inventory, availability, shipping, these are just a few things that business owners need to manage, and the more stores you have, the bigger the challenge. Admin costs grow with each store, leading the business owner to wonder if it’s worth the challenge to expand. With Magento’s PWA POS, these questions are a thing of the past. You have instant access to all sales, inventory, and operations of every store. This lets you refine the operations in each store and easily switch from one location to another via the admin panel.

Inventory Management in Magento Admin Panel

Instant Use with Full Benefits

Ease of use is critical in the fast-paced modern world. The PWA POS streamlines the post-transaction phase. This means that customers receive their products or services without hold-ups from inefficient processing. They get what they want. Ease of use is the key to making your product available to your customer. The most beautiful thing about PWAs is that they offer an app-like experience without actually having to download an app. You get all the benefits and none of the downsides. Offline experience, instant loading, and no download.

Omnichannel Experience

Omnichannel is one of the holy grails of current eCommerce platforms. Last year, the big trend was multichannel. But we’ve moved on. Multichannel let the customer reach the site through any device. Omnichannel means that a customer can begin the sale on one device, and finish it on another without having to start from the beginning. Seamless integration happens across all channels. That’s what PWA POS system deliver to you as a business and helps to reach your customers and your business goals. Online fulfillment is integrated so that the customer can interact with the site, shifting devices when they need, and purchasing the product from the most efficient location.

PWA POS Key Features

Magestore’s PWA POS comes loaded with features to simplify your sales and boost efficiency. The login takes less than 3 seconds. Products can be held and processed at your convenience. It allows you to establish coupon codes for customers. You can add customer details for shipping and provide shipping options. All information from prior sales is at your fingertips. Customer status and order history can be accessed in seconds. Plus, this system lets customers leave a deposit to lock in a product. PWA POS is corresponding to the 2 devices: iPad, Android Tablet. It will be easy to work with customers via PWA app, not with a web version. It will save the time of the staff and the store owner.

How to Add PWA POS to Home Screen

In reality, you can have different scenarios with your customer at the store. PWA POS cover different situations that might appear. And you will understand them better with the features of the system and how they work.

Customer Management

How many customers can you handle at once? With the traditional methods, your POS gives you a hard ceiling. It means that you have a maximum limit on the number of sales you can make in an hour or a day. However, Magestore PWA POS shatters this ceiling. You can handle loads of customer requests, and stock availability is updated instantly. Transactions can be completed in less than ten seconds, and barcode scans are processed in less than one second. Plus, more than 12,000 orders can be processed in a single hour.

Working with Multiple Customers

The traditional POS limits the number of customers that can be processed at once by the number of available cash registers. Once you set up a PWA POS, you can create multiple orders at the same time. Orders can also be held and processed later, whenever you or the customer are ready to finalize the sale on checkout. When reviewing details of the sale, customers can be looked up in under a second. And when they win, you win.

POS feature to Work with Multiple Customers at Checkout

Filtering Customers

Each customer will have viewing and purchasing histories on your POS system. Being able to explore these histories lets you know what the customer wants. It lets you know what they are more likely to purchase later. Magento’s PWA POS gives you access to all customer history, letting you make targeted product recommendations and send new product offers that up conversions. Also, you can filter your customers in a system by the name, orders status, and location.

Synchronization

One of the challenges in eCommerce is to manually import or export information between the CMS and the POS. Synchronization provides and answers to this. It automatically integrates information from all aspects of the business. Stock information, customer information, orders, and sales are all fed into a single integrated database. Real-time sync incorporates information from Magento and POS. Offline sync lets merchants effortlessly manage the business without the internet connection and saves all actions that were performed during this period.

Partial Payments

One feature that increases customer convenience is partial payment. Customers may not be able to able to pay for the entire purchase at once. PWA POS lets you accept partial sales from a customer and then handles the later payments with no hassle.

Partial Payments PWA POSRefunds

Customer satisfaction requires refunds. Customers tend to change their mind. Sometimes they bought something that didn’t fit or made an impulse purchase they later regret. Magento’s PWA POS eliminates these challenges and makes the refund process as simple as the sale itself. You can fill out the refund right out from the system.

Reward Points and Coupons

Repeat customers come from incentives. We all love a sale. So, when you give your customers coupons and reward points, you dramatically increase conversion rates. PWA POS makes it easy to incorporate reward points and coupons at checkout as well.

Payment Methods

When it comes down to it, customers will want to pay with all sorts of different methods. Cash, credit card, PayPal, Stripe, set up your site so that the customers can pay as they want. Customers may want to split payments between different methods, and they will want to be able to use the methods that are easy for them. You can choose split payment on the screen at checkout, so the customer can pay half cash and half credit card, for example. Magento’s PWA POS is designed with this in mind, making purchases simple and cutting out the hassle.

Cash

Cash is king. This is how it’s been from the beginning of the business and it’s not likely to change anytime soon. This is just basic business protocol. If you have a physical location, it’s a necessity.

Credit Card

The second most common form of payment is with credit or debit card. And any online shop will need to be able to process this kind of payment. In fact, with both online and physical store, this is the first, the most preferred method of payment. So processing credit cards and debit cards are absolutely critical for the success of your business. PWA POS makes this simple, cutting out the middleman.

PayPal

PayPal is the second most common form of payment for online purchases. Until the game changes, making your site PayPal accessible is an absolute necessity. PayPal is easy to set up, operates across the world, and makes payment simple. PayPal payments come default in the PWA POS system, making it a breeze for you to use the highest ranking international payment site with no additional steps.

Authorize.net

Authorize.net is set up for secure payments and invoicing, as well as recurring payments, secure customer data, and a wide range of different payment types. Plus, it makes checkout simple and includes automatic synchronization with Quickbooks. It might not be the top choice for online payments, but it comes close. PWA POS comes standard with Authorize.net features.

Stripe

This is a scalable, flexible tool for processing online payments. It provides a comprehensive toolkit for Internet businesses. Magestoremade Stripe available for its new POS service. Regardless of the type of business you run, Stripe is a payment option you want to provide to your customers.

Bambora

Bambora is an up-and-coming service that shouldn’t be overlooked in this new digital explosion. Though it may not have as much press as PayPal or Authorize.net, it’s still in the top of the rankings. Like the payment processing methods described above, Magento’s PWA POS comes equipped with facilities to process payments through Bambora. It offers tailored payment solutions to handle a wide range of payment sources. It’s a key payment processing platform for any site of the future.

Online Fulfillment

Ok. So you’ve got your orders in. The sale is made. What’s next? This is where order fulfillment comes in. It’s the post-transaction aspect of the sale. What happens after the customer has made the purchase. And, it’s key to the whole process. Online fulfillment is all about making sure your customer gets what they’ve ordered. This might require shipping or inventory handling. It might mean wrapping up the product in the checkout line. A customer can choose the preferred shipping method and delivery date.

POS and Location Management

Your customers are buying online. And, depending on the type of product, they’ll want something in their hands to complete the sale. This means that you’ll have to work with a physical inventory, based in a physical location. When you use Magento’s PWA POS, your inventory is correlated between all sites and shipping is the process in the most efficient way possible. It lets you give your customers what they want as quickly as possible.

Partial Payments Feature

Denomination

It’s a no-brainer that different countries will use different currencies. Some methods of payment processing require multiple conversions from one currency to the next. Each time currency is converted, you lose a bit. So the key is to find methods that cut the number of conversions. Magento’s PWA POS intelligently connects a user to the source, cutting out all the middlemen to make the highest profits from your sale.

Configuration with Google API

Sitemaps are a key to SEO. When you set up a sitemap with Google API, you use a free Google service to coordinate maps, routes, and places with the site. If you have a physical location, this is absolutely essential for your service. It connects your customers with your physical offerings. They can find you, which means you get more conversions. Google API sitemaps make your site more efficient for the customers and for yourself.

Configuration with Google API from the Magento Admin

Overall, PWA POS by Magestore is a robust solution for the online and offline retailer, who wants to be omnichannel and cooperate with the customers successfully. It has lots of time-saving and innovative features for customers as online fulfillment, partial and split payments, easy navigation, online and offline synchronization, and other great tools. It will help you to control your inventory and plan product distribution among stores, quick reaction to stock fulfillment. Also, you will be able to proceed customers’ requests in a flexible manner and a short time.

Magento 2 Demo Features: Overview

One of the things that put Magento® ahead of other CMS options is its secure network of community support and online learning resources. Magento has been designed so that it’s pretty intuitive to use. Plus, Magento is an open source, and anyone wanting to find out more about it has access to countless resources online. However, you need some time to learn how to set up certain settings and fill out your store with the information. Today, we’ll be showcasing the Magento 2 demo. This is a free online resource that lets business owners to explore the Magento 2 backend or interface with the frontend like a user. You can look into site features and functionality with sample information for a first-hand feel for how it works before finally selecting a CMS. Read on for a detailed look into the demo.

Magento Latest Version Features

The latest version of Magento 2 significant improvements in performance and security, as well as enhancements to shipping options, the dotmailer extension, and Amazon Pay features. More than 150 fixes have been included in the core code, and 25 improvements have been made to security. These improvements include refinements to the catalog indexing process, product sorting, and the checkout process.

Another benefit of the Magento community is that users can send feedback in and any bugs or usability improvements will be included in the next version. The current version features more than 350 adjustments based on user feedback. Several of the core-bundled extensions have been enhanced. Amazon Pay is now included in the payment options, and the current version of Magento features a payment provider gateway, making it easier than ever before to integrate your store with payment providers. The dotmailer extension has been updated for better GDPR compliance, including consent captures and warnings when you attempt to include non-subscribers on the account. These are just a few of the enhancements you’ll see when exploring the demo. Learn more about its features below.

Magento Demo Login

When you want to login to the Magento CMS demo, just follow the demo link and sign in as an admin. Take a moment to set up your username and password, and you’re in! The demo has sample information that can be worked with just as you will work with your live eCommerce site.

You can check out the frontend to see what your customers see when they visit the website or explore the backend, changing settings and configurations to see how these settings shift site functionality and customer experience.

Magento Demo Store Admin Panel

You’ll be directed to the opening page for the demo once you log in. The admin sidebar is along the left side of the screen. This is the central control panel for your site. This lets you navigate the entire backend of the site. Dashboard, System, Customers, Content, Marketing, Reports, Sales and Find Partner Extension. Here are some of the options and functionality of each section.

Dashboard

The Dashboard is the homepage of the Magento 2 test site. It features details regarding sales and customers. You can use this information to refine product listings, showcase bestsellers, and check sales within a given time frame. It provides an overview of company productivity and site success. The Dashboard also gives you access to information about last order, lifetime sales, and average orders.

There’s also a row of tabs that let you look into your new and existing customers, bestsellers and most viewed products. Plus, you can search in intervals of a day, a week, a month, one year, and two years. The Dashboard also features a notification icon in the top right of the page. This will let you keep up with any important changes or updates. It showcases the essential aspects of Magento functionality.

Sales

Sales Section

The Sales section will let you go in-depth when exploring Sales. There are seven options in the Sales menu:

  • Orders
  • Invoices
  • Shipments
  • Dispatches
  • Credit Memos
  • Billing Agreements
  • Transactions

The Order section is where you’ll go to input a new order. It keeps track of orders, shipping information and payment information, and the grand total. The Dispatches section shows the orders ready to ship. It helps you keep track of shipping schedules. It also lets you print dispatches for each order to go out. This makes paperwork easy. The invoices section can generate invoices and access all order information: customer names and dates and numbers of invoices and orders, to start. The transaction menu shows what’s happening with each sale being processed.

Magento’s Billing Agreement functionality makes checkout faster and easier by saving payment details for future orders. The Billings Agreement section keeps track of all billing agreements with each customer. When processing refunds, you can make a note in the files by going to the Credit Memos menu. Magento Wholesale Fast Order is featured on the frontend. This lets customers make repeat bulk purchases without having to enter each product individually.

Catalog Features

Catalog Section

The Catalog menu has been simplified in the new version. It now has only two selections: Products and Categories. In Products, you can add products and configure your product display. It also indicates the type of each product and lets you search by product type. The Categories section allows you to group products by type. It also generates meta-information automatically by product type. This section lets you control product listing and showcasing. The Categories menu lets you set up swatches and categories, create product grids, and arrange product listings.

Customer Segmentation

Customers Section

The Customers section offers basic client information and shopping history. Address, email, and phone number information are stored in each user file. These files show whether orders were made online or in a physical store. Order dates, amounts, and products for each order are included in this section. It lets you do customer segmentation, grouping customers with others that have similar shopping habits.

The Customers menu will also show when they first became customers and whether they are online at the moment or not. Customer files and new customers are automatically updated from orders on the frontend. They can also be added manually in the backend by admin.

Advanced Marketing Features

Marketing Features Section

The Marketing section offers key Magento features for helping customers find you. In one menu, manage email and newsletter templates, subscriber lists and queues. You can set up discounts, promotions, and pricing rules.

This is also the place to go to refine your SEO and search details. The Marketing section also allows you to manage user reviews and automate the sales process.

Content

Content Section

Moving on to the Content tab, this part of the backend allows you to manage the structure and aesthetics of your site. You can arrange pages, set up widgets, and manage the content of your blocks. It also lets you set up the design elements of your storefront. You can come here to change the website themes and configuration. You can also create a schedule for staging content updates at desired times.

Advanced Reporting

Advanced Reporting Section

In the Reports tab, you can find all the information you need, about any aspect of your company. You can find all the product information and automation details. You can explore sales and marketing details and access full reports on new customers, order counts, and order details. You can check into the totals for specific payment options, abandoned carts, and newsletter problem reports. The Advanced Reporting section also lets you explore details in even greater depth. Tax and billing regions, orders and revenue, everything is right at your fingertips. Check new customer accounts, coupon users, product wishlists, and a host of other details.

Stores

Stores Section

The Stores section is another improvement over Magento 1. It centralizes all store details on a single menu. You can come here to change your preferred currency and manage the currency rate. You can adjust your settings, establishing all the needed configurations in your storefront. This sets up all frontend actions to tailor site experience and eCommerce functionality. You can also pull up all the tax and shipping information and manage product attributes. This is where you go to find all tax rules, zones, and rates, shipping carriers and locations, and current terms and conditions.

Configuration

Your configuration is like the anatomy of your site. It lets you set up bootstrap parameters and tailor your command-line utilities like running indexes, disabling and enabling cache types and setting up translations. The Configuration menu also provides options for setting up themes or message queues, and for handling the production and storage sections. Payment options can be configured in the sales section of this menu and any settings changed here will be saved onto the site.

System

System Section

The System section lets you set up permissions and for all users, lock certain users out and establish user roles. You can come here to import adjustments to the website and export details to other platforms. Up to 25Mb can be transferred per import or export file. The import history of your site is saved, so you can keep track of all imported files. Tax rates can also be imported and exported between sites. In Systems, you can manage and integrate your extensions, set up extensions, and create backups. These are just a few of the features you can make use of. This page also links to Amazon logs and lets you manage encryption keys.

Tools

Tools Section

The System section also includes a collection of tools that come with Magento 2. They are great for managing your caches or indexes. You’ll probably want to refresh the cache after adding new configurations to make sure that they are locked in. Another useful tool is the backup function. Save copies of your site so that you can go back to an old version if needed. Finally, the Web Setup Wizard tool makes adding and remove modules a cinch. It also keeps track of which modules are dependent upon one another. It makes sure all supporting modules are enabled and prevents you from activating conflicting modules at once.

Magento 2 provides everything you need to keep track of your store and update your site. Plus its intuitive interface guarantees that site upkeep will be quick and simple. Its tools and features are great for midsize to big businesses.

Broken Magento Shopping Cart: Cause and Solution

Today, we will be examining the broken cart bug in Magento® 2. Below, you will see a step-by-step description of the Magento cart problem and a method for fixing it.

Description of the Problem

There is one Magento 2 bug inherited from Magento 1 that has not yet been fixed at the core level. Here is the gist of the bug: A customer goes to a site, logs in, and adds a product to their cart. Then, the customer may attempt to log in again after some time has passed. In Magento 1, the customer receives a message about a fatal error (administrators see a link to a report). The administrator will see the same fatal error if they want to edit or view this customer’s account. In Magento 2, the customer can’t add products to their cart and go to checkout, but static pages, categories, and product pages are available. When this happens, the server administrator sees the following message in the global error log:

[Mon Aug 06 16:49:26.148250 2018] [:error] [pid 10400] [client 127.0.0.1:49255] PHP Fatal error: Uncaught Error: Call to a member function getThumbnail() on null in /var/www/zenzii_beta/vendor/magento/module-configurable-product/CustomerData/ConfigurableItem.php:66\nStack trace:\n#0 /var/www/zenzii_beta/vendor/magento/module-checkout/CustomerData/DefaultItem.php(78): Magento\\ConfigurableProduct\\CustomerData\\ConfigurableItem->getProductForThumbnail()\n#1 /var/www/zenzii_beta/vendor/magento/module-checkout/CustomerData/AbstractItem.php(31): Magento\\Checkout\\CustomerData\\DefaultItem->doGetItemData()\n#2 /var/www/zenzii_beta/vendor/magento/framework/Interception/Interceptor.php(58): Magento\\Checkout\\CustomerData\\AbstractItem->getItemData(Object(Magento\\Quote\\Model\\Quote\\Item))\n#3 /var/www/zenzii_beta/vendor/magento/framework/Interception/Interceptor.php(138): Magento\\ConfigurableProduct\\CustomerData\\ConfigurableItem\\Interceptor->___callParent('getItemData', Array)\n#4 /var/www/zenzii_beta/vendor/magento/framework/Interception/Interceptor.php(153): Magento\\ConfigurableProduct\\CustomerData\\ConfigurableItem\\Intercep in /var/www/zenzii_beta/vendor/magento/module-configurable-product/CustomerData/ConfigurableItem.php on line 66, referer: http://zenzii-beta.loc/index.php/all-necklaceThis is the broken cart bug and one of Magento 2 issues. The following conditions are needed to reproduce it:
  1. The site must allow product configuration
  2. A logged-in customer must add a configured product to their cart
  3. The server administrator must delete the same product option (the simple product) that the customer added to their basket, and then the customer must log back into the site.

Below, we examine the reason for this bug using an example with Magento 2.2 code. We also examine a method for fixing it.

Why the Bug Occurs with Magento 2.2, and How to Fix It

When a user adds a configured product to their cart, two cart elements are actually added: the configured product and the simple product. In this case, the parent element is the configured product, and the hidden element is the simple product. Magento gets the weight, cost, and SKU from the simple product. What happens if the administrator deletes the simple product that the user has configured and added to their cart?

The following plugin is defined in the Magento_Quote core module

<type name="Magento\Catalog\Model\ResourceModel\Product">
    <plugin name="clean_quote_items_after_product_delete" type="Magento\Quote\Model\Product\Plugin\RemoveQuoteItems"/>
    <plugin name="update_quote_items_after_product_save" type="Magento\Quote\Model\Product\Plugin\UpdateQuoteItems"/>
</type>

Let’s examine the class of the clean_quote_items_after_product_delete plugin.

{
    /**
     * @var \Magento\Quote\Model\Product\QuoteItemsCleanerInterface
     */
    private $quoteItemsCleaner;
    /**
     * @param \Magento\Quote\Model\Product\QuoteItemsCleanerInterface $quoteItemsCleaner
     */
    public function __construct(\Magento\Quote\Model\Product\QuoteItemsCleanerInterface $quoteItemsCleaner)
    {
        $this->quoteItemsCleaner = $quoteItemsCleaner;
    }
    /**
     * @param ProductResource $subject
     * @param ProductResource $result
     * @param \Magento\Catalog\Api\Data\ProductInterface $product
     * @return ProductResource
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function afterDelete(
        ProductResource $subject,
        ProductResource $result,
        \Magento\Catalog\Api\Data\ProductInterface $product
    ) {
        $this->quoteItemsCleaner->execute($product);
        return $result;
    }
}

Note that until version 2.2, the around plugin was used instead of after, since after plugins didn’t support the input parameters of the original method. The \Magento\Quote\Model\Product\QuoteItemsCleanerInterface class looks as follows.

class QuoteItemsCleaner implements \Magento\Quote\Model\Product\QuoteItemsCleanerInterface
{
    /**
     * @var \Magento\Quote\Model\ResourceModel\Quote\Item
     */
    private $itemResource;
    /**
     * @param \Magento\Quote\Model\ResourceModel\Quote\Item $itemResource
     */
    public function __construct(\Magento\Quote\Model\ResourceModel\Quote\Item $itemResource)
    {
        $this->itemResource = $itemResource;
    }
    /**
     * {@inheritdoc}
     */
    public function execute(\Magento\Catalog\Api\Data\ProductInterface $product)
    {
        $this->itemResource->getConnection()->delete(
            $this->itemResource->getMainTable(),
            'product_id = ' . $product->getId()
        );
    }
}

As you can see, when the administrator deletes a product, the plugin simply deletes all the elements in the carts of all the users who had added the product. But the parent element isn’t deleted from the cart, and we end up with an orphaned item. To understand what is happening when trying to display the contents of a cart on the front end, we look at the code

namespace Magento\ConfigurableProduct\CustomerData;
use Magento\Catalog\Model\Config\Source\Product\Thumbnail as ThumbnailSource;
use Magento\Checkout\CustomerData\DefaultItem;
/**
 * Configurable item
 */
class ConfigurableItem extends DefaultItem
{
    /**
     * @var \Magento\Framework\App\Config\ScopeConfigInterface
     */
    protected $_scopeConfig;
    /**
     * @param \Magento\Catalog\Helper\Image $imageHelper
     * @param \Magento\Msrp\Helper\Data $msrpHelper
     * @param \Magento\Framework\UrlInterface $urlBuilder
     * @param \Magento\Catalog\Helper\Product\ConfigurationPool $configurationPool
     * @param \Magento\Checkout\Helper\Data $checkoutHelper
     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
     * @param \Magento\Framework\Escaper|null $escaper
     */
    public function __construct(
        \Magento\Catalog\Helper\Image $imageHelper,
        \Magento\Msrp\Helper\Data $msrpHelper,
        \Magento\Framework\UrlInterface $urlBuilder,
        \Magento\Catalog\Helper\Product\ConfigurationPool $configurationPool,
        \Magento\Checkout\Helper\Data $checkoutHelper,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Framework\Escaper $escaper = null
    ) {
        parent::__construct(
            $imageHelper,
            $msrpHelper,
            $urlBuilder,
            $configurationPool,
            $checkoutHelper,
            $escaper
        );
        $this->_scopeConfig = $scopeConfig;
    }
    /**
     * {@inheritdoc}
     */
    protected function getProductForThumbnail()
    {
        /**
         * Show parent product thumbnail if it must be always shown according to the related setting in system config
         * or if child thumbnail is not available
         */
        $config = $this->_scopeConfig->getValue(
            \Magento\ConfigurableProduct\Block\Cart\Item\Renderer\Configurable::CONFIG_THUMBNAIL_SOURCE,
            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
        );
        $product = $config == ThumbnailSource::OPTION_USE_PARENT_IMAGE
            || (!$this->getChildProduct()->getThumbnail() || $this->getChildProduct()->getThumbnail() == 'no_selection')
            ? $this->getProduct()
            : $this->getChildProduct();
        return $product;
    }
    /**
     * Get item configurable child product
     *
     * @return \Magento\Catalog\Model\Product
     */
    protected function getChildProduct()
    {
        if ($option = $this->item->getOptionByCode('simple_product')) {
            return $option->getProduct();
        }
        return $this->getProduct();
    }
}

An attempt to retrieve the child product, which doesn’t exist, also results in this error. In fact, until version 2.1.3, a foreign key from the catalog_product_entity table was used instead of the plugin. This key deleted cart items for deleted products.

A fix for this error will be described below. The best option, in this case, is to delete the parent element from the cart along with the child. Unfortunately, you cannot use a foreign key to do this, since the child element is already linked to the parent by a foreign key. The solution that uses a MySQL trigger will also not work. MySQL doesn’t allow the same table to be used in the delete subquery, and it doesn’t allow deleting from the same table in the deletion trigger. This is because in such cases MySQL cannot determine the presence of circular references in queries, and it simply blocks them. Let’s add a trigger to the database:

DELIMITER //
create trigger quote_item_delete after deleting on quote_item for each row
begin
if OLD.parent_item_id is not NULL then
delete from quote_item where item_id = OLD.parent_item_id;
end if;

end;//
DELIMITER ;

Then, an attempt from the admin panel to delete the product will result in an error message for the administrator, and the following error will be added to the log: “SQLSTATE[HY000]: General error: 1442 Can’t update table ‘quote_item’ in stored function/trigger because it is already used by statement which invoked this stored function/trigger., query was:..”Therefore, you have to delete the parent element on the Magento side. Let’s create a module for this, which will consist of the following files.

registration.php

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Web4pro_BrokenCart',
    __DIR__
);
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="Web4pro_BrokenCart" setup_version="0.0.1"></module>
</config>

etc/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">
    <preference for="Magento\Quote\Model\Product\QuoteItemsCleanerInterface" type="Web4pro\BrokenCart\Model\QuoteItemsCleaner" />
</config>

As you can see, we replaced the class for implementing the interface Magento\Quote\Model\Product\QuoteItemsCleanerInterface. The class will have the following implementation:

namespace Web4pro\BrokenCart\Model;
class QuoteItemsCleaner extends  \Magento\Quote\Model\Product\QuoteItemsCleaner
{
    /**
     * @var \Magento\Quote\Model\ResourceModel\Quote\Item
     */
    protected $itemResource;
    /**
     * @param \Magento\Quote\Model\ResourceModel\Quote\Item $itemResource
     */
    public function __construct(\Magento\Quote\Model\ResourceModel\Quote\Item $itemResource)
    {
        $this->itemResource = $itemResource;
        parent::__construct($itemResource);
    }
    public function execute(\Magento\Catalog\Api\Data\ProductInterface $product){
        $select = $this->itemResource->getConnection()->select();
        $select->from($this->itemResource->getMainTable(),'parent_item_id')
               ->where('parent_item_id is not NULL and product_id='.$product->getId());
        $parentItemIds = $this->itemResource->getConnection()->fetchCol($select);
        if(count($parentItemIds)){
            $this->itemResource->getConnection()
                 ->delete($this->itemResource->getMainTable(),'item_id in ('.implode(',',$parentItemIds).')');
        }
        return parent::execute($product);
    }
}

Website Launch Checklist: The Step by Step Process

Launching a new website can be a daunting task. And yet, it’s the first step for any online business owner. Here’s a website launch checklist to help you get your site up and running.So you want to build a website. It’s a critical step for any online shop and it has to be gotten right, but making a site can be a complicated process. It involves lots of steps and details. Choosing a CMS, performance optimization, navigation details, each element is critical for making your online store successful. Here are some tips to show you how to start a website and make it work.

What Do You Need to Make a Website?

A key element in exploring how to launch a website is to think about your goals. Do you want to start a business from the beginning? Maybe you want to expand your current business or to make a brand new site for it? Not only your basement, but it is also important to consider all the steps of making your site alive. You’ve come to the decision, but what’s the next? Look at the key points to consider to build a great site with the example of 3 CMS: Magento®, Drupal, and WordPress.

Choose the Right CMS for your site

Magento 2, WordPress, and Drupal are among the best CMS options. Magento 2 offers advanced product browsing and is both cross-browser and mobile compatible. It uses an intuitive interface and has excellent SEO and catalog management features. Drupal is module-based and easy to install, allowing unlimited customization. It is an excellent platform for organizing and categorizing products. WordPress is another common platform and it excels for simple sites. It offers a wide range of features and themes, extensive tutorials, and a dedicated support staff. Why do we consider them? Each solution fit certain business size and type of industry. So, it’s up to you what to choose. Below we will explain what features and benefits are included in each solution.

Make Sure It’s Secure

Site security is a key feature to consider. This protects customers and your site, and it makes the consumer feel safe entering their data for payment. So, use 24/7 monitoring scripts. Also, store all sensitive data, like website credentials, passwords, and customer information, in a secure database. Finally, it’s best to make copies of your site so that it can be recovered if any problems arise. A final copy should be made when the site is launched, and regular copies should be made with each further update.

While security is important regardless of the CMS, know that WordPress sites will require an extra measure of vigilance. Regarding Magento, it is highly secure and you can add more or fewer security features. Drupal also has basic security and advanced security that can be implemented with additional modules.

Website Performance

As customers navigate the site, they will first notice site performance. Once a site is optimized for performance, the web pages will load quickly and information will be cached to make the experience faster for repeat visitors. Decreasing lag time keeps customers engaged and increases conversions. You can test website performance with free online services like GT Metrix. There are also a number of plugins available to optimize web performance. Some popular choices are Autoptimize, WP Rocket, and Swift Performance. WordPress, Drupal, and Magento can be optimized with tools and right build website. However, Magento is the most robust solution, so it needs a bit more optimization work.

SEO Site Optimization

For an online store to be successful, it has to come up in a search. So, it needs SEO. Some tips: use unique page titles and meta descriptions. Keywords are important as well. Include no more than ten keywords in the copy for each page. Set up metadata for social media sharing content and RSS. Your website also needs an XML sitemap listed with search engines. Finally, URLs should be kept current and reflect page information. Online services like Woorank and Google Analytics will help you assess your SEO ranking. Several plugins for SEO are also available to up your site ranking. All of the platforms have basic SEO features to use for website’s visibility.

High Usability

Ease of use means customers will take more time on the site. It is easier to buy and conversion rates are higher. For the best usability, make the site easy to navigate and use an intuitive interface. Make sure the call-to-action buttons are simple to understand and marked clearly.

Intuitive Interface

An intuitive interface does what your customers expect. It makes sense, so users can go directly where they want on the site without having to spend time figuring out the navigation. To create an intuitive interface, put yourself in the client’s place. If this was your first visit, would it be easy to find and buy the product you’re looking for? Also, it is important to have simple navigation to each category and product, so your customers will find exactly what they want.

Familiar Icons

It is tempting to get fancy when creating the site. This is good for some things. Themes, embedded videos, a font that reflects your product. Other things, like cart and account icons, should be made how users have come to expect them. Use familiar buttons and icons. This makes it not confusing and time-saving for customers to take actions on your store.

Easy Navigation

Clear, simple navigation helps out in a couple of ways. First, it helps customers find products and information. Second, it improves the SEO ranking. Strong site navigation means that data can be effectively indexed by search engines. Here are some tips for easy navigation:

  • Include a search feature
  • Include ALT text with clickable images
  • Use accurate navigation titles
  • Incorporate clickable links in all navigation elements
  • Divide site categories clearly
  • Keep navigation consistent throughout the site

Useful Functionality

Functionality is the key to customer engagement. It’s the interactive aspect of the site. Site functionality of your site depends on your product and desired customers. Keep in mind the purpose of the site, and build the functionality to make that purpose happen. Try to let your customers reach the point of sale with a few clicks as possible. Keep it simple and direct, and treat customers as if they are valued guests. If we will compare Magento, Drupal and WordPress – each of them has different modules and extensions to add all necessary features to the store.

Filtering Products

To make your eCommerce site user-friendly, you’ll want to let customers search by price and type of product. Product filtering is a faceted search that lets customers find products with the qualities they want. It incorporates details like size, color, price, and reviews. Keep in mind that your site is performing a service. Design each feature to inform the customers and help them find what they want with a minimum of steps.

Reorder Feature

It’s a lot easier to develop a relationship with existing clients than to constantly seek out new ones. So, the reorder feature is essential. It helps previous customers place new orders without going through the hassle of entering payment information all over again. Remember, the fewer steps mean more conversions.

Availability and Out-of-Stock Features

This comes back to the choice of CMS. Each includes with different stock features and plugins. Consider the functionality and qualities your site needs. Then, check into the CMS to find out if they come standard with it. Remember that there is a difference between and feature bloat. It isn’t necessary to get every feature on the planet. Look for the ones that improve the customer’s experience.

Analytics

Analytics is a measurement of how customers work with the website. In-demand keywords, click-through rates, bounce rates, and conversions. Watching the analytics lets you refine your website based on what your customers want. Google offers free online services like Analytics, AdWords, and Webmaster to monitor site activity. Make sure to set up and sync them. Arrange funnels and goals in the analytic software, and make sure the website includes analytics codes.

GDPR Compliance

It is essential to protect clients’ information. GDPR establishes guidelines and laws to give people more control over personal information. Remember PCI compliance if your site processes credit cards. Make service terms, privacy policies, and cookie usage visible and clear. Consider clients with disabilities and make the site accessible for them. Several GDPR plugins and extensions are available to get your site GDPR compliant.

Clients’ Feedback

The success of an online shop is all about building relationships with clients. In providing them a chance to give feedback, you give them a voice. This lets your clients know you value them. Plus, the reviews, testimonials, and other information your clients provide give you valuable tips to refine your site.

In the end, we want to provide you the overall table of comparison of all the main characteristics to consider before the website launch. As it was mentioned earlier, we choose 3 well-known CMS: Magento, Drupal and WordPress and you can see their benefits by key parameters.

FunctionalityMagento 2DrupalWordPress
UsabilityAverage. You need a developer to set up all the features and customizations. However, the basic admin settings and admin panel usage are quite intuitive.Average. It requires a developer help.Simple. You will find everything on the admin panel.
SecurityHigh-level of security, including reCaptcha, Signifyd fraud protection tool and password management.High. Frequently update of modules and patches.Basic. You can use password management to protect your login.
Website PerformanceAverage. However, you can optimize it with Varnish page caching and admin rendering and other optimization techniques.Hight. Drupal is less resource intensive and it’s easy to support thousands of pages.Average. If you optimize your store promptly, you will have high-speed loading pages.
SEOHigh. You can add all the necessary information, Alt-text, meta tags, descriptions and use the full power of keywords and other SEO tools.High. There are all of the SEO features available with the additional modules and plenty of responsive themes for the sites.Basic. It offers several SEO tools to implement them for the store.
AnalyticsHigh. Magento has advanced reporting and also daily reports on a dashboard.Average. You can install Google Analytics for your site.Average. You can choose among various analytics tools on the plugins market.
GDPR ComplianceHigh, i.e., there are lots of GDPR extensions and also it is easy to make all the pop-ups and website sections to make your store compliant.Average. Drupal offers software tools for the GDPR regulation to implement them for the site. However, the most important documentation part is the responsibility of the store owner.High. Self-hosted WordPress.org sites have a built-in policy generator. Also, you can use various plugins to add some information if needed.
CustomizationHigh-level of scalability gives an ability to extend and add any different useful features for the store.High. It has a lot of extensive features and customizations.High. There are many templates and plugins available for free. That is why customization is easy.

How to Find a Magento Services Company That Cares

Magento® 2 is recognized as the leading platform in the field of eCommerce. It is scalable, customizable, and provides all the functionality suitable for any type of online business. Plus, Magento offers an excellent support community and top-notch security features. It’s the platform you want for building a new site, site maintenance, upgrades, or new extensions.

Now that you know you’re working with the best platform around, what’s next? Find a Magento developer! So, the question becomes, how can you find the best Magento services company for your site? More importantly, what qualities are needed in your developer to make your online shop the best that it can be? Let’s explore the criteria needed to choose the web agency that will bring your site to the top of the ranks.

Where to Start?

When choosing your Magento web agency, you want to make sure that they fit your specifications. The best web developer will be able to optimize your site for SEO and provide ongoing support and maintenance. The key is to do your homework. Look into the level of experience, both of the company and the specialists on their team. Explore the developer’s portfolio and all reviews and testimonials available. Finally, look into location and pricing. While you’ll want to make sure the project is within budget, it is equally important to ensure that you choose a developer that can make your site perfect.

Size of the Market

With the popularity of Magento 2, there are around a thousand companies on the market, serving more than a quarter million merchants worldwide. According to Magento website’s information, there are around 315,000 trained Magento developers. Some web agencies may not be reliable and others may be based in a different time zone or operate primarily in a different language. Some developers specialize in certain types of sites or businesses. With so many companies on the market, one of the best places to start is a research and review firm. Clutch is an excellent site for ratings and reviews of lead IT companies. It’s data-driven. The reviews are verified. It provides everything you need to separate the wheat from the chaff and find the best agency. You can check their top web development companies’ rank to filter the search results.

Market

Portfolio

Any developer worth their salt will have a long list of satisfied merchants that can attest to their skills and service. After narrowing down your selection, explore each company’s portfolio. You’ll find out how long they have been in business, what industries they’ve serviced, and the types of development work they’ve performed. Different companies will have experience building different custom extensions and creating specific functionalities. Visit the sites that the developer has built before to see their work in action.

Portfolio

Reviews

After checking the portfolio, look into testimonials and reviews. It’s important to hear what their previous customers have said about them. Other clients that have used the developer will be able to let you know how they deal with challenges or emergencies as they arise. They’ll be able to give reports on availability and communication. Also, each site has unique challenges, specific products, custom personalization, and functionalities. By looking into reviews, you’ll be able to see how the web agency has implemented these features for their other clients.

Location

Magento’s popularity means agencies and web developers can be discovered across the globe. So, location is one important consideration when choosing your Magento developer. Qualified developers located in different countries, but regional economy means that rates in some countries will be smaller. This can be appealing, especially if you’re on a tight budget. At the same time, you may need to contend with communication challenges or availability issues. When working with a developer in a different time zone, make sure that all your sites requirements are clearly laid out at the beginning. Also, some problems need prompt attention. You’ll want to ensure your web agency is available to address any problems within an acceptable timeframe.

Platform-Oriented

Each platform has its own unique coding requirements, extensions, features, and modules, features. While it’s nice to be a jack of all trades, you’ll do best with a developer that has mastered your platform. When using a Magento eCommerce platform, it’s best to seek out a web agency with a high degree of Magento expertise. While checking the company’s portfolio, research the platforms they’ve used. The web agency you want for your site will show a history of well-designed Magento sites with satisfied customers. This lets you know they’ve got the experience needed to make your site truly top notch.

Social Media Activity

In the digital era, social media has become an invaluable tool for finding the best agency. LinkedIn, Twitter, and Facebook is social networking sites that help customers and clients to come together. They provide excellent places to begin a search and allow you to explore customer feedback beyond what is presented on their website. When you look into a company’s social media site, you can find out how active they are. Learning about their activity in social media will help you to get the full picture of their professionalism. High activity means that the developer is up to date with the newest features, extensions, and upgrades.

Reliable Experience

When searching for a web agency, remember to look into all levels of Magento experience. This means that the agency should be certified by Magento. Quality assurance and project management in addition to frontend and backend site development will be a benefit. When vetting your developer, make sure to ask what kind of teams they have worked with and what industries they have designed for. Site execution and management are two essential areas. The site must be executed in the way that you want and need to get the best results. Finally, there will be times when it’s necessary to make changes and adjustments to the site. A professional company will be skilled and capable of making these changes when necessary.

Industry Expertise

In the vetting process, consider that each industry has a specific set of requirements for a website look and feel. You should look at the designs, themes, functionalities, and features that make a site aesthetic, profitable, and successful. Look for Magento services with industry-relevant experience. You want to find an agency that can tailor your site to specifications. If they have experience in the industry, they’ll know how to engage your customers and showcase your products. The right agency will show the expertise necessary to complete the project for your client.

Long-Term Partnership

When trying to find Magento certified developer, here’s a final consideration: longevity. Satisfied relationship means things are going well. This is a trustworthy sign of a solid and reliable working partner. When checking the portfolios of prospective web developers, look for those that have long-term partnerships with many digital and consulting agencies. This means that they can do the work and meet the needs of their clients over time.

Magento Freelancer or Agency: Who Will Suit Your Project?

One of the most important decision points for Magento® store owners is whether to go for a Magento freelancer or Magento development agency. As the operator or managers of an eCommerce store, you completely understand that the decision can get confusing at times. In this article, we will provide you with a comparative analysis about which choice is the suitable option for you.

Difference Between Magento Development Agency and Magento Freelancer

The pros of Magento freelancers are that you will get the flexibility that you need in your firm. Freelancers usually prefer to work alone and charge a comparatively lower price. They are usually experts in a particular field and are able to use specialized knowledge or skill for completing the work. We would recommend choosing an experienced Magento developer if your project is on a small scale level.

The cons of hiring a freelancer include the fact that they cannot be master of everything! Hence, they lack diversity when it comes to managing your website. The low operation cost and flexibility comes with a price as well. Since freelancers prefer to work during their own time, they tend to be unreliable at times and communication with them is less formalized.

The core competency of Magento development agency is the fact that they work in a team. The team provides diversity and the set of skill sets that you need for effective project management. Communicating work with them is actually much more convenient and easier. In usual cases, Magento development agencies have a separate client servicing department to deal with your feedback and queries.

Definitely going for Magento development agency is the better choice to go for. The price differs, but you will see it as more of an investment when you hire an experienced Magento 2 developer from agencies rather than an unnecessary cost.

Questions to Consider Before Making a Choice

When it comes to making a choice, it is easier to make the final call when you have some set standards of distinction or specific criteria to compare with. A Magento developer guide can be useful in this aspect. Some of the common questions you need to consider before making the choice are as follows:

  • What value will a Magento development agency or freelancer add to my website?
  • What are the pros and cons of each option?
  • What is the cost associated with a certain decision?
  • Will the undertaken cost be actually useful to my business?

Do You Need One Magento Developer or a Team?

Yes, Magento has a user-friendly interface, but a lot of back-end work goes for that kind of interface and development. The burning question here is whether you should opt for a developer or a team? The table below will help you better assess the situation.

Criteria of distinctionAgencyFreelancer
PricingMagento development cost of agencies is usually on the project basis. They charge around $8000 or more depending on the project size and type of work that should be done.The cost for freelancers is relatively cheaper and usually calculated on an hourly basis. The cost could start from $15 per hour to more depending on the experience of the freelancer.
KnowledgeIn agencies, there is a guarantee that you will find experienced Magento developers and a team with complementary skills.From country to country, the knowledge or level of expertise might vary for each freelancer.
SupportThe level of support is much more comprehensive for agencies. Constant communication and feedback is the key to building the right product. In fact, you will get the support of your store even after the development process will be finished. You may find a need in constant support and updates.With freelancers, it is difficult to provide constant feedback and get the work done on time specifically for complex projects.
Project ManagementAgencies are more prone to informing you on what stage of the project you are in. Project managers will help you with communication and timelines. Even if you hire a dedicated Magento developer, you will be provided with the updates during your collaboration.With freelancers, the communication channel will be optional. However, it is not a guarantee of constant communication and strict deadlines.
Additional ServicesWith migration, integration and customization support, it is always recommended that you choose an agency. Their team will have better knowledge and experience.Freelancers are known to be more reliable for performing standardized tasks rather than customized ones.

Where to Find Magento Developers?

Now that you understood that Magento developers can add a great deal of value to your business, here are tips about where to find a Magento developer.

Magento-Related Events

You will find a great networking opportunity in Magento related events and eCommerce conferences and seminars. Talking with professionals in the field will give you a better perspective.

Magento Certification Directory

Magento certification directory usually has the list of the skilled and experienced Magento developers. However, if you are looking for a full team, this is not the right place to search.

Research and Review Platforms

Review and research platforms such as Clutch, Angel.co, Extract is the best way to find eligible Magento development and eCommerce agencies. You will find honest reviews and area of expertise there which will help to make a conscious decision.

Freelance platforms

Platforms such as oDesk, Elance and much more will provide you with the right service you need. All you need to do is sign up there and post your project requirement and details. You will find a list of freelancers willing to do that job.

Social Media

LinkedIn, Twitter and Facebook can also be a good platform to look for eligible Magento developers.

How to Find the Best Magento Development Company

When you have an eCommerce business, one of the first things you have to consider is who you’re going to choose to develop your site. The developer or Magento® services company will determine how your site is built and executed. Still, this is a job that can be done by experienced developers.

To check if the company has a reliable experience, you need to look through:

  • The overall number of years in development
  • eCommerce expertise
  • Brand Reputation
  • Company’s presence on trusted listings and research & review platforms.

We’ve created the guide, which will aid you in filtering through the various number of companies worldwide.

Criteria for the Best Magento Development Company

Deciding which Magento web development company can be a time-consuming task for anyone. It’s hard to narrow down who you should hire, and it’s even harder to decide how you can narrow down the search field. There are a few criteria you can follow to ensure that your company gets the best it deserves.

Overall Years of eCommerce Experience

One of the best ways to find the right team for your eCommerce site is to find one with experience in the field. These people will be more prepared to deal with your site and any problems that can arise because they have knowledge not only in the development part but overall experience in this specific type of business field.

The more experience a company has, the more likely it has a strong brand reputation and reviews about the quality of its work. You’ll find people who have reviewed the company or posted comments about them. These reviews are important because they provide inside information into the development team you’re thinking of hiring.

Experienced Magento Developer in Team

When you want to hire a team to develop your site, you should look for a team that has an experienced Magento 2 developers among them. The overall experience of the developer should be more than 4 years and preferably Magento certification.

Types of Past Projects

Whoever you decide to hire should have a portfolio for you to look over. You can always ask to see this portfolio when you conduct an interview or when you send them a message. You should ask them what kind of companies they’ve worked with in the past, what kind of teams they’ve been a part of, etc.

Company’s Location

You can find Magento developers or agencies anywhere in the world. The rate depends on the country where a company is located and experience as we mentioned above. The only one thing that you should be aware of and consider before choosing the specific company is the time zone. If you use a dedicated approach or you hire offshore developers, it means that you will have a different time with them and the management should be explicitly planned. However, it is not an issue, if you hire a full team with project managers from the company’s side that will control the development process carefully. No matter where you choose to hire your developer on, you must ensure that terms are agreed upon.

Pricing Models

This is one of the most important features of anyone who owns a business. You have to figure out your pricing models, as well as how much you’re willing to pay. Next, you have to ask how much your site’s development is going to cost. There are a few models you can follow when it comes to the cost of your project.

Dedicated Team Model

Business owners love the dedicated team model. That’s because it usually involves a contract between the developer and the business owner. In this contract, specific terms are agreed upon.

Both parties have to agree on the requirements on the project as well as its length. Each dedicated team focuses entirely on projects for a single company before taking on new clients. If you go with this pricing model, you have the confidence in knowing that your company is the priority. Also, the huge benefit is that you take full or partial control over the project management.

Time & Material Model

The time and material model is popular among many contractors and developers. If you’re going to hire someone as your developer and you agree upon the time and material model, you can expect to pay for the developer’s time and the cost of his or her work.

Fixed Price Model

The fixed price model works exactly as its name suggests: you hire a developer for a project by the price agreed. This may include materials or it may not, but you don’t have to worry about being charged hourly or having hidden costs. The fixed price model can look different depending on what you and any other parties agree upon. You can be charged a fixed price every week, every two weeks, or every month.

QA And Testing

There are two components that are absolutely vital for the site future: your Q&A section of the site and the execution of your site.

The Q&A section of your eCommerce site will allow your potential customers to understand your business better. For those who aren’t sure if they want to choose a certain company, this section can be a deciding factor.

Next, you have to make sure that your site can be executed properly. When you’re going to hire a developer, you should consider asking them what their process is for making changes on your eCommerce site. Not only this, but you should ask if they have measures to reverse any changes in case something goes wrong. No matter what, hiring a team which is fully professional and have all the needed specialists will give you the best projects result at the end.

Availability of Support and Maintenance

After your eCommerce site is developed and deployed, you’ll need to have someone that can provide support and maintenance for your site. Your brand will develop over time, so you may need to consider hiring someone who can work for you over the long term. If the person developing your site isn’t willing to provide more long-term support, you may have to find someone who is. If you need someone to make changes to your live site, you may want to ask what their process is and whether they keep track of these changes.

10 Magento 2 eCommerce Themes: Best Selection of 2018

Magento® is one of the hottest eCommerce platforms on the market, and it’s easy to see why. Magento has a dedicated community of developers and a wide range of easily accessible documentation. Add to that a host of features like pre-coded templates, payment platforms, and themes to fit every online store, and it’s no wonder that Magento has gained popularity so quickly.

But there’s a downside to having many options. How do you know which one is right for your shop? So, to cut through the confusion here’s a breakdown of the top 10 Magento 2 themes. We’ll explore the features and pricing of each, plus service and which is most suitable for different kinds of online store.

What Is the Magento 2 Theme?

Essentially, a theme is an online storefront. It’s the layout of the page, how the menus are arranged, the color scheme, and the general aesthetic presentation. This may seem small, but developers know that the theme can make all the difference when it comes to bounce rates, conversion rates, and overall site success.

For example, you want a professional theme and one that reflects your product or service. Different colors and layouts are suitable for different business. A site that selling tech products will want a clean layout with colors that make your products stand out, while a fashion site needs to have a bit more flash to engage the customers.

Finally, the best themes work well with SEO and are technologically advanced, fitting for all mobile devices and browsers. This means that you’ll be looking for Magento 2 responsive themes capable of adjusting layouts to fit different screen sizes. The good news is that Magento offers themes suitable for all business needs. Let’s have a look at those that top the market for 2018.

Top Magento 2 Themes 2018

Here is a brief review of the best themes on the market this year. We highlight key features, pricing, service, and the niche they work best for. To explore any theme more fully, simply click the link in the heading.

Ultimo Responsive Magento Theme

Ultimo Magento Themes Ultimo is an ideal theme for those that are starting off. It can be customized easily and is extremely user-friendly. This means that it’s suitable for any type of online store. Ultimo also comes with an advanced admin module. This makes it simple to customize product categories based on certain search parameters. Plus, Ultimo is SEO optimized out-of-the-box. It can be installed in a couple of minutes and comes with free updates.

Some Key Features of Ultimo:

  • Multi-Store Ready
  • Responsive, Customizable Layout
  • Unlimited Colors and Custom Subthemes
  • High-Quality Brand Logos
  • More than 50 Content Placeholders
  • 12-Column Fluid Grid System

Ultimo is available for $99. This includes future updates, quality control checking by Envato, and 6 months of Infortis support. An additional $31.50 will extend the support to 12 months.

Fastest Multipurpose Responsive Theme

Fastest Magento Theme

This theme is aptly named – it was designed to be the fastest-loading theme on the market. It also provides a wide range of customizable options, making it suitable for any type of business. Fastest is loaded with extra features that come free with the package. From social sharing to brand tools, it provides everything you need to tailor the site to your product.

Some Key Features of Fastest:

  • Brand pages featuring SEO optimization, layer navigation, and social networking
  • Brand search boxes and brand list widgets
  • Brand logos, banners, and descriptions
  • Custom Ajax carts
  • Simple blog extensions
  • Pop-up newsletters and promo panels

Fastest can be purchased for $99. The package comes with free features like Ajax Layered Navigation and the Codazon slideshow extension. It also comes with 6 months free support from Codazon, quality control from Envato, and future updates. An additional six months of support can be purchased for $31.50.

Unero Minimalist Magento 2 and 1 Theme

Unero Minimalistic Magento Theme

Unero is designed to eliminate the non-essentials so that the products will stand out. This makes it suitable for a wide range of different businesses, including decoration, furniture, fashion, and more. It also has features which support an omnichannel approach, allowing customers to locate physical shops or buy directly from the site. Its streamlined layout makes site navigation easy, boosting customer engagement and increasing conversion rates.

Some Key Features of Unero:

  • MGS Frontend Builder
  • Simple blog extensions
  • 360-degree image view
  • Advanced Reports
  • Ajax Fly Cart
  • Social login

Like Ultimo and Fastest, the Unero theme costs only $99 and comes with Envato quality checking, 6months of free service (through ArrowHiTech), and future updates. Also like the themes above, service can be extended to 12 months for only $31.50.

Bencher Responsive Magento 1 & 2 Theme

Bencher Responsive ThemeBencher is another excellent theme all-around, good for any type of online store. It is designed to be easy to customize and responsive to every screen size and resolution. This makes it great for both PC and mobile devices. Bencher makes an excellent starter theme for unique sites and products, as it can be tailored to your exact specifications.

Some Key Features of Bencher:

  • Custom social media integration
  • Top Menu and Extra Menu
  • Custom Hover for product image
  • Untimated Colors Power Admin
  • Ajax cart
  • Simple Blog Extensions

Bencher is one of the least expensive themes in this list, able to be purchased for only $84. This package also includes future update, Envato quality checking, and six months of support through Alotheme. This support can be extended to twelve months with a payment of $25.88.

Hermes Premium Responsive Magento 2 & 1 Theme

Hermes Premium Responsive Theme

The adaptable, intuitive design of Hermes Magento theme makes it simple to customize. It includes six basic designs which can then be adjusted as needed to suit your store. This makes it yet another theme that works well with any type of business. It also means that your theme can be tailored with a minimum of time and effort. Hermes also has Lazy Loading so that it responds quickly and with a minimum of lag time.

Some Key Features of Hermes:

  • New Products Slider Extension
  • Smart Megamenu
  • Moo-Cloudzoom Product Image Zoom Extension
  • Categories Product Extension
  • Flexible styling, fonts, and colors
  • Ajax Layered Navigation

Hermes is the least expensive theme on this list, able to be purchased for only $55. The basic package includes six months of service by The_Blue_Sky, future updates, and Envato quality checking. The support can be extended to twelve months with no more than $15.

HippoSpa – SPA Store Magento Theme

Hippospa ThemeHippoSpa is a theme designed specifically for spa and wellness products. It combines eye-catching layouts with smooth performance and responsiveness. HippoSpa also specializes in SEO optimization, making it easy for customers to find your site. Add to that a clean content structure, two custom page designs, and extreme customizability, and you have a theme that can have your site up and look amazing in no time at all.

Some Key Features of HippoSpa:

  • Free assistance 24/7
  • SEO and Performance optimization
  • Cross-browser compatibility
  • Newsletter Pop-up
  • MegaMenu
  • Featured Products Theme Options

HippoSpa can be purchased for $179. Support is free, but other services will have to be bought individually. These include installation, which costs $49 and hosting, which costs $27. Additional options include the SEO boost for $99 and the 1-year SSL certificate for $10.

Pearl Responsive Theme

Pearl Magento 2 ThemePearl has been developed to be the ideal theme for fashion websites. The design focuses on elements that showcase your products in all their glory. Perfect spacing, parallax, sliders, modern lookbooks, the theme contains everything you need to engage customers with the image of the product. Pearl is also highly customizable, allowing you to create a unique appeal that reflects your brand.

Some Key Features of Pearl:

  • Plenty of frontend admin control options
  • Unlimited color options and Google fonts
  • Ajax Cart and Quick View
  • Flexible Header and Footer Options
  • Flexible Product Page Design
  • Google Analytics Advanced eCommerce Tag Manager

Pearl can be purchased for $499 and comes with three months of free service.

iShop Electronic Magento 2 Theme

Ishop Electronic Magento Theme

If you’re looking for a theme designed to support electronic and technological products, iShop is the perfect solution. It offers a clean layout and intuitive navigation, with features that showcase your products without crowding the page. iShop also offers full responsiveness, high performance, and extreme customizability. Its professional design helps to boost traffic and conversion rates for any online electronic store.

Some Key Features of iShop:

  • MegaMenu
  • Flexible Architecture
  • Cross-browser Compatibility
  • Social Options
  • Newsletter Pop-up
  • Google Web Fonts
  • Carousel Product Listing and Configurable Swatches

The iShop theme costs $179 and comes with free 24/7 access to a pro support team. Installation runs an additional $49, and hosting is provided for $27. Optional services like SSL certificates and SEO boosts can be purchased along with the theme for additional fees.

Magetique – AMP-Ready Magento 2 Theme

Magetique Premium Magento ThemeMagetique requires a minimum of programming skills or CSS knowledge to make a top-notch site. It’s also very versatile. The basic theme includes five layouts designed to fit virtually any online store. On-screen elements, pages blocks, and pages themselves can be edited easily and with a minimum of challenge. Plus, it’s fully responsive, loads quickly, and is optimized for mobile devices. Magetique is an excellent starter theme and can be customized and tailored to precise specifications.

Some Key Features of Magetique:

  • Intuitive Interface
  • Parallax and Video Background
  • Cross-browser Compatibility
  • MegaMenu
  • Social Options
  • Advanced Theme Options

Magetique can be purchased for $179 and offers 24/7 free support. Installation and hosting are extra: $27 for hosting and $49 for installation. A 1-year SSL certificate can be purchased for $10 dollars, and SEO optimization will cost an additional $99.

Recuidi Healthy Food Store Magento Theme

Recuidi Food Theme

The prime theme of 2018 for online healthy food stores is Recuidi. It offers a wide selection of theme options that are perfectly suited to showcase food with gorgeous colors and aesthetic presentation. Recuidi uses many banners and live-search functionality, making it easy for customers to find products, recipes, and other offerings quickly and with minimum effort. If you’re ready to set up an online organic food store or expand your physical store with online options, Recuidi offers a simple and professional solution.

Some Key Features of Recuidi:

  • MegaMenu
  • Newsletter Pop-up
  • Products Filter
  • Social Options
  • Features Products
  • Parallax and Video Background

Recuidi can be purchased for $179 and comes with free 24/7 service. Just as with iShop and Magetique, installation for Recuidi costs $49 and hosting can be bought for $27. Also as with the other themes, SEO and other options can be purchased for an additional charge.

Must-Have Magento Extensions to Spike Your Sales

If you own an eCommerce store you’ve probably used or have thought of using Magento® 2. This platform is known for its various benefits; including, the generation of sales and increased conversions. Today we will share top Magento extensions to increase your sales results.

What is Magento Extension?

Magento extensions are tools that allow you to enhance your Magento store. You can customize the site by installing extensions from the Magento extension store.

Magento Marketing Extensions

Among its many extensions, Magento offers marketing features that allow merchants to expand their marketing techniques, reach, etc. The method in which they do this depends entirely on the extension that’s being used. Below, you will find top extensions to increase the results from your marketing efforts.

Loyalty Program by Amasty

This extension is available with both the Community and the Enterprise editions. By using this marketing tool, merchants are able to create loyalty programs for their customers and clients. They can create rewards for those who receive points or who shop often.

A major benefit of using this extension is that merchants can choose among several promotional offers and it includes16 discount codes.

Coupon Link by Web Solutions NYC

By using Coupon Link, merchants are able to create links that are associated with coupon codes. When customers use these links, it provides them with a discount or coupon.

The way it works will depend on how you want to run your store. Most often, the URL is used in blog posts and marketing schemes.

MailBot by Beeketing

MailBot allows merchants to create pre-made campaigns. These include anything from scheduling emails or picking products to display. This is a benefit for anyone who is stressed on time because you can prepare all of your emails in advance to ensure the exact time of your email marketing campaign.

Gift Card by Aheadwords

This extension allows merchants to create gift cards for their customers and clients. The cards are customizable with this extension and the merchants can specify the values of the cards.

Clients and customers are able to use these cards to specify their own gift vouchers based on what their individual preferences are.

Subscribe at Checkout by Mageside

One of the most important factors in marketing is ensuring that your customers are subscribed to your newsletters. That’s because, after the initial sale, you can send them emails that will remind them you’re still around and that you have products that could be interesting for them.

With this extension, you can force your customers to subscribe by email before they checkout.

Rich Snippets by Atwix

The Rich Snippets extension allows you to show more detailed results. When your customers search for your products they’ll see more details about your every item.

Studies show that when eCommerce sites use Rich Snippets, their results tend to show up in higher positions. These results show up 20% to 30% more in increasing their ranking positions.

Even if you make everything to attract your customers with offers and provide them with your product updates, if you have some issues with navigation at your site, they will force difficulties when browsing around. That is why we suggest you the best extensions to improve the user experience at your store.

Best Free and Paid Magento 2 Extensions for Usability

If you’re looking for Magento eCommerce extensions to increase your store’s reach and usability, you might be wondering if there are any you can get without having to pay anything at all. That’s what we’re going to discuss in this section!

Improved Layered Navigation by Amasty

This Magento Commerce extension is one that many install in their Magento eCommerce store(s) because it allows customers to browse through your product catalog more comfortably.

The major benefit of using eCommerce extensions is that your customers have more access to your products. When they have this access to your products, they have the opportunity to buy them more easily.

Beyond this, you can also create the menu to suit your needs, as well as the needs of your clients. The SEO feature of this extension allows you to increase your ranking on Google because you can tailor your URLs and page names to include keywords.

AJAX Cart Pro for Magento 2 by Aheadwords

The AJAX Cart Pro for Magento 2 extension is one of the Magento ?ommunity extensions that allows merchants to create an “Add to cart” feature that immediately adds products from your website to their carts. These products can also have reviews and small descriptions added to them with this feature.

Request for Quote by FME

This is the perfect extension for anyone who wants to offer quotes to their clients. You can install fields for your customers or clients to fill out their personal information. Once they’ve done this, they have the opportunity to send the information to you in order to get an accurate quote or cost of the product.

Share Buttons by Neklo

Any merchant knows the importance of expanding their reach on social media. If you have Instagram, Twitter, Facebook, or Youtube pages, this widget tool allows you to share your site with your other websites. The Share Buttons extension also serves as a Magento blog extension.

Your customers can share your site to their own pages. This is the digital equivalent of word-to-mouth; only, hundreds of people can be exposed to your site at a time.

Detailed Product Review by MageWorkshop

When customers have a good or bad experience with your store, they might want to leave a detailed review about it. This allows potential customers who are using a Magento search module to get an idea about your products.

Development of Extensions

Now that you know about the various extensions available for Magento eCommerce business owners, you might be wondering about how extensions can influence the development of your site and how you can develop extensions on your site.

How to Install Plugin in Magento?

Installing a Magento plugin can be challenging; however, it is very manageable for all merchants when they use the following steps.

First, you should download or purchase the plugin you’re looking for. If a ZIP file is downloaded, you’ll have to unzip it. Some computers come with programs that automatically unzip folders when you try to open them.

Next, you’ll have to disable the Cache. Run the command and your extension will be installed from that moment. For the full guide, you can refer to our How to section.

How to Make Extension in Magento?

If you want to make your own extension in Magento, you’ll have to start out by disabling your Magento cache. Next, you’ll have to put Magento into developer mode by going to Magento 2 root in your terminal.

From here, you’ll have to create a Hello World module folder. You’ll also have to create a file called etc/module.xml, enable the module, and create a controller. This will give you an ability to create custom modules.

Managing the Magento 2.2.4 Category Tree Checkbox Bug

When using Magento® 2.2.4, a bug was identified in the category tree on the page for editing pricing rules. When trying to create pricing rules by product category (for a catalog or cart) not every category appeared in the category tree (a component of the form for generating a pricing rule for a category). More precisely, the root category of the first store, the first category of the store, and all of its child categories were displayed. Other categories were not displayed in the tree.

To fix this problem, we must analyze the implementation of the component, which you can see in the sample code in the next section.

Analysis of the Component for Price Rule by Product Category

Like the majority of Magento 2 components, this component has a back end and front end part (Javascript). A problem like this could be caused either by the fact that not all categories were transferred from the backend or by the fact that some categories weren’t rendered by the component in the Javascript tree for some reason. The component is implemented by the Magento\Catalog\Block\Adminhtml\Category\Checkboxes\Tree block. This block’s template, Magento_Catalog: catalog/category/checkboxes/tree.phtml, is set in its methods, and in it, the component is initialized by data in JSON format. The template looks like this in Magento 2.2.4:

<?php $_divId = 'tree-div_' . time() ?>
<div id="<?= /* @escapeNotVerified */ $_divId ?>" class="tree"></div>
<script id="ie-deferred-loader" defer="defer" src="//:"></script>
<script>
    require(["Magento_Catalog/js/category-checkbox-tree"], function (element) {
        element({
            "dataUrl":       "<?= /* @escapeNotVerified */ $block->getLoadTreeUrl() ?>" ,
            "divId":         "<?= /* @escapeNotVerified */$_divId ?>",
            "rootVisible":   <?php if ($block->getRoot()->getIsVisible()): ?>true<?php else : ?>false<?php endif; ?>,
            "useAjax":       <?= /* @escapeNotVerified */ $block->getUseAjax() ?>,
            "currentNodeId": <?= (int)$block->getCategoryId() ?>,
            "jsFormObject":  <?= /* @escapeNotVerified */ $block->getJsFormObject() ?>,
            "name":          "<?= /* @escapeNotVerified */ htmlentities($block->getRoot()->getName()) ?>",
            "checked":       "<?= /* @escapeNotVerified */ $block->getRoot()->getChecked() ?>",
            "allowDrop":     <?php if ($block->getRoot()->getIsVisible()): ?>true<?php else : ?>false<?php endif; ?>,
            "rootId":        <?= (int)$block->getRoot()->getId() ?>,
            "expanded":      <?= (int)$block->getIsWasExpanded() ?>,
            "categoryId":    <?= (int)$block->getCategoryId() ?>,
            "treeJson":      <?= /* @escapeNotVerified */ $block->getTreeJson() ?>
        });
    })
</s

As you can see, the Javascript component is implemented in a separate JS file: Magento_Catalog/js/category-checkbox-tree. This is an important difference from all previous versions since previously the Javascript of this component was implemented in the template, not put to a separate file. The code of this Javascript component is as follows:

define([
    'jquery',
    'prototype',
    'extjs/ext-tree-checkbox',
    'mage/adminhtml/form'
], function (jQuery) {
    'use strict';
    return function (config) {
        var tree,
            options = {
                dataUrl: config.dataUrl,
                divId: config.divId,
                rootVisible: config.rootVisible,
                useAjax: config.useAjax,
                currentNodeId: config.currentNodeId,
                jsFormObject: config.jsFormObject,
                name: config.name,
                checked: config.checked,
                allowDrop: config.allowDrop,
                rootId: config.rootId,
                expanded: config.expanded,
                categoryId: config.categoryId,
                treeJson: config.treeJson
            },
            data = {},
            parameters = {},
            root = {},
            len = 0,
            key = '',
            i = 0;
        /* eslint-disable */
        /**
         * Fix ext compatibility with prototype 1.6
         */
        Ext.lib.Event.getTarget = function (e) {// eslint-disable-line no-undef
            var ee = e.browserEvent || e;
            return ee.target ? Event.element(ee) : null;
        };
        /**
         * @param {Object} el
         * @param {Object} config
         */
        Ext.tree.TreePanel.Enhanced = function (el, config) {// eslint-disable-line no-undef
            Ext.tree.TreePanel.Enhanced.superclass.constructor.call(this, el, config);// eslint-disable-line no-undef
        };
        Ext.extend(Ext.tree.TreePanel.Enhanced, Ext.tree.TreePanel, {// eslint-disable-line no-undef
            /* eslint-enable */
            /**
             * @param {Object} config
             * @param {Boolean} firstLoad
             */
            loadTree: function (config, firstLoad) {// eslint-disable-line no-shadow
                parameters = config.parameters,
                data = config.data,
                root = new Ext.tree.TreeNode(parameters);// eslint-disable-line no-undef
                if (typeof parameters.rootVisible != 'undefined') {
                    this.rootVisible = parameters.rootVisible * 1;
                }
                this.nodeHash = {};
                this.setRootNode(root);
                if (firstLoad) {
                    this.addListener('click', this.categoryClick.createDelegate(this));
                }
                this.loader.buildCategoryTree(root, data);
                this.el.dom.innerHTML = '';
                // render the tree
                this.render();
            },
            /**
             * @param {Object} node
             */
            categoryClick: function (node) {
                node.getUI().check(!node.getUI().checked());
            }
        });
        jQuery(function () {
            var categoryLoader = new Ext.tree.TreeLoader({// eslint-disable-line no-undef
                dataUrl: config.dataUrl
            });
            /**
             * @param {Object} response
             * @param {Object} parent
             * @param {Function} callback
             */
            categoryLoader.processResponse = function (response, parent, callback) {
                config = JSON.parse(response.responseText);
                this.buildCategoryTree(parent, config);
                if (typeof callback === 'function') {
                    callback(this, parent);
                }
            };
            /**
             * @param {Object} config
             * @returns {Object}
             */
            categoryLoader.createNode = function (config) {// eslint-disable-line no-shadow
                var node;
                config.uiProvider = Ext.tree.CheckboxNodeUI;// eslint-disable-line no-undef
                if (config.children && !config.children.length) {
                    delete config.children;
                    node = new Ext.tree.AsyncTreeNode(config);// eslint-disable-line no-undef
                } else {
                    node = new Ext.tree.TreeNode(config);// eslint-disable-line no-undef
                }
                return node;
            };
            /**
             * @param {Object} parent
             * @param {Object} config
             * @param {Integer} i
             */
            categoryLoader.processCategoryTree = function (parent, config, i) {// eslint-disable-line no-shadow
                var node,
                    _node = {};
                config[i].uiProvider = Ext.tree.CheckboxNodeUI;// eslint-disable-line no-undef
                _node = Object.clone(config[i]);
                if (_node.children && !_node.children.length) {
                    delete _node.children;
                    node = new Ext.tree.AsyncTreeNode(_node);// eslint-disable-line no-undef
                } else {
                    node = new Ext.tree.TreeNode(config[i]);// eslint-disable-line no-undef
                }
                parent.appendChild(node);
                node.loader = node.getOwnerTree().loader;
                if (_node.children) {
                    categoryLoader.buildCategoryTree(node, _node.children);
                }
            };
            /**
             * @param {Object} parent
             * @param {Object} config
             * @returns {void}
             */
            categoryLoader.buildCategoryTree = function (parent, config) {// eslint-disable-line no-shadow
                if (!config) {
                    return null;
                }
                if (parent && config && config.length) {
                    for (i = 0; i < config.length; i  ) {
                        categoryLoader.processCategoryTree(parent, config, i);
                    }
                }
            };
            /**
             *
             * @param {Object} hash
             * @param {Object} node
             * @returns {Object}
             */
            categoryLoader.buildHashChildren = function (hash, node) {// eslint-disable-line no-shadow
                // eslint-disable-next-line no-extra-parens
                if ((node.childNodes.length > 0) || (node.loaded === false && node.loading === false)) {
                    hash.children = [];
                    for (i = 0, len = node.childNodes.length; i < len; i  ) {
                        /* eslint-disable */
                        if (!hash.children) {
                            hash.children = [];
                        }
                        /* eslint-enable */
                        hash.children.push(this.buildHash(node.childNodes[i]));
                    }
                }
                return hash;
            };
            /**
             * @param {Object} node
             * @returns {Object}
             */
            categoryLoader.buildHash = function (node) {
                var hash = {};
                hash = this.toArray(node.attributes);
                return categoryLoader.buildHashChildren(hash, node);
            };
            /**
             * @param {Object} attributes
             * @returns {Object}
             */
            categoryLoader.toArray = function (attributes) {
                data = {};
                for (key in attributes) {
                    if (attributes[key]) {
                        data[key] = attributes[key];
                    }
                }
                return data;
            };
            categoryLoader.on('beforeload', function (treeLoader, node) {
                treeLoader.baseParams.id = node.attributes.id;
            });
            /* eslint-disable */
            categoryLoader.on('load', function () {
                varienWindowOnload();
            });
            tree = new Ext.tree.TreePanel.Enhanced(options.divId, {
                animate: false,
                loader: categoryLoader,
                enableDD: false,
                containerScroll: true,
                selModel: new Ext.tree.CheckNodeMultiSelectionModel(),
                rootVisible: options.rootVisible,
                useAjax: options.useAjax,
                currentNodeId: options.currentNodeId,
                addNodeTo: false,
                rootUIProvider: Ext.tree.CheckboxNodeUI
            });
            tree.on('check', function (node) {
                options.jsFormObject.updateElement.value = this.getChecked().join(', ');
                varienElementMethods.setHasChanges(node.getUI().checkbox);
            }, tree);
            // set the root node
            //jscs:disable requireCamelCaseOrUpperCaseIdentifiers
            parameters = {
                text: options.name,
                draggable: false,
                checked: options.checked,
                uiProvider: Ext.tree.CheckboxNodeUI,
                allowDrop: options.allowDrop,
                id: options.rootId,
                expanded: options.expanded,
                category_id: options.categoryId
            };
            //jscs:enable requireCamelCaseOrUpperCaseIdentifiers
            tree.loadTree({
                parameters: parameters, data: options.treeJson
            }, true);
            /* eslint-enable */
        });
    };
});

As you can see, this component is a Javascript function that initializes an object (the category tree) and also auxiliary objects, which allow to display a category tree with checkboxes in the browser. The libraries jQuery, prototype, and extjs are used to do this. The last two of these have been used since Magento 1.

Using the Javascript browser debugger, I was able to establish that the category tree from the back end is completely transferred and the problem with rendering occurs at the Javascript component level. The location of the error was established, after detailed analysis, to be the buildCategoryTree method of the categoryLoader object. In the component, it looks as follows:

categoryLoader.buildCategoryTree = function (parent, config) {// eslint-disable-line no-shadow
    if (!config) {
        return null;
    }
    if (parent && config && config.length) {
        for (i = 0; i < config.length; i  ) {
            categoryLoader.processCategoryTree(parent, config, i);
        }
    }
};

The problem was in the loop counter variable i. The developers of the last version of the Magento_Catalog module made the variable global within the whole component. As a result, after rendering all of the first category’s child categories, of which there were 42, the cycle was complete. This is because there were far fewer subcategories in the root category, and they were not rendered. The variable should have been made locally in the buildCategoryTree method. It then would have been visible in the processCategoryTree method as well, since it would have been passed as a parameter. In fact, in the component’s implementation in previous versions, this variable was local, which you can see below (in an example from Magento 2.2.3):

categoryLoader.buildCategoryTree = function(parent, config)
    {
        if (!config) return null;

        if (parent && config && config.length){
            for (var i = 0; i < config.length; i  ) {
                config[i].uiProvider = Ext.tree.CheckboxNodeUI;
                var node;
                var _node = Object.clone(config[i]);
                if (_node.children && !_node.children.length) {
                    delete(_node.children);
                    node = new Ext.tree.AsyncTreeNode(_node);
                } else {
                    node = new Ext.tree.TreeNode(config[i]);
                }
                parent.appendChild(node);
                node.loader = node.getOwnerTree().loader;
                if (_node.children) {
                    this.buildCategoryTree(node, _node.children);
                }
            }
        }
    };

The reason for this bug was established, but another problem arose while attempting to fix it. All of the component’s objects exist only in local variables within the component’s functions and are not visible externally. Passing them into the component of some object that can call external code within the component is also not possible because the component doesn’t call external callback functions and doesn’t throw events. A mixin can’t be created because the component is a Javascript function and doesn’t have methods or properties available from outside.

Ultimately, we decided to completely rewrite the component, although that only required changing one line. This is better than editing the component in the core module. You must replace the template that initializes the component, and you must replace the existing component call in the template with the correct one.

Changes to the Component Code for Fixing the Category Display Problem

Since we’re dealing with a block of the admin panel, the adminhtml_block_html_before event handler can be used, which almost all admin panel blocks call before output. We implement this:

<event name="adminhtml_block_html_before">
    <observer name="default_product" instance="Web4pro\Defaultproduct\Observer\Changetemplate" shared="false" />
</event>
class Changetemplate implements \Magento\Framework\Event\ObserverInterface {

...
    public function execute(\Magento\Framework\Event\Observer $observer){

        if($block = $observer->getEvent()->getBlock()){
.
           if($block instanceof \Magento\Catalog\Block\Adminhtml\Category\Checkboxes\Tree){
               $block->setTemplate('Web4pro_Defaultproduct::tree.phtml');
           }
        }
    }
}

The new template will look as follows:

<?php $_divId = 'tree-div_' . time() ?>
<div id="<?= /* @escapeNotVerified */ $_divId ?>" class="tree"></div>
<script id="ie-deferred-loader" defer="defer" src="//:"></script>
<script>
    require(["Web4pro_Defaultproduct/js/category-checkbox-tree"], function (element) {
        element({
            "dataUrl":       "<?= /* @escapeNotVerified */ $block->getLoadTreeUrl() ?>" ,
            "divId":         "<?= /* @escapeNotVerified */$_divId ?>",
            "rootVisible":   <?php if ($block->getRoot()->getIsVisible()): ?>true<?php else : ?>false<?php endif; ?>,
            "useAjax":       <?= /* @escapeNotVerified */ $block->getUseAjax() ?>,
            "currentNodeId": <?= (int)$block->getCategoryId() ?>,
            "jsFormObject":  <?= /* @escapeNotVerified */ $block->getJsFormObject() ?>,
            "name":          "<?= /* @escapeNotVerified */ htmlentities($block->getRoot()->getName()) ?>",
            "checked":       "<?= /* @escapeNotVerified */ $block->getRoot()->getChecked() ?>",
            "allowDrop":     <?php if ($block->getRoot()->getIsVisible()): ?>true<?php else : ?>false<?php endif; ?>,
            "rootId":        <?= (int)$block->getRoot()->getId() ?>,
            "expanded":      <?= (int)$block->getIsWasExpanded() ?>,
            "categoryId":    <?= (int)$block->getCategoryId() ?>,
            "treeJson":      <?= /* @escapeNotVerified */ $block->getTreeJson() ?>
        });
    })
<

The new component will look as follows:

define([
    'jquery',
    'prototype',
    'extjs/ext-tree-checkbox',
    'mage/adminhtml/form'
], function (jQuery) {
    'use strict';
    return function (config) {
        var tree,
            options = {
                dataUrl: config.dataUrl,
                divId: config.divId,
                rootVisible: config.rootVisible,
                useAjax: config.useAjax,
                currentNodeId: config.currentNodeId,
                jsFormObject: config.jsFormObject,
                name: config.name,
                checked: config.checked,
                allowDrop: config.allowDrop,
                rootId: config.rootId,
                expanded: config.expanded,
                categoryId: config.categoryId,
                treeJson: config.treeJson
            },
            data = {},
            parameters = {},
            root = {},
            len = 0,
            key = '',
            i = 0;
        /* eslint-disable */
        /**
         * Fix ext compatibility with prototype 1.6
         */
        Ext.lib.Event.getTarget = function (e) {// eslint-disable-line no-undef
            var ee = e.browserEvent || e;
            return ee.target ? Event.element(ee) : null;
        };
        /**
         * @param {Object} el
         * @param {Object} config
         */
        Ext.tree.TreePanel.Enhanced = function (el, config) {// eslint-disable-line no-undef
            Ext.tree.TreePanel.Enhanced.superclass.constructor.call(this, el, config);// eslint-disable-line no-undef
        };
        Ext.extend(Ext.tree.TreePanel.Enhanced, Ext.tree.TreePanel, {// eslint-disable-line no-undef
            /* eslint-enable */
            /**
             * @param {Object} config
             * @param {Boolean} firstLoad
             */
            loadTree: function (config, firstLoad) {// eslint-disable-line no-shadow
                parameters = config.parameters,
                data = config.data,
                root = new Ext.tree.TreeNode(parameters);// eslint-disable-line no-undef
                if (typeof parameters.rootVisible != 'undefined') {
                    this.rootVisible = parameters.rootVisible * 1;
                }
                this.nodeHash = {};
                this.setRootNode(root);
                if (firstLoad) {
                    this.addListener('click', this.categoryClick.createDelegate(this));
                }
                this.loader.buildCategoryTree(root, data);
                this.el.dom.innerHTML = '';
                // render the tree
                this.render();
            },
            /**
             * @param {Object} node
             */
            categoryClick: function (node) {
                node.getUI().check(!node.getUI().checked());
            }
        });
        jQuery(function () {
            var categoryLoader = new Ext.tree.TreeLoader({// eslint-disable-line no-undef
                dataUrl: config.dataUrl
            });
            /**
             * @param {Object} response
             * @param {Object} parent
             * @param {Function} callback
             */
            categoryLoader.processResponse = function (response, parent, callback) {
                config = JSON.parse(response.responseText);
                this.buildCategoryTree(parent, config);
                if (typeof callback === 'function') {
                    callback(this, parent);
                }
            };
            /**
             * @param {Object} config
             * @returns {Object}
             */
            categoryLoader.createNode = function (config) {// eslint-disable-line no-shadow
                var node;
                config.uiProvider = Ext.tree.CheckboxNodeUI;// eslint-disable-line no-undef
                if (config.children && !config.children.length) {
                    delete config.children;
                    node = new Ext.tree.AsyncTreeNode(config);// eslint-disable-line no-undef
                } else {
                    node = new Ext.tree.TreeNode(config);// eslint-disable-line no-undef
                }
                return node;
            };
            /**
             * @param {Object} parent
             * @param {Object} config
             * @param {Integer} i
             */
            categoryLoader.processCategoryTree = function (parent, config, i) {// eslint-disable-line no-shadow
                var node,
                    _node = {};
                config[i].uiProvider = Ext.tree.CheckboxNodeUI;// eslint-disable-line no-undef
                _node = Object.clone(config[i]);
                if (_node.children && !_node.children.length) {
                    delete _node.children;
                    node = new Ext.tree.AsyncTreeNode(_node);// eslint-disable-line no-undef
                } else {
                    node = new Ext.tree.TreeNode(config[i]);// eslint-disable-line no-undef
                }
                parent.appendChild(node);
                node.loader = node.getOwnerTree().loader;
                if (_node.children) {
                    categoryLoader.buildCategoryTree(node, _node.children);
                }
            };
            /**
             * @param {Object} parent
             * @param {Object} config
             * @returns {void}
             */
            categoryLoader.buildCategoryTree = function (parent, config) {// eslint-disable-line no-shadow
                if (!config) {
                    return null;
                }
                if (parent && config && config.length) {
                    for (var i = 0; i < config.length; i  ) {
                        categoryLoader.processCategoryTree(parent, config, i);
                    }
                }
            };
            /**
             *
             * @param {Object} hash
             * @param {Object} node
             * @returns {Object}
             */
            categoryLoader.buildHashChildren = function (hash, node) {// eslint-disable-line no-shadow
                // eslint-disable-next-line no-extra-parens
                if ((node.childNodes.length > 0) || (node.loaded === false && node.loading === false)) {
                    hash.children = [];
                    for (i = 0, len = node.childNodes.length; i < len; i  ) {
                        /* eslint-disable */
                        if (!hash.children) {
                            hash.children = [];
                        }
                        /* eslint-enable */
                        hash.children.push(this.buildHash(node.childNodes[i]));
                    }
                }
                return hash;
            };
            /**
             * @param {Object} node
             * @returns {Object}
             */
            categoryLoader.buildHash = function (node) {
                var hash = {};
                hash = this.toArray(node.attributes);
                return categoryLoader.buildHashChildren(hash, node);
            };
            /**
             * @param {Object} attributes
             * @returns {Object}
             */
            categoryLoader.toArray = function (attributes) {
                data = {};
                for (key in attributes) {
                    if (attributes[key]) {
                        data[key] = attributes[key];
                    }
                }
                return data;
            };
            categoryLoader.on('beforeload', function (treeLoader, node) {
                treeLoader.baseParams.id = node.attributes.id;
            });
            /* eslint-disable */
            categoryLoader.on('load', function () {
                varienWindowOnload();
            });
            tree = new Ext.tree.TreePanel.Enhanced(options.divId, {
                animate: false,
                loader: categoryLoader,
                enableDD: false,
                containerScroll: true,
                selModel: new Ext.tree.CheckNodeMultiSelectionModel(),
                rootVisible: options.rootVisible,
                useAjax: options.useAjax,
                currentNodeId: options.currentNodeId,
                addNodeTo: false,
                rootUIProvider: Ext.tree.CheckboxNodeUI
            });
            tree.on('check', function (node) {
                options.jsFormObject.updateElement.value = this.getChecked().join(', ');
                varienElementMethods.setHasChanges(node.getUI().checkbox);
            }, tree);
            // set the root node
            //jscs:disable requireCamelCaseOrUpperCaseIdentifiers
            parameters = {
                text: options.name,
                draggable: false,
                checked: options.checked,
                uiProvider: Ext.tree.CheckboxNodeUI,
                allowDrop: options.allowDrop,
                id: options.rootId,
                expanded: options.expanded,
                category_id: options.categoryId
            };
            //jscs:enable requireCamelCaseOrUpperCaseIdentifiers
            tree.loadTree({
                parameters: parameters, data: options.treeJson
            }, true);
            /* eslint-enable */
        });
    };
});

As you can see, it differs from the original by only one line. However, now all categories created are available when editing the pricing rule.