質問

I need to add several order statuses. Could not found info how to implement it via Data Patches

正しい解決策はありません

他のヒント

The answer is pretty simple.

  1. Create folder Setup/Patch/Data in your module
  2. Create class UpdateOrderStatuses (listing below)
  3. Implement method apply in the class UpdateOrderStatuses.
  4. 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;

  1. Create folder Setup/Patch/Data in your module
  2. Create the class (i.e. AddManuallyClosedOrderStatus)
  3. 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 [];
        }
    }
  1. run bin/magento setup:upgrade

Hope this will help someone who is looking to do the same thing with model and resource models.

Cheers!

ライセンス: CC-BY-SA帰属
所属していません magento.stackexchange
scroll top