3

I'd like to create a new order state like processing, complete and etc.. Using my custom module (without using the admin panel).

How can I do that?

Thanks

4 Answers 4

2

In the block, controller or model of your custom module

<?php

namespace Custom\Module\Block\Path;

class Sample
extends \Magento\Framework\View\Element\Template implements \Magento\Framework\View\Element\BlockInterface
{
    protected $status;

    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Magento\Sales\Model\Order\Status $status,
        array $data = []
    ) {
        parent::__construct($context, $data);
        $this->status = $status;
    }

    public function setCustomStatus(){
        // create status
        $this->status->setData('status', 'your_status') //code
             ->setData('label', 'Your New Status') //title
             ->save();

        // assign your state in to Magento order states
        $this->status->assignState(\Magento\Sales\Model\Order::STATE_NEW, true);
    }

}

Here is the list of Magento order states, which is found in file \Magento\Sales\Model\Order

const STATE_NEW = 'new';

const STATE_PENDING_PAYMENT = 'pending_payment';

const STATE_PROCESSING = 'processing';

const STATE_COMPLETE = 'complete';

const STATE_CLOSED = 'closed';

const STATE_CANCELED = 'canceled';

const STATE_HOLDED = 'holded';

const STATE_PAYMENT_REVIEW = 'payment_review';
3
  • how to do it in custom module ? you mentioned to edit in core file Commented Jun 20, 2017 at 4:10
  • First part is how you do it in your module, it's not editing core files.
    – Tomi
    Commented Jun 20, 2017 at 4:13
  • add di code for both class so it will clear confusion for new magento2 developer and also mention module xml i feel its very imp Commented Jun 20, 2017 at 4:15
3

This should be done by a data patch these days. First create the data patch file:

bin/magento setup:db-declaration:generate-patch <module-name> <patch-name>

Then add and adjust the following code in the created patch file apply() method:

    // Add status
    $this->moduleDataSetup->getConnection()->insertOnDuplicate(
        $this->moduleDataSetup->getTable('sales_order_status'),
        ['status' => 'code', 'label' => 'Label']
    );

    // Add status to state
    $states = [
        [
            'status'     => 'code',
            'state'      => 'complete',
            'is_default' => 0,
            'visible_on_front' => 1
        ]
    ];

    foreach ($states as $state) {
        $this->moduleDataSetup->getConnection()->insertOnDuplicate(
            $this->moduleDataSetup->getTable('sales_order_status_state'),
            $state
        );
    }

After this, run bin/magento setup:upgrade and the status will be added to database tables sales_order_status and sales_order_status_state.

0

Also can be create through UpgradeData from your custom module. You can add new state and status using below code and also assign status to state.

public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context) {


if (version_compare($context->getVersion(), '1.1.0', '<')) {

        /**
         * Install order status
         */
        $data = [];
        $statuses = [
        'custom_status1' => __('Custom Status 1'),
        'custom_status2' => __('Custom Status 2'),
        ];

        foreach ($statuses as $code => $info) {
            $data[] = ['status' => $code, 'label' => $info];
        }

        $setup->getConnection()->insertArray($setup->getTable('sales_order_status'), ['status', 'label'], $data);

        /**
         * Install order states
         */
        $data = [];

        $states = [
        'custom_state1' => [
        'label' => __('Custom State 1'),
        'statuses' => ['custom_status1' => ['default' => '0']],
        'visible_on_front' => true,
        ],
        'custom_state2' => [
        'label' => __('Custom State 1'),
        'statuses' => ['custom_status2' => ['default' => '1']],
        'visible_on_front' => true,
        ]
        ];

        foreach ($states as $code => $info) {
            if (isset($info['statuses'])) {
                foreach ($info['statuses'] as $status => $statusInfo) {
                    $data[] = [
                    'status' => $status,
                    'state' => $code,
                    'is_default' => is_array($statusInfo) && isset($statusInfo['default']) ? 1 : 0,
                    ];
                }
            }
        }

        /**
         * Assign status to state
         */
        $setup->getConnection()->insertArray(
            $setup->getTable('sales_order_status_state'),
            ['status', 'state', 'is_default'],
            $data
            );

    }

}

Hope this will help.

0

You can new state & status of order using installData script in your modules. You can try below code :

use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;

use Magento\Sales\Setup\SalesSetupFactory;

class InstallData implements \Magento\Framework\Setup\InstallDataInterface
{
     public function __construct(
        SalesSetupFactory $salesSetupFactory

    ) {
        $this->salesSetupFactory = $salesSetupFactory;       
    }

    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {


        $setup->startSetup();

        $salesSetup = $this->salesSetupFactory->create(['setup' => $setup]);

        /**
         * Install eav entity types to the eav/entity_type table
         */
        $salesSetup->installEntities();

        /**
         * Install order statuses from config
         */
        $data1 = [];
        $statuses = [
            'custom_status1' => __('Custom Status 1'),
            'custom_status2' => __('Custom Status 2'),


        ];
        foreach ($statuses as $code => $info) {
            $data1[] = ['status' => $code, 'label' => $info];
        }
        //$setup->getConnection()->insertArray($setup->getTable('sales_order_status'), ['status', 'label'], $data1);
        $setup->getConnection()->insertArray($setup->getTable('sales_order_status'), ['status', 'label'], $data1);

        /**
         * Install order states from config
         */
        $data2 = [];
        $states = [
            'custom_status1' => [
                'label' => __('Custom Status 1'),
                'statuses' => ['custom_status1' => ['default' => '1']],
                'visible_on_front' => true,
            ],
            'custom_status2' => [
                'label' => __('Custom Status 2'),
                'statuses' => ['custom_status2' => ['default' => '1']],
                'visible_on_front' => true,
            ]

        ];

        foreach ($states as $code => $info) {
            if (isset($info['statuses'])) {
                foreach ($info['statuses'] as $status => $statusInfo) {
                    $data2[] = [
                        'status' => $status,
                        'state' => $code,
                        'is_default' => is_array($statusInfo) && isset($statusInfo['default']) ? 1 : 0,
                    ];
                }
            }
        }

        /** Assign status to state */

        $setup->getConnection()->insertArray(
            $setup->getTable('sales_order_status_state'),
            ['status', 'state', 'is_default'],
            $data2
        );

        /** Update visibility for states */
        $states = ['custom_status1','custom_status2'];
        foreach ($states as $state) {
            $setup->getConnection()->update(
                $setup->getTable('sales_order_status_state'),
                ['visible_on_front' => 1],
                ['state = ?' => $state]
            );
        }

        $setup->endSetup();
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.