Add new Order Statuses to Magento 2.3 using declarative scheme approach
-
16-04-2021 - |
Question
I need to add several order statuses. Could not found info how to implement it via Data Patches
No correct solution
OTHER TIPS
The answer is pretty simple.
- Create folder
Setup/Patch/Data
in your module - Create class
UpdateOrderStatuses
(listing below) - Implement method
apply
in the classUpdateOrderStatuses
. - run
bin/magento setup:upgrade
After that Magento runs your patch and in case of success - add your patch path to patch_list
table.
class UpdateOrderStatuses implements DataPatchInterface
{
/**
* @var \Magento\Framework\Setup\ModuleDataSetupInterface
*/
private $moduleDataSetup;
public function __construct(
\Magento\Framework\Setup\ModuleDataSetupInterface $moduleDataSetup
) {
$this->moduleDataSetup = $moduleDataSetup;
}
/**
* {@inheritdoc}
*/
public function apply()
{
// Insert statuses
// use insertOnDuplicate(), insertArray() etc here
$this->moduleDataSetup->getConnection()->insertOnDuplicate(
$this->moduleDataSetup->getTable('sales_order_status'),
['status' => 'new_status', 'label' => 'New Label']
);
//Bind status to state
$states = [
[
'status' => 'new_status',
'state' => 'processing',
'is_default' => 0,
],
[
'status' => 'new_status',
'state' => 'complete',
'is_default' => 0,
],
[
'status' => 'new_status',
'state' => 'closed',
'is_default' => 0,
],
];
foreach ($states as $state) {
$this->moduleDataSetup->getConnection()->insertOnDuplicate(
$this->moduleDataSetup->getTable('sales_order_status_state'),
$state
);
}
}
/**
* {@inheritdoc}
*/
public static function getDependencies()
{
return [];
}
/**
* {@inheritdoc}
*/
public function getAliases()
{
return [];
}
}
This will be similar to the above answer but with adding the order status via ResouceModel and Model classes. Tested in M2 version 2.3.5
Steps;
- Create folder Setup/Patch/Data in your module
- Create the class (i.e. AddManuallyClosedOrderStatus)
- Add the patch class content
<?php
namespace Vendor\Module\Setup\Patch\Data;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Framework\Setup\Patch\PatchRevertableInterface;
use Magento\Sales\Model\ResourceModel\Order\Status;
use Magento\Sales\Model\Order\StatusFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
/**
* Class to add Manually Closed order status
*/
class AddManuallyClosedOrderStatus implements DataPatchInterface, PatchRevertableInterface
{
const ORDER_STATUS = 'manually_closed';
const ORDER_STATUS_LABEL = 'Manually Closed';
const ORDER_STATES = ['processing', 'complete', 'closed'];
/**
* @var Status
*/
private $orderStatusResourceModel;
/**
* @var StatusFactory
*/
private $orderStatusFactory;
/**
* @var ModuleDataSetupInterface
*/
private $moduleDataSetup;
/**
* AddManuallyClosedOrderStatus constructor.
* @param Status $orderStatusResourceModel
* @param StatusFactory $orderStatusFactory
*/
public function __construct(
Status $orderStatusResourceModel,
StatusFactory $orderStatusFactory,
ModuleDataSetupInterface $moduleDataSetup
) {
$this->orderStatusResourceModel = $orderStatusResourceModel;
$this->orderStatusFactory = $orderStatusFactory;
$this->moduleDataSetup = $moduleDataSetup;
}
/**
* {@inheritdoc}
*/
public function apply()
{
$manuallyCloseOrderStatus = $this->orderStatusFactory->create();
$manuallyCloseOrderStatus->setStatus(self::ORDER_STATUS);
$manuallyCloseOrderStatus->setLabel(self::ORDER_STATUS_LABEL);
// save the custom order status
$this->orderStatusResourceModel->save($manuallyCloseOrderStatus);
// assign the custom order status to state
foreach (self::ORDER_STATES as $state) {
$this->orderStatusResourceModel->assignState(
self::ORDER_STATUS,
$state,
0,
true
);
}
}
/**
* {@inheritdoc}
*/
public static function getDependencies()
{
return [];
}
/**
* {@inheritdoc}
*/
public function revert()
{
// revert the changes if custom order status not be used in any order
if (!$this->orderStatusResourceModel->checkIsStatusUsed(self::ORDER_STATUS)) {
// un-assign the status from order state
foreach (self::ORDER_STATES as $state) {
$this->orderStatusResourceModel->unassignState(self::ORDER_STATUS, $state);
}
// remove the custom order status
$this->moduleDataSetup->getConnection()->startSetup();
$tableName = $this->moduleDataSetup->getTable('sales_order_status');
$this->moduleDataSetup->getConnection()->delete($tableName, ['status = ?' => self::ORDER_STATUS]);
$this->moduleDataSetup->getConnection()->endSetup();
}
}
/**
* {@inheritdoc}
*/
public function getAliases()
{
return [];
}
}
- run bin/magento setup:upgrade
Hope this will help someone who is looking to do the same thing with model and resource models.
Cheers!
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange