@medusajs/promotion 3.0.0-snapshot-20250410112222 → 3.0.0-snapshot-20251104011621

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
@@ -18,15 +18,17 @@ const _models_1 = require("../models");
18
18
  const _types_1 = require("../types");
19
19
  const _utils_1 = require("../utils");
20
20
  const joiner_config_1 = require("../joiner-config");
21
+ const build_promotion_rule_query_filter_from_context_1 = require("../utils/compute-actions/build-promotion-rule-query-filter-from-context");
21
22
  class PromotionModuleService extends (0, utils_1.MedusaService)({
22
23
  Promotion: _models_1.Promotion,
23
24
  ApplicationMethod: _models_1.ApplicationMethod,
24
25
  Campaign: _models_1.Campaign,
25
26
  CampaignBudget: _models_1.CampaignBudget,
27
+ CampaignBudgetUsage: _models_1.CampaignBudgetUsage,
26
28
  PromotionRule: _models_1.PromotionRule,
27
29
  PromotionRuleValue: _models_1.PromotionRuleValue,
28
30
  }) {
29
- constructor({ baseRepository, promotionService, applicationMethodService, promotionRuleService, promotionRuleValueService, campaignService, campaignBudgetService, }, moduleDeclaration) {
31
+ constructor({ baseRepository, promotionService, applicationMethodService, promotionRuleService, promotionRuleValueService, campaignService, campaignBudgetService, campaignBudgetUsageService, }, moduleDeclaration) {
30
32
  // @ts-ignore
31
33
  super(...arguments);
32
34
  this.moduleDeclaration = moduleDeclaration;
@@ -37,44 +39,102 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
37
39
  this.promotionRuleValueService_ = promotionRuleValueService;
38
40
  this.campaignService_ = campaignService;
39
41
  this.campaignBudgetService_ = campaignBudgetService;
42
+ this.campaignBudgetUsageService_ = campaignBudgetUsageService;
40
43
  }
41
44
  __joinerConfig() {
42
45
  return joiner_config_1.joinerConfig;
43
46
  }
44
- listActivePromotions(filters, config, sharedContext) {
47
+ async listActivePromotions(filters, config, sharedContext) {
48
+ const activePromotions = await this.listActivePromotions_(filters, config, sharedContext);
49
+ return this.baseRepository_.serialize(activePromotions);
50
+ }
51
+ async listActivePromotions_(filters, config, sharedContext) {
52
+ // Ensure we share the same now date across all filters
53
+ const now = new Date();
45
54
  const activeFilters = {
55
+ status: utils_1.PromotionStatus.ACTIVE,
46
56
  $or: [
47
57
  {
48
- status: utils_1.PromotionStatus.ACTIVE,
49
58
  campaign_id: null,
50
59
  ...filters,
51
60
  },
52
61
  {
53
- status: utils_1.PromotionStatus.ACTIVE,
54
62
  ...filters,
55
63
  campaign: {
56
64
  ...filters?.campaign,
57
65
  $and: [
58
66
  {
59
- $or: [{ starts_at: null }, { starts_at: { $lte: new Date() } }],
67
+ $or: [{ starts_at: null }, { starts_at: { $lte: now } }],
60
68
  },
61
69
  {
62
- $or: [{ ends_at: null }, { ends_at: { $gt: new Date() } }],
70
+ $or: [{ ends_at: null }, { ends_at: { $gt: now } }],
63
71
  },
64
72
  ],
65
73
  },
66
74
  },
67
75
  ],
68
76
  };
69
- return this.listPromotions(activeFilters, config, sharedContext);
77
+ return await this.promotionService_.list(activeFilters, config, sharedContext);
78
+ }
79
+ async registerCampaignBudgetUsageByAttribute_(budgetId, attributeValue, sharedContext = {}) {
80
+ const [campaignBudgetUsagePerAttributeValue] = await this.campaignBudgetUsageService_.list({
81
+ budget_id: budgetId,
82
+ attribute_value: attributeValue,
83
+ }, { relations: ["budget"] }, sharedContext);
84
+ if (!campaignBudgetUsagePerAttributeValue) {
85
+ await this.campaignBudgetUsageService_.create({
86
+ budget_id: budgetId,
87
+ attribute_value: attributeValue,
88
+ used: utils_1.MathBN.convert(1),
89
+ }, sharedContext);
90
+ }
91
+ else {
92
+ const limit = campaignBudgetUsagePerAttributeValue.budget.limit;
93
+ const newUsedValue = utils_1.MathBN.add(campaignBudgetUsagePerAttributeValue.used ?? 0, 1);
94
+ if (limit && utils_1.MathBN.gt(newUsedValue, limit)) {
95
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_ALLOWED, "Promotion usage exceeds the budget limit.");
96
+ }
97
+ await this.campaignBudgetUsageService_.update({
98
+ id: campaignBudgetUsagePerAttributeValue.id,
99
+ used: newUsedValue,
100
+ }, sharedContext);
101
+ }
70
102
  }
71
- async registerUsage(computedActions, sharedContext = {}) {
103
+ async revertCampaignBudgetUsageByAttribute_(budgetId, attributeValue, sharedContext = {}) {
104
+ const [campaignBudgetUsagePerAttributeValue] = await this.campaignBudgetUsageService_.list({
105
+ budget_id: budgetId,
106
+ attribute_value: attributeValue,
107
+ }, {}, sharedContext);
108
+ if (!campaignBudgetUsagePerAttributeValue) {
109
+ return;
110
+ }
111
+ if (utils_1.MathBN.lte(campaignBudgetUsagePerAttributeValue.used ?? 0, 1)) {
112
+ await this.campaignBudgetUsageService_.delete(campaignBudgetUsagePerAttributeValue.id, sharedContext);
113
+ }
114
+ else {
115
+ await this.campaignBudgetUsageService_.update({
116
+ id: campaignBudgetUsagePerAttributeValue.id,
117
+ used: utils_1.MathBN.sub(campaignBudgetUsagePerAttributeValue.used ?? 0, 1),
118
+ }, sharedContext);
119
+ }
120
+ }
121
+ /**
122
+ * Register the usage of promotions in the campaign budget and
123
+ * increment the used value if the budget is not exceeded,
124
+ * throws an error if the budget is exceeded.
125
+ *
126
+ * @param computedActions - The computed actions to register usage for.
127
+ * @param registrationContext - The context of the campaign budget usage.
128
+ * @returns void
129
+ * @throws {MedusaError} - If the promotion usage exceeds the budget limit.
130
+ */
131
+ async registerUsage(computedActions, registrationContext, sharedContext = {}) {
72
132
  const promotionCodes = computedActions
73
133
  .map((computedAction) => computedAction.code)
74
134
  .filter(Boolean);
75
135
  const campaignBudgetMap = new Map();
76
136
  const promotionCodeUsageMap = new Map();
77
- const existingPromotions = await this.listActivePromotions({ code: promotionCodes }, { relations: ["campaign", "campaign.budget"] }, sharedContext);
137
+ const existingPromotions = await this.listActivePromotions_({ code: promotionCodes }, { relations: ["campaign", "campaign.budget", "campaign.budget.usages"] }, sharedContext);
78
138
  for (const promotion of existingPromotions) {
79
139
  if (promotion.campaign?.budget) {
80
140
  campaignBudgetMap.set(promotion.campaign?.budget.id, promotion.campaign?.budget);
@@ -95,11 +155,13 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
95
155
  if (!campaignBudgetData) {
96
156
  continue;
97
157
  }
98
- campaignBudgetData.used = utils_1.MathBN.add(campaignBudgetData.used ?? 0, computedAction.amount);
158
+ // Calculate the new budget value
159
+ const newUsedValue = utils_1.MathBN.add(campaignBudgetData.used ?? 0, computedAction.amount);
99
160
  if (campaignBudget.limit &&
100
- utils_1.MathBN.gt(campaignBudgetData.used, campaignBudget.limit)) {
101
- continue;
161
+ utils_1.MathBN.gt(newUsedValue, campaignBudget.limit)) {
162
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_ALLOWED, "Promotion usage exceeds the budget limit.");
102
163
  }
164
+ campaignBudgetData.used = newUsedValue;
103
165
  campaignBudgetMap.set(campaignBudget.id, campaignBudgetData);
104
166
  }
105
167
  if (campaignBudget.type === utils_1.CampaignBudgetType.USAGE) {
@@ -107,28 +169,55 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
107
169
  if (promotionAlreadyUsed) {
108
170
  continue;
109
171
  }
110
- const campaignBudgetData = {
111
- id: campaignBudget.id,
112
- used: utils_1.MathBN.add(campaignBudget.used ?? 0, 1),
113
- };
172
+ const newUsedValue = utils_1.MathBN.add(campaignBudget.used ?? 0, 1);
114
173
  if (campaignBudget.limit &&
115
- utils_1.MathBN.gt(campaignBudgetData.used, campaignBudget.limit)) {
174
+ utils_1.MathBN.gt(newUsedValue, campaignBudget.limit)) {
175
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_ALLOWED, "Promotion usage exceeds the budget limit.");
176
+ }
177
+ campaignBudgetMap.set(campaignBudget.id, {
178
+ id: campaignBudget.id,
179
+ used: newUsedValue,
180
+ });
181
+ promotionCodeUsageMap.set(promotion.code, true);
182
+ }
183
+ if (campaignBudget.type === utils_1.CampaignBudgetType.USE_BY_ATTRIBUTE) {
184
+ const promotionAlreadyUsed = promotionCodeUsageMap.get(promotion.code) || false;
185
+ if (promotionAlreadyUsed) {
116
186
  continue;
117
187
  }
118
- campaignBudgetMap.set(campaignBudget.id, campaignBudgetData);
188
+ const attribute = campaignBudget.attribute;
189
+ const attributeValue = registrationContext[attribute];
190
+ if (!attributeValue) {
191
+ continue;
192
+ }
193
+ await this.registerCampaignBudgetUsageByAttribute_(campaignBudget.id, attributeValue, sharedContext);
194
+ const newUsedValue = utils_1.MathBN.add(campaignBudget.used ?? 0, 1);
195
+ // update the global budget usage to keep track but it is not used anywhere atm
196
+ campaignBudgetMap.set(campaignBudget.id, {
197
+ id: campaignBudget.id,
198
+ used: newUsedValue,
199
+ });
119
200
  promotionCodeUsageMap.set(promotion.code, true);
120
201
  }
202
+ }
203
+ if (campaignBudgetMap.size > 0) {
121
204
  const campaignBudgetsData = [];
122
205
  for (const [_, campaignBudgetData] of campaignBudgetMap) {
206
+ // usages by attribute are updated separatley
207
+ if (campaignBudgetData.usages) {
208
+ const { usages, ...campaignBudgetDataWithoutUsages } = campaignBudgetData;
209
+ campaignBudgetsData.push(campaignBudgetDataWithoutUsages);
210
+ continue;
211
+ }
123
212
  campaignBudgetsData.push(campaignBudgetData);
124
213
  }
125
214
  await this.campaignBudgetService_.update(campaignBudgetsData, sharedContext);
126
215
  }
127
216
  }
128
- async revertUsage(computedActions, sharedContext = {}) {
217
+ async revertUsage(computedActions, registrationContext, sharedContext = {}) {
129
218
  const promotionCodeUsageMap = new Map();
130
219
  const campaignBudgetMap = new Map();
131
- const existingPromotions = await this.listActivePromotions({
220
+ const existingPromotions = await this.listActivePromotions_({
132
221
  code: computedActions
133
222
  .map((computedAction) => computedAction.code)
134
223
  .filter(Boolean),
@@ -153,7 +242,9 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
153
242
  if (!campaignBudgetData) {
154
243
  continue;
155
244
  }
156
- campaignBudgetData.used = utils_1.MathBN.sub(campaignBudgetData.used ?? 0, computedAction.amount);
245
+ // Calculate new used value and ensure it doesn't go below 0
246
+ const newUsedValue = utils_1.MathBN.sub(campaignBudgetData.used ?? 0, computedAction.amount);
247
+ campaignBudgetData.used = utils_1.MathBN.lt(newUsedValue, 0) ? 0 : newUsedValue;
157
248
  campaignBudgetMap.set(campaignBudget.id, campaignBudgetData);
158
249
  }
159
250
  if (campaignBudget.type === utils_1.CampaignBudgetType.USAGE) {
@@ -161,14 +252,44 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
161
252
  if (promotionAlreadyUsed) {
162
253
  continue;
163
254
  }
255
+ // Calculate new used value and ensure it doesn't go below 0
256
+ const newUsedValue = utils_1.MathBN.sub(campaignBudget.used ?? 0, 1);
257
+ const usedValue = utils_1.MathBN.lt(newUsedValue, 0) ? 0 : newUsedValue;
164
258
  campaignBudgetMap.set(campaignBudget.id, {
165
259
  id: campaignBudget.id,
166
- used: utils_1.MathBN.sub(campaignBudget.used ?? 0, 1),
260
+ used: usedValue,
167
261
  });
168
262
  promotionCodeUsageMap.set(promotion.code, true);
169
263
  }
264
+ if (campaignBudget.type === utils_1.CampaignBudgetType.USE_BY_ATTRIBUTE) {
265
+ const promotionAlreadyUsed = promotionCodeUsageMap.get(promotion.code) || false;
266
+ if (promotionAlreadyUsed) {
267
+ continue;
268
+ }
269
+ const attribute = campaignBudget.attribute;
270
+ const attributeValue = registrationContext[attribute];
271
+ if (!attributeValue) {
272
+ continue;
273
+ }
274
+ await this.revertCampaignBudgetUsageByAttribute_(campaignBudget.id, attributeValue, sharedContext);
275
+ const newUsedValue = utils_1.MathBN.sub(campaignBudget.used ?? 0, 1);
276
+ const usedValue = utils_1.MathBN.lt(newUsedValue, 0) ? 0 : newUsedValue;
277
+ // update the global budget usage to keep track but it is not used anywhere atm
278
+ campaignBudgetMap.set(campaignBudget.id, {
279
+ id: campaignBudget.id,
280
+ used: usedValue,
281
+ });
282
+ promotionCodeUsageMap.set(promotion.code, true);
283
+ }
284
+ }
285
+ if (campaignBudgetMap.size > 0) {
170
286
  const campaignBudgetsData = [];
171
287
  for (const [_, campaignBudgetData] of campaignBudgetMap) {
288
+ if (campaignBudgetData.usages) {
289
+ const { usages, ...campaignBudgetDataWithoutUsages } = campaignBudgetData;
290
+ campaignBudgetsData.push(campaignBudgetDataWithoutUsages);
291
+ continue;
292
+ }
172
293
  campaignBudgetsData.push(campaignBudgetData);
173
294
  }
174
295
  await this.campaignBudgetService_.update(campaignBudgetsData, sharedContext);
@@ -178,52 +299,58 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
178
299
  const { prevent_auto_promotions: preventAutoPromotions } = options;
179
300
  const computedActions = [];
180
301
  const { items = [], shipping_methods: shippingMethods = [] } = applicationContext;
181
- const appliedItemCodes = [];
182
- const appliedShippingCodes = [];
183
302
  const codeAdjustmentMap = new Map();
303
+ // Pre-process items and shipping methods to build adjustment map efficiently
304
+ for (const item of items) {
305
+ if (!item.adjustments?.length)
306
+ continue;
307
+ for (const adjustment of item.adjustments) {
308
+ if (!(0, utils_1.isString)(adjustment.code))
309
+ continue;
310
+ if (!codeAdjustmentMap.has(adjustment.code)) {
311
+ codeAdjustmentMap.set(adjustment.code, { items: [], shipping: [] });
312
+ }
313
+ codeAdjustmentMap.get(adjustment.code).items.push(adjustment);
314
+ }
315
+ }
316
+ for (const shippingMethod of shippingMethods) {
317
+ if (!shippingMethod.adjustments?.length)
318
+ continue;
319
+ for (const adjustment of shippingMethod.adjustments) {
320
+ if (!(0, utils_1.isString)(adjustment.code))
321
+ continue;
322
+ if (!codeAdjustmentMap.has(adjustment.code)) {
323
+ codeAdjustmentMap.set(adjustment.code, { items: [], shipping: [] });
324
+ }
325
+ codeAdjustmentMap.get(adjustment.code).shipping.push(adjustment);
326
+ }
327
+ }
328
+ const appliedCodes = Array.from(codeAdjustmentMap.keys());
184
329
  const methodIdPromoValueMap = new Map();
185
- // Keeps a map of all elgible items in the buy section and its eligible quantity
186
- const eligibleBuyItemMap = new Map();
187
- // Keeps a map of all elgible items in the target section and its eligible quantity
188
- const eligibleTargetItemMap = new Map();
189
- const automaticPromotions = preventAutoPromotions
190
- ? []
191
- : await this.listActivePromotions({ is_automatic: true }, { select: ["code"] }, sharedContext);
192
- // Promotions we need to apply includes all the codes that are passed as an argument
193
- // to this method, along with any automatic promotions that can be applied to the context
194
- const automaticPromotionCodes = automaticPromotions.map((p) => p.code);
195
- const promotionCodesToApply = [
196
- ...promotionCodes,
197
- ...automaticPromotionCodes,
198
- ];
199
- items.forEach((item) => {
200
- item.adjustments?.forEach((adjustment) => {
201
- if ((0, utils_1.isString)(adjustment.code)) {
202
- const adjustments = codeAdjustmentMap.get(adjustment.code) || [];
203
- adjustments.push(adjustment);
204
- codeAdjustmentMap.set(adjustment.code, adjustments);
205
- appliedItemCodes.push(adjustment.code);
330
+ const promotionCodesToApply = [...promotionCodes, ...appliedCodes];
331
+ const uniquePromotionCodes = Array.from(new Set(promotionCodesToApply));
332
+ let queryFilter = { code: uniquePromotionCodes };
333
+ if (!preventAutoPromotions) {
334
+ const rulePrefilteringFilters = await (0, build_promotion_rule_query_filter_from_context_1.buildPromotionRuleQueryFilterFromContext)(applicationContext, sharedContext);
335
+ let prefilteredAutomaticPromotionIds = [];
336
+ if (rulePrefilteringFilters) {
337
+ const promotions = await this.promotionService_.list({
338
+ $and: [{ is_automatic: true }, rulePrefilteringFilters],
339
+ }, { select: ["id"] }, sharedContext);
340
+ prefilteredAutomaticPromotionIds = promotions.map((promotion) => promotion.id);
341
+ }
342
+ const automaticPromotionFilter = rulePrefilteringFilters
343
+ ? {
344
+ id: { $in: prefilteredAutomaticPromotionIds },
206
345
  }
207
- });
208
- });
209
- shippingMethods.forEach((shippingMethod) => {
210
- shippingMethod.adjustments?.forEach((adjustment) => {
211
- if ((0, utils_1.isString)(adjustment.code)) {
212
- const adjustments = codeAdjustmentMap.get(adjustment.code) || [];
213
- adjustments.push(adjustment);
214
- codeAdjustmentMap.set(adjustment.code, adjustments);
215
- appliedShippingCodes.push(adjustment.code);
346
+ : { is_automatic: true };
347
+ queryFilter = automaticPromotionFilter
348
+ ? {
349
+ $or: [{ code: uniquePromotionCodes }, automaticPromotionFilter],
216
350
  }
217
- });
218
- });
219
- const promotions = await this.listActivePromotions({
220
- code: [
221
- ...promotionCodesToApply,
222
- ...appliedItemCodes,
223
- ...appliedShippingCodes,
224
- ],
225
- }, {
226
- take: null,
351
+ : queryFilter;
352
+ }
353
+ const promotions = await this.listActivePromotions_(queryFilter, {
227
354
  order: { application_method: { value: "DESC" } },
228
355
  relations: [
229
356
  "application_method",
@@ -236,43 +363,74 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
236
363
  "campaign",
237
364
  "campaign.budget",
238
365
  ],
239
- });
366
+ }, sharedContext);
240
367
  const existingPromotionsMap = new Map(promotions.map((promotion) => [promotion.code, promotion]));
241
- // We look at any existing promo codes applied in the context and recommend
242
- // them to be removed to start calculations from the beginning and refresh
243
- // the adjustments if they are requested to be applied again
244
- const appliedCodes = [...appliedShippingCodes, ...appliedItemCodes];
245
- for (const appliedCode of appliedCodes) {
246
- const adjustments = codeAdjustmentMap.get(appliedCode) || [];
247
- const action = appliedShippingCodes.includes(appliedCode)
248
- ? utils_1.ComputedActions.REMOVE_SHIPPING_METHOD_ADJUSTMENT
249
- : utils_1.ComputedActions.REMOVE_ITEM_ADJUSTMENT;
250
- adjustments.forEach((adjustment) => computedActions.push({
251
- action,
252
- adjustment_id: adjustment.id,
253
- code: appliedCode,
254
- }));
368
+ const automaticPromotionCodes = [];
369
+ for (const promotion of promotions) {
370
+ if (promotion.is_automatic) {
371
+ automaticPromotionCodes.push(promotion.code);
372
+ }
255
373
  }
256
- // We sort the promo codes to apply with buy get type first as they
257
- // are likely to be most valuable.
258
- const sortedPermissionsToApply = promotions
259
- .filter((p) => promotionCodesToApply.includes(p.code))
374
+ for (const [code, adjustments] of codeAdjustmentMap.entries()) {
375
+ for (const adjustment of adjustments.items) {
376
+ computedActions.push({
377
+ action: utils_1.ComputedActions.REMOVE_ITEM_ADJUSTMENT,
378
+ adjustment_id: adjustment.id,
379
+ code,
380
+ });
381
+ }
382
+ for (const adjustment of adjustments.shipping) {
383
+ computedActions.push({
384
+ action: utils_1.ComputedActions.REMOVE_SHIPPING_METHOD_ADJUSTMENT,
385
+ adjustment_id: adjustment.id,
386
+ code,
387
+ });
388
+ }
389
+ }
390
+ const promotionCodeSet = new Set(promotionCodes);
391
+ const automaticPromotionCodeSet = new Set(automaticPromotionCodes);
392
+ const sortedPromotionsToApply = promotions
393
+ .filter((p) => promotionCodeSet.has(p.code) ||
394
+ automaticPromotionCodeSet.has(p.code))
260
395
  .sort(_utils_1.ComputeActionUtils.sortByBuyGetType);
261
- for (const promotionToApply of sortedPermissionsToApply) {
396
+ const eligibleBuyItemMap = new Map();
397
+ const eligibleTargetItemMap = new Map();
398
+ for (const promotionToApply of sortedPromotionsToApply) {
262
399
  const promotion = existingPromotionsMap.get(promotionToApply.code);
263
- const { application_method: applicationMethod, rules: promotionRules = [], } = promotion;
264
- if (!applicationMethod) {
400
+ if (!promotion.application_method) {
265
401
  continue;
266
402
  }
403
+ const { application_method: applicationMethod, rules: promotionRules = [], } = promotion;
404
+ if (promotion.campaign?.budget?.type === utils_1.CampaignBudgetType.USE_BY_ATTRIBUTE) {
405
+ const attribute = promotion.campaign?.budget?.attribute;
406
+ const budgetUsageContext = _utils_1.ComputeActionUtils.getBudgetUsageContextFromComputeActionContext(applicationContext);
407
+ const attributeValue = budgetUsageContext[attribute];
408
+ if (!attributeValue) {
409
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Attribute value for "${attribute}" is required by promotion campaing budget`);
410
+ }
411
+ const [campaignBudgetUsagePerAttribute] = (await this.campaignBudgetUsageService_.list({
412
+ budget_id: promotion.campaign?.budget?.id,
413
+ attribute_value: attributeValue,
414
+ }, {}, sharedContext));
415
+ if (campaignBudgetUsagePerAttribute) {
416
+ const action = _utils_1.ComputeActionUtils.computeActionForBudgetExceeded(promotion, 1, campaignBudgetUsagePerAttribute);
417
+ if (action) {
418
+ computedActions.push(action);
419
+ continue;
420
+ }
421
+ }
422
+ }
423
+ const isCurrencyCodeValid = !(0, utils_1.isPresent)(applicationMethod.currency_code) ||
424
+ applicationContext.currency_code === applicationMethod.currency_code;
267
425
  const isPromotionApplicable = (0, _utils_1.areRulesValidForContext)(promotionRules, applicationContext, utils_1.ApplicationMethodTargetType.ORDER);
268
- if (!isPromotionApplicable) {
426
+ if (!isPromotionApplicable || !isCurrencyCodeValid) {
269
427
  continue;
270
428
  }
271
429
  if (promotion.type === utils_1.PromotionType.BUYGET) {
272
430
  const computedActionsForItems = _utils_1.ComputeActionUtils.getComputedActionsForBuyGet(promotion, applicationContext[utils_1.ApplicationMethodTargetType.ITEMS], methodIdPromoValueMap, eligibleBuyItemMap, eligibleTargetItemMap);
273
431
  computedActions.push(...computedActionsForItems);
274
432
  }
275
- if (promotion.type === utils_1.PromotionType.STANDARD) {
433
+ else if (promotion.type === utils_1.PromotionType.STANDARD) {
276
434
  const isTargetOrder = applicationMethod.target_type === utils_1.ApplicationMethodTargetType.ORDER;
277
435
  const isTargetItems = applicationMethod.target_type === utils_1.ApplicationMethodTargetType.ITEMS;
278
436
  const isTargetShipping = applicationMethod.target_type ===
@@ -310,13 +468,19 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
310
468
  "campaign.budget",
311
469
  ],
312
470
  }, sharedContext);
313
- return Array.isArray(data) ? promotions : promotions[0];
471
+ return await this.baseRepository_.serialize(Array.isArray(data) ? promotions : promotions[0]);
314
472
  }
315
473
  async createPromotions_(data, sharedContext = {}) {
316
474
  const promotionsData = [];
317
475
  const applicationMethodsData = [];
318
476
  const campaignsData = [];
319
- const existingCampaigns = await this.campaignService_.list({ id: data.map((d) => d.campaign_id).filter((id) => (0, utils_1.isString)(id)) }, { relations: ["budget"] }, sharedContext);
477
+ const campaignIds = data
478
+ .filter((d) => d.campaign_id)
479
+ .map((d) => d.campaign_id)
480
+ .filter((id) => (0, utils_1.isString)(id));
481
+ const existingCampaigns = campaignIds.length > 0
482
+ ? await this.campaignService_.list({ id: campaignIds }, { relations: ["budget"] }, sharedContext)
483
+ : [];
320
484
  const promotionCodeApplicationMethodDataMap = new Map();
321
485
  const promotionCodeRulesDataMap = new Map();
322
486
  const methodTargetRulesMap = new Map();
@@ -390,21 +554,32 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
390
554
  methodBuyRulesMap.set(promotion.id, buyRulesData);
391
555
  }
392
556
  }
393
- await this.createPromotionRulesAndValues_(promotionCodeRulesDataMap.get(promotion.code) || [], "promotions", promotion, sharedContext);
557
+ if (promotionCodeRulesDataMap.has(promotion.code)) {
558
+ await this.createPromotionRulesAndValues_(promotionCodeRulesDataMap.get(promotion.code) || [], "promotions", promotion, sharedContext);
559
+ }
394
560
  }
395
- const createdApplicationMethods = await this.applicationMethodService_.create(applicationMethodsData, sharedContext);
396
- const createdCampaigns = await this.createCampaigns(campaignsData, sharedContext);
561
+ const createdApplicationMethods = applicationMethodsData.length > 0
562
+ ? await this.applicationMethodService_.create(applicationMethodsData, sharedContext)
563
+ : [];
564
+ const createdCampaigns = campaignsData.length > 0
565
+ ? await this.createCampaigns(campaignsData, sharedContext)
566
+ : [];
397
567
  for (const campaignData of campaignsData) {
398
568
  const promotions = campaignData.promotions;
399
569
  const campaign = createdCampaigns.find((c) => c.campaign_identifier === campaignData.campaign_identifier);
400
- if (!campaign || !promotions || !promotions.length) {
401
- continue;
570
+ if (campaign && promotions && promotions.length) {
571
+ await this.addPromotionsToCampaign({ id: campaign.id, promotion_ids: promotions.map((p) => p.id) }, sharedContext);
402
572
  }
403
- await this.addPromotionsToCampaign({ id: campaign.id, promotion_ids: promotions.map((p) => p.id) }, sharedContext);
404
573
  }
405
574
  for (const applicationMethod of createdApplicationMethods) {
406
- await this.createPromotionRulesAndValues_(methodTargetRulesMap.get(applicationMethod.promotion.id) || [], "method_target_rules", applicationMethod, sharedContext);
407
- await this.createPromotionRulesAndValues_(methodBuyRulesMap.get(applicationMethod.promotion.id) || [], "method_buy_rules", applicationMethod, sharedContext);
575
+ const targetRules = methodTargetRulesMap.get(applicationMethod.promotion.id);
576
+ if (targetRules && targetRules.length > 0) {
577
+ await this.createPromotionRulesAndValues_(targetRules, "method_target_rules", applicationMethod, sharedContext);
578
+ }
579
+ const buyRules = methodBuyRulesMap.get(applicationMethod.promotion.id);
580
+ if (buyRules && buyRules.length > 0) {
581
+ await this.createPromotionRulesAndValues_(buyRules, "method_buy_rules", applicationMethod, sharedContext);
582
+ }
408
583
  }
409
584
  return createdPromotions;
410
585
  }
@@ -479,12 +654,17 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
479
654
  }
480
655
  async updatePromotionRules_(data, sharedContext = {}) {
481
656
  const promotionRuleIds = data.map((d) => d.id);
482
- const promotionRules = await this.listPromotionRules({ id: promotionRuleIds }, { relations: ["values"] }, sharedContext);
483
- const invalidRuleId = (0, utils_1.arrayDifference)((0, utils_1.deduplicate)(promotionRuleIds), promotionRules.map((pr) => pr.id));
657
+ const promotionRules = await this.promotionRuleService_.list({ id: promotionRuleIds }, { relations: ["values"] }, sharedContext);
658
+ const existingPromotionRuleIds = [];
659
+ const promotionRulesMap = new Map();
660
+ for (const promotionRule of promotionRules) {
661
+ existingPromotionRuleIds.push(promotionRule.id);
662
+ promotionRulesMap.set(promotionRule.id, promotionRule);
663
+ }
664
+ const invalidRuleId = (0, utils_1.arrayDifference)((0, utils_1.deduplicate)(promotionRuleIds), existingPromotionRuleIds);
484
665
  if (invalidRuleId.length) {
485
666
  throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Promotion rules with id - ${invalidRuleId.join(", ")} not found`);
486
667
  }
487
- const promotionRulesMap = new Map(promotionRules.map((pr) => [pr.id, pr]));
488
668
  const rulesToUpdate = [];
489
669
  const ruleValueIdsToDelete = [];
490
670
  const ruleValuesToCreate = [];
@@ -547,6 +727,7 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
547
727
  throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Can't add buy rules to a ${utils_1.PromotionType.STANDARD} promotion`);
548
728
  }
549
729
  (0, _utils_1.validatePromotionRuleAttributes)(rulesData);
730
+ const promotionRuleValuesDataToCreate = [];
550
731
  for (const ruleData of rulesData) {
551
732
  const { values, ...rest } = ruleData;
552
733
  const promotionRuleData = {
@@ -560,8 +741,9 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
560
741
  value: ruleValue,
561
742
  promotion_rule: createdPromotionRule,
562
743
  }));
563
- await this.promotionRuleValueService_.create(promotionRuleValuesData, sharedContext);
744
+ promotionRuleValuesDataToCreate.push(...promotionRuleValuesData);
564
745
  }
746
+ await this.promotionRuleValueService_.create(promotionRuleValuesDataToCreate, sharedContext);
565
747
  return createdPromotionRules;
566
748
  }
567
749
  async removePromotionRules(promotionId, ruleIds, sharedContext = {}) {
@@ -651,7 +833,7 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
651
833
  const campaignsData = [];
652
834
  const updateBudgetData = [];
653
835
  const createBudgetData = [];
654
- const existingCampaigns = await this.listCampaigns({ id: campaignIds }, { relations: ["budget"] }, sharedContext);
836
+ const existingCampaigns = await this.campaignService_.list({ id: campaignIds }, { relations: ["budget"] }, sharedContext);
655
837
  const existingCampaignsMap = new Map(existingCampaigns.map((campaign) => [campaign.id, campaign]));
656
838
  for (const updateCampaignData of data) {
657
839
  const { budget: budgetData, ...campaignData } = updateCampaignData;
@@ -689,7 +871,7 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
689
871
  }
690
872
  return updatedCampaigns;
691
873
  }
692
- async addPromotionsToCampaign(data, sharedContext) {
874
+ async addPromotionsToCampaign(data, sharedContext = {}) {
693
875
  const ids = await this.addPromotionsToCampaign_(data, sharedContext);
694
876
  return { ids };
695
877
  }
@@ -717,7 +899,7 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
717
899
  })), sharedContext);
718
900
  return promotionsToAdd.map((promo) => promo.id);
719
901
  }
720
- async removePromotionsFromCampaign(data, sharedContext) {
902
+ async removePromotionsFromCampaign(data, sharedContext = {}) {
721
903
  const ids = await this.removePromotionsFromCampaign_(data, sharedContext);
722
904
  return { ids };
723
905
  }
@@ -745,17 +927,50 @@ __decorate([
745
927
  ], PromotionModuleService.prototype, "listActivePromotions", null);
746
928
  __decorate([
747
929
  (0, utils_1.InjectManager)(),
748
- __param(1, (0, utils_1.MedusaContext)()),
749
- __param(1, (0, utils_1.MedusaContext)()),
930
+ __param(2, (0, utils_1.MedusaContext)()),
750
931
  __metadata("design:type", Function),
751
- __metadata("design:paramtypes", [Array, Object]),
932
+ __metadata("design:paramtypes", [Object, Object, Object]),
933
+ __metadata("design:returntype", Promise)
934
+ ], PromotionModuleService.prototype, "listActivePromotions_", null);
935
+ __decorate([
936
+ (0, utils_1.InjectTransactionManager)(),
937
+ __param(2, (0, utils_1.MedusaContext)()),
938
+ __metadata("design:type", Function),
939
+ __metadata("design:paramtypes", [String, String, Object]),
940
+ __metadata("design:returntype", Promise)
941
+ ], PromotionModuleService.prototype, "registerCampaignBudgetUsageByAttribute_", null);
942
+ __decorate([
943
+ (0, utils_1.InjectTransactionManager)(),
944
+ __param(2, (0, utils_1.MedusaContext)()),
945
+ __metadata("design:type", Function),
946
+ __metadata("design:paramtypes", [String, String, Object]),
947
+ __metadata("design:returntype", Promise)
948
+ ], PromotionModuleService.prototype, "revertCampaignBudgetUsageByAttribute_", null);
949
+ __decorate([
950
+ (0, utils_1.InjectTransactionManager)(),
951
+ (0, utils_1.EmitEvents)()
952
+ /**
953
+ * Register the usage of promotions in the campaign budget and
954
+ * increment the used value if the budget is not exceeded,
955
+ * throws an error if the budget is exceeded.
956
+ *
957
+ * @param computedActions - The computed actions to register usage for.
958
+ * @param registrationContext - The context of the campaign budget usage.
959
+ * @returns void
960
+ * @throws {MedusaError} - If the promotion usage exceeds the budget limit.
961
+ */
962
+ ,
963
+ __param(2, (0, utils_1.MedusaContext)()),
964
+ __metadata("design:type", Function),
965
+ __metadata("design:paramtypes", [Array, Object, Object]),
752
966
  __metadata("design:returntype", Promise)
753
967
  ], PromotionModuleService.prototype, "registerUsage", null);
754
968
  __decorate([
755
- (0, utils_1.InjectManager)(),
756
- __param(1, (0, utils_1.MedusaContext)()),
969
+ (0, utils_1.InjectTransactionManager)(),
970
+ (0, utils_1.EmitEvents)(),
971
+ __param(2, (0, utils_1.MedusaContext)()),
757
972
  __metadata("design:type", Function),
758
- __metadata("design:paramtypes", [Array, Object]),
973
+ __metadata("design:paramtypes", [Array, Object, Object]),
759
974
  __metadata("design:returntype", Promise)
760
975
  ], PromotionModuleService.prototype, "revertUsage", null);
761
976
  __decorate([
@@ -766,7 +981,8 @@ __decorate([
766
981
  __metadata("design:returntype", Promise)
767
982
  ], PromotionModuleService.prototype, "computeActions", null);
768
983
  __decorate([
769
- (0, utils_1.InjectManager)()
984
+ (0, utils_1.InjectManager)(),
985
+ (0, utils_1.EmitEvents)()
770
986
  // @ts-expect-error
771
987
  ,
772
988
  __param(1, (0, utils_1.MedusaContext)()),
@@ -782,7 +998,8 @@ __decorate([
782
998
  __metadata("design:returntype", Promise)
783
999
  ], PromotionModuleService.prototype, "createPromotions_", null);
784
1000
  __decorate([
785
- (0, utils_1.InjectManager)()
1001
+ (0, utils_1.InjectManager)(),
1002
+ (0, utils_1.EmitEvents)()
786
1003
  // @ts-expect-error
787
1004
  ,
788
1005
  __param(1, (0, utils_1.MedusaContext)()),
@@ -798,7 +1015,8 @@ __decorate([
798
1015
  __metadata("design:returntype", Promise)
799
1016
  ], PromotionModuleService.prototype, "updatePromotions_", null);
800
1017
  __decorate([
801
- (0, utils_1.InjectManager)()
1018
+ (0, utils_1.InjectManager)(),
1019
+ (0, utils_1.EmitEvents)()
802
1020
  // @ts-ignore
803
1021
  ,
804
1022
  __param(1, (0, utils_1.MedusaContext)()),
@@ -815,6 +1033,7 @@ __decorate([
815
1033
  ], PromotionModuleService.prototype, "updatePromotionRules_", null);
816
1034
  __decorate([
817
1035
  (0, utils_1.InjectManager)(),
1036
+ (0, utils_1.EmitEvents)(),
818
1037
  __param(2, (0, utils_1.MedusaContext)()),
819
1038
  __metadata("design:type", Function),
820
1039
  __metadata("design:paramtypes", [String, Array, Object]),
@@ -822,6 +1041,7 @@ __decorate([
822
1041
  ], PromotionModuleService.prototype, "addPromotionRules", null);
823
1042
  __decorate([
824
1043
  (0, utils_1.InjectManager)(),
1044
+ (0, utils_1.EmitEvents)(),
825
1045
  __param(2, (0, utils_1.MedusaContext)()),
826
1046
  __metadata("design:type", Function),
827
1047
  __metadata("design:paramtypes", [String, Array, Object]),
@@ -829,6 +1049,7 @@ __decorate([
829
1049
  ], PromotionModuleService.prototype, "addPromotionTargetRules", null);
830
1050
  __decorate([
831
1051
  (0, utils_1.InjectManager)(),
1052
+ (0, utils_1.EmitEvents)(),
832
1053
  __param(2, (0, utils_1.MedusaContext)()),
833
1054
  __metadata("design:type", Function),
834
1055
  __metadata("design:paramtypes", [String, Array, Object]),
@@ -843,6 +1064,7 @@ __decorate([
843
1064
  ], PromotionModuleService.prototype, "createPromotionRulesAndValues_", null);
844
1065
  __decorate([
845
1066
  (0, utils_1.InjectManager)(),
1067
+ (0, utils_1.EmitEvents)(),
846
1068
  __param(2, (0, utils_1.MedusaContext)()),
847
1069
  __metadata("design:type", Function),
848
1070
  __metadata("design:paramtypes", [String, Array, Object]),
@@ -857,6 +1079,7 @@ __decorate([
857
1079
  ], PromotionModuleService.prototype, "removePromotionRules_", null);
858
1080
  __decorate([
859
1081
  (0, utils_1.InjectManager)(),
1082
+ (0, utils_1.EmitEvents)(),
860
1083
  __param(2, (0, utils_1.MedusaContext)()),
861
1084
  __metadata("design:type", Function),
862
1085
  __metadata("design:paramtypes", [String, Array, Object]),
@@ -877,7 +1100,8 @@ __decorate([
877
1100
  __metadata("design:returntype", Promise)
878
1101
  ], PromotionModuleService.prototype, "removeApplicationMethodRules_", null);
879
1102
  __decorate([
880
- (0, utils_1.InjectManager)()
1103
+ (0, utils_1.InjectManager)(),
1104
+ (0, utils_1.EmitEvents)()
881
1105
  // @ts-expect-error
882
1106
  ,
883
1107
  __param(1, (0, utils_1.MedusaContext)()),
@@ -893,7 +1117,8 @@ __decorate([
893
1117
  __metadata("design:returntype", Promise)
894
1118
  ], PromotionModuleService.prototype, "createCampaigns_", null);
895
1119
  __decorate([
896
- (0, utils_1.InjectManager)()
1120
+ (0, utils_1.InjectManager)(),
1121
+ (0, utils_1.EmitEvents)()
897
1122
  // @ts-expect-error
898
1123
  ,
899
1124
  __param(1, (0, utils_1.MedusaContext)()),
@@ -910,6 +1135,8 @@ __decorate([
910
1135
  ], PromotionModuleService.prototype, "updateCampaigns_", null);
911
1136
  __decorate([
912
1137
  (0, utils_1.InjectManager)(),
1138
+ (0, utils_1.EmitEvents)(),
1139
+ __param(1, (0, utils_1.MedusaContext)()),
913
1140
  __metadata("design:type", Function),
914
1141
  __metadata("design:paramtypes", [Object, Object]),
915
1142
  __metadata("design:returntype", Promise)
@@ -923,6 +1150,8 @@ __decorate([
923
1150
  ], PromotionModuleService.prototype, "addPromotionsToCampaign_", null);
924
1151
  __decorate([
925
1152
  (0, utils_1.InjectManager)(),
1153
+ (0, utils_1.EmitEvents)(),
1154
+ __param(1, (0, utils_1.MedusaContext)()),
926
1155
  __metadata("design:type", Function),
927
1156
  __metadata("design:paramtypes", [Object, Object]),
928
1157
  __metadata("design:returntype", Promise)