
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.
Click one of our contacts below to chat on WhatsApp