I have an menu option to create multiple shipments from selected orders in an extension.
It works on some stores (tested) but the store I'm trying to get it to work on (2.3.1) uses MSI and I'm wondering if it's something to do with that?
protected function massAction(AbstractCollection $collection)
{
$countShipOrder = 0;
foreach ($collection->getItems() as $order)
{
try
{
$shipOrder = $this->_shipOrder->create();
$ship = $shipOrder->shipOrder($order->getId());
$countShipOrder++;
}
catch (\Exception $e)
{
$this->messageManager->addError(__('Order Shipments Already Created For : %1',$order['increment_id']));
}
}
$countNonShipOrder = $collection->count() - $countShipOrder;
if ($countShipOrder) {
$string = $countShipOrder.' success, '.$countNonShipOrder .' fails';
$this->messageManager->addSuccess(__('Order shipments processed : %1.', $string));
}
$this->_redirect('sales/order/index');
}
class ShipOrder extends \Magento\Framework\Model\AbstractModel
{
protected $_scopeConfig;
protected $_order;
protected $_orderConverter;
protected $eventManager;
public function __construct(
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
\Magento\Sales\Model\OrderFactory $order,
\Magento\Sales\Model\Convert\OrderFactory $orderConverter,
\Magento\Framework\Event\Manager $eventManager,
\Magento\Framework\Model\Context $context
){
$this->_scopeConfig = $scopeConfig;
$this->_order = $order;
$this->eventManager = $eventManager;
$this->_orderConverter = $orderConverter;
}
public function shipOrder($orderId)
{
//load by order
$order = $this->_order->create()->load($orderId);
// Check if order can be shipped or has already shipped
if ( !$order->canShip()) {
throw new \Magento\Framework\Exception\LocalizedException(
__('You can\'t create an shipment for order increment id: %1', $order->getIncrementId())
);
return false;
}
else {
$shipment = $this->createShipment($order);
return $shipment;
}
}
public function createShipment($order){
// Initialize the order shipment object
$convertOrder = $this->_orderConverter->create();
$shipment = $convertOrder->toShipment($order);
// Loop through order items
foreach ($order->getAllItems() as $orderItem) {
// Check if order item has qty to ship or is virtual
if (! $orderItem->getQtyToShip() || $orderItem->getIsVirtual()) {
continue;
}
$qtyShipped = $orderItem->getQtyToShip();
// Create shipment item with qty
$shipmentItem = $convertOrder->itemToShipmentItem($orderItem)->setQty($qtyShipped);
// Add shipment item to shipment
$shipment->addItem($shipmentItem);
}
// Register shipment
$shipment->register();
$shipment->getOrder()->setIsInProcess(true);
try {
// Save created shipment and order
$shipment->save();
$shipment->getOrder()->save();
return $shipment;
} catch (\Exception $e) {
throw new \Magento\Framework\Exception\LocalizedException(__($e->getMessage()));
}
}
That final try catch where it tries to save the shipment is where the error is being thrown.
The undefined variable sourceCode
is coming from /vendor/magento/module-inventory-shipping/Observer/SourceDeductionProcessor.php on line 112
sourceCode
references?$this->isSingleSourceMode->execute()
and$shipment->getExtensionAttributes()
fail the conditions therefore the$sourceCode
variable is never initialise. You will need to find out why both of those fail. Use a debugger and trace it down.