- Issue created by @rszrama
- π©πͺGermany jurgenhaas Gottmadingen
Thanks @rszrama for raising this important concern. I do wonder, though, what we can do about it. ECA just exposes the API provided by commerce to developers. In other words, it allows subscribing to commerce events and then execute action plugins. So, in general, I guess we either need to document which steps are necessary to be taken by the user when they build action chains on certain events, or make actions safe to take care of it in certain contexts.
For the specific case in the ID, I guess we're talking about the
ChangePriceInCartAction
action plugin. Is there any service or event in commerce that should be called so that commerce can update all the relevant components? If so, it would be pretty simple to use a callback from within the action plugin here:$newPrice = new Price($newPrice, 'USD'); $entity->setUnitPrice($newPrice, TRUE); $entity->save();
Alternatively, wouldn't it be even better, if
setUnitPrice
was taking care of the necessary follow-up actions? - πΊπΈUnited States nicxvan
- πΊπΈUnited States rszrama
ECA just exposes the API provided by commerce to developers.
True, but Commerce expects this particular API function to be used in concert with other functions (i.e., the creation of related adjustments and the proper ordering of unit price adjustments relative to other systems, like tax and promotion).
Is there any service or event in commerce that should be called so that commerce can update all the relevant components?
This operation is intended to be part of the order refresh system. This is controlled by and documented in the Order module's
OrderRefresh
service. It is not event based, so it does not fall within the typical "Event -> Condition -> Action" workflow this module presumes. However, you could theoretically treat the various steps of the process as individual events. These include order preprocessing (to reset the order to an initialized state in the event a processor has created order level adjustments that need to be removed), base price resolving to establish the initial unit price of each order item, and then order processing, which typically includes iterating over order items to manipulate their prices and adjustments.Thus, if what you want in ECA is the ability to set a static price on an order item, I would have ECA define a price resolver that uses its own event to let an ECA configuration specify a price. This is different from setting a price on an order item, though, in that a price resolver's job is to return a price, not set it directly on the order item. It has a more limited context to work with as well.
At the end of the day, the ECA model just isn't an automatic fit for Commerce price calculation / order refreshing, especially because even if you do the above, the price resolver still needs a sort order, and that may differ from application to application even within the same site. These are the kinds of questions we hoped to tease out in commerce_eca, we just haven't gotten to it yet. π
- πΊπΈUnited States freelock Seattle
Commented in Slack #ECA channel with a link to an old blog post where I created a custom price resolver.
So what I'm wondering now is if it's possible to alter a price resolver's priority -- or have a price resolver derivative that allows a price resolver instance (or multiple instances) to get created with a specified priority. Wondering if this might be possible with a Symfony Decorator, if there's not a more Drupal-specific way?
When I was previously implementing a "pay what you want" scheme in commerce, I looked into using a price resolver, but ran into the problem that price resolvers had been intentionally designed to be restrictive (not having any way to access the price entered by the user in the add to cart form, aka order item fields).
I then tried using adjustments next, but the UX for adjustments on order items in Commerce is not very good; adjustments are displayed with little detail and shown next to the grand total for the order/cart, instead of being displayed next to the subtotal for each order item.
For the "pay what you want" scheme, I had to fall back to directly setting the unit price on the order item and just manually making sure that it was only performed in response to specific events within the order refresh process.
several other systems interact with these draft prices until the point of order placement, and the order of operations is often very important
As a workaround, perhaps ECA commerce could trigger an order refresh after the price is changed, so that it effectively becomes the "first" in the chain of processors. But it would have to be an optional feature that is disabled by default, as it can cause infinite loops if the action was itself triggered by an order refresh.