Discountable amounts by adjustments#6371
Merged
mamhoff merged 6 commits intosolidusio:mainfrom Jan 6, 2026
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6371 +/- ##
==========================================
+ Coverage 89.48% 89.49% +0.01%
==========================================
Files 980 981 +1
Lines 20438 20471 +33
==========================================
+ Hits 18289 18321 +32
- Misses 2149 2150 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
tvdeyen
reviewed
Nov 17, 2025
This was referenced Nov 17, 2025
5f2c828 to
fc5b38b
Compare
This was referenced Nov 20, 2025
fc5b38b to
bd24d6b
Compare
67487b3 to
ea30703
Compare
Prior to this, the `adjustment_label` method on
`SolidusPromotions::Benefit` could only output a relatively static
string. This commit allows calculators to define one of these methods:
- `#line_item_adjustment_label(line_item, options = {})`
- `#shipment_adjustment_label(shipment, options = {})`
- `#shipping_rate_adjustment_label(shipping_rate, options = {})`
- `#price_adjustment_label(price, options = {})`
These have access to the inner workings of the calculator, so they can
provide dynamic labels (to reflect e.g. which tier a promotion chooses,
making that transparent to the customer.
If a promotion calculator implements a dynamic
`#{adjustable}_adjustment_label` method, we need to update the
adjustment label when it changes. This makes sure that is the case.
96fab42 to
00fec51
Compare
00fec51 to
e3c0bbf
Compare
tvdeyen
reviewed
Dec 22, 2025
Member
tvdeyen
left a comment
There was a problem hiding this comment.
This is a really great improvement. I have some nits about naming and overall API design, because I would like to make sure that the introduced classes are not used publicly.
b3e5d37 to
7872e08
Compare
mamhoff
commented
Dec 22, 2025
Contributor
Author
mamhoff
left a comment
There was a problem hiding this comment.
Added some comments after rebasing
7872e08 to
5377e72
Compare
tvdeyen
approved these changes
Dec 22, 2025
Member
tvdeyen
left a comment
There was a problem hiding this comment.
Reads extremely well and is a great change
|
|
||
| module SolidusPromotions | ||
| class OrderAdjuster | ||
| class SetDiscountsToZero |
Member
There was a problem hiding this comment.
This could now be a module, no?
This module recalculates all promo totals after promotion calculation has finished, and marks any adjustments with an amount of zero for destruction.
Now that the promotion order adjuster does not persist things to the database any longer, we can calculate promo totals even in dry runs (and get better results). The `PersistDiscountedOrder` class is slated for deletion, but that is the next commit.
This service object sets all discounts on an order - adjustments on shipments and line items, and shipping rate discounts on shipping rates - to an amount of zero. This service module is intended to run within the order adjuster, before promotion calculation. Promotion calculation will then re-calculate the amounts, with the effect that adjustments that need to change will be changed, while adjustments that do not need to change will not have changes (and will therefore also not be saved).
We want the individual benefits to issue exactly the kind of object that will discount the adjustable object, so we need to generate the right kind of discount object for each adjustable type. This allows us to remove the `PersistDiscountedOrder` class, and it makes the promotion system more understandable and more in line with the rest of Solidus. Specifically, we can now check for adjustments when calculating promotion discounts (this is pretty big!), and `promotion.discounted_amount` can be called from outside the promotion calculation loop.
5377e72 to
ac699f3
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR changes the new promotion system to calculate discounts entirely via adjustments rather than using in-memory
ItemDiscountobjects.The advantage of this approach is that it allows to a) calculate discountable amounts for line items outside of the
DiscountOrderloop. This is useful for calculating discounted prices, a feature I have on the roadmap. It specifically covers needs like the one addressed in this commit. This way, we have one system of record, not two.The other advantage is that we can remove the pretty complex
PersistDiscountedOrdercode, and just rely onorder.save!to do the right thing.It also dovetails nicely with the work on the in-memory order updater.
Checklist
Check out our PR guidelines for more details.
The following are mandatory for all PRs:
The following are not always needed: