<p>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</p>
<pre><code>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-&gt;sender;
            if (!$order-&gt;id) {
                return;
            }

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

            $orderRecord-&gt;orderStatusId = 1337;
            $orderRecord-&gt;save();
        }
    );
</code></pre>
<p>If it doesn't work with this event, try using the event <code>Order::EVENT_AFTER_SAVE</code></p>

CC BY-SA 4.0
2022-06-11T21:18:07.730Z
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
Maarten Heideman
CC BY-SA 4.0
2022-06-13T06:17:00.290Z
Have you tried EVENT_AFTER_SAVE ?
RomanAvr
CC BY-SA 4.0
2022-06-13T06:52:13.930Z
Yes tried, but same problem. Looks like the save order resets the status to default every time
Maarten Heideman
CC BY-SA 4.0
2022-06-13T09:58:19.040Z
Do you have any other modules/plugins that change order status?
For example, webhooks from a payment system or something like that?
RomanAvr
CC BY-SA 4.0
2022-06-14T08:17:51.637Z
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); }}`
Maarten Heideman
CC BY-SA 4.0
2022-06-15T09:42:27.850Z
Nice job, we got em!
RomanAvr
CC BY-SA 4.0
2022-06-10T12:47:28.647Z
2022-06-10T12:47:28.647Z
RomanAvr
<p>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 <code>$event-&gt;sender-&gt;orderId</code>.</p>
<pre><code>/**
         * update status
         *
         * @return void
         */
        Event::on(
          Order::class,
          Order::EVENT_AFTER_COMPLETE_ORDER,
          function (Event $event) {
            $order = \craft\commerce\Plugin::getInstance()-&gt;getOrders()-&gt;getOrderById($event-&gt;sender-&gt;orderId);
            if ($order) {
              $order-&gt;orderStatusId = 5; // order status ebooks send is 5
              $result = Craft::$app-&gt;getElements()-&gt;saveElement($order);
            }
          }
        );
</code></pre>
<p>==== UPDATE ====</p>
<p>Final working solution:</p>
<pre><code>        /**
         * 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-&gt;sender;
            if (!$order-&gt;id) {
                return;
            }

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

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

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

<craft3><plugin-craftcommerce><plugin-craftcommerce3>
How I'll get the orderId in EVENT_AFTER_COMPLETE_ORDER in craft commerce?
# How I'll get the orderId in EVENT_AFTER_COMPLETE_ORDER in craft commerce?

(Asked by: username_0 on 2022-06-10)

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);
            }
          }
      );

**Tags:** craft3, plugin-craftcommerce, plugin-craftcommerce3


---

## 1 answers

### Answer by username_1 on 2022-06-10. Score: 2 | Accepted answer

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

> **Comments:**
> **username_0**: 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  
> **username_1**: Have you tried EVENT_AFTER_SAVE ?  
> **username_0**: Yes tried, but same problem. Looks like the save order resets the status to default every time  
> **username_1**: Do you have any other modules/plugins that change order status? For example, webhooks from a payment system or something like that?  
> **username_0**: 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); }}`  
> **username_1**: Nice job, we got em!  

---

