fix(dashboard,promotion): percentage promotions + set currency code on percentage promotions (#13161)

This commit is contained in:
Riqwan Thamir authored and GitHub committed 2025-08-07 13:07:41 +02:00
1 parent 9725bff25d
commit 224eaedf5c
5 files changed
+150 -11

No files matched your search

@@ -2725,6 +2725,7 @@ medusaIntegrationTestRunner({
)
})
describe("With promotions", () => {
it("should only apply promotion on discountable items", async () => {
const notDiscountableProduct = (
await api.post(
@@ -3450,7 +3451,10 @@ medusaIntegrationTestRunner({
let updated = await api.post(
`/store/carts/${cart.id}`,
{
promo_codes: [taxInclPromotion50.code, taxInclPromotion100.code],
promo_codes: [
taxInclPromotion50.code,
taxInclPromotion100.code,
],
},
storeHeaders
)
@@ -3733,6 +3737,131 @@ medusaIntegrationTestRunner({
})
)
})
describe("Percentage promotions", () => {
it("should apply a percentage promotion to a cart", async () => {
const percentagePromotion = (
await api.post(
`/admin/promotions`,
{
code: "PERCENTAGE_PROMOTION",
type: PromotionType.STANDARD,
status: PromotionStatus.ACTIVE,
is_automatic: false,
application_method: {
type: "percentage",
target_type: "items",
allocation: "each",
value: 100,
max_quantity: 1,
currency_code: "usd",
target_rules: [],
},
},
adminHeaders
)
).data.promotion
cart = (
await api.post(
`/store/carts`,
{
currency_code: "usd",
sales_channel_id: salesChannel.id,
region_id: region.id,
shipping_address: shippingAddressData,
items: [
{ variant_id: product.variants[0].id, quantity: 1 },
],
},
storeHeadersWithCustomer
)
).data.cart
let updated = await api.post(
`/store/carts/${cart.id}`,
{
promo_codes: [percentagePromotion.code],
},
storeHeadersWithCustomer
)
expect(updated.status).toEqual(200)
expect(updated.data.cart).toEqual(
expect.objectContaining({
items: expect.arrayContaining([
expect.objectContaining({
adjustments: expect.arrayContaining([
expect.objectContaining({
code: percentagePromotion.code,
}),
]),
}),
]),
})
)
})
it("should not apply a percentage promotion to a cart if cart currency is not the same as the promotion currency", async () => {
const percentagePromotion = (
await api.post(
`/admin/promotions`,
{
code: "PERCENTAGE_PROMOTION",
type: PromotionType.STANDARD,
status: PromotionStatus.ACTIVE,
is_automatic: false,
application_method: {
type: "percentage",
target_type: "items",
allocation: "each",
value: 100,
max_quantity: 1,
currency_code: "eur",
target_rules: [],
},
},
adminHeaders
)
).data.promotion
cart = (
await api.post(
`/store/carts`,
{
currency_code: "usd",
sales_channel_id: salesChannel.id,
region_id: region.id,
shipping_address: shippingAddressData,
items: [
{ variant_id: product.variants[0].id, quantity: 1 },
],
},
storeHeadersWithCustomer
)
).data.cart
let updated = await api.post(
`/store/carts/${cart.id}`,
{
promo_codes: [percentagePromotion.code],
},
storeHeadersWithCustomer
)
expect(updated.status).toEqual(200)
expect(updated.data.cart).toEqual(
expect.objectContaining({
items: expect.arrayContaining([
expect.objectContaining({
adjustments: [],
}),
]),
})
)
})
})
})
})
describe("POST /store/carts/:id/customer", () => {
@@ -47,12 +47,10 @@ export const CreateCampaignFormFields = ({ form, fieldScope = "" }) => {
if (isTypeSpend) {
form.setValue(`campaign.budget.currency_code`, promotionCurrencyValue)
}
if (watchValueType === "usage") {
} else {
form.setValue(`campaign.budget.currency_code`, null)
}
}, [watchValueType])
}, [promotionCurrencyValue, isTypeSpend])
if (promotionCurrencyValue) {
const formCampaignBudget = form.getValues().campaign?.budget
@@ -128,7 +128,7 @@ export const RulesFormField = ({
{t(`promotions.fields.conditions.${ruleType}.description`)}
</Text>
{fields.map((fieldRule: any, index) => {
{fields.map((fieldRule, index) => {
const identifier = fieldRule.id
return (
@@ -157,11 +157,23 @@ export const RulesFormField = ({
(ao) => ao.id === e
)
update(index, {
const fieldRuleOverrides: typeof fieldRule = {
...fieldRule,
values: [],
disguised: currentAttributeOption?.disguised || false,
})
}
if (currentAttributeOption?.operators?.length === 1) {
fieldRuleOverrides.operator =
currentAttributeOption.operators[0].value
}
if (fieldRuleOverrides.operator === "eq") {
fieldRuleOverrides.values = ""
} else {
fieldRuleOverrides.values = []
}
update(index, fieldRuleOverrides)
onChange(e)
}
@@ -299,7 +299,7 @@ export const CreatePromotionForm = () => {
const formData = form.getValues()
let campaignQuery: object = {}
if (isFixedValueType && formData.application_method.currency_code) {
if (formData.application_method.currency_code) {
campaignQuery = {
budget: { currency_code: formData.application_method.currency_code },
}
@@ -521,7 +521,7 @@ export default class PromotionModuleService
}
const isCurrencyCodeValid =
!isDefined(applicationMethod.currency_code) ||
!isPresent(applicationMethod.currency_code) ||
applicationContext.currency_code === applicationMethod.currency_code
const isPromotionApplicable = areRulesValidForContext(