Skip to content

magento 2.4 set canShip to false makes the order virtual

On my magento I have two different types of orders:

  • regular orders which follow magento standard flow
  • custom order which have to be in a custom status before they can be shipped, eg:
    — order is placed by customer and I can see it in magento backend in the pending status
    — the order gets paid so the invoice is created and the order goes into Processing state
    — then I manually set the order to custom status (“ready”) and only if the order is in this custom status, then I can create the shipment, which means that if I try to ship this order while it is still in the processing status, then the shipment must not be created!

I tried blocking the creation of the shipment by using an after plugin on the MagentoSalesModelOrder::canShip() :

public function afterCanShip(
    MagentoSalesModelOrder $subject,
    $result
)
{
    if($subject->getState() == "processing" && $subject->getStatus() !== "ready") return false;
    return $result; 
}

This seems to work but in reality it transforms the order in a virtual order so what happens is that as soon as I create my invoice, the order doesn’t switch from pending to processing but it switches directly from pending to dispatched even if no shipment is created.

What I need is that the shipment is not created AND the status stays in processing.. so basically no changes at all must be applied.. is there a way to achieve this?