Problem/Motivation:
Currently, customer service representatives must navigate away from the main order interface to the order edit page whenever they need to manage coupons. This creates an inefficient workflow that disrupts the natural order management process.
The existing implementation forces users to:
- Leave their current context
- Add coupons
- Return to the original interface
Proposed resolution:
Implement a comprehensive add coupon directly within the order interface:
- Add a "Add Coupon" action link alongside existing order actions
- Display coupon management interface in a modal dialog
- Remove existing coupons individually
- Add new coupons (multiple per session)
- View all currently applied coupons
Issue fork commerce-3545954
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #5
jsacksick commentedLet's rename the action to "Manage coupons" and also remove the "Add order item" local action.
Comment #6
tbkot commentedThe action is renamed. I left options for the action link to pass the test, as the form should open in the modal. It needs to be removed when #3551783: Create Order Actions Menu is merged, or if this ticket is merged first, we need to update it within #3551783: Create Order Actions Menu.
Another issue I'm faced with is when we make any changes on the form (apply/remove coupon) and press "Cancel," it affects the order items due to the OrderRefresh service, which saves order items and rebuilds adjustments. I have to refactor this as well
Comment #7
jsacksick commentedThis looks mostly good... The only thing I'm worried about is the fact that we remove all promotion adjustments. This is ok I'd say in most cases, but in the scenario where a placed order is updated, this might cause a promotion previously applied (without coupons) to be removed and not reapplied.
Perhaps an edge case we can live with as we can assume that if a merchant adjusts the coupons, this should take predecence over previously applied promotions.
Also, we're still injecting the order refresh service and not using it.
Comment #8
jsacksick commentedHm... Re-reading the code, I don't really see where order items are saved? Are we relying on the order refresh service to save the order items? What if it's a placed order?
I also don't really understand why within reapplyPromotions() we remove and re-add order items?
Comment #9
jsacksick commentedThis needs additional work as it doesn't work properly for placed orders.
So I think we need to make a decision, either we try supporting placed orders properly, and for that I think we need to explicitly save order items... Or we don't make the action available for non draft orders...
If we do limit this to draft orders only, then the code can be simplified to simply save the order, as draft orders are automatically refreshed on order save.
I actually do prefer the approach of manually invoking the promotion order processor, as this is basically doing a "scoped" order refresh, but the current logic doesn't work for placed orders.
Also, we need additional test coverage to test various use cases.
Finally, I think there is an issue with Shipping promotions as Shipping uses a different adjustment type "shipping_promotion".
Comment #10
jsacksick commentedI was thinking of updating the following method:
to accept a second parameter
$promotion_idso applying/removing a coupon for example only remove adjustments previously added by the promotion ID referenced by the coupon.This avoid messing with promotion adjustments previously added by other promotions (in case promotions are stacked). This is particularly useful for placed orders.
But then I realized there are other issues to take into account. The tax might need to be reapplied / recalculated as well... So perhaps as a v1 it's safer to only support draft orders as we could end up recalculating promotions for placed orders and end up with wrong tax adjustments... The tax is always calculated post promotion.
The other solution would be to reapply taxes as well...
Will keep digging tomorrow.
Last problem I just thought of... In case of a promotion affecting the order item unit price, we actually need to increase the unit price prior to applying the promotion...
All of these concerns ^ do not exist if we only care about draft orders...
Comment #11
jsacksick commentedI'm now hiding the manage coupons action for non draft orders, we still do need the reapplyPromotions() logic for the estimate, since we allow estimating before committing the changes.
But I'm afraid we can't handle shipping promotions properly without duplicating code from Commerce shipping which is far from ideal...
Also I somehow broke the estimate calculation.
Comment #12
tbkot commentedComment #14
jsacksick commentedMerged!