-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Discountable amounts by adjustments #6371
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Discountable amounts by adjustments #6371
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6371 +/- ##
==========================================
+ Coverage 89.45% 89.47% +0.01%
==========================================
Files 974 979 +5
Lines 20322 20412 +90
==========================================
+ Hits 18179 18263 +84
- Misses 2143 2149 +6 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
| it " will not create the adjustment" do | ||
| expect { | ||
| subject | ||
| order.save! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We only want to check for amount zero and marked for destruction here and not save the order.
promotions/app/models/concerns/solidus_promotions/discountable.rb
Outdated
Show resolved
Hide resolved
promotions/app/models/concerns/solidus_promotions/discountable.rb
Outdated
Show resolved
Hide resolved
5f2c828 to
fc5b38b
Compare
Similar to the work in solidusio#6360, this improves the DSL for creating benefits. Rather than having to define one method that cares for applicability to a discountable, we now simply define that a benefit `#can_discount?` an object if its public interface has `#discount_{discountable_type}` defined. This does not change the implementation of the different methods, but that will come when we refactor the promotion system to use a single system of record for discounts. Then, different objects will need different discount records (line items and shipment use adjustments, but shipping rates use shipping rate discounts etc.). I'm not doing the work for adding deprecation warnings here, as this code was never meant to be overridden up to now. Also fixes some AI slop in the docs.
Instead, follow the deprecation message's instructions.
In the unlikely case people have used these modules, warn if they are included.
This allows setting the current promotion lane to the current thread, and run computations with the current promotion lane set. This is useful for calculating what the discounted amount of a promotable is within e.g. the `default` lane even if there are adjustments for the `post` lane. I'm using `Thread.current` here because we don't always have an order to store the current lane on.
This will return the lanes that came before the current lane. Useful for finding the discountable amount by lane.
This can be used to select all adjustments of an adjustable - a line item or shipment - that are associated to a promotion benefit by lanes. This is useful for getting the current discountable amount programmatically, as will be seen in upcoming commits.
This can be used to calculate the current discountable amount while calculating promotions.
When we call order.reset_discounts, we don't want to deal with those that are currently valid/eligible during promotion recalulcation, we want all discounts to be zero. We could destroy them, but zeroing them is more efficient, because it's likely that an adjustment might not change during adjustment recalculation, in which case we don't need to destroy and re-create.
We want the individual benefits to issue exactly the kind of object that
will discount it, so we need to make some adjustments:
- Dynamically call a discount_#{discountable_type} method
- Create the right kind of discount object per discountable type in
those methods
- Always test the compute_* methods simulating a calculation process
This way we can have a single source of truth for what's being discounted.
Also removes the now-unnecessary `PersistDiscountedOrder` class.
Calculators now rely on `discountable_amount`, which goes back to `previous_lane_discounts`. We need to stub it, because using the SolidusPromotions::Promotion.within_lane helper will reset it (often during spec setup).
fc5b38b to
bd24d6b
Compare
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: