Promotions and LineItem's eligibility #4755
Replies: 2 comments 4 replies
-
Looking at the code there's also a stream of About the problem you describe I'll just say that's yet another manifestation of how the current promotion system could use a replacement. Maybe we need a pluggable system in which you can swap a promotion system for another one… or maybe a middleware like system in which an order goes through different transformers that will create adjustments… or something else. But it's evident that the current solution only covers well only a handful of cases, a few more can be forced to work in the system, and many others are completely out of its league. |
Beta Was this translation helpful? Give feedback.
-
@RyanofWoods I wrote up a whole post about this before checking here, only to find you beat me to it by two weeks 😆 Pasting my post here - definitely agree with you, and I have a solution that I think makes sense - would love to hear your thoughts on it! (You too, @elia!) TL;DR: Discounting a specific product in an order is kind of weird, and break separation of concerns. The ProblemAssuming the following: In theory, once the order is determined to be eligible for the promotion, the promotion rules role should end, and the promotion actions role should start. Most of the time, that's how it works. Consider the following: Promotion A applies a $10 discount to orders that are over $100. The promotion rule verifies that the order is over $100. The promotion action applies a $10 discount. Simple! However, if you discount specific products, that's not how it works. In this case, the promotion rules verify eligibility, then the promotion action checks the promotion rules to determine what items it should apply to, then it applies discounts. In other words, the promotion rule is determining both eligibility and has a say in application. Here's the counterpart to the first example: Promotion B applies a $10 discount to Product A on orders that have Product A. The promotion rule verifies that the order has Product A. The promotion action checks each line item against the promotion rule. The promotion action applies discounts wherever the promotion rules say it should. The promotion rules responsibility - which usually ends at "eligibility" extended in this case to "application". The ArgumentI think the original line of thinking was that the promotion rule should determine eligibility for the order, then determine if each line item is eligible. My argument is that when we check the line items, we're already in the "application" phase - the "eligibility" phase has passed, and that's all the rule should be concerned about. Application should solely be the responsibility of the promotion actions. This causes some issues that I think others have experiences as well - the option value, product, and taxon rules require a lot of insider knowledge to use effectively. You have to know that if you use the product rule with the item adjustment action, that you're creating this promotion:
The Solution?The product, taxon, and option value rules should change from:
With that change, we're losing the ability to apply discounts only to certain products - but that should be the domain of the promotion action anyway, as it deals with application. So, we'll need a way to target products, option values, and/or taxons on the two promotion actions that care about that (create item adjustment + create quantity adjustment). They should change from:
With these two changes, application is solely the responsibility of the promotion action, and the promotion rule only deals with eligibility. No more crossed responsibilities! 🎉 |
Beta Was this translation helpful? Give feedback.
-
Overall, the promotion's system is pretty flexible out of the box, thanks to the different models. As a recap:
However, promotion rules actually do more than they state. They can actually also state whether the promotion adjustments should be made on the promotable (the LineItem in most cases) via
actionable?
. This breaks their single responsibility as well as makes the Rule less reusable...Not one model is solely responsible for this logic, so it can end up in a rule, action and or even a calculator. For example, say you want to create an adjustment on the most expensive item:
The most expensive item adjustment is a bit of a special case as other
actionable?
cases can work nicely with other rules, such as item types, but still it makes the rule less reusable.I am thinking this logic could be extracted out to a new model for the
CreateItemAdjustments
Promotion action, perhaps filters or something. They could just use LineItem scopes and/or selects. But note, like above, some filters could clash if you want the most expensive item but also to exclude item types (the most expensive item on the order could be the excluded type).Beta Was this translation helpful? Give feedback.
All reactions