How to add Custom Random Order Number in Magento 2

Written by Rutvik Monpara

Apr 24, 2023

How to add Custom Random Order Number in Magento 2
  • By default, Magento 2 generates order numbers sequentially, based on the time of the order. However, in some cases, you may want to use custom random order numbers instead. For example, you may want to use a different numbering system for your orders, or you may want to prevent customers from being able to predict the next order number. In this article, we will show you how to add a custom random order number in Magento 2.
  • To add a custom order number in Magento 2, you can follow these steps.

Step 1 : Register your module
Create a custom module in Magento 2.

Step 2 : Create Configuration

  • Create system.xml file at

app/code/Dolphin/CustomOrderNumber/etc/adminhtml/ folder

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
   <system>
      <tab id="dolphin" sortOrder="200" translate="label">
         <label>Dolphin</label>
      </tab>
      <section id="custom_order_number" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="210" translate="label">
         <label>Custom Order Number</label>
         <tab>dolphin</tab>
         <resource>Dolphin_CustomOrderNumber::config</resource>
         <group id="general" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="10" translate="label">
            <label>General</label>
            <field id="order" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="10" translate="label" type="text">
               <label>Order Number</label>
               <comment/>
            </field>
            <field id="invoice" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="10" translate="label" type="text">
               <label>Invoice Number</label>
               <comment/>
            </field>
            <field id="shipment" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="10" translate="label" type="text">
               <label>Shipment Number</label>
               <comment/>
            </field>
            <field id="creditmemo" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="10" translate="label" type="text">
               <label>Credit Memo Number</label>
               <comment><![CDATA[
                  Leave blank for default increment number.<br/>
                  <b>Sample Format</b><br/>
                  ABC_{str3}{num3}{increment_id}<br/>
                  <br/>
                  <b>The Following variables can be used.</b><br/>
                        {increment_id} - Default increment id.<br/>
                        {str3} - Random string with 3 characters.<br/>
                        {num3} - Random number with 3 digits.<br/>
                        <b>If the number is greater than 9 then take 9 static.</b><br/>]]>
                    </comment>
            </field>
         </group>
      </section>
   </system>
</config>

 

How to add Custom Random Order Number in Magento 2

Here is the screenshot of configuration.
Leave blank for Magento default increment number.
The Following variables can be used.

  • {increment_id} – Default increment id.
  • {strX} – Random string with X characters.
  • {numX} – Random number with X digits.
  • If the number is greater than 9 then it’ll consider 9 only.

Sample Format

  • ABC_{str3}{num3}{increment_id}

Step 3 : Override the Sequence.php file
Create di.xml at app/code/Dolphin/CustomOrderNumber/etc folder

<?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\SalesSequence\Model\Sequence" type="Dolphin\CustomOrderNumber\Model\Sequence" />
</config>

Step 4 : Create Sequence.php for apply custom number
Create a file Sequence.php at app/code/Dolphin/CustomOrderNumber/Model folder for extend class from Magento\SalesSequence\Model\Sequence.

<?php

namespace Dolphin\CustomOrderNumber\Model;

use Magento\Framework\App\ResourceConnection as AppResource;
use Magento\SalesSequence\Model\Meta;
use Magento\SalesSequence\Model\ResourceModel\Profile;
use Magento\Store\Model\ScopeInterface;
use Magento\Sales\Model\ResourceModel\Order\CollectionFactory as OrderCollection;
use Magento\Framework\Math\Random;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;

class Sequence extends \Magento\SalesSequence\Model\Sequence
{

    /**
     * @var string
     */
    private $lastIncrementId;

    /**
     * @var ScopeConfigInterface
     */
    protected $scopeConfig;

    /**
     * @var StoreManagerInterface
     */
    protected $storeManager;

    /**
     * @var Meta
     */
    private $meta;

    /**
     * @var Profile
     */
    protected $profile;

    /**
     * @var false|\Magento\Framework\DB\Adapter\AdapterInterface
     */
    private $connection;

    /**
     * @var string
     */
    private $pattern;
    public $temp;

    /**
     * @param ScopeConfigInterface $scopeConfig
     * @param StoreManagerInterface $storeManager
     * @param Random $mathRandom
     * @param OrderCollection $orderCollection
     * @param Profile $profile
     * @param Meta $meta
     * @param AppResource $resource
     * @param string $pattern
     */
    public function __construct(
        ScopeConfigInterface $scopeConfig,
        StoreManagerInterface $storeManager,
        Random $mathRandom,
        OrderCollection $orderCollection,
        Profile $profile,
        Meta $meta,
        AppResource $resource,
        $pattern = self::DEFAULT_PATTERN
    ) {

        $this->meta = $meta;
        $this->connection = $resource->getConnection('sales');
        $this->pattern = $pattern;
        $this->profile = $profile;
        $this->scopeConfig = $scopeConfig;
        $this->storeManager = $storeManager;
        $this->mathRandom = $mathRandom;
        $this->orderCollection = $orderCollection;
        parent::__construct($meta, $resource, $pattern);
    }

    /**
     * Retrieve current value
     *
     * @return string
     */

    public function getCurrentValue()
    {
        if (!isset($this->lastIncrementId)) {
            return null;
        }

        $storeId = $this->meta->getData('store_id');
        $metaEntityType = $this->meta->getEntityType();

        if ($metaEntityType == 'order') {
            $pattern = $this->getOrderFormat($storeId);
        }
        if ($metaEntityType == 'invoice') {
            $pattern = $this->getInvoiceFormat($storeId);
        }
        if ($metaEntityType == 'shipment') {
            $pattern = $this->getShipmentFormat($storeId);
        }
        if ($metaEntityType == 'creditmemo') {
            $pattern = $this->getCreditMemoFormat($storeId);
        } else {
            $this->meta->getActiveProfile()->getPrefix();
        }
        $incrementId = sprintf(
            $this->pattern,
            '',
            $this->calculateCurrentValue(),
            $this->meta->getActiveProfile()->getSuffix()
        );

        return $this->generateIncrementId($pattern, $incrementId, $metaEntityType);
    }

    public function getOrderFormat($storeId)
    {
        return $this->scopeConfig->getValue(
            'custom_order_number/general/order',
            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
            $storeId
        );
    }

    public function getInvoiceFormat($storeId)
    {
        return $this->scopeConfig->getValue(
            'custom_order_number/general/invoice',
            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
            $storeId
        );
    }

    public function getShipmentFormat($storeId)
    {
        return $this->scopeConfig->getValue(
            'custom_order_number/general/shipment',
            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
            $storeId
        );
    }

    public function getCreditMemoFormat($storeId)
    {
        return $this->scopeConfig->getValue(
            'custom_order_number/general/creditmemo',
            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
            $storeId
        );
    }

    /**
     * Retrieve next value
     *
     * @return string
     */
    public function getNextValue()
    {
        $this->connection->insert($this->meta->getSequenceTable(), []);
        $this->lastIncrementId = $this->connection->lastInsertId($this->meta->getSequenceTable());
        return $this->getCurrentValue();
    }

    /**
     * Calculate current value depends on start value
     *
     * @return string
     */
    private function calculateCurrentValue()
    {
        return ($this->lastIncrementId - $this->meta->getActiveProfile()->getStartValue())
         * $this->meta->getActiveProfile()->getStep() + $this->meta->getActiveProfile()->getStartValue();
    }

    public function generateIncrementId($patterns, $incrementId, $type)
    {
        $collection = $this->orderCollection->create();
        $pattern = $this->generatePattern($patterns, $incrementId);
        if ($type == 'order') {
            $collection->addFieldtoFilter('main_table.increment_id', $pattern);
        }
        if ($type == 'invoice') {
            $collection->getSelect()->joinLeft(
                        ['sales_invoice' => 'sales_invoice'],
                        'main_table.entity_id = sales_invoice.order_id',
                        []
                    );
            $collection->addFieldtoFilter('sales_invoice.increment_id', $pattern);
        }
        if ($type == 'shipment') {
            $collection->getSelect()->joinLeft(
                        ['sales_shipment' => 'sales_shipment'],
                        'main_table.entity_id = sales_shipment.order_id',
                        []
                    );
            $collection->addFieldtoFilter('sales_shipment.increment_id', $pattern);
        }
        if ($type == 'creditmemo') {
            $collection->getSelect()->joinLeft(
                        ['sales_creditmemo' => 'sales_creditmemo'],
                        'main_table.entity_id = sales_creditmemo.order_id',
                        []
                    );
            $collection->addFieldtoFilter('sales_creditmemo.increment_id', $pattern);
        }
        if (count($collection)) {
            return $this->generateIncrementId($patterns, $incrementId, $type);
        }

        return $pattern;
    }

    public function generatePattern($patterns, $incrementId)
    {
        if ($patterns) {
            $patterns = str_replace('{', ',{', $patterns);
            $patterns = str_replace('}', '},', $patterns);
            $patterns = explode(',', $patterns);
            $patterns = array_filter($patterns);

            $orderNumber = '';
            foreach ($patterns as $pattern) {
                $pattern = preg_replace('/\s+/', '', $pattern);
                if (str_contains($pattern, '{') || str_contains($pattern, '}')) {
                    $pattern = preg_replace('/(.*){(.*)}(.*)/s', '\2', $pattern);
                    if (str_contains($pattern, 'num')) {
                        $number = str_replace('num', '', $pattern);
                        if (is_numeric($number)) {
                            $orderNumber .= $this->mathRandom->getRandomString($number > 9 ? 9 : $number, '0123456789');
                        }
                    } else if (str_contains($pattern, 'str')) {
                        $string = str_replace('str', '', $pattern);
                        if (is_numeric($string)) {
                            $orderNumber .= $this->mathRandom->getRandomString($string > 9 ? 9 : $string, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
                        }
                    } else if ($pattern == 'increment_id') {
                        $orderNumber .= $incrementId;
                    }
                } else {
                    $orderNumber .= $pattern;
                }
            }

            return $orderNumber;
        } else {
            return $incrementId;
        }
    }
}

The generateIncrementId() method generates a unique increment ID based on the specified pattern and type.
If the increment ID is not unique, it generates a new one and checks again until a unique increment ID is found.

Implementing a custom random order number can be a useful feature for your Magento 2 store to enhance the security and uniqueness of your order numbers. With the right steps and guidance, you can successfully implement this feature and provide a more personalized experience for your customers.

That’s it! I hope this technical blog will help you find what you were looking for.

Rutvik Monpara

Author

Experienced Magento 2 Developer with a proven track record in crafting robust e-commerce solutions. Specialized in custom module development, proficient in PHP, MySQL, and adept at problem-solving within the Magento 2 framework.

We can help you with

  • Dedicated Team
  • Setup Extended Team
  • Product Development
  • Custom App Development

Schedule a Developer Interview And Get 7 Days Risk-Free Trial

Fill out the form below, and one of our technical experts will reach out to you within 12 hours.

    Google
    |

    4.8

    Google
    |

    4.8

    Google
    |

    4.9

    Google
    |

    4.8

    Google
    |

    4.9

    Copyright © 2024 DOLPHIN WEB SOLUTION. All rights reserved.

    ×

    Hello!

    Click one of our contacts below to chat on WhatsApp

    × How can I help you?
    TO TOP