Step 1 : Register your module
Create a custom module in Magento 2.
Step 2 : Create Configuration
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>
Here is the screenshot of configuration.
Leave blank for Magento default increment number.
The Following variables can be used.
Sample Format
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.