2

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);
4

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.

  • 2
    Never use Object Manager.. use the Factory (Magento\Sales\Model\Order\StatusFactory) – CompactCode Oct 23 '17 at 3:15
3
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]
        );
    }
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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