Question

I've built a plugin that catches the order beforeSave event in order to add some extra data to the an order attribute. The problem is that when this plugin fires it causes an error:

Uncaught TypeError: Argument 1 passed to Magento\Sales\Model\OrderRepository::save() must implement interface Magento\Sales\Api\Data\OrderInterface, string given, called in /var/www/html/vendor/magento/framework/Interception/Interceptor.php on line 58 and defined in /var/www/html/vendor/magento/module-sales/Model/OrderRepository.php:156
Stack trace:
#0 /var/www/html/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Sales\Model\OrderRepository->save('sales_order', 'order', NULL, NULL, NULL, NULL, Array, NULL, NULL, Array, true, 'order', Object(Magento\Store\Model\StoreManager), Object(Magento\Sales\Model\Order\Config), Object(Magento\Catalog\Model\ProductRepository\Interceptor), Object(Magento\Catalog\Model\ResourceModel\Product\CollectionFactory), Object(Magento\Sales\Model\ResourceModel\Order\Item\CollectionFactory), Object(Magento\Catalog\Model\Product\Visibility), Object(Magento\Sales\Model\Service\InvoiceService), Object(Magento\Directory\Model\CurrencyF"

I've cut down my plugin so it does absolutely nothing other than return the same object in gets at the start and I'm still getting this same issue. For example;

class OrderPlugin
{

protected $_logger;
protected $_orderApi;
protected $_orderAttributeFactory;
protected $_orderExtensionFactory;

public function __construct(\Psr\Log\LoggerInterface $logger, Data $helper, \MyModule\Shipstation\Model\OrderAttributeFactory $orderAttributeFactory, OrderExtensionFactory $orderExtensionFactory)
{
    $this->_logger = $logger;
    $this->helper = $helper;
    $this->_orderAttributeFactory = $orderAttributeFactory;
    $this->_orderExtensionFactory = $orderExtensionFactory;
}

public function beforeSave(\Magento\Sales\Api\OrderRepositoryInterface $subject, \Magento\Sales\Api\Data\OrderInterface $order){

    //$resultOrder = $this->saveFarmisonOrderIDAttribute($resultOrder);

    return $order;

}

my di.xml looks like;

<type name="Magento\Sales\Api\OrderRepositoryInterface">
    <plugin name="MyModule_Shipstation::orderPlugin" type="MyModule\Shipstation\Plugin\OrderPlugin" />
    <plugin name="MyModule_Shipstation::deliverydatePlugin" type="MyModule\Shipstation\Plugin\DeliveryDatePlugin" />
</type>

If I totally comment out my beforeSave method then the save works correctly as expected/

Was it helpful?

Solution

The solution I found was to simply remove the return from the function. Setting that value I wanted on the order object was enough and simply removing the return allowed the code to run as expected.

public function beforeSave(\Magento\Sales\Model\OrderRepository $subject, $resultOrder){

       $this->saveOrderIDAttribute($resultOrder);

}

What I don't know is why beforeSave doesn't like having the Order object returned. Where as afterGet works exactly as I would expect and accepts the order object from the return.

public function afterGet(\Magento\Sales\Api\OrderRepositoryInterface $subject, \Magento\Sales\Api\Data\OrderInterface $order){

    $order = $this->getOrderIDAttribute($order);

    return $order;
}

OTHER TIPS

You can try this way,

app/code/Vendor/Module/etc/di.xml

<type name="Magento\Sales\Model\Order">
    <plugin name="Plugin Name" type="Vendor\Module\Plugin\Order" sortOrder="10" disabled="false"/>
</type>

app/code/Vendor/Module/Plugin/Order.php

public function beforeSave(\Magento\Sales\Model\Order $subject)
{
$subject->getData() 
// this is your order Data before saving it
}

Hope it Helps.

Change di.xml

<type name="Magento\Sales\Api\OrderRepositoryInterface">
    <plugin name="MyModule_OrderPlugin" type="MyModule\Shipstation\Plugin\OrderPlugin" />
    <plugin name="MyModule_DeliveryDatePlugin" type="MyModule\Shipstation\Plugin\DeliveryDatePlugin" />
</type>
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top