-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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
feat(core): Add maxDiscountAmount to PromotionItemAction #2964
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
All contributors have signed the CLA ✍️ ✅ |
I have read the CLA Document and I hereby sign the CLA |
It appears that the unit test failures in this PR are due to the value of the compatibility field in the TestPlugin. Some TestPlugins had their compatibility set to ^2.0.0 when this PR was created, and they have now all been changed to ^3.0.0. If the tests need to be rerun, please leave a comment! |
Hi, thanks for your contribution. I want to make sure I fully understand this change. From your explanation and from looking at the code changes, it looks like the result of the The problem this seems to be fixing is the specific scenario where you want to have a specific fixed discount on an OrderLine which is consistent for any quantity value. I understand the current issue whereby the return value of the Given that, my first thought is that I'd like to explore alternative solutions to adding the
Alternative proposalHere's an example of another approach which might be able to solve the issue in a backward-compatible way: What if we allow the execute(ctx, orderLine, args) {
if (lineContainsIds(args.productVariantIds, orderLine)) {
const unitPrice = ctx.channel.pricesIncludeTax ? orderLine.unitPriceWithTax : orderLine.unitPrice;
const lineDiscount = args.discount * -1;
return {
amount: lineDiscount,
discountMode: 'line' // 'unit' would be the other possibility
}
}
return 0;
}, Then we would know, if Just returning a number (the current API) is equivalent to setting Happy to hear any feedback you have on that idea. |
Hi, thank you for the great idea proposal. The core of this PR is to add a maximum discount amount to the PromotionItemAction, which specifies the maximum discount amount for each orderLine unit. I wanted to solve this issue, and the maxDiscountAmount() function is one way I proposed to do so. I considered other methods, such as adding a column to the Promotion Entity or extending the type of adjustment, but I thought the simplest way to implement this without modifying the admin UI was to add the maxDiscountAmount function with the same arguments as the execute function. However, I think your proposal to return the response of the execute function as an object and add a discountMode to determine whether to apply the quantity multiplication to the orderLine is a good alternative. Implementing it this way would allow not only setting a maximum discount amount but also a fixed discount amount. Thank you for your idea proposal. I will add a commit to the PR to revise it according to your suggestions. |
Thanks for the quick follow-up. Do you think you would also be able to include relevant e2e tests for this feature? If so they would go in this file: https://github.com/vendure-ecommerce/vendure/blob/f1753432c42c8616cd51add8629f65cc107899d6/packages/core/e2e/order-promotion.e2e-spec.ts |
d9629f7
to
9784149
Compare
…d write test code for it
9784149
to
92c2655
Compare
Hi To add an object to the return type of the
Additionally, I added test case and included the However, there is one issue. I would like some advice on this issue. |
I see that all of the e2e tests are passing currently. In the above comment, are you referring to a test you made locally that you did not include in the PR? If so, you could commit the failing test and I can take a look at it. |
I have added the failed test case. |
OK I looked into this and found the reason for the test failure: it is because of the default MoneyStrategy that Vendure uses, which applies rounding in a non-optimal way (it rounds the amount and then multiplies by quantity), for backwards-compatibility reasons. To fix this we can create a custom MoneyStrategy for the test suite: class TestMoneyStrategy extends DefaultMoneyStrategy {
round(value: number, quantity = 1): number {
return Math.round(value * quantity);
}
}
describe('Promotions applied to Orders', () => {
const { server, adminClient, shopClient } = createTestEnvironment(
mergeConfig(testConfig(), {
dbConnectionOptions: { logging: true },
paymentOptions: {
paymentMethodHandlers: [testSuccessfulPaymentMethod],
},
// add here
entityOptions: {
moneyStrategy: new TestMoneyStrategy(),
},
}),
); This should make the failing test pass. Actually we should also update the default money strategy for the next minor version to use this more correct rounding logic, but that can be a separate issue. |
Understood. I believe that it would be better in the long term to not only implement a more precise rounding logic but also to separate However, I don't think this is an issue that should be addressed in this PR. What do you think about this? |
If we were to plan introducing a Pros:
Cons:
I actually think I prefer that suggestion - the simplicity of always having a |
I agree. While flexible code can be valuable in actual operating environments, I will submit a new PR for the |
Since a PR with the same purpose has been merged, I will close this PR. |
Description
In the case of PromotionItemAction, there is an issue where the maximum discount amount cannot be specified because the orderLine quantity is multiplied after executing the apply function of the Promotion Entity.
To address this, we have added a maxDiscountAmount method to the PromotionItemAction class, which takes the same arguments as the execute method, allowing customization of the maximum discount amount. Additionally, we have modified the PromotionItemAction apply process to compare the discount amount with the maxDiscountAmount and apply the maximum discount amount if necessary.
The maxDiscountAmount is optional and will not conflict with existing Promotion Actions.
Checklist
📌 Always: