fix: skip promotion usage limit checks on edit flows (#14176)

* fix: skip promotion usage limit checks on edit flows

* feat: add test check
This commit is contained in:
Frane Polić
2025-12-01 18:29:15 +01:00
committed by GitHub
parent 0f835381e9
commit 8ddf8b4d76
5 changed files with 35 additions and 4 deletions

View File

@@ -0,0 +1,7 @@
---
"@medusajs/promotion": patch
"@medusajs/core-flows": patch
"@medusajs/types": patch
---
fix: skip promotion usage limit checks on edit flows

View File

@@ -1437,6 +1437,16 @@ medusaIntegrationTestRunner({
adminHeaders
)
const promotionModule = getContainer().resolve(Modules.PROMOTION)
// check that adjustments are computed for promotions that exceeded usage limit (we ignore usage limits on edit flows)
// @ts-ignore
await promotionModule.updatePromotions({
id: appliedPromotion.id,
limit: 1,
used: 1,
})
let result = await api.post(
"/admin/exchanges",
{

View File

@@ -29,7 +29,7 @@ export type ComputeAdjustmentsForPreviewWorkflowInput = {
/**
* The order's details.
*/
order: OrderDTO & {
order: OrderDTO & {
/**
* The promotions applied to the order.
*/
@@ -52,7 +52,7 @@ export const computeAdjustmentsForPreviewWorkflowId =
*
* You can use this workflow within your customizations or your own custom workflows, allowing you to compute adjustments
* in your custom flows.
*
*
* @since v2.12.0
*
* @example
@@ -110,6 +110,9 @@ export const computeAdjustmentsForPreviewWorkflow = createWorkflow(
const actions = getActionsToComputeFromPromotionsStep({
computeActionContext: actionsToComputeItemsInput,
promotionCodesToApply: orderPromotions,
options: {
skip_usage_limit_checks: true,
},
})
const { lineItemAdjustmentsToCreate } =

View File

@@ -295,4 +295,11 @@ export interface ComputeActionOptions {
* automatically. If not provided, the automatic promotions are applied.
*/
prevent_auto_promotions?: boolean
/**
* Whether to skip the usage limit checks.
* Useful when recomputing adjustment for promotions that are already applied as a part of edit/exchange flows.
*
*/
skip_usage_limit_checks?: boolean
}

View File

@@ -634,7 +634,10 @@ export default class PromotionModuleService
options: PromotionTypes.ComputeActionOptions = {},
@MedusaContext() sharedContext: Context = {}
): Promise<PromotionTypes.ComputeActions[]> {
const { prevent_auto_promotions: preventAutoPromotions } = options
const {
prevent_auto_promotions: preventAutoPromotions,
skip_usage_limit_checks: skipUsageLimitChecks,
} = options
const computedActions: PromotionTypes.ComputeActions[] = []
const { items = [], shipping_methods: shippingMethods = [] } =
applicationContext
@@ -806,6 +809,7 @@ export default class PromotionModuleService
} = promotion
if (
!skipUsageLimitChecks &&
promotion.campaign?.budget?.type === CampaignBudgetType.USE_BY_ATTRIBUTE
) {
const attribute = promotion.campaign?.budget?.attribute!
@@ -847,7 +851,7 @@ export default class PromotionModuleService
}
// Check promotion usage limit
if (typeof promotion.limit === "number") {
if (!skipUsageLimitChecks && typeof promotion.limit === "number") {
if ((promotion.used ?? 0) >= promotion.limit) {
computedActions.push({
action: ComputedActions.PROMOTION_LIMIT_EXCEEDED,