0

While creating a module, the following error occurs after creating a custom cli command:

Area code not set: Area code must be set before starting a session. 

I have already stated the area code in the execute() method of the command class, but this doesn't resolve the problem.

Sync command:

<?php

namespace Vendor\Module\Console\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class Sync extends Command
{
    /**
     * @var \Magento\Framework\App\State
     **/
    private $state;

    /**
     * @var \Vendor\Module\Model\Action\Action
     **/
    public $action;


    public function __construct(
        \Vendor\Module\Model\Action\Action $action,
        \Magento\Framework\App\State $state

    ) {
        $this->action = $action;
        $this->state = $state;
        parent::__construct();
    }

    protected function configure()
    {
        $this->setName('vendor:module:sync')
            ->setDescription('Syncs with FTP server');
        parent::configure();
    }

    public function execute(InputInterface $input, OutputInterface $output) {
        $this->state->setAreaCode(\Magento\Framework\App\Area::AREA_CRONTAB); //have tried every area (adminhtml, frontend, global)
        $this->action->Connect();
    }
}

Action class:

<?php

Namespace Vendor\Module\Model\Action;

class Action {

    protected $article;

    public function __construct(
        \Vendor\Module\Model\Shipment\Create\ShipmentCreator $shipmentCreator
    ) {
        $this->shipmentCreator = $shipmentCreator;
    }

    public function Connect() {
    }
}

The error is arises when I add my shipment code in the constructor of the action class. Without the shipment code in the Action constructor everything works accordingly.

ShipmentCreator:

<?php

namespace Vendor\Module\Model\Shipment\Create;

class ShipmentCreator extends \Magento\Framework\View\Element\Template
{
    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Magento\Sales\Api\OrderRepositoryInterface $orderRepository,
        \Magento\Sales\Model\Convert\OrderFactory $convertOrderFactory,
        \Magento\Framework\DB\TransactionFactory $transactionFactory,
        \Magento\Sales\Model\Order\Email\Sender\ShipmentSender $shipmentSender,
        \Magento\Framework\Message\ManagerInterface $messageManager,
        array $data = []
    )
    {
        $this->orderRepository = $orderRepository;
        $this->orderConverter = $convertOrderFactory->create();
        $this->transactionFactory = $transactionFactory;
        $this->messageManager = $messageManager;
        $this->shipmentSender = $shipmentSender;
        parent::__construct($context, $data);
    }

    /**
     * Create Shipment Based on Order Object
     * @param \Magento\Sales\Model\Order $order
     * @return $this
     */
    public function generateShipment($orderId)
    {
        try {
            $order = $this->orderRepository->get($orderId);
            if (!$order->getId()) {
                throw new \Magento\Framework\Exception\LocalizedException(__('The order no longer exists.'));
            }

            /* check shipment exist for order or not */
            if ($order->canShip()) {
                // Initialize the order shipment object
                $shipment = $this->orderConverter->toShipment($order);
                foreach ($order->getAllItems() AS $orderItem) {
                    // Check if order item has qty to ship or is order is virtual
                    if (!$orderItem->getQtyToShip() || $orderItem->getIsVirtual()) {
                        continue;
                    }
                    $qtyShipped = $orderItem->getQtyToShip();
                    // Create shipment item with qty
                    $shipmentItem = $this->orderConverter->itemToShipmentItem($orderItem)->setQty($qtyShipped);
                    // Add shipment item to shipment
                    $shipment->addItem($shipmentItem);
                }
                // Register shipment
                $shipment->register();

                $shipment->getOrder()->setIsInProcess(true);

                try {
                    $transaction = $this->transactionFactory->create()->addObject($shipment)
                        ->addObject($shipment->getOrder())
                        ->save();
                    echo $shipmentId = $shipment->getIncrementId();
                } catch (\Exception $e) {
                    $this->messageManager->addError(__('We can\'t generate shipment.'));
                }

                if ($shipment) {
                    try {
                        $this->shipmentSender->send($shipment);
                    } catch (\Exception $e) {
                        $this->messageManager->addError(__('We can\'t send the shipment right now.'));
                    }
                }

                return $shipmentId;
            }
        } catch (\Exception $e) {
            $this->messageManager->addError($e->getMessage());
        }

        return true;
    }
}

Are you guys able to reproduce the error and help me find a solution? Any help would be appreciated!

2 Answers 2

0

Inject \Magento\Framework\App\State to your command and use setAreaCode to set the areacode.

Use one of the values from \Magento\Framework\App\Area to do this.

1
  • Already did this! If you look at the first code snippet I shared, the state object is injected and the execute() method sets the area code.
    – Digitaq
    Commented Mar 27, 2019 at 14:53
0

Problem is fixed with the help of this answer!

https://magento.stackexchange.com/a/200004/65919

Changing shipmentNotifier to shipmentNotifierFactory and then instantiating the class with shipmentCreatorFactory->create() fixed the Area is not set problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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