-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Add #discounted_amount by adjustments
#6379
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?
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6379 +/- ##
==========================================
+ Coverage 89.45% 89.47% +0.01%
==========================================
Files 974 978 +4
Lines 20322 20357 +35
==========================================
+ Hits 18179 18214 +35
Misses 2143 2143 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
8084c84 to
a101831
Compare
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.
a101831 to
3be73ac
Compare
#discounted_amount by adjustments
This will return the lanes that came before the current lane. Useful for finding the discountable amount by lane. If no lane is present, we just return all lanes, as the expectation is that any adjustments that are present and promotion adjustments would be relevant as we're outside the promotion calculation process.
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.
This is more accurate than the current `discountable_amount`: It described the amount the item has already been adjusted by, according to the current promotion lane, and what the item has been adjusted by due to discounts from the promotion system if called from outside the promotion system. It's very similar to `total_before_tax`, but excludes any manual adjustments.
If we mark any discounts for destruction, they should not be part of the total.
3be73ac to
536b0ce
Compare
tvdeyen
left a comment
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.
This is very clever code, but honestly I am not very happy with this approach.
I would like to not mix in even more modules into already large objects (LineItem, Shipment, etc.) just for storing an in memory calculation.
That we now have a raise condition in a module so we are sure that we never call that public methods outside of the promotion run is a smell imo.
Maybe we can use some kind of object that holds the current state during calculation instead of the objects itself?
Would like to have some thoughts from other @solidusio/core-team members as well .
promotions/app/models/concerns/solidus_promotions/adjustment_discounts.rb
Show resolved
Hide resolved
I've tried - hard, over many months - to use a specialized order object just for promotion calculation. However, in order to discount an order, it needs to be mutated, and I have not found a way to expose all of the order to calculators and conditions (because that's what the calling code expects) from an object that is another class than The goal of this work is to actually go closer to the real order object. To use adjustments/shipping rate discounts to store discounts, rather than the double bookkeeping we have now with discounts while calculating promotions, and adjustments outside of it. A side requirement I have is to require as little change to conditions and calculators as possible, as many stores have many custom conditions and calculators. |
We don't need to re-implement ActiveSupport::CurrentAttributes. Also, CurrentAttributes implements exactly what we need.
00fd257 to
ac0f616
Compare
This work allows us to remove the The idea in #6371 is to store the results of all calculations on objects that we will ultimately store in the database. |
Since there's concern about the method surface of Shipment, Shipping Rate and Line Item, I'll move `previous_lane_discounts` to the private section.
Summary
This adds the
DiscountedAmountmodule to the promotion system. It is preparatory work to be able to calculate thediscounted_amountfor each discountable item depending on the current promotion lane, without taking into account adjustments/discounts from later lanes or discounts that are market for destruction.This just adds methods, their use will be done in a subsequent PR.
Extracted from #6371 .
This introduces an Object to hold the current promotion lane while calculating, and adds a couple of methods in order to replace a couple of older methods.
New:
discountable.discounted_amount. Will replacediscountable.discountable_amount.Rationale: When called from within the promotion system, these mean the same thing (we can only discount from what is still available to discount, and if there's previous discounts, the discountable amount is equal to the discounted amount). Also:
discounted_amountis calculated from real adjustments, so it can be called from outside the promotion system, and the return value will make sense (it will be equal tototal_before_taxunless someone adds manual adjustments somewhere. That's why this should stay public.New:
discountable.previous_lane_discounts. Will replacediscountable.current_discountsRationale: We need a different name for this as it returns an array of adjustments, rather than an array of
SolidusPromotion::ItemDiscountobjects. I could make this private, too, as it's only used fromdiscounted_amountabove.New:
discountable.current_lane_discounts. Replaces a local variable in the order discounter.Rationale: We need to know which discounts are being currently added in the current lane so that we can mark those for destruction that we don't want. Here's where it will be used (draft PR): ea4cd30#diff-828a39d27bc67194ff2509c675bf0148420849b1fcafabe848605f4e2d81f085R69.
Checklist
Check out our PR guidelines for more details.
The following are mandatory for all PRs:
The following are not always needed: