Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
If an order is created programmtically and the state isn't set to "draft", this order never gets refreshed (in time), therefore, the adjustments are not calculated.
One solution is to change (probably more work need to be done) order->preSave()
from
// Refresh draft orders on every save.
if ($this->getState()->value == 'draft' && empty($this->getRefreshState())) {
$this->setRefreshState(self::REFRESH_ON_SAVE);
}
$this->recalculateTotalPrice();
to
// Refresh draft orders on every save.
if ($this->getState()->value == 'draft' || empty($this->getRefreshState())) {
$this->setRefreshState(self::REFRESH_ON_SAVE);
}
$this->recalculateTotalPrice();
Comment | File | Size | Author |
---|---|---|---|
#6 | orders_created_without-2841101-6.patch | 1.51 KB | skyredwang |
Comments
Comment #2
skyredwangThe patch has an improved solution.
Comment #3
mglamanThat's kind of the point. You only make modifications to draft orders. Once it's not a draft it's considered immutable unless changing to a different state (validation -> complete) or some other factor (accepting payment, refunding payment.) Nothing should affect it's price.
What is the use case and why would you want to alter the price of an order when it is is no longer a draft / has been placed?
Comment #4
skyredwangA common use case would be: a project defines its own order states and workflow. Some orders are created and processed heedlessly and not necessarily set to "draft" when ready to be saved in Drupal commerce. Therefore, Order system wants to give those orders refresh at least once when they come in, so they will have the chance to bring in adjustments into total price.
Here is a concrete example: if a client side is a vending machine, there will be 10 machines. Each one takes care of its sales and orders, then they sync back to a central commerce system, how would you recommend to solve the problem that the order total price isn't correct when there is discount, tax involved?
Comment #5
bojanz CreditAttribution: bojanz at Centarro commentedWe enforce that every order workflow must have a "draft" state so that point is moot.
The REST use case is clearly about recording a fully processed order. In which case it would be wrong for Commerce to do any kind of processing and calculation of its own. Such an order has no need for Commerce taxes or promotions.
I think it makes more sense to ensure that the total price can be set instead. That way the REST client is responsible for every amount. I believe $order->total_price is accessible directly and that we're just missing a setter, but I might be wrong.
Comment #6
skyredwangThis is the patch for the total price setter.
Comment #7
agoradesign CreditAttribution: agoradesign commented$order->total_price is accessible directly, I have already used that a few times
Comment #8
skyredwangI tried
before called $order-save(). $order-save() will override the total again.
Then, I realize, in the REST use case, $order-save() has to be called twice anyway, the first time to generate the order id, then the second time to add in order items.
So, if we have to call save twice, then I can always set the state to 'draft' for the first time, then whatever state received for the second save.
I tested it out, it actually works.
Comment #9
mglamanI'm going to mark this as closed because it works as designed. We do not want a
:: setTotalPrice
method, as this is assumed to be generated based off of order items and adjustments on each level.As stated previously we want a draft order.
This verifies it works as designed.