How to set properties on orderlines in Umbraco Com...
# help-with-umbraco
n
I need to set some properties on an orderline whenever a product is being added to an order. My initial thought, derived from my uCommerce experince, would be to add a task, in this case a handler, that would set those properties. So, I thought that I might just make a class that inherits
NotificationEventHandlerBase<OrderProductAddingNotification>
and look at the values that are passed into the handler. Lo and behold, there is a property called
Properties
. It's a dictionary that can be manipulated, eg. not an
IReadOnlyDictionary
. It is also not marked as nullable so I figured I could use that. Digging through some decompiled code, it actually seems that the values in this property will be added to the orderline. Excellent. However. The
Properties
property on the
OrderProductAddingNotification
object is
null
and only has a getter so I wont be able to instantiate the property my self. I also tried the
OrderProductAddedNotification
, same result and the
OrderLineAddingNotification
only has a readonly dictionary. So, how do I set properties on an orderline, whenever a product is added? I'm using Umbraco Commerce 15.0.1
s
In Umbraco commerce 13 (I guess this should not really be different). you can make the order or orderline writeable to for instance update the quantity, you can also set Properties where you can pass a dictionary (just a quick snippet). Basicly you need a writeable order where you can then add stuff to the line
Copy code
var order = _commerceApi.GetOrCreateCurrentOrder(store.Id)
                    .AsWritable(uow);

                foreach (var orderLine in order.OrderLines)
                {
                    order.WithOrderLine(orderLine.Id).SetQuantity(2).SetProperties(new Dictionary<string, string>
                    {
                        { "key1", "value1" },
                    });
                }
n
I know I can make the order writable. But that seems like a workaround rather than the preferred way to do it. My problem is that I expect an event that is being called when a product is being added to the order, can actually modify how the orderline is being created. Your example suggests that I will have to make the order writable and save changes every time the event is being triggered. That may be fine if you have only one event. But I may need multiple. And why does the event have a "Properties"-settings that is null?
Further more, how can I edit a line on an order from the
OrderProductAddingNotification
handler. As I understand it, this event is fired before the line is event created.
m
"In the Commerce API, everything is read-only for performance so you need to make it writable to add the product."
https://docs.umbraco.com/umbraco-commerce/how-to-guides/delete-item tucked away here.. so making writeable would be the preferred way?
s
I guess you would want the OrderLineAddingNotification which is fired before creating the order line. I guess (don't know for sure) is that the productadding/added part is after the order line creation? I guess it would be helpfull to have a flow of the different notifications per action so we know when to hook into parts. I guess an issue could be made to request documentation updates in the commerce GitHub.
m
n
I went with the
OrderLineAddingNotification
route. But it's weird there are multiple notifications that suggests doing the same thing. But the documentation contradicts itself. It either implies that I should create a single handler that handles everything per notification, or many handlers. If I create multiple handlers, It's unclear that they will be run sequentially or parallel. This page, https://docs.umbraco.com/umbraco-commerce/key-concepts/unit-of-work, tells me that I should have all writes in a single unit of work. But in a multi-handler scenario, that would be impossible. And a single handler scenario can easily become very crowded and complex. I went with a single handler and implementing my own pipeline to handle edits in a sequential way wrapped in a single unit of work. However, the pipeline api is badly documented as well. What I learned, is that all tasks are singleton. This makes injecting services difficult. I went with injecting the
IFactory
service and requesting services through this. But I'm not sure if this is the preferred way of doing it.
... oh by the way... How do I tell a notification handler, that it has failed and thus should not continue? Eg. on the
OrderLineAddingNotification
handler, how do I prevent the line being added if some case is present? Eg. "you cannot add this product because xyz".
m
https://docs.umbraco.com/umbraco-cms/reference/notifications/contentservice-notifications#usage
notification.CancelOperation()
in other umbraco notification handlers.
n
No such method on either
OrderLineAddingNotification
or
OrderLineChangingNotification
n
Not cancelable. Just been looking through a decompiled version, it only fires the events. It has no logic to handle a cancel event. The only way, and the way I'm doing it now, is to throw an exception. https://cdn.discordapp.com/attachments/1338523406638780429/1339194085977882634/image.png?ex=67add52f&is=67ac83af&hm=9383f960fedcca21ff28cad98a200e508f81b68b712da35793cc2f5becf54a57&
m
some good insights here if you've not seen.. https://github.com/umbraco/Umbraco.Commerce.Issues/discussions
n
There was a thread made a few weeks ago by my colleague. Moving the discussion there: https://github.com/umbraco/Umbraco.Commerce.Issues/discussions/613
15 Views