I finally realized that the class Magento\SalesSequence\Model\ResourceModel\Meta
is responsible for setting the active_profile
to the meta
object used by the Magento\SalesSequence\Model\Sequence
class to generate the final number.
The active_profile
is read from the sales_sequence_profile
databate table which contains fixed value. Someone with only static requirements can simply manually edit these table fields or create a very simple module for accessing and editing the profiles already used by Magento default.
In my case using dynamic variables, not only based on a specific store view but on current date for example is a requirement therefore I couldn't rely on these static database values.
Solution - Overriding the Meta
class
I was able to achieve my goal by simply overriding the class Magento\SalesSequence\Model\ResourceModel\Meta
. While this class is usually solicited for grabing the current sequence profile from the database, with a simple override we can adapt it so it passes the Prefix and Suffix to the Magento\SalesSequence\Model\Sequence
class which will use them to generate the final number. This class also gives us access to some useful parameters as the entity_type
and store_id
via the $object
variable.
Working Example
NameSpace/Module/etc/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
<preference for="Magento\SalesSequence\Model\ResourceModel\Meta" type="NameSpace\Module\Override\SalesSequence\ResourceModel\Meta" />
</config>
NameSpace/Module/Override/SalesSequence/ResourceModel/Meta.php
<?php
namespace NameSpace\Module\Override\SalesSequence\ResourceModel;
class Meta extends \Magento\SalesSequence\Model\ResourceModel\Meta
{
protected function _afterLoad(\Magento\Framework\Model\AbstractModel $object)
{
$entityType = $object->getEntityType(); //order/invoice/creditmemo/shipment
$storeId = $object->getStoreId(); //CURRENT STORE ID
$activeProfile = $this->resourceProfile->loadActiveProfile($object->getId());
$activeProfile->setPrefix('ORD-'); //SET CUSTOM PREFIX - DEFAULT: store_id
$activeProfile->setSuffix('A'); //SET CUSTOM SUFFIX
$activeProfile->setStartValue('1'); //SET START VALUE - DEFAULT: 1
$activeProfile->setStep('1'); //SET INCREMENT STEP - DEFAULT: 1
//[UPDATE] USEFUL FOR SHARED ORDER NUMBERS WITHIN MULTIPLE STORES
$object->setSequenceTable('custom_table'); //SET CUSTOM INCREMENT TABLE - DEFAULT: sequence_{entity_type}_{store_id}
//SET DATA TO active_profile
$object->setData(
'active_profile',
$activeProfile
);
return $this;
}
}
?>
This above solution gives some flexibility but does not allow to edit the number padding or to reset the sequence after a certain period.
Edit Pattern & Padding
To edit the Pattern, one might simply override the DEFAULT_PATTERN
constant inside the Magento\SalesSequence\Model\Sequence
class.
Reseting Sequence after X Period
This should be possible by simply resetting the AUTO_INCREMENT for the specific sequence_{entity_type}_{store_id}
table following certain conditions from inside our Meta
class. This way, as our number will be generated by the Sequence
class, the next value will start over from the start_value
.
Best Answer
First you need to track order status changes,
Magento is provide to
track old data and new changed data
usinggetOrigData()
andgetData()
on save event fire.So easily using the feature,you can getchanges Status and on basic of this,you can fire the Sms
Error:
When sales_order_save_after event is
fire
then you can getonly one order data
that means code at observer is wrong.Solution:
As i said that when Model is saving then you can get old and new Data using
Current Data:
$Object->getOrigData();
and
Changing new Data :
$object->getData()
Using those function when you can easy track
order status changes
.And suggesting to you that use event sales_order_save_commit_after instead of
sales_order_save_after
because if any issue has occurred during the save magento is roll back to old data and show the errors.you can Old status by
$OldStatus=$order->getOrigData('status'
)and new Status
Code: