2

I'll want to update an orderStatus in craft commerce after the order is complete for a specific (digital) pruduct type. To send an extra email with download links, confirm email is already send based on the default status. To do that I'll use an event like this, but how I'll get the orderId from the event, looks like this id is only in the private _lineItems. So I'll can't use $event->sender->orderId.

/**
         * update status
         *
         * @return void
         */
        Event::on(
          Order::class,
          Order::EVENT_AFTER_COMPLETE_ORDER,
          function (Event $event) {
            $order = \craft\commerce\Plugin::getInstance()->getOrders()->getOrderById($event->sender->orderId);
            if ($order) {
              $order->orderStatusId = 5; // order status ebooks send is 5
              $result = Craft::$app->getElements()->saveElement($order);
            }
          }
        );

==== UPDATE ====

Final working solution:

        /**
         * Update orderstatus to send downloads mail for digital products
         *
         * @return void
         */
        Event::on(
          Order::class,
          Order::EVENT_AFTER_COMPLETE_ORDER,
          function (Event $event) {
            $order = $event->sender;
            if (!$order->id) {
                return;
            }

            $digitalProductTypeIds = [8,9,10];
            $digitalStatusId = 5;
            $updateStatus = false;

            // Loop through lineitems and search for digital products based on productype
            foreach ($order->lineItems as $product) {
              if( isset($product->snapshot['product']) && in_array($product->snapshot['product']['typeId'],$digitalProductTypeIds) )
              {
                $updateStatus = true;
                break;
              }
            }

            // Update orderstatus id if digital products present in the order
            if($updateStatus){
              $order->orderStatusId = $digitalStatusId;
              Craft::$app->getElements()->saveElement($order);
            }
          }
      );

1 Answer 1

2

Since it's a property-read, you can't do it with Order as an element, but you can try to deal with it via recorders, something like that

use yii\base\Event;
use craft\commerce\elements\Order;
use craft\commerce\records\Order as OrderRecord;
// ...

    Event::on(
        Order::class,
        Order::EVENT_AFTER_COMPLETE_ORDER,
        function (Event $e) {
            $order = $e->sender;
            if (!$order->id) {
                return;
            }

            $orderRecord = OrderRecord::findOne($order->id);
            if (!$orderRecord) {
                throw new \Exception('Invalid order ID: ' . $this->id);
            }

            $orderRecord->orderStatusId = 1337;
            $orderRecord->save();
        }
    );

If it doesn't work with this event, try using the event Order::EVENT_AFTER_SAVE

6
  • Its the answer on my question. Thanx! Leaves me with the next issue. Witch event? Because if I use EVENT_AFTER_COMPLETE_ORDER the status changes back to default. Status history shows default, ebook (5), default and sending 3 mails instead of 2 because the status changes back to default Commented Jun 11, 2022 at 21:18
  • Have you tried EVENT_AFTER_SAVE ?
    – RomanAvr
    Commented Jun 13, 2022 at 6:17
  • Yes tried, but same problem. Looks like the save order resets the status to default every time Commented Jun 13, 2022 at 6:52
  • Do you have any other modules/plugins that change order status? For example, webhooks from a payment system or something like that?
    – RomanAvr
    Commented Jun 13, 2022 at 9:58
  • 1
    Found the problem. The order data is already present in the $e->sender, you have to use that without query the order again, like this: Event::on(Order::class,Order::EVENT_AFTER_COMPLETE_ORDER,function (Event $event) {$order = $event->sender; if (!$order->id) { return; } // Update orderstatus id if($order->id == 1){ $order->orderStatusId = 5; Craft::$app->getElements()->saveElement($order); }} Commented Jun 14, 2022 at 8:17

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.