Question

I'm stuck on trying to create a new order state programmatically.
So far I'm only able to read the currently available states from

\Magento\Sales\Model\Config\Source\Order\Status

I am unable to find a model I can fill let alone some kind of interface, api or Manager for order states.

In magento 1.9 this was done using the following code:

model = Mage::getModel('sales/order_status')->load('error');
$model->setStatus('error');
$model->setLabel('Not Sent To XXX');
$model->save();
$model->assignState(Mage_Sales_Model_Order::STATE_HOLDED, false);
Was it helpful?

Solution

We should take a look some tests:

dev/tests/integration/testsuite/Magento/Payment/_files/order_status.php

/** @var \Magento\Sales\Model\Order\Status $status */
$status = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Sales\Model\Order\Status');
//status for state new
$status->setData('status', 'custom_new_status')->setData('label', 'Test Status')->save();
$status->assignState(\Magento\Sales\Model\Order::STATE_NEW, true);
//status for state canceled
$status->setData('status', 'custom_canceled_status')->setData('label', 'Test Status')->unsetData('id')->save();
$status->assignState(\Magento\Sales\Model\Order::STATE_CANCELED, true);

We can use Object Manager or inject Magento\Sales\Model\Order\Status in the constructor.

OTHER TIPS

class InstallData implements InstallDataInterface
 {
 /**
 * Sales setup factory
 *
 * @var SalesSetupFactory
 */
 private $salesSetupFactory;

 /**
 * @var Builder
 */
 private $sequenceBuilder;

 /**
 * @var SequenceConfig
 */
 private $sequenceConfig;

 /**
 * @param SalesSetupFactory $salesSetupFactory
 * @param Builder $sequenceBuilder
 * @param SequenceConfig $sequenceConfig
 */

public function __construct(
    SalesSetupFactory $salesSetupFactory,
    Builder $sequenceBuilder,
    SequenceConfig $sequenceConfig
) {
    $this->salesSetupFactory = $salesSetupFactory;
    $this->sequenceBuilder = $sequenceBuilder;
    $this->sequenceConfig = $sequenceConfig;
}

/**
 * {@inheritdoc}
 * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
 */
public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
    /** @var \Magento\Sales\Setup\SalesSetup $salesSetup */
    $salesSetup = $this->salesSetupFactory->create(['setup' => $setup]);

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

    /**
     * Install order statuses from config
     */
    $data = [];
    //New order status
    $statuses = [
        'new_state_code_1' => __('New state label 1'),
        'new_state_code_2' => __('New state label 2'),
        'new_state_code_3' =>__('New state label 3'),
        'new_state_code_4' =>__('New state label 4')
    ];

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

    $data = [];

    //prepare data for associate status to state
    foreach ($statuses as $code => $label) {

        $item = [
            'label' => __($label),
            'statuses' => [$code => ['default' => '1'], $code => []],
            'visible_on_front' => true];
        $states[$code] = $item;
    }

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

    //Insert row for associate
    $setup->getConnection()->insertArray(
        $setup->getTable('sales_order_status_state'),
        ['status', 'state', 'is_default'],
        $data
    );

    /** Update visibility for states */
    $states = ['new', 'processing', 'complete', 'closed', 'canceled', 'holded', 'payment_review'];
    foreach ($states as $state) {
        $setup->getConnection()->update(
            $setup->getTable('sales_order_status_state'),
            ['visible_on_front' => 1],
            ['state = ?' => $state]
        );
    }
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top