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.

Was it helpful?

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);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top