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
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';
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
.
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.
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();
}
}