How to create custom order status using an extension / module in Magento 2
-
15-04-2021 - |
Question
I was wondering whether there is any way to create custom Orders statuses in Magento 2. I am developing a Magento Extension in which I have to add some custom order status to Magento 2 orders.
Solution
If you are developing a module then you can use below script in your InstallData.php
use Magento\Sales\Model\Order\Status;
protected $orderStatus;
public function __construct(
...
Status $orderStatus,
....
) {
....
$this->orderStatus = $orderStatus;
....
}
$data['status']='new_test'; // status code must be unique
$data['label']='Test'; // status label
$data['store_labels']=array('1'=>'Test'); // status label store wise here 1 is my store id you can change with your store id
$orderStatus=$this->orderStatus->setData($data)->setStatus($data['status'])
try {
$orderStatus->save();
}
catch (\Exception $e) {
echo $e->getMessage();
}
OTHER TIPS
You don't need to develop a new module. Just add a new order status on admin panal. Go to
Store->Order Status
Click Create new status, and fill in required fields.
If you want to read the new status, let's say, you set the new status code as "abcde". You can get the order status from the following code:
$order->getState()
Ref:
For an example you can also check like default PayPal extension do that. Check file your-magento-dir/vendor/magento/module-paypal/Setup/InstallData.php
There you will find part of the code
$data = [];
$statuses = [
'pending_paypal' => __('Pending PayPal'),
'paypal_reversed' => __('PayPal Reversed'),
'paypal_canceled_reversal' => __('PayPal Canceled Reversal'),
];
foreach ($statuses as $code => $info) {
$data[] = ['status' => $code, 'label' => $info];
}
$setup->getConnection()
->insertArray($setup->getTable('sales_order_status'), ['status', 'label'], $data);
If you want you can define more options in $data
array.
Here is more elegant way. (You should avoid installing store-specific data):
<?php
namespace Vendor\Extension\Setup;
use Exception;
use Magento\Framework\Exception\AlreadyExistsException;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Sales\Model\Order\Status;
use Magento\Sales\Model\Order\StatusFactory;
use Magento\Sales\Model\ResourceModel\Order\Status as StatusResource;
use Magento\Sales\Model\ResourceModel\Order\StatusFactory as StatusResourceFactory;
class InstallData implements InstallDataInterface
{
/**
* Status Factory
*
* @var StatusFactory
*/
protected $statusFactory;
/**
* Status Resource Factory
*
* @var StatusResourceFactory
*/
protected $statusResourceFactory;
/**
* InstallData constructor
*
* @param StatusFactory $statusFactory
* @param StatusResourceFactory $statusResourceFactory
*/
public function __construct(
StatusFactory $statusFactory,
StatusResourceFactory $statusResourceFactory
) {
$this->statusFactory = $statusFactory;
$this->statusResourceFactory = $statusResourceFactory;
}
/**
* @param ModuleDataSetupInterface $setup
* @param ModuleContextInterface $context
* @throws Exception
*/
public function install(
ModuleDataSetupInterface $setup,
ModuleContextInterface $context
) {
$setup->startSetup();
$this->addStatus("status_code", "New status label", "state_for_status");
$setup->endSetup();
}
/**
* Create new order processing status and assign it to the existent state
*
* @return void
*
* @throws Exception
*/
protected function addStatus($statusCode, $label, $state)
{
/** @var StatusResource $statusResource */
$statusResource = $this->statusResourceFactory->create();
/** @var Status $status */
$status = $this->statusFactory->create();
$status->setData([
'status' => $statusCode,
'label' => $label,
]);
try {
$statusResource->save($status);
} catch (AlreadyExistsException $exception) {
return;
}
$status->assignState($state, false, true);
}
}