@medusajs/promotion 3.0.0-snapshot-20250410105645 → 3.0.0-snapshot-20251104004624

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/dist/migrations/Migration20240227120221.d.ts +1 -1
  2. package/dist/migrations/Migration20240227120221.d.ts.map +1 -1
  3. package/dist/migrations/Migration20240227120221.js +1 -1
  4. package/dist/migrations/Migration20240227120221.js.map +1 -1
  5. package/dist/migrations/Migration20240617102917.d.ts +1 -1
  6. package/dist/migrations/Migration20240617102917.d.ts.map +1 -1
  7. package/dist/migrations/Migration20240617102917.js +1 -1
  8. package/dist/migrations/Migration20240617102917.js.map +1 -1
  9. package/dist/migrations/Migration20240624153824.d.ts +1 -1
  10. package/dist/migrations/Migration20240624153824.d.ts.map +1 -1
  11. package/dist/migrations/Migration20240624153824.js +1 -1
  12. package/dist/migrations/Migration20240624153824.js.map +1 -1
  13. package/dist/migrations/Migration20241211061114.d.ts +1 -1
  14. package/dist/migrations/Migration20241211061114.d.ts.map +1 -1
  15. package/dist/migrations/Migration20241211061114.js +1 -1
  16. package/dist/migrations/Migration20241211061114.js.map +1 -1
  17. package/dist/migrations/Migration20250113094144.d.ts +1 -1
  18. package/dist/migrations/Migration20250113094144.d.ts.map +1 -1
  19. package/dist/migrations/Migration20250113094144.js +1 -1
  20. package/dist/migrations/Migration20250113094144.js.map +1 -1
  21. package/dist/migrations/Migration20250120110700.d.ts +1 -1
  22. package/dist/migrations/Migration20250120110700.d.ts.map +1 -1
  23. package/dist/migrations/Migration20250120110700.js +1 -1
  24. package/dist/migrations/Migration20250120110700.js.map +1 -1
  25. package/dist/migrations/Migration20250226130616.d.ts +1 -1
  26. package/dist/migrations/Migration20250226130616.d.ts.map +1 -1
  27. package/dist/migrations/Migration20250226130616.js +1 -1
  28. package/dist/migrations/Migration20250226130616.js.map +1 -1
  29. package/dist/migrations/Migration20250508081510.d.ts +6 -0
  30. package/dist/migrations/Migration20250508081510.d.ts.map +1 -0
  31. package/dist/migrations/Migration20250508081510.js +14 -0
  32. package/dist/migrations/Migration20250508081510.js.map +1 -0
  33. package/dist/migrations/Migration20250828075407.d.ts +6 -0
  34. package/dist/migrations/Migration20250828075407.d.ts.map +1 -0
  35. package/dist/migrations/Migration20250828075407.js +34 -0
  36. package/dist/migrations/Migration20250828075407.js.map +1 -0
  37. package/dist/migrations/Migration20250909083125.d.ts +6 -0
  38. package/dist/migrations/Migration20250909083125.d.ts.map +1 -0
  39. package/dist/migrations/Migration20250909083125.js +25 -0
  40. package/dist/migrations/Migration20250909083125.js.map +1 -0
  41. package/dist/migrations/Migration20250916120552.d.ts +6 -0
  42. package/dist/migrations/Migration20250916120552.d.ts.map +1 -0
  43. package/dist/migrations/Migration20250916120552.js +14 -0
  44. package/dist/migrations/Migration20250916120552.js.map +1 -0
  45. package/dist/migrations/Migration20250917143818.d.ts +6 -0
  46. package/dist/migrations/Migration20250917143818.d.ts.map +1 -0
  47. package/dist/migrations/Migration20250917143818.js +18 -0
  48. package/dist/migrations/Migration20250917143818.js.map +1 -0
  49. package/dist/migrations/Migration20250919122137.d.ts +6 -0
  50. package/dist/migrations/Migration20250919122137.d.ts.map +1 -0
  51. package/dist/migrations/Migration20250919122137.js +14 -0
  52. package/dist/migrations/Migration20250919122137.js.map +1 -0
  53. package/dist/migrations/Migration20251006000000.d.ts +6 -0
  54. package/dist/migrations/Migration20251006000000.d.ts.map +1 -0
  55. package/dist/migrations/Migration20251006000000.js +16 -0
  56. package/dist/migrations/Migration20251006000000.js.map +1 -0
  57. package/dist/models/application-method.d.ts +183 -24
  58. package/dist/models/application-method.d.ts.map +1 -1
  59. package/dist/models/campaign-budget-usage.d.ts +268 -0
  60. package/dist/models/campaign-budget-usage.d.ts.map +1 -0
  61. package/dist/models/campaign-budget-usage.js +31 -0
  62. package/dist/models/campaign-budget-usage.js.map +1 -0
  63. package/dist/models/campaign-budget.d.ts +82 -24
  64. package/dist/models/campaign-budget.d.ts.map +1 -1
  65. package/dist/models/campaign-budget.js +17 -1
  66. package/dist/models/campaign-budget.js.map +1 -1
  67. package/dist/models/campaign.d.ts +63 -24
  68. package/dist/models/campaign.d.ts.map +1 -1
  69. package/dist/models/index.d.ts +1 -0
  70. package/dist/models/index.d.ts.map +1 -1
  71. package/dist/models/index.js +3 -1
  72. package/dist/models/index.js.map +1 -1
  73. package/dist/models/promotion-rule-value.d.ts +360 -19
  74. package/dist/models/promotion-rule-value.d.ts.map +1 -1
  75. package/dist/models/promotion-rule-value.js +17 -2
  76. package/dist/models/promotion-rule-value.js.map +1 -1
  77. package/dist/models/promotion-rule.d.ts +182 -23
  78. package/dist/models/promotion-rule.d.ts.map +1 -1
  79. package/dist/models/promotion-rule.js +13 -0
  80. package/dist/models/promotion-rule.js.map +1 -1
  81. package/dist/models/promotion.d.ts +59 -6
  82. package/dist/models/promotion.d.ts.map +1 -1
  83. package/dist/models/promotion.js +7 -0
  84. package/dist/models/promotion.js.map +1 -1
  85. package/dist/schema/index.d.ts +1 -1
  86. package/dist/schema/index.d.ts.map +1 -1
  87. package/dist/schema/index.js +1 -0
  88. package/dist/schema/index.js.map +1 -1
  89. package/dist/services/promotion-module.d.ts +420 -77
  90. package/dist/services/promotion-module.d.ts.map +1 -1
  91. package/dist/services/promotion-module.js +345 -116
  92. package/dist/services/promotion-module.js.map +1 -1
  93. package/dist/tsconfig.tsbuildinfo +1 -1
  94. package/dist/types/campaign-budget.d.ts +10 -0
  95. package/dist/types/campaign-budget.d.ts.map +1 -1
  96. package/dist/utils/compute-actions/build-promotion-rule-query-filter-from-context.d.ts +12 -0
  97. package/dist/utils/compute-actions/build-promotion-rule-query-filter-from-context.d.ts.map +1 -0
  98. package/dist/utils/compute-actions/build-promotion-rule-query-filter-from-context.js +188 -0
  99. package/dist/utils/compute-actions/build-promotion-rule-query-filter-from-context.js.map +1 -0
  100. package/dist/utils/compute-actions/buy-get.d.ts +3 -2
  101. package/dist/utils/compute-actions/buy-get.d.ts.map +1 -1
  102. package/dist/utils/compute-actions/buy-get.js +251 -84
  103. package/dist/utils/compute-actions/buy-get.js.map +1 -1
  104. package/dist/utils/compute-actions/index.d.ts +1 -0
  105. package/dist/utils/compute-actions/index.d.ts.map +1 -1
  106. package/dist/utils/compute-actions/index.js +1 -0
  107. package/dist/utils/compute-actions/index.js.map +1 -1
  108. package/dist/utils/compute-actions/line-items.d.ts +3 -4
  109. package/dist/utils/compute-actions/line-items.d.ts.map +1 -1
  110. package/dist/utils/compute-actions/line-items.js +74 -40
  111. package/dist/utils/compute-actions/line-items.js.map +1 -1
  112. package/dist/utils/compute-actions/shipping-methods.d.ts +4 -3
  113. package/dist/utils/compute-actions/shipping-methods.d.ts.map +1 -1
  114. package/dist/utils/compute-actions/shipping-methods.js +20 -6
  115. package/dist/utils/compute-actions/shipping-methods.js.map +1 -1
  116. package/dist/utils/compute-actions/sort-by-price.d.ts +4 -0
  117. package/dist/utils/compute-actions/sort-by-price.d.ts.map +1 -0
  118. package/dist/utils/compute-actions/sort-by-price.js +16 -0
  119. package/dist/utils/compute-actions/sort-by-price.js.map +1 -0
  120. package/dist/utils/compute-actions/usage.d.ts +14 -2
  121. package/dist/utils/compute-actions/usage.d.ts.map +1 -1
  122. package/dist/utils/compute-actions/usage.js +27 -2
  123. package/dist/utils/compute-actions/usage.js.map +1 -1
  124. package/dist/utils/index.js +17 -7
  125. package/dist/utils/index.js.map +1 -1
  126. package/dist/utils/validations/application-method.d.ts.map +1 -1
  127. package/dist/utils/validations/application-method.js +15 -0
  128. package/dist/utils/validations/application-method.js.map +1 -1
  129. package/dist/utils/validations/promotion-rule.d.ts +3 -2
  130. package/dist/utils/validations/promotion-rule.d.ts.map +1 -1
  131. package/dist/utils/validations/promotion-rule.js +52 -45
  132. package/dist/utils/validations/promotion-rule.js.map +1 -1
  133. package/package.json +15 -28
@@ -8,123 +8,290 @@ const usage_1 = require("./usage");
8
8
  function sortByPrice(a, b) {
9
9
  return utils_1.MathBN.lt(a.subtotal, b.subtotal) ? 1 : -1;
10
10
  }
11
- /*
12
- Grabs all the items in the context where the rules apply
13
- We then sort by price to prioritize most valuable item
14
- */
15
- function filterItemsByPromotionRules(itemsContext, rules) {
16
- return itemsContext
17
- .filter((item) => (0, validations_1.areRulesValidForContext)(rules || [], item, utils_1.ApplicationMethodTargetType.ITEMS))
18
- .sort(sortByPrice);
19
- }
20
- function getComputedActionsForBuyGet(promotion, itemsContext, methodIdPromoValueMap, eligibleBuyItemMap, eligibleTargetItemMap) {
21
- const computedActions = [];
22
- const minimumBuyQuantity = utils_1.MathBN.convert(promotion.application_method?.buy_rules_min_quantity ?? 0);
23
- const itemsMap = new Map(itemsContext.map((i) => [i.id, i]));
11
+ function isValidPromotionContext(promotion, itemsContext) {
24
12
  if (!itemsContext) {
25
13
  throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `"items" should be present as an array in the context to compute actions`);
26
14
  }
27
- const eligibleBuyItems = filterItemsByPromotionRules(itemsContext, promotion.application_method?.buy_rules);
28
- const eligibleBuyItemQuantity = utils_1.MathBN.sum(...eligibleBuyItems.map((item) => item.quantity));
29
- /*
30
- Get the total quantity of items where buy rules apply. If the total sum of eligible items
31
- does not match up to the minimum buy quantity set on the promotion, return early.
32
- */
33
- if (utils_1.MathBN.gt(minimumBuyQuantity, eligibleBuyItemQuantity)) {
34
- return [];
15
+ if (!itemsContext?.length) {
16
+ return false;
35
17
  }
36
- /*
37
- Eligibility of a BuyGet promotion can span across line items. Once an item has been chosen
38
- as eligible, we can't use this item or its partial remaining quantity when we apply the promotion on
39
- the target item.
18
+ const minimumBuyQuantity = utils_1.MathBN.convert(promotion.application_method?.buy_rules_min_quantity ?? 0);
19
+ if (utils_1.MathBN.lte(minimumBuyQuantity, 0) ||
20
+ !promotion.application_method?.buy_rules?.length) {
21
+ return false;
22
+ }
23
+ return true;
24
+ }
25
+ function normalizePromotionApplicationConfiguration(promotion) {
26
+ const minimumBuyQuantity = utils_1.MathBN.convert(promotion.application_method?.buy_rules_min_quantity ?? 0);
27
+ const targetApplyQuantity = utils_1.MathBN.convert(promotion.application_method?.apply_to_quantity ?? 0);
28
+ const maximumApplyQuantity = utils_1.MathBN.convert(promotion.application_method?.max_quantity ?? 1);
29
+ const applicablePercentage = promotion.application_method?.value ?? 100;
30
+ return {
31
+ minimumBuyQuantity,
32
+ targetApplyQuantity,
33
+ maximumApplyQuantity,
34
+ applicablePercentage,
35
+ };
36
+ }
37
+ function calculateRemainingQuantities(eligibleItems, itemsMap, currentPromotionCode) {
38
+ const remainingQuantities = new Map();
39
+ for (const item of eligibleItems) {
40
+ let consumedByOtherPromotions = utils_1.MathBN.convert(0);
41
+ for (const [code, eligibleItems] of itemsMap) {
42
+ if (code === currentPromotionCode) {
43
+ continue;
44
+ }
45
+ for (const eligibleItem of eligibleItems) {
46
+ if (eligibleItem.item_id === item.id) {
47
+ consumedByOtherPromotions = utils_1.MathBN.add(consumedByOtherPromotions, eligibleItem.quantity);
48
+ }
49
+ }
50
+ }
51
+ const remaining = utils_1.MathBN.sub(item.quantity, consumedByOtherPromotions);
52
+ remainingQuantities.set(item.id, utils_1.MathBN.max(remaining, 0));
53
+ }
54
+ return remainingQuantities;
55
+ }
56
+ /*
57
+ Determines which buy and target items should be used for a promotion application.
40
58
 
41
- We build the map here to use when we apply promotions on the target items.
42
- */
59
+ We run the following steps to prepare the promotion application state to be used within an application loop:
60
+ 1. Selecting enough buy items to satisfy the minimum buy quantity requirement from the remaining buy quantities
61
+ 2. Identifying target eligible items for application (excluding those used in buy rules) from the remaining target quantities
62
+ 3. Ensuring the application doesn't exceed max_quantity limits for the target items
63
+ 4. Returns a valid application state or marks it invalid if requirements can't be met
64
+ */
65
+ function preparePromotionApplicationState(eligibleBuyItems, eligibleTargetItems, remainingBuyQuantities, remainingTargetQuantities, applicationConfig, appliedPromotionQuantity) {
66
+ const totalRemainingBuyQuantity = utils_1.MathBN.sum(...Array.from(remainingBuyQuantities.values()));
67
+ if (utils_1.MathBN.lt(totalRemainingBuyQuantity, applicationConfig.minimumBuyQuantity)) {
68
+ return { buyItems: [], targetItems: [], isValid: false };
69
+ }
70
+ const eligibleItemsByPromotion = [];
71
+ let accumulatedQuantity = utils_1.MathBN.convert(0);
43
72
  for (const eligibleBuyItem of eligibleBuyItems) {
44
- const eligibleItemsByPromotion = eligibleBuyItemMap.get(promotion.code) || [];
45
- const accumulatedQuantity = eligibleItemsByPromotion.reduce((acc, item) => utils_1.MathBN.sum(acc, item.quantity), utils_1.MathBN.convert(0));
46
- // If we have reached the minimum buy quantity from the eligible items for this promotion,
47
- // we can break early and continue to applying the target items
48
- if (utils_1.MathBN.gte(accumulatedQuantity, minimumBuyQuantity)) {
73
+ if (utils_1.MathBN.gte(accumulatedQuantity, applicationConfig.minimumBuyQuantity)) {
49
74
  break;
50
75
  }
51
- const eligibleQuantity = utils_1.MathBN.sum(...eligibleItemsByPromotion
52
- .filter((buy) => buy.item_id === eligibleBuyItem.id)
53
- .map((b) => b.quantity));
54
- const reservableQuantity = utils_1.MathBN.min(eligibleBuyItem.quantity, utils_1.MathBN.sub(minimumBuyQuantity, eligibleQuantity));
55
- // If we have reached the required minimum quantity, we break the loop early
76
+ const availableQuantity = remainingBuyQuantities.get(eligibleBuyItem.id) || utils_1.MathBN.convert(0);
77
+ if (utils_1.MathBN.lte(availableQuantity, 0)) {
78
+ continue;
79
+ }
80
+ const reservableQuantity = utils_1.MathBN.min(availableQuantity, utils_1.MathBN.sub(applicationConfig.minimumBuyQuantity, accumulatedQuantity));
56
81
  if (utils_1.MathBN.lte(reservableQuantity, 0)) {
57
- break;
82
+ continue;
58
83
  }
59
84
  eligibleItemsByPromotion.push({
60
85
  item_id: eligibleBuyItem.id,
61
- quantity: utils_1.MathBN.min(eligibleBuyItem.quantity, reservableQuantity).toNumber(),
86
+ quantity: reservableQuantity.toNumber(),
62
87
  });
63
- eligibleBuyItemMap.set(promotion.code, eligibleItemsByPromotion);
88
+ accumulatedQuantity = utils_1.MathBN.add(accumulatedQuantity, reservableQuantity);
64
89
  }
65
- const eligibleTargetItems = filterItemsByPromotionRules(itemsContext, promotion.application_method?.target_rules);
66
- const targetQuantity = utils_1.MathBN.convert(promotion.application_method?.apply_to_quantity ?? 0);
67
- /*
68
- In this loop, we build a map of eligible target items and quantity applicable to these items.
69
-
70
- Here we remove the quantity we used previously to identify eligible buy items
71
- from the eligible target items.
72
-
73
- This is done to prevent applying promotion to the same item we use to qualify the buy rules.
74
- */
90
+ if (utils_1.MathBN.lt(accumulatedQuantity, applicationConfig.minimumBuyQuantity)) {
91
+ return { buyItems: [], targetItems: [], isValid: false };
92
+ }
93
+ const quantitiesUsedInBuyRules = new Map();
94
+ for (const buyItem of eligibleItemsByPromotion) {
95
+ const currentValue = quantitiesUsedInBuyRules.get(buyItem.item_id) || utils_1.MathBN.convert(0);
96
+ quantitiesUsedInBuyRules.set(buyItem.item_id, utils_1.MathBN.add(currentValue, buyItem.quantity));
97
+ }
98
+ const targetItemsByPromotion = [];
99
+ let availableTargetQuantity = utils_1.MathBN.convert(0);
75
100
  for (const eligibleTargetItem of eligibleTargetItems) {
76
- const inapplicableQuantity = utils_1.MathBN.sum(...Array.from(eligibleBuyItemMap.values())
77
- .flat(1)
78
- .filter((buy) => buy.item_id === eligibleTargetItem.id)
79
- .map((b) => b.quantity));
80
- const applicableQuantity = utils_1.MathBN.sub(eligibleTargetItem.quantity, inapplicableQuantity);
81
- const fulfillableQuantity = utils_1.MathBN.min(targetQuantity, applicableQuantity);
82
- // If we have reached the required quantity to target from this item, we
83
- // move on to the next item
101
+ const availableTargetQuantityForItem = remainingTargetQuantities.get(eligibleTargetItem.id) || utils_1.MathBN.convert(0);
102
+ const quantityUsedInBuyRules = quantitiesUsedInBuyRules.get(eligibleTargetItem.id) || utils_1.MathBN.convert(0);
103
+ const applicableQuantity = utils_1.MathBN.sub(availableTargetQuantityForItem, quantityUsedInBuyRules);
104
+ if (utils_1.MathBN.lte(applicableQuantity, 0)) {
105
+ continue;
106
+ }
107
+ const remainingNeeded = utils_1.MathBN.sub(applicationConfig.targetApplyQuantity, availableTargetQuantity);
108
+ const remainingMaxQuantityAllowance = utils_1.MathBN.sub(applicationConfig.maximumApplyQuantity, appliedPromotionQuantity);
109
+ const fulfillableQuantity = utils_1.MathBN.min(remainingNeeded, applicableQuantity, remainingMaxQuantityAllowance);
84
110
  if (utils_1.MathBN.lte(fulfillableQuantity, 0)) {
85
111
  continue;
86
112
  }
87
- const targetItemsByPromotion = eligibleTargetItemMap.get(promotion.code) || [];
88
113
  targetItemsByPromotion.push({
89
114
  item_id: eligibleTargetItem.id,
90
- quantity: utils_1.MathBN.min(fulfillableQuantity, targetQuantity).toNumber(),
115
+ quantity: fulfillableQuantity.toNumber(),
91
116
  });
92
- eligibleTargetItemMap.set(promotion.code, targetItemsByPromotion);
93
- }
94
- const targetItemsByPromotion = eligibleTargetItemMap.get(promotion.code) || [];
95
- const targettableQuantity = targetItemsByPromotion.reduce((sum, item) => utils_1.MathBN.sum(sum, item.quantity), utils_1.MathBN.convert(0));
96
- // If we were able to match the target requirements across all line items, we return early.
97
- if (utils_1.MathBN.lt(targettableQuantity, targetQuantity)) {
98
- return [];
117
+ availableTargetQuantity = utils_1.MathBN.add(availableTargetQuantity, fulfillableQuantity);
118
+ if (utils_1.MathBN.gte(availableTargetQuantity, applicationConfig.targetApplyQuantity)) {
119
+ break;
120
+ }
99
121
  }
100
- let remainingQtyToApply = utils_1.MathBN.convert(targetQuantity);
101
- for (const targetItem of targetItemsByPromotion) {
122
+ const isValid = utils_1.MathBN.gte(availableTargetQuantity, applicationConfig.targetApplyQuantity);
123
+ return {
124
+ buyItems: eligibleItemsByPromotion,
125
+ targetItems: targetItemsByPromotion,
126
+ isValid,
127
+ };
128
+ }
129
+ /*
130
+ Applies promotion to the target items selected by preparePromotionApplicationState.
131
+
132
+ This function performs the application by:
133
+ 1. Calculating promotion amounts based on item prices and promotion percentage
134
+ 2. Checking promotion budget limits to prevent overspending
135
+ 3. Updating promotional value tracking maps for cross-promotion coordination
136
+ 4. Accumulating total promotion amounts per item across all applications
137
+ 5. Returns computed actions
138
+ */
139
+ function applyPromotionToTargetItems(targetItems, itemIdPromotionAmountMap, methodIdPromoValueMap, promotion, itemsMap, applicationConfig) {
140
+ const computedActions = [];
141
+ let appliedPromotionQuantity = utils_1.MathBN.convert(0);
142
+ let remainingQtyToApply = utils_1.MathBN.convert(applicationConfig.targetApplyQuantity);
143
+ for (const targetItem of targetItems) {
144
+ if (utils_1.MathBN.lte(remainingQtyToApply, 0)) {
145
+ break;
146
+ }
102
147
  const item = itemsMap.get(targetItem.item_id);
103
148
  const appliedPromoValue = methodIdPromoValueMap.get(item.id) ?? utils_1.MathBN.convert(0);
104
149
  const multiplier = utils_1.MathBN.min(targetItem.quantity, remainingQtyToApply);
105
- const applicableAmount = utils_1.MathBN.mult(utils_1.MathBN.div(item.subtotal, item.quantity), multiplier);
106
- const applicablePercentage = promotion.application_method?.value ?? 100;
107
- const amount = utils_1.MathBN.mult(applicableAmount, applicablePercentage).div(100);
108
- const newRemainingQtyToApply = utils_1.MathBN.sub(remainingQtyToApply, multiplier);
109
- if (utils_1.MathBN.lt(newRemainingQtyToApply, 0) || utils_1.MathBN.lte(amount, 0)) {
110
- break;
111
- }
112
- else {
113
- remainingQtyToApply = newRemainingQtyToApply;
150
+ const pricePerUnit = utils_1.MathBN.div(item.subtotal, item.quantity);
151
+ const applicableAmount = utils_1.MathBN.mult(pricePerUnit, multiplier);
152
+ const amount = utils_1.MathBN.mult(applicableAmount, applicationConfig.applicablePercentage).div(100);
153
+ if (utils_1.MathBN.lte(amount, 0)) {
154
+ continue;
114
155
  }
156
+ remainingQtyToApply = utils_1.MathBN.sub(remainingQtyToApply, multiplier);
115
157
  const budgetExceededAction = (0, usage_1.computeActionForBudgetExceeded)(promotion, amount);
116
158
  if (budgetExceededAction) {
117
159
  computedActions.push(budgetExceededAction);
118
160
  continue;
119
161
  }
120
162
  methodIdPromoValueMap.set(item.id, utils_1.MathBN.add(appliedPromoValue, amount).toNumber());
121
- computedActions.push({
122
- action: utils_1.ComputedActions.ADD_ITEM_ADJUSTMENT,
123
- item_id: item.id,
124
- amount,
125
- code: promotion.code,
126
- });
163
+ const currentPromotionAmount = itemIdPromotionAmountMap.get(item.id) ?? utils_1.MathBN.convert(0);
164
+ itemIdPromotionAmountMap.set(item.id, utils_1.MathBN.add(currentPromotionAmount, amount));
165
+ appliedPromotionQuantity = utils_1.MathBN.add(appliedPromotionQuantity, multiplier);
166
+ }
167
+ return { computedActions, appliedPromotionQuantity };
168
+ }
169
+ /*
170
+ Updates the remaining quantities of the eligible items (buy and target) based on the application.
171
+ This is used to prevent double-usage of the same item in the next iteration of the
172
+ application loop.
173
+
174
+ We track the total consumed quantities per item to handle buy+target scenarios of the same item.
175
+ */
176
+ function updateEligibleItemQuantities(remainingBuyQuantities, remainingTargetQuantities, application) {
177
+ const totalConsumedQuantities = new Map();
178
+ for (const buyItem of application.buyItems) {
179
+ const currentConsumed = totalConsumedQuantities.get(buyItem.item_id) || utils_1.MathBN.convert(0);
180
+ totalConsumedQuantities.set(buyItem.item_id, utils_1.MathBN.add(currentConsumed, buyItem.quantity));
181
+ }
182
+ for (const targetItem of application.targetItems) {
183
+ const currentConsumed = totalConsumedQuantities.get(targetItem.item_id) || utils_1.MathBN.convert(0);
184
+ totalConsumedQuantities.set(targetItem.item_id, utils_1.MathBN.add(currentConsumed, targetItem.quantity));
185
+ }
186
+ // Update remaining quantities of buy and target items based on totalConsumedQuantities tracked from previous iterations
187
+ for (const [itemId, consumedQuantity] of totalConsumedQuantities) {
188
+ if (remainingBuyQuantities.has(itemId)) {
189
+ const currentBuyRemaining = remainingBuyQuantities.get(itemId) || utils_1.MathBN.convert(0);
190
+ remainingBuyQuantities.set(itemId, utils_1.MathBN.sub(currentBuyRemaining, consumedQuantity));
191
+ }
192
+ if (remainingTargetQuantities.has(itemId)) {
193
+ const currentTargetRemaining = remainingTargetQuantities.get(itemId) || utils_1.MathBN.convert(0);
194
+ remainingTargetQuantities.set(itemId, utils_1.MathBN.sub(currentTargetRemaining, consumedQuantity));
195
+ }
196
+ }
197
+ }
198
+ function updateEligibleItems(totalEligibleItemsMap, applicationItems) {
199
+ for (const item of applicationItems) {
200
+ const existingItem = totalEligibleItemsMap.get(item.item_id);
201
+ // If the item already exists, we add the quantity to the existing item
202
+ if (existingItem) {
203
+ existingItem.quantity = utils_1.MathBN.add(existingItem.quantity, item.quantity).toNumber();
204
+ }
205
+ else {
206
+ totalEligibleItemsMap.set(item.item_id, { ...item });
207
+ }
208
+ }
209
+ }
210
+ function createComputedActionsFromPromotionApplication(itemIdPromotionAmountMap, promotionCode) {
211
+ const computedActions = [];
212
+ for (const [itemId, totalAmount] of itemIdPromotionAmountMap) {
213
+ if (utils_1.MathBN.gt(totalAmount, 0)) {
214
+ computedActions.push({
215
+ action: utils_1.ComputedActions.ADD_ITEM_ADJUSTMENT,
216
+ item_id: itemId,
217
+ amount: totalAmount,
218
+ code: promotionCode,
219
+ });
220
+ }
221
+ }
222
+ return computedActions;
223
+ }
224
+ /*
225
+ Grabs all the items in the context where the rules apply
226
+ We then sort by price to prioritize most valuable item
227
+ */
228
+ function filterItemsByPromotionRules(itemsContext, rules) {
229
+ return itemsContext
230
+ .filter((item) => (0, validations_1.areRulesValidForContext)(rules || [], item, utils_1.ApplicationMethodTargetType.ITEMS))
231
+ .sort(sortByPrice);
232
+ }
233
+ function getComputedActionsForBuyGet(promotion, itemsContext, methodIdPromoValueMap, eligibleBuyItemMap, eligibleTargetItemMap) {
234
+ if (!isValidPromotionContext(promotion, itemsContext)) {
235
+ return [];
236
+ }
237
+ const applicationConfig = normalizePromotionApplicationConfiguration(promotion);
238
+ const itemsMap = new Map(itemsContext.map((i) => [i.id, i]));
239
+ const eligibleBuyItems = filterItemsByPromotionRules(itemsContext, promotion.application_method?.buy_rules);
240
+ const eligibleTargetItems = filterItemsByPromotionRules(itemsContext, promotion.application_method?.target_rules);
241
+ const remainingBuyQuantities = calculateRemainingQuantities(eligibleBuyItems, eligibleBuyItemMap, promotion.code);
242
+ const remainingTargetQuantities = calculateRemainingQuantities(eligibleTargetItems, eligibleTargetItemMap, promotion.code);
243
+ const totalEligibleBuyItemsMap = new Map();
244
+ const totalEligibleTargetItemsMap = new Map();
245
+ const itemIdPromotionAmountMap = new Map();
246
+ const computedActions = [];
247
+ const MAX_PROMOTION_ITERATIONS = 1000;
248
+ let iterationCount = 0;
249
+ let appliedPromotionQuantity = utils_1.MathBN.convert(0);
250
+ /*
251
+ This loop continues applying the promotion until one of the stopping conditions is met:
252
+ - No more items satisfy the minimum buy quantity requirement
253
+ - Maximum applicable promotion quantity is reached
254
+ - No valid target items can be found for promotion application
255
+ - Maximum iteration count is reached (safety check)
256
+
257
+ Each iteration:
258
+ 1. Prepares an application state (selects buy items + eligible target items)
259
+ 2. Applies promotion to the selected target items
260
+ 3. Updates remaining quantities to prevent double-usage in next iteration
261
+ 4. Updates the total eligible items for next iteration
262
+ */
263
+ while (true) {
264
+ iterationCount++;
265
+ if (iterationCount > MAX_PROMOTION_ITERATIONS) {
266
+ console.warn(`Buy-get promotion ${promotion.code} exceeded maximum iterations (${MAX_PROMOTION_ITERATIONS}). Breaking loop to prevent infinite execution.`);
267
+ break;
268
+ }
269
+ // We prepare an application state for the promotion to be applied on all eligible items
270
+ // We use this as a source of truth to update the remaining quantities of the eligible items
271
+ // and the total eligible items
272
+ const applicationState = preparePromotionApplicationState(eligibleBuyItems, eligibleTargetItems, remainingBuyQuantities, remainingTargetQuantities, applicationConfig, appliedPromotionQuantity);
273
+ // If the application state is not valid, we break the loop
274
+ // If it is not valid, it means that there are no more eligible items to apply the promotion to
275
+ // for the configuration of the promotion
276
+ if (!applicationState.isValid) {
277
+ break;
278
+ }
279
+ // We apply the promotion to the target items based on the target items that are eligible
280
+ // and the remaining quantities of the target items
281
+ const application = applyPromotionToTargetItems(applicationState.targetItems, itemIdPromotionAmountMap, methodIdPromoValueMap, promotion, itemsMap, applicationConfig);
282
+ computedActions.push(...application.computedActions);
283
+ // Computed actions being generated means that the promotion is applied.
284
+ // We now need to update the remaining quantities of the eligible items and the total eligible items
285
+ // to be used in the next iteration of the loop
286
+ appliedPromotionQuantity = utils_1.MathBN.add(appliedPromotionQuantity, application.appliedPromotionQuantity);
287
+ updateEligibleItemQuantities(remainingBuyQuantities, remainingTargetQuantities, applicationState);
288
+ updateEligibleItems(totalEligibleBuyItemsMap, applicationState.buyItems);
289
+ updateEligibleItems(totalEligibleTargetItemsMap, applicationState.targetItems);
127
290
  }
291
+ const finalActions = createComputedActionsFromPromotionApplication(itemIdPromotionAmountMap, promotion.code);
292
+ computedActions.push(...finalActions);
293
+ eligibleBuyItemMap.set(promotion.code, Array.from(totalEligibleBuyItemsMap.values()));
294
+ eligibleTargetItemMap.set(promotion.code, Array.from(totalEligibleTargetItemsMap.values()));
128
295
  return computedActions;
129
296
  }
130
297
  function sortByBuyGetType(a, b) {
@@ -1 +1 @@
1
- {"version":3,"file":"buy-get.js","sourceRoot":"","sources":["../../../src/utils/compute-actions/buy-get.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"buy-get.js","sourceRoot":"","sources":["../../../src/utils/compute-actions/buy-get.ts"],"names":[],"mappings":";;AA2cA,kEA6IC;AAED,4CAmDC;AAvoBD,qDAMkC;AAClC,gDAAwD;AACxD,mCAAwD;AAQxD,SAAS,WAAW,CAAC,CAAwB,EAAE,CAAwB;IACrE,OAAO,cAAM,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AACnD,CAAC;AAED,SAAS,uBAAuB,CAC9B,SAA0E,EAC1E,YAAqC;IAErC,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,mBAAW,CACnB,mBAAW,CAAC,KAAK,CAAC,YAAY,EAC9B,yEAAyE,CAC1E,CAAA;IACH,CAAC;IAED,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,kBAAkB,GAAG,cAAM,CAAC,OAAO,CACvC,SAAS,CAAC,kBAAkB,EAAE,sBAAsB,IAAI,CAAC,CAC1D,CAAA;IAED,IACE,cAAM,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC,CAAC;QACjC,CAAC,SAAS,CAAC,kBAAkB,EAAE,SAAS,EAAE,MAAM,EAChD,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,0CAA0C,CACjD,SAA0E;IAE1E,MAAM,kBAAkB,GAAG,cAAM,CAAC,OAAO,CACvC,SAAS,CAAC,kBAAkB,EAAE,sBAAsB,IAAI,CAAC,CAC1D,CAAA;IACD,MAAM,mBAAmB,GAAG,cAAM,CAAC,OAAO,CACxC,SAAS,CAAC,kBAAkB,EAAE,iBAAiB,IAAI,CAAC,CACrD,CAAA;IACD,MAAM,oBAAoB,GAAG,cAAM,CAAC,OAAO,CACzC,SAAS,CAAC,kBAAkB,EAAE,YAAY,IAAI,CAAC,CAChD,CAAA;IACD,MAAM,oBAAoB,GAAG,SAAS,CAAC,kBAAkB,EAAE,KAAK,IAAI,GAAG,CAAA;IAEvE,OAAO;QACL,kBAAkB;QAClB,mBAAmB;QACnB,oBAAoB;QACpB,oBAAoB;KACrB,CAAA;AACH,CAAC;AAED,SAAS,4BAA4B,CACnC,aAAsC,EACtC,QAAqC,EACrC,oBAA4B;IAE5B,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAA0B,CAAA;IAE7D,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;QACjC,IAAI,yBAAyB,GAAG,cAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QAEjD,KAAK,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC,IAAI,QAAQ,EAAE,CAAC;YAC7C,IAAI,IAAI,KAAK,oBAAoB,EAAE,CAAC;gBAClC,SAAQ;YACV,CAAC;YAED,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;gBACzC,IAAI,YAAY,CAAC,OAAO,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;oBACrC,yBAAyB,GAAG,cAAM,CAAC,GAAG,CACpC,yBAAyB,EACzB,YAAY,CAAC,QAAQ,CACtB,CAAA;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,SAAS,GAAG,cAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,yBAAyB,CAAC,CAAA;QACtE,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,cAAM,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAA;IAC5D,CAAC;IAED,OAAO,mBAAmB,CAAA;AAC5B,CAAC;AAeD;;;;;;;;EAQE;AACF,SAAS,gCAAgC,CACvC,gBAAyC,EACzC,mBAA4C,EAC5C,sBAAmD,EACnD,yBAAsD,EACtD,iBAAkC,EAClC,wBAAwC;IAExC,MAAM,yBAAyB,GAAG,cAAM,CAAC,GAAG,CAC1C,GAAG,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,CAAC,CAC/C,CAAA;IAED,IACE,cAAM,CAAC,EAAE,CAAC,yBAAyB,EAAE,iBAAiB,CAAC,kBAAkB,CAAC,EAC1E,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;IAC1D,CAAC;IAED,MAAM,wBAAwB,GAAmB,EAAE,CAAA;IACnD,IAAI,mBAAmB,GAAG,cAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IAE3C,KAAK,MAAM,eAAe,IAAI,gBAAgB,EAAE,CAAC;QAC/C,IAAI,cAAM,CAAC,GAAG,CAAC,mBAAmB,EAAE,iBAAiB,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAC1E,MAAK;QACP,CAAC;QAED,MAAM,iBAAiB,GACrB,sBAAsB,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC,IAAI,cAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QAErE,IAAI,cAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC,EAAE,CAAC;YACrC,SAAQ;QACV,CAAC;QAED,MAAM,kBAAkB,GAAG,cAAM,CAAC,GAAG,CACnC,iBAAiB,EACjB,cAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,kBAAkB,EAAE,mBAAmB,CAAC,CACtE,CAAA;QAED,IAAI,cAAM,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC,CAAC,EAAE,CAAC;YACtC,SAAQ;QACV,CAAC;QAED,wBAAwB,CAAC,IAAI,CAAC;YAC5B,OAAO,EAAE,eAAe,CAAC,EAAE;YAC3B,QAAQ,EAAE,kBAAkB,CAAC,QAAQ,EAAE;SACxC,CAAC,CAAA;QAEF,mBAAmB,GAAG,cAAM,CAAC,GAAG,CAAC,mBAAmB,EAAE,kBAAkB,CAAC,CAAA;IAC3E,CAAC;IAED,IAAI,cAAM,CAAC,EAAE,CAAC,mBAAmB,EAAE,iBAAiB,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACzE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;IAC1D,CAAC;IAED,MAAM,wBAAwB,GAAG,IAAI,GAAG,EAA0B,CAAA;IAElE,KAAK,MAAM,OAAO,IAAI,wBAAwB,EAAE,CAAC;QAC/C,MAAM,YAAY,GAChB,wBAAwB,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,cAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QAEpE,wBAAwB,CAAC,GAAG,CAC1B,OAAO,CAAC,OAAO,EACf,cAAM,CAAC,GAAG,CAAC,YAAY,EAAE,OAAO,CAAC,QAAQ,CAAC,CAC3C,CAAA;IACH,CAAC;IAED,MAAM,sBAAsB,GAAmB,EAAE,CAAA;IACjD,IAAI,uBAAuB,GAAG,cAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IAE/C,KAAK,MAAM,kBAAkB,IAAI,mBAAmB,EAAE,CAAC;QACrD,MAAM,8BAA8B,GAClC,yBAAyB,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAAE,CAAC,IAAI,cAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QAE3E,MAAM,sBAAsB,GAC1B,wBAAwB,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAAE,CAAC,IAAI,cAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QAE1E,MAAM,kBAAkB,GAAG,cAAM,CAAC,GAAG,CACnC,8BAA8B,EAC9B,sBAAsB,CACvB,CAAA;QAED,IAAI,cAAM,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC,CAAC,EAAE,CAAC;YACtC,SAAQ;QACV,CAAC;QAED,MAAM,eAAe,GAAG,cAAM,CAAC,GAAG,CAChC,iBAAiB,CAAC,mBAAmB,EACrC,uBAAuB,CACxB,CAAA;QAED,MAAM,6BAA6B,GAAG,cAAM,CAAC,GAAG,CAC9C,iBAAiB,CAAC,oBAAoB,EACtC,wBAAwB,CACzB,CAAA;QAED,MAAM,mBAAmB,GAAG,cAAM,CAAC,GAAG,CACpC,eAAe,EACf,kBAAkB,EAClB,6BAA6B,CAC9B,CAAA;QAED,IAAI,cAAM,CAAC,GAAG,CAAC,mBAAmB,EAAE,CAAC,CAAC,EAAE,CAAC;YACvC,SAAQ;QACV,CAAC;QAED,sBAAsB,CAAC,IAAI,CAAC;YAC1B,OAAO,EAAE,kBAAkB,CAAC,EAAE;YAC9B,QAAQ,EAAE,mBAAmB,CAAC,QAAQ,EAAE;SACzC,CAAC,CAAA;QAEF,uBAAuB,GAAG,cAAM,CAAC,GAAG,CAClC,uBAAuB,EACvB,mBAAmB,CACpB,CAAA;QAED,IACE,cAAM,CAAC,GAAG,CAAC,uBAAuB,EAAE,iBAAiB,CAAC,mBAAmB,CAAC,EAC1E,CAAC;YACD,MAAK;QACP,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,cAAM,CAAC,GAAG,CACxB,uBAAuB,EACvB,iBAAiB,CAAC,mBAAmB,CACtC,CAAA;IAED,OAAO;QACL,QAAQ,EAAE,wBAAwB;QAClC,WAAW,EAAE,sBAAsB;QACnC,OAAO;KACR,CAAA;AACH,CAAC;AAED;;;;;;;;;EASE;AACF,SAAS,2BAA2B,CAClC,WAA2B,EAC3B,wBAAqD,EACrD,qBAAkD,EAClD,SAA0E,EAC1E,QAA4C,EAC5C,iBAAkC;IAKlC,MAAM,eAAe,GAAoC,EAAE,CAAA;IAC3D,IAAI,wBAAwB,GAAG,cAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IAChD,IAAI,mBAAmB,GAAG,cAAM,CAAC,OAAO,CACtC,iBAAiB,CAAC,mBAAmB,CACtC,CAAA;IAED,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,IAAI,cAAM,CAAC,GAAG,CAAC,mBAAmB,EAAE,CAAC,CAAC,EAAE,CAAC;YACvC,MAAK;QACP,CAAC;QAED,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAE,CAAA;QAC9C,MAAM,iBAAiB,GACrB,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,cAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QACzD,MAAM,UAAU,GAAG,cAAM,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAA;QACvE,MAAM,YAAY,GAAG,cAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAA;QAC7D,MAAM,gBAAgB,GAAG,cAAM,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;QAC9D,MAAM,MAAM,GAAG,cAAM,CAAC,IAAI,CACxB,gBAAgB,EAChB,iBAAiB,CAAC,oBAAoB,CACvC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QAEV,IAAI,cAAM,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC;YAC1B,SAAQ;QACV,CAAC;QAED,mBAAmB,GAAG,cAAM,CAAC,GAAG,CAAC,mBAAmB,EAAE,UAAU,CAAC,CAAA;QAEjE,MAAM,oBAAoB,GAAG,IAAA,sCAA8B,EACzD,SAAS,EACT,MAAM,CACP,CAAA;QAED,IAAI,oBAAoB,EAAE,CAAC;YACzB,eAAe,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAA;YAC1C,SAAQ;QACV,CAAC;QAED,qBAAqB,CAAC,GAAG,CACvB,IAAI,CAAC,EAAE,EACP,cAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,QAAQ,EAAE,CACjD,CAAA;QAED,MAAM,sBAAsB,GAC1B,wBAAwB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,cAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QAE5D,wBAAwB,CAAC,GAAG,CAC1B,IAAI,CAAC,EAAE,EACP,cAAM,CAAC,GAAG,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAC3C,CAAA;QAED,wBAAwB,GAAG,cAAM,CAAC,GAAG,CAAC,wBAAwB,EAAE,UAAU,CAAC,CAAA;IAC7E,CAAC;IAED,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,CAAA;AACtD,CAAC;AAED;;;;;;EAME;AACF,SAAS,4BAA4B,CACnC,sBAAmD,EACnD,yBAAsD,EACtD,WAAiC;IAEjC,MAAM,uBAAuB,GAAG,IAAI,GAAG,EAA0B,CAAA;IAEjE,KAAK,MAAM,OAAO,IAAI,WAAW,CAAC,QAAQ,EAAE,CAAC;QAC3C,MAAM,eAAe,GACnB,uBAAuB,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,cAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QAEnE,uBAAuB,CAAC,GAAG,CACzB,OAAO,CAAC,OAAO,EACf,cAAM,CAAC,GAAG,CAAC,eAAe,EAAE,OAAO,CAAC,QAAQ,CAAC,CAC9C,CAAA;IACH,CAAC;IAED,KAAK,MAAM,UAAU,IAAI,WAAW,CAAC,WAAW,EAAE,CAAC;QACjD,MAAM,eAAe,GACnB,uBAAuB,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,cAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QAEtE,uBAAuB,CAAC,GAAG,CACzB,UAAU,CAAC,OAAO,EAClB,cAAM,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,CAAC,QAAQ,CAAC,CACjD,CAAA;IACH,CAAC;IAED,wHAAwH;IACxH,KAAK,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,IAAI,uBAAuB,EAAE,CAAC;QACjE,IAAI,sBAAsB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACvC,MAAM,mBAAmB,GACvB,sBAAsB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,cAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;YAEzD,sBAAsB,CAAC,GAAG,CACxB,MAAM,EACN,cAAM,CAAC,GAAG,CAAC,mBAAmB,EAAE,gBAAgB,CAAC,CAClD,CAAA;QACH,CAAC;QAED,IAAI,yBAAyB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1C,MAAM,sBAAsB,GAC1B,yBAAyB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,cAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;YAE5D,yBAAyB,CAAC,GAAG,CAC3B,MAAM,EACN,cAAM,CAAC,GAAG,CAAC,sBAAsB,EAAE,gBAAgB,CAAC,CACrD,CAAA;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAC1B,qBAAgD,EAChD,gBAAgC;IAEhC,KAAK,MAAM,IAAI,IAAI,gBAAgB,EAAE,CAAC;QACpC,MAAM,YAAY,GAAG,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAE5D,uEAAuE;QACvE,IAAI,YAAY,EAAE,CAAC;YACjB,YAAY,CAAC,QAAQ,GAAG,cAAM,CAAC,GAAG,CAChC,YAAY,CAAC,QAAQ,EACrB,IAAI,CAAC,QAAQ,CACd,CAAC,QAAQ,EAAE,CAAA;QACd,CAAC;aAAM,CAAC;YACN,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,IAAI,EAAE,CAAC,CAAA;QACtD,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,6CAA6C,CACpD,wBAAqD,EACrD,aAAqB;IAErB,MAAM,eAAe,GAAoC,EAAE,CAAA;IAE3D,KAAK,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,IAAI,wBAAwB,EAAE,CAAC;QAC7D,IAAI,cAAM,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC;YAC9B,eAAe,CAAC,IAAI,CAAC;gBACnB,MAAM,EAAE,uBAAe,CAAC,mBAAmB;gBAC3C,OAAO,EAAE,MAAM;gBACf,MAAM,EAAE,WAAW;gBACnB,IAAI,EAAE,aAAa;aACpB,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,OAAO,eAAe,CAAA;AACxB,CAAC;AAED;;;EAGE;AACF,SAAS,2BAA2B,CAClC,YAAqC,EACrC,KAAyC;IAEzC,OAAO,YAAY;SAChB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CACf,IAAA,qCAAuB,EACrB,KAAK,IAAI,EAAE,EACX,IAAI,EACJ,mCAA2B,CAAC,KAAK,CAClC,CACF;SACA,IAAI,CAAC,WAAW,CAAC,CAAA;AACtB,CAAC;AAED,SAAgB,2BAA2B,CACzC,SAA0E,EAC1E,YAAqC,EACrC,qBAAkD,EAClD,kBAA+C,EAC/C,qBAAkD;IAElD,IAAI,CAAC,uBAAuB,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,CAAC;QACtD,OAAO,EAAE,CAAA;IACX,CAAC;IAED,MAAM,iBAAiB,GACrB,0CAA0C,CAAC,SAAS,CAAC,CAAA;IAEvD,MAAM,QAAQ,GAAG,IAAI,GAAG,CACtB,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CACnC,CAAA;IAED,MAAM,gBAAgB,GAAG,2BAA2B,CAClD,YAAY,EACZ,SAAS,CAAC,kBAAkB,EAAE,SAAS,CACxC,CAAA;IAED,MAAM,mBAAmB,GAAG,2BAA2B,CACrD,YAAY,EACZ,SAAS,CAAC,kBAAkB,EAAE,YAAY,CAC3C,CAAA;IAED,MAAM,sBAAsB,GAAG,4BAA4B,CACzD,gBAAgB,EAChB,kBAAkB,EAClB,SAAS,CAAC,IAAK,CAChB,CAAA;IAED,MAAM,yBAAyB,GAAG,4BAA4B,CAC5D,mBAAmB,EACnB,qBAAqB,EACrB,SAAS,CAAC,IAAK,CAChB,CAAA;IAED,MAAM,wBAAwB,GAAG,IAAI,GAAG,EAAwB,CAAA;IAChE,MAAM,2BAA2B,GAAG,IAAI,GAAG,EAAwB,CAAA;IACnE,MAAM,wBAAwB,GAAG,IAAI,GAAG,EAA0B,CAAA;IAClE,MAAM,eAAe,GAAoC,EAAE,CAAA;IAE3D,MAAM,wBAAwB,GAAG,IAAI,CAAA;IACrC,IAAI,cAAc,GAAG,CAAC,CAAA;IACtB,IAAI,wBAAwB,GAAG,cAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IAEhD;;;;;;;;;;;;MAYE;IACF,OAAO,IAAI,EAAE,CAAC;QACZ,cAAc,EAAE,CAAA;QAEhB,IAAI,cAAc,GAAG,wBAAwB,EAAE,CAAC;YAC9C,OAAO,CAAC,IAAI,CACV,qBAAqB,SAAS,CAAC,IAAI,iCAAiC,wBAAwB,iDAAiD,CAC9I,CAAA;YAED,MAAK;QACP,CAAC;QACD,wFAAwF;QACxF,4FAA4F;QAC5F,+BAA+B;QAC/B,MAAM,gBAAgB,GAAG,gCAAgC,CACvD,gBAAgB,EAChB,mBAAmB,EACnB,sBAAsB,EACtB,yBAAyB,EACzB,iBAAiB,EACjB,wBAAwB,CACzB,CAAA;QAED,2DAA2D;QAC3D,+FAA+F;QAC/F,yCAAyC;QACzC,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC;YAC9B,MAAK;QACP,CAAC;QAED,yFAAyF;QACzF,mDAAmD;QACnD,MAAM,WAAW,GAAG,2BAA2B,CAC7C,gBAAgB,CAAC,WAAW,EAC5B,wBAAwB,EACxB,qBAAqB,EACrB,SAAS,EACT,QAAQ,EACR,iBAAiB,CAClB,CAAA;QAED,eAAe,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,eAAe,CAAC,CAAA;QAEpD,wEAAwE;QACxE,oGAAoG;QACpG,+CAA+C;QAC/C,wBAAwB,GAAG,cAAM,CAAC,GAAG,CACnC,wBAAwB,EACxB,WAAW,CAAC,wBAAwB,CACrC,CAAA;QAED,4BAA4B,CAC1B,sBAAsB,EACtB,yBAAyB,EACzB,gBAAgB,CACjB,CAAA;QAED,mBAAmB,CAAC,wBAAwB,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAA;QACxE,mBAAmB,CACjB,2BAA2B,EAC3B,gBAAgB,CAAC,WAAW,CAC7B,CAAA;IACH,CAAC;IAED,MAAM,YAAY,GAAG,6CAA6C,CAChE,wBAAwB,EACxB,SAAS,CAAC,IAAK,CAChB,CAAA;IACD,eAAe,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,CAAA;IAErC,kBAAkB,CAAC,GAAG,CACpB,SAAS,CAAC,IAAK,EACf,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,MAAM,EAAE,CAAC,CAC9C,CAAA;IACD,qBAAqB,CAAC,GAAG,CACvB,SAAS,CAAC,IAAK,EACf,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,MAAM,EAAE,CAAC,CACjD,CAAA;IAED,OAAO,eAAe,CAAA;AACxB,CAAC;AAED,SAAgB,gBAAgB,CAAC,CAAC,EAAE,CAAC;IACnC,IAAI,CAAC,CAAC,IAAI,KAAK,qBAAa,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,qBAAa,CAAC,MAAM,EAAE,CAAC;QACvE,OAAO,CAAC,CAAC,CAAA,CAAC,+BAA+B;IAC3C,CAAC;SAAM,IACL,CAAC,CAAC,IAAI,KAAK,qBAAa,CAAC,MAAM;QAC/B,CAAC,CAAC,IAAI,KAAK,qBAAa,CAAC,MAAM,EAC/B,CAAC;QACD,OAAO,CAAC,CAAA,CAAC,+BAA+B;IAC1C,CAAC;SAAM,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7B,gGAAgG;QAChG,IAAI,CAAC,CAAC,kBAAkB,CAAC,KAAK,GAAG,CAAC,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC;YAC5D,OAAO,CAAC,CAAA,CAAC,2BAA2B;QACtC,CAAC;aAAM,IAAI,CAAC,CAAC,kBAAkB,CAAC,KAAK,GAAG,CAAC,CAAC,kBAAkB,CAAC,KAAK,EAAE,CAAC;YACnE,OAAO,CAAC,CAAC,CAAA,CAAC,0BAA0B;QACtC,CAAC;QAED;;;;UAIE;QACF,IAAI,CAAC,CAAC,IAAI,KAAK,qBAAa,CAAC,MAAM,EAAE,CAAC;YACpC,IACE,CAAC,CAAC,kBAAkB,CAAC,sBAAsB;gBAC3C,CAAC,CAAC,kBAAkB,CAAC,sBAAsB,EAC3C,CAAC;gBACD,OAAO,CAAC,CAAA;YACV,CAAC;iBAAM,IACL,CAAC,CAAC,kBAAkB,CAAC,sBAAsB;gBAC3C,CAAC,CAAC,kBAAkB,CAAC,sBAAsB,EAC3C,CAAC;gBACD,OAAO,CAAC,CAAC,CAAA;YACX,CAAC;YAED,IACE,CAAC,CAAC,kBAAkB,CAAC,iBAAiB;gBACtC,CAAC,CAAC,kBAAkB,CAAC,iBAAiB,EACtC,CAAC;gBACD,OAAO,CAAC,CAAA;YACV,CAAC;iBAAM,IACL,CAAC,CAAC,kBAAkB,CAAC,iBAAiB;gBACtC,CAAC,CAAC,kBAAkB,CAAC,iBAAiB,EACtC,CAAC;gBACD,OAAO,CAAC,CAAC,CAAA;YACX,CAAC;QACH,CAAC;QAED,OAAO,CAAC,CAAA,CAAC,iDAAiD;IAC5D,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,CAAA,CAAC,+DAA+D;IAC1E,CAAC;AACH,CAAC"}
@@ -1,4 +1,5 @@
1
1
  export * from "./buy-get";
2
2
  export * from "./line-items";
3
+ export * from "./shipping-methods";
3
4
  export * from "./usage";
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/compute-actions/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,cAAc,cAAc,CAAA;AAC5B,cAAc,SAAS,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/compute-actions/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,cAAc,cAAc,CAAA;AAC5B,cAAc,oBAAoB,CAAA;AAClC,cAAc,SAAS,CAAA"}
@@ -16,5 +16,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./buy-get"), exports);
18
18
  __exportStar(require("./line-items"), exports);
19
+ __exportStar(require("./shipping-methods"), exports);
19
20
  __exportStar(require("./usage"), exports);
20
21
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/compute-actions/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4CAAyB;AACzB,+CAA4B;AAC5B,0CAAuB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/compute-actions/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4CAAyB;AACzB,+CAA4B;AAC5B,qDAAkC;AAClC,0CAAuB"}
@@ -1,6 +1,5 @@
1
- import { ApplicationMethodAllocationValues, PromotionTypes } from "@medusajs/framework/types";
1
+ import { ApplicationMethodAllocationValues, InferEntityType, PromotionTypes } from "@medusajs/framework/types";
2
2
  import { ApplicationMethodTargetType as TargetType } from "@medusajs/framework/utils";
3
- export declare function getComputedActionsForItems(promotion: PromotionTypes.PromotionDTO, items: PromotionTypes.ComputeActionContext[TargetType.ITEMS], appliedPromotionsMap: Map<string, number>, allocationOverride?: ApplicationMethodAllocationValues): PromotionTypes.ComputeActions[];
4
- export declare function getComputedActionsForShippingMethods(promotion: PromotionTypes.PromotionDTO, shippingMethods: PromotionTypes.ComputeActionContext[TargetType.SHIPPING_METHODS], appliedPromotionsMap: Map<string, number>): PromotionTypes.ComputeActions[];
5
- export declare function getComputedActionsForOrder(promotion: PromotionTypes.PromotionDTO, itemApplicationContext: PromotionTypes.ComputeActionContext, methodIdPromoValueMap: Map<string, number>): PromotionTypes.ComputeActions[];
3
+ import { Promotion } from "../../models";
4
+ export declare function getComputedActionsForItems(promotion: PromotionTypes.PromotionDTO | InferEntityType<typeof Promotion>, items: PromotionTypes.ComputeActionContext[TargetType.ITEMS], appliedPromotionsMap: Map<string, number>, allocationOverride?: ApplicationMethodAllocationValues): PromotionTypes.ComputeActions[];
6
5
  //# sourceMappingURL=line-items.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"line-items.d.ts","sourceRoot":"","sources":["../../../src/utils/compute-actions/line-items.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,EAEjC,cAAc,EACf,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAML,2BAA2B,IAAI,UAAU,EAE1C,MAAM,2BAA2B,CAAA;AAgBlC,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,cAAc,CAAC,YAAY,EACtC,KAAK,EAAE,cAAc,CAAC,oBAAoB,CAAC,UAAU,CAAC,KAAK,CAAC,EAC5D,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACzC,kBAAkB,CAAC,EAAE,iCAAiC,GACrD,cAAc,CAAC,cAAc,EAAE,CASjC;AAED,wBAAgB,oCAAoC,CAClD,SAAS,EAAE,cAAc,CAAC,YAAY,EACtC,eAAe,EAAE,cAAc,CAAC,oBAAoB,CAAC,UAAU,CAAC,gBAAgB,CAAC,EACjF,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACxC,cAAc,CAAC,cAAc,EAAE,CAIjC;AAED,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,cAAc,CAAC,YAAY,EACtC,sBAAsB,EAAE,cAAc,CAAC,oBAAoB,EAC3D,qBAAqB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACzC,cAAc,CAAC,cAAc,EAAE,CAOjC"}
1
+ {"version":3,"file":"line-items.d.ts","sourceRoot":"","sources":["../../../src/utils/compute-actions/line-items.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,EAEjC,eAAe,EACf,cAAc,EACf,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAOL,2BAA2B,IAAI,UAAU,EAC1C,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAiBnC,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,cAAc,CAAC,YAAY,GAAG,eAAe,CAAC,OAAO,SAAS,CAAC,EAC1E,KAAK,EAAE,cAAc,CAAC,oBAAoB,CAAC,UAAU,CAAC,KAAK,CAAC,EAC5D,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACzC,kBAAkB,CAAC,EAAE,iCAAiC,GACrD,cAAc,CAAC,cAAc,EAAE,CASjC"}
@@ -1,10 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getComputedActionsForItems = getComputedActionsForItems;
4
- exports.getComputedActionsForShippingMethods = getComputedActionsForShippingMethods;
5
- exports.getComputedActionsForOrder = getComputedActionsForOrder;
6
4
  const utils_1 = require("@medusajs/framework/utils");
7
5
  const validations_1 = require("../validations");
6
+ const sort_by_price_1 = require("./sort-by-price");
8
7
  const usage_1 = require("./usage");
9
8
  function validateContext(contextKey, context) {
10
9
  if (!context) {
@@ -15,41 +14,60 @@ function getComputedActionsForItems(promotion, items, appliedPromotionsMap, allo
15
14
  validateContext("items", items);
16
15
  return applyPromotionToItems(promotion, items, appliedPromotionsMap, allocationOverride);
17
16
  }
18
- function getComputedActionsForShippingMethods(promotion, shippingMethods, appliedPromotionsMap) {
19
- validateContext("shipping_methods", shippingMethods);
20
- return applyPromotionToItems(promotion, shippingMethods, appliedPromotionsMap);
21
- }
22
- function getComputedActionsForOrder(promotion, itemApplicationContext, methodIdPromoValueMap) {
23
- return getComputedActionsForItems(promotion, itemApplicationContext[utils_1.ApplicationMethodTargetType.ITEMS], methodIdPromoValueMap, utils_1.ApplicationMethodAllocation.ACROSS);
24
- }
25
17
  function applyPromotionToItems(promotion, items, appliedPromotionsMap, allocationOverride) {
26
18
  const { application_method: applicationMethod } = promotion;
19
+ if (!applicationMethod) {
20
+ return [];
21
+ }
27
22
  const allocation = applicationMethod?.allocation || allocationOverride;
28
- const computedActions = [];
29
- const applicableItems = getValidItemsForPromotion(items, promotion);
30
23
  const target = applicationMethod?.target_type;
31
- const isTargetShippingMethod = target === utils_1.ApplicationMethodTargetType.SHIPPING_METHODS;
24
+ if (!items?.length || !target) {
25
+ return [];
26
+ }
27
+ const computedActions = [];
28
+ let applicableItems = getValidItemsForPromotion(items, promotion);
29
+ if (!applicableItems.length) {
30
+ return computedActions;
31
+ }
32
+ if (allocation === utils_1.ApplicationMethodAllocation.ONCE) {
33
+ applicableItems = applicableItems.sort(sort_by_price_1.sortLineItemByPriceAscending);
34
+ }
32
35
  const isTargetLineItems = target === utils_1.ApplicationMethodTargetType.ITEMS;
33
36
  const isTargetOrder = target === utils_1.ApplicationMethodTargetType.ORDER;
34
- let lineItemsTotal = utils_1.MathBN.convert(0);
37
+ const promotionValue = applicationMethod?.value ?? 0;
38
+ const maxQuantity = applicationMethod?.max_quantity;
39
+ let remainingQuota = maxQuantity ?? 0;
40
+ let lineItemsAmount = utils_1.MathBN.convert(0);
35
41
  if (allocation === utils_1.ApplicationMethodAllocation.ACROSS) {
36
- lineItemsTotal = applicableItems.reduce((acc, item) => utils_1.MathBN.sub(utils_1.MathBN.add(acc, item.subtotal), appliedPromotionsMap.get(item.id) ?? 0), utils_1.MathBN.convert(0));
42
+ lineItemsAmount = applicableItems.reduce((acc, item) => utils_1.MathBN.sub(utils_1.MathBN.add(acc, promotion.is_tax_inclusive ? item.original_total : item.subtotal), appliedPromotionsMap.get(item.id) ?? 0), utils_1.MathBN.convert(0));
43
+ if (utils_1.MathBN.lte(lineItemsAmount, 0)) {
44
+ return computedActions;
45
+ }
37
46
  }
38
47
  for (const item of applicableItems) {
39
- const appliedPromoValue = appliedPromotionsMap.get(item.id) ?? 0;
40
- const maxQuantity = isTargetShippingMethod
41
- ? 1
42
- : applicationMethod?.max_quantity;
43
- if (isTargetShippingMethod) {
44
- item.quantity = 1;
48
+ if (allocation === utils_1.ApplicationMethodAllocation.ONCE &&
49
+ remainingQuota <= 0) {
50
+ break;
45
51
  }
52
+ if (utils_1.MathBN.lte(promotion.is_tax_inclusive ? item.original_total : item.subtotal, 0)) {
53
+ continue;
54
+ }
55
+ const appliedPromoValue = appliedPromotionsMap.get(item.id) ?? 0;
56
+ const effectiveMaxQuantity = allocation === utils_1.ApplicationMethodAllocation.ONCE
57
+ ? Math.min(remainingQuota ?? 0, Number(item.quantity))
58
+ : maxQuantity;
59
+ // If the allocation is once, we rely on the existing logic for each allocation, as the calculate is the same: apply the promotion value to the line item
60
+ const effectiveAllocation = allocation === utils_1.ApplicationMethodAllocation.ONCE
61
+ ? utils_1.ApplicationMethodAllocation.EACH
62
+ : allocation;
46
63
  const amount = (0, utils_1.calculateAdjustmentAmountFromPromotion)(item, {
47
- value: applicationMethod?.value ?? 0,
64
+ value: promotionValue,
48
65
  applied_value: appliedPromoValue,
49
- max_quantity: maxQuantity,
66
+ is_tax_inclusive: promotion.is_tax_inclusive,
67
+ max_quantity: effectiveMaxQuantity,
50
68
  type: applicationMethod?.type,
51
- allocation,
52
- }, lineItemsTotal);
69
+ allocation: effectiveAllocation,
70
+ }, lineItemsAmount);
53
71
  if (utils_1.MathBN.lte(amount, 0)) {
54
72
  continue;
55
73
  }
@@ -59,34 +77,50 @@ function applyPromotionToItems(promotion, items, appliedPromotionsMap, allocatio
59
77
  continue;
60
78
  }
61
79
  appliedPromotionsMap.set(item.id, utils_1.MathBN.add(appliedPromoValue, amount));
80
+ if (allocation === utils_1.ApplicationMethodAllocation.ONCE) {
81
+ // We already know exactly how many units we applied via effectiveMaxQuantity
82
+ const quantityApplied = Math.min(effectiveMaxQuantity, Number(item.quantity));
83
+ remainingQuota -= quantityApplied;
84
+ }
62
85
  if (isTargetLineItems || isTargetOrder) {
63
86
  computedActions.push({
64
87
  action: utils_1.ComputedActions.ADD_ITEM_ADJUSTMENT,
65
88
  item_id: item.id,
66
89
  amount,
67
90
  code: promotion.code,
68
- });
69
- }
70
- if (isTargetShippingMethod) {
71
- computedActions.push({
72
- action: utils_1.ComputedActions.ADD_SHIPPING_METHOD_ADJUSTMENT,
73
- shipping_method_id: item.id,
74
- amount,
75
- code: promotion.code,
91
+ is_tax_inclusive: promotion.is_tax_inclusive,
76
92
  });
77
93
  }
78
94
  }
79
95
  return computedActions;
80
96
  }
81
97
  function getValidItemsForPromotion(items, promotion) {
98
+ if (!items?.length || !promotion?.application_method) {
99
+ return [];
100
+ }
82
101
  const isTargetShippingMethod = promotion.application_method?.target_type === utils_1.ApplicationMethodTargetType.SHIPPING_METHODS;
83
- return (items?.filter((item) => {
84
- const isSubtotalPresent = "subtotal" in item;
85
- const isQuantityPresent = "quantity" in item;
86
- const isPromotionApplicableToItem = (0, validations_1.areRulesValidForContext)(promotion?.application_method?.target_rules, item, utils_1.ApplicationMethodTargetType.ITEMS);
87
- return (isPromotionApplicableToItem &&
88
- (isQuantityPresent || isTargetShippingMethod) &&
89
- isSubtotalPresent);
90
- }) || []);
102
+ const targetRules = promotion.application_method?.target_rules ?? [];
103
+ const hasTargetRules = targetRules.length > 0;
104
+ if (isTargetShippingMethod && !hasTargetRules) {
105
+ return items.filter((item) => item && "subtotal" in item && utils_1.MathBN.gt(item.subtotal, 0));
106
+ }
107
+ return items.filter((item) => {
108
+ if (!item) {
109
+ return false;
110
+ }
111
+ if ("is_discountable" in item && !item.is_discountable) {
112
+ return false;
113
+ }
114
+ if (!("subtotal" in item) || utils_1.MathBN.lte(item.subtotal, 0)) {
115
+ return false;
116
+ }
117
+ if (!isTargetShippingMethod && !("quantity" in item)) {
118
+ return false;
119
+ }
120
+ if (!hasTargetRules) {
121
+ return true;
122
+ }
123
+ return (0, validations_1.areRulesValidForContext)(promotion?.application_method?.target_rules, item, utils_1.ApplicationMethodTargetType.ITEMS);
124
+ });
91
125
  }
92
126
  //# sourceMappingURL=line-items.js.map