Shopware 6: Order Events and Versioning

This blogpost is written with Shopware version in mind.

We are currently working on a plugin which adjusts a couple of order values after an order has been placed. While digging into the code, my colleague Carl and me found some astonishing stuff that’s actually quite hard to understand. Therefore don’t trust anything you read here and make sure to test everything accordingly.

A little info on versioning can be found in the Shopware documentation as well.

Anyway, as of Shopware 6.5, when you open an order in the backend, you are immediately in an “edit” context. Back in 6.4 one needed to click on “edit” in the upper right to get into this context, but in 6.5 you are directly editing an order.

In particular, that means that right when you open up an order, a lot of *.written events are fired, although nothing happened yet.

Why are all these *.written events fired?

Because once you start editing an order aka open one up in the backend, Shopware creates a new version of the order, as well as a new version of the delivery, the addresses, and probably even of the line items and payments associated with it – although we didn’t test the latter, so that’s just an assumption.

Every time you change something, e.g. to adjust the address, an AJAX request is fired which saves the changes to the new version. When you close the order now, none of your changes are actually applied, and that new version should be deleted. At least there is JS code taking care of that. But if the JS is not executed the version basically becomes a ghost, remaining lonely and forgotten about in the database. Maybe there is a scheduled task to clean that up – we have no clue. If you know, leave us a comment!

When and how to save the order

So, the question is: When is the order really updated and how do we know which event – out of the myriad there is – actually fires when that happens, so we can “do stuff” then?

Our solution to this consists of two parts:

1. Instead of listening for an EntityWrittenEvent, we listen for an EntityWrittenContainerEvent

The container event has the advantage that we get all the writes together. The write on the order, on the addresses and the delivery for example. In our case, we had the problem that – when listening to the specific EntityWrittenEvents for addresses and delivery – we weren’t able to retrieve the id of the related order, as for some (possibly good) reason, that’s not part of the written changes.

2. We always test the version of the written entity like so:
$event->getPayloads()[*]['versionId'] === \Shopware\Core\Defaults::LIVE_VERSION

This one’s the more important part. If you want to know wether your order or any other versioned entity has changed, make sure that the changed versionId is the LIVE_VERSION id. This way you can filter out the “real” changes while ignoring everything else.

Last but not least, here’s a list of all the versioned entities – most likely incomplete, but probably better than nothing:

  • CategoryDefinition
  • CmsBlock
  • CmsPageDefinition
  • CmsSection
  • CmsSlot
  • LandingPageDefinition
  • OrderAddress
  • OrderCustomer
  • OrderDefinition
  • OrderDelivery
  • OrderDeliveryPosition
  • OrderLineItem
  • OrderLineItemDownload
  • OrderTransaction
  • OrderTransactionCapture
  • OrderTransactionCaptureRefund
  • OrderTransactionCaptureRefundPosition
  • ProductConfiguratorSetting
  • ProductDefinition
  • ProductDownload
  • ProductManufacturer
  • ProductMedia
  • ProductPrice
  • ProductSearchKeyword

If you have any questions, feel free to leave us a comment or drop us an email.

We hope this helps you in the dark and treacherous jungle of versioned entities!

2 Kommentare zu „Shopware 6: Order Events and Versioning

Kommentar verfassen