@medusajs/promotion 0.0.5-snapshot-20240916110643 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. package/dist/index.d.ts +4 -5
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +20 -5
  4. package/dist/initialize/index.d.ts +5 -0
  5. package/dist/initialize/index.d.ts.map +1 -0
  6. package/dist/initialize/index.js +16 -0
  7. package/dist/joiner-config.d.ts +8 -1
  8. package/dist/joiner-config.d.ts.map +1 -1
  9. package/dist/joiner-config.js +35 -9
  10. package/dist/loaders/connection.d.ts +5 -0
  11. package/dist/loaders/connection.d.ts.map +1 -0
  12. package/dist/loaders/connection.js +41 -0
  13. package/dist/loaders/container.d.ts +3 -0
  14. package/dist/loaders/container.d.ts.map +1 -0
  15. package/dist/loaders/container.js +34 -0
  16. package/dist/loaders/index.d.ts +3 -0
  17. package/dist/loaders/index.d.ts.map +1 -0
  18. package/dist/loaders/index.js +18 -0
  19. package/dist/migrations/Migration20240227120221.d.ts.map +1 -1
  20. package/dist/migrations/Migration20240227120221.js +2 -10
  21. package/dist/models/application-method.d.ts +6 -4
  22. package/dist/models/application-method.d.ts.map +1 -1
  23. package/dist/models/application-method.js +6 -16
  24. package/dist/models/campaign-budget.d.ts +5 -6
  25. package/dist/models/campaign-budget.d.ts.map +1 -1
  26. package/dist/models/campaign-budget.js +4 -8
  27. package/dist/models/campaign.d.ts +4 -3
  28. package/dist/models/campaign.d.ts.map +1 -1
  29. package/dist/models/campaign.js +13 -10
  30. package/dist/models/promotion-rule-value.d.ts +1 -2
  31. package/dist/models/promotion-rule-value.d.ts.map +1 -1
  32. package/dist/models/promotion-rule-value.js +1 -1
  33. package/dist/models/promotion-rule.d.ts +1 -1
  34. package/dist/models/promotion-rule.d.ts.map +1 -1
  35. package/dist/models/promotion.d.ts +4 -5
  36. package/dist/models/promotion.d.ts.map +1 -1
  37. package/dist/models/promotion.js +4 -8
  38. package/dist/module-definition.d.ts +5 -0
  39. package/dist/module-definition.d.ts.map +1 -0
  40. package/dist/module-definition.js +50 -0
  41. package/dist/repositories/campaign.d.ts +16 -0
  42. package/dist/repositories/campaign.d.ts.map +1 -0
  43. package/dist/repositories/campaign.js +90 -0
  44. package/dist/repositories/index.d.ts +3 -0
  45. package/dist/repositories/index.d.ts.map +1 -0
  46. package/dist/repositories/index.js +7 -0
  47. package/dist/services/promotion-module.d.ts +26 -41
  48. package/dist/services/promotion-module.d.ts.map +1 -1
  49. package/dist/services/promotion-module.js +72 -271
  50. package/dist/types/application-method.d.ts +10 -12
  51. package/dist/types/application-method.d.ts.map +1 -1
  52. package/dist/types/campaign-budget.d.ts +6 -8
  53. package/dist/types/campaign-budget.d.ts.map +1 -1
  54. package/dist/types/campaign.d.ts +8 -6
  55. package/dist/types/campaign.d.ts.map +1 -1
  56. package/dist/types/promotion.d.ts +2 -2
  57. package/dist/types/promotion.d.ts.map +1 -1
  58. package/dist/utils/compute-actions/buy-get.d.ts +3 -6
  59. package/dist/utils/compute-actions/buy-get.d.ts.map +1 -1
  60. package/dist/utils/compute-actions/buy-get.js +30 -94
  61. package/dist/utils/compute-actions/line-items.d.ts.map +1 -1
  62. package/dist/utils/compute-actions/line-items.js +5 -5
  63. package/dist/utils/compute-actions/shipping-methods.d.ts +2 -2
  64. package/dist/utils/compute-actions/shipping-methods.d.ts.map +1 -1
  65. package/dist/utils/compute-actions/shipping-methods.js +18 -16
  66. package/dist/utils/compute-actions/usage.d.ts +3 -2
  67. package/dist/utils/compute-actions/usage.d.ts.map +1 -1
  68. package/dist/utils/compute-actions/usage.js +11 -4
  69. package/dist/utils/validations/application-method.d.ts.map +1 -1
  70. package/dist/utils/validations/application-method.js +2 -2
  71. package/dist/utils/validations/promotion-rule.d.ts +2 -2
  72. package/dist/utils/validations/promotion-rule.d.ts.map +1 -1
  73. package/dist/utils/validations/promotion-rule.js +2 -22
  74. package/package.json +14 -9
  75. package/dist/migrations/Migration20240617102917.d.ts +0 -6
  76. package/dist/migrations/Migration20240617102917.d.ts.map +0 -1
  77. package/dist/migrations/Migration20240617102917.js +0 -15
  78. package/dist/migrations/Migration20240624153824.d.ts +0 -6
  79. package/dist/migrations/Migration20240624153824.d.ts.map +0 -1
  80. package/dist/migrations/Migration20240624153824.js +0 -15
  81. package/dist/schema/index.d.ts +0 -3
  82. package/dist/schema/index.d.ts.map +0 -1
  83. package/dist/schema/index.js +0 -98
@@ -18,14 +18,14 @@ 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
- class PromotionModuleService extends (0, utils_1.MedusaService)({
22
- Promotion: _models_1.Promotion,
23
- ApplicationMethod: _models_1.ApplicationMethod,
24
- Campaign: _models_1.Campaign,
25
- CampaignBudget: _models_1.CampaignBudget,
26
- PromotionRule: _models_1.PromotionRule,
27
- PromotionRuleValue: _models_1.PromotionRuleValue,
28
- }) {
21
+ const generateMethodForModels = [
22
+ _models_1.ApplicationMethod,
23
+ _models_1.Campaign,
24
+ _models_1.CampaignBudget,
25
+ _models_1.PromotionRule,
26
+ _models_1.PromotionRuleValue,
27
+ ];
28
+ class PromotionModuleService extends utils_1.ModulesSdkUtils.abstractModuleServiceFactory(_models_1.Promotion, generateMethodForModels, joiner_config_1.entityNameToLinkableKeysMap) {
29
29
  constructor({ baseRepository, promotionService, applicationMethodService, promotionRuleService, promotionRuleValueService, campaignService, campaignBudgetService, }, moduleDeclaration) {
30
30
  // @ts-ignore
31
31
  super(...arguments);
@@ -45,19 +45,14 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
45
45
  const promotionCodes = computedActions
46
46
  .map((computedAction) => computedAction.code)
47
47
  .filter(Boolean);
48
- const campaignBudgetMap = new Map();
48
+ const promotionCodeCampaignBudgetMap = new Map();
49
49
  const promotionCodeUsageMap = new Map();
50
- const existingPromotions = await this.listPromotions({ code: promotionCodes }, {
51
- relations: ["campaign", "campaign.budget"],
52
- take: null,
53
- }, sharedContext);
54
- for (const promotion of existingPromotions) {
55
- if (promotion.campaign?.budget) {
56
- campaignBudgetMap.set(promotion.campaign?.budget.id, promotion.campaign?.budget);
57
- }
58
- }
50
+ const existingPromotions = await this.list({ code: promotionCodes }, { relations: ["application_method", "campaign", "campaign.budget"] }, sharedContext);
59
51
  const existingPromotionsMap = new Map(existingPromotions.map((promotion) => [promotion.code, promotion]));
60
52
  for (let computedAction of computedActions) {
53
+ if (!_utils_1.ComputeActionUtils.canRegisterUsage(computedAction)) {
54
+ continue;
55
+ }
61
56
  const promotion = existingPromotionsMap.get(computedAction.code);
62
57
  if (!promotion) {
63
58
  continue;
@@ -67,16 +62,14 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
67
62
  continue;
68
63
  }
69
64
  if (campaignBudget.type === utils_1.CampaignBudgetType.SPEND) {
70
- const campaignBudgetData = campaignBudgetMap.get(campaignBudget.id);
71
- if (!campaignBudgetData) {
72
- continue;
73
- }
74
- campaignBudgetData.used = utils_1.MathBN.add(campaignBudgetData.used ?? 0, computedAction.amount);
65
+ const campaignBudgetData = promotionCodeCampaignBudgetMap.get(campaignBudget.id) || { id: campaignBudget.id, used: campaignBudget.used ?? 0 };
66
+ campaignBudgetData.used =
67
+ (campaignBudgetData.used ?? 0) + computedAction.amount;
75
68
  if (campaignBudget.limit &&
76
- utils_1.MathBN.gt(campaignBudgetData.used, campaignBudget.limit)) {
69
+ campaignBudgetData.used > campaignBudget.limit) {
77
70
  continue;
78
71
  }
79
- campaignBudgetMap.set(campaignBudget.id, campaignBudgetData);
72
+ promotionCodeCampaignBudgetMap.set(campaignBudget.id, campaignBudgetData);
80
73
  }
81
74
  if (campaignBudget.type === utils_1.CampaignBudgetType.USAGE) {
82
75
  const promotionAlreadyUsed = promotionCodeUsageMap.get(promotion.code) || false;
@@ -85,69 +78,17 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
85
78
  }
86
79
  const campaignBudgetData = {
87
80
  id: campaignBudget.id,
88
- used: utils_1.MathBN.add(campaignBudget.used ?? 0, 1),
81
+ used: (campaignBudget.used ?? 0) + 1,
89
82
  };
90
83
  if (campaignBudget.limit &&
91
- utils_1.MathBN.gt(campaignBudgetData.used, campaignBudget.limit)) {
92
- continue;
93
- }
94
- campaignBudgetMap.set(campaignBudget.id, campaignBudgetData);
95
- promotionCodeUsageMap.set(promotion.code, true);
96
- }
97
- const campaignBudgetsData = [];
98
- for (const [_, campaignBudgetData] of campaignBudgetMap) {
99
- campaignBudgetsData.push(campaignBudgetData);
100
- }
101
- await this.campaignBudgetService_.update(campaignBudgetsData, sharedContext);
102
- }
103
- }
104
- async revertUsage(computedActions, sharedContext = {}) {
105
- const promotionCodeUsageMap = new Map();
106
- const campaignBudgetMap = new Map();
107
- const existingPromotions = await this.listPromotions({
108
- code: computedActions
109
- .map((computedAction) => computedAction.code)
110
- .filter(Boolean),
111
- }, {
112
- relations: ["campaign", "campaign.budget"],
113
- take: null,
114
- }, sharedContext);
115
- for (const promotion of existingPromotions) {
116
- if (promotion.campaign?.budget) {
117
- campaignBudgetMap.set(promotion.campaign?.budget.id, promotion.campaign?.budget);
118
- }
119
- }
120
- const existingPromotionsMap = new Map(existingPromotions.map((promotion) => [promotion.code, promotion]));
121
- for (let computedAction of computedActions) {
122
- const promotion = existingPromotionsMap.get(computedAction.code);
123
- if (!promotion) {
124
- continue;
125
- }
126
- const campaignBudget = promotion.campaign?.budget;
127
- if (!campaignBudget) {
128
- continue;
129
- }
130
- if (campaignBudget.type === utils_1.CampaignBudgetType.SPEND) {
131
- const campaignBudgetData = campaignBudgetMap.get(campaignBudget.id);
132
- if (!campaignBudgetData) {
84
+ campaignBudgetData.used > campaignBudget.limit) {
133
85
  continue;
134
86
  }
135
- campaignBudgetData.used = utils_1.MathBN.sub(campaignBudgetData.used ?? 0, computedAction.amount);
136
- campaignBudgetMap.set(campaignBudget.id, campaignBudgetData);
137
- }
138
- if (campaignBudget.type === utils_1.CampaignBudgetType.USAGE) {
139
- const promotionAlreadyUsed = promotionCodeUsageMap.get(promotion.code) || false;
140
- if (promotionAlreadyUsed) {
141
- continue;
142
- }
143
- campaignBudgetMap.set(campaignBudget.id, {
144
- id: campaignBudget.id,
145
- used: utils_1.MathBN.sub(campaignBudget.used ?? 0, 1),
146
- });
87
+ promotionCodeCampaignBudgetMap.set(campaignBudget.id, campaignBudgetData);
147
88
  promotionCodeUsageMap.set(promotion.code, true);
148
89
  }
149
90
  const campaignBudgetsData = [];
150
- for (const [_, campaignBudgetData] of campaignBudgetMap) {
91
+ for (const [_, campaignBudgetData] of promotionCodeCampaignBudgetMap) {
151
92
  campaignBudgetsData.push(campaignBudgetData);
152
93
  }
153
94
  await this.campaignBudgetService_.update(campaignBudgetsData, sharedContext);
@@ -161,13 +102,9 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
161
102
  const appliedShippingCodes = [];
162
103
  const codeAdjustmentMap = new Map();
163
104
  const methodIdPromoValueMap = new Map();
164
- // Keeps a map of all elgible items in the buy section and its eligible quantity
165
- const eligibleBuyItemMap = new Map();
166
- // Keeps a map of all elgible items in the target section and its eligible quantity
167
- const eligibleTargetItemMap = new Map();
168
105
  const automaticPromotions = preventAutoPromotions
169
106
  ? []
170
- : await this.listPromotions({ is_automatic: true }, { select: ["code"], take: null }, sharedContext);
107
+ : await this.list({ is_automatic: true }, { select: ["code"], take: null }, sharedContext);
171
108
  // Promotions we need to apply includes all the codes that are passed as an argument
172
109
  // to this method, along with any automatic promotions that can be applied to the context
173
110
  const automaticPromotionCodes = automaticPromotions.map((p) => p.code);
@@ -195,7 +132,7 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
195
132
  }
196
133
  });
197
134
  });
198
- const promotions = await this.listPromotions({
135
+ const promotions = await this.list({
199
136
  code: [
200
137
  ...promotionCodesToApply,
201
138
  ...appliedItemCodes,
@@ -246,12 +183,12 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
246
183
  if (!applicationMethod) {
247
184
  continue;
248
185
  }
249
- const isPromotionApplicable = (0, _utils_1.areRulesValidForContext)(promotionRules, applicationContext, utils_1.ApplicationMethodTargetType.ORDER);
186
+ const isPromotionApplicable = (0, _utils_1.areRulesValidForContext)(promotionRules, applicationContext);
250
187
  if (!isPromotionApplicable) {
251
188
  continue;
252
189
  }
253
190
  if (promotion.type === utils_1.PromotionType.BUYGET) {
254
- const computedActionsForItems = _utils_1.ComputeActionUtils.getComputedActionsForBuyGet(promotion, applicationContext[utils_1.ApplicationMethodTargetType.ITEMS], methodIdPromoValueMap, eligibleBuyItemMap, eligibleTargetItemMap);
191
+ const computedActionsForItems = _utils_1.ComputeActionUtils.getComputedActionsForBuyGet(promotion, applicationContext[utils_1.ApplicationMethodTargetType.ITEMS], methodIdPromoValueMap);
255
192
  computedActions.push(...computedActionsForItems);
256
193
  }
257
194
  if (promotion.type === utils_1.PromotionType.STANDARD) {
@@ -272,13 +209,12 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
272
209
  }
273
210
  }
274
211
  }
275
- (0, utils_1.transformPropertiesToBigNumber)(computedActions, { include: ["amount"] });
276
212
  return computedActions;
277
213
  }
278
- async createPromotions(data, sharedContext = {}) {
214
+ async create(data, sharedContext = {}) {
279
215
  const input = Array.isArray(data) ? data : [data];
280
- const createdPromotions = await this.createPromotions_(input, sharedContext);
281
- const promotions = await this.listPromotions({ id: createdPromotions.map((p) => p.id) }, {
216
+ const createdPromotions = await this.create_(input, sharedContext);
217
+ const promotions = await this.list({ id: createdPromotions.map((p) => p.id) }, {
282
218
  relations: [
283
219
  "application_method",
284
220
  "application_method.target_rules",
@@ -294,45 +230,31 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
294
230
  }, sharedContext);
295
231
  return Array.isArray(data) ? promotions : promotions[0];
296
232
  }
297
- async createPromotions_(data, sharedContext = {}) {
233
+ async create_(data, sharedContext = {}) {
298
234
  const promotionsData = [];
299
235
  const applicationMethodsData = [];
300
236
  const campaignsData = [];
301
- const existingCampaigns = await this.campaignService_.list({ id: data.map((d) => d.campaign_id).filter((id) => (0, utils_1.isString)(id)) }, { relations: ["budget"] }, sharedContext);
302
237
  const promotionCodeApplicationMethodDataMap = new Map();
303
238
  const promotionCodeRulesDataMap = new Map();
304
239
  const methodTargetRulesMap = new Map();
305
240
  const methodBuyRulesMap = new Map();
306
241
  const promotionCodeCampaignMap = new Map();
307
242
  for (const { application_method: applicationMethodData, rules: rulesData, campaign: campaignData, campaign_id: campaignId, ...promotionData } of data) {
308
- promotionCodeApplicationMethodDataMap.set(promotionData.code, applicationMethodData);
243
+ if (applicationMethodData) {
244
+ promotionCodeApplicationMethodDataMap.set(promotionData.code, applicationMethodData);
245
+ }
309
246
  if (rulesData) {
310
247
  promotionCodeRulesDataMap.set(promotionData.code, rulesData);
311
248
  }
312
249
  if (campaignData && campaignId) {
313
250
  throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Provide either the 'campaign' or 'campaign_id' parameter; both cannot be used simultaneously.`);
314
251
  }
315
- if (!campaignData && !campaignId) {
316
- promotionsData.push({ ...promotionData });
317
- continue;
318
- }
319
- const existingCampaign = existingCampaigns.find((c) => c.id === campaignId);
320
- if (campaignId && !existingCampaign) {
321
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, `Could not find campaign with id - ${campaignId}`);
322
- }
323
- const campaignCurrency = campaignData?.budget?.currency_code ||
324
- existingCampaigns.find((c) => c.id === campaignId)?.budget
325
- ?.currency_code;
326
- if (campaignData?.budget?.type === utils_1.CampaignBudgetType.SPEND &&
327
- campaignCurrency !== applicationMethodData?.currency_code) {
328
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Currency between promotion and campaigns should match`);
329
- }
330
252
  if (campaignData) {
331
253
  promotionCodeCampaignMap.set(promotionData.code, campaignData);
332
254
  }
333
255
  promotionsData.push({
334
256
  ...promotionData,
335
- campaign_id: campaignId,
257
+ campaign: campaignId,
336
258
  });
337
259
  }
338
260
  const createdPromotions = await this.promotionService_.create(promotionsData, sharedContext);
@@ -375,14 +297,8 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
375
297
  await this.createPromotionRulesAndValues_(promotionCodeRulesDataMap.get(promotion.code) || [], "promotions", promotion, sharedContext);
376
298
  }
377
299
  const createdApplicationMethods = await this.applicationMethodService_.create(applicationMethodsData, sharedContext);
378
- const createdCampaigns = await this.createCampaigns(campaignsData, sharedContext);
379
- for (const campaignData of campaignsData) {
380
- const promotions = campaignData.promotions;
381
- const campaign = createdCampaigns.find((c) => c.campaign_identifier === campaignData.campaign_identifier);
382
- if (!campaign || !promotions || !promotions.length) {
383
- continue;
384
- }
385
- await this.addPromotionsToCampaign({ id: campaign.id, promotion_ids: promotions.map((p) => p.id) }, sharedContext);
300
+ if (campaignsData.length) {
301
+ await this.createCampaigns(campaignsData, sharedContext);
386
302
  }
387
303
  for (const applicationMethod of createdApplicationMethods) {
388
304
  await this.createPromotionRulesAndValues_(methodTargetRulesMap.get(applicationMethod.promotion.id) || [], "method_target_rules", applicationMethod, sharedContext);
@@ -390,10 +306,10 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
390
306
  }
391
307
  return createdPromotions;
392
308
  }
393
- async updatePromotions(data, sharedContext = {}) {
309
+ async update(data, sharedContext = {}) {
394
310
  const input = Array.isArray(data) ? data : [data];
395
- const updatedPromotions = await this.updatePromotions_(input, sharedContext);
396
- const promotions = await this.listPromotions({ id: updatedPromotions.map((p) => p.id) }, {
311
+ const updatedPromotions = await this.update_(input, sharedContext);
312
+ const promotions = await this.list({ id: updatedPromotions.map((p) => p.id) }, {
397
313
  relations: [
398
314
  "application_method",
399
315
  "application_method.target_rules",
@@ -407,34 +323,25 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
407
323
  }, sharedContext);
408
324
  return Array.isArray(data) ? promotions : promotions[0];
409
325
  }
410
- async updatePromotions_(data, sharedContext = {}) {
326
+ async update_(data, sharedContext = {}) {
411
327
  const promotionIds = data.map((d) => d.id);
412
328
  const existingPromotions = await this.promotionService_.list({ id: promotionIds }, { relations: ["application_method"] });
413
- const existingCampaigns = await this.campaignService_.list({ id: data.map((d) => d.campaign_id).filter((d) => (0, utils_1.isPresent)(d)) }, { relations: ["budget"] });
414
329
  const existingPromotionsMap = new Map(existingPromotions.map((promotion) => [promotion.id, promotion]));
415
330
  const promotionsData = [];
416
331
  const applicationMethodsData = [];
417
332
  for (const { application_method: applicationMethodData, campaign_id: campaignId, ...promotionData } of data) {
418
- const existingCampaign = existingCampaigns.find((c) => c.id === campaignId);
419
- const existingPromotion = existingPromotionsMap.get(promotionData.id);
420
- const existingApplicationMethod = existingPromotion?.application_method;
421
- const promotionCurrencyCode = existingApplicationMethod?.currency_code ||
422
- applicationMethodData?.currency_code;
423
- if (campaignId && !existingCampaign) {
424
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Could not find campaign with id ${campaignId}`);
425
- }
426
- if (campaignId &&
427
- existingCampaign?.budget?.type === utils_1.CampaignBudgetType.SPEND &&
428
- existingCampaign.budget.currency_code !== promotionCurrencyCode) {
429
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Currency code doesn't match for campaign (${campaignId}) and promotion (${existingPromotion.id})`);
430
- }
431
- if ((0, utils_1.isDefined)(campaignId)) {
432
- promotionsData.push({ ...promotionData, campaign_id: campaignId });
333
+ if (campaignId) {
334
+ promotionsData.push({ ...promotionData, campaign: campaignId });
433
335
  }
434
336
  else {
435
337
  promotionsData.push(promotionData);
436
338
  }
437
- if (!applicationMethodData || !existingApplicationMethod) {
339
+ if (!applicationMethodData) {
340
+ continue;
341
+ }
342
+ const existingPromotion = existingPromotionsMap.get(promotionData.id);
343
+ const existingApplicationMethod = existingPromotion?.application_method;
344
+ if (!existingApplicationMethod) {
438
345
  continue;
439
346
  }
440
347
  if (applicationMethodData.allocation &&
@@ -454,10 +361,9 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
454
361
  }
455
362
  return updatedPromotions;
456
363
  }
457
- // @ts-ignore
458
364
  async updatePromotionRules(data, sharedContext = {}) {
459
365
  const updatedPromotionRules = await this.updatePromotionRules_(data, sharedContext);
460
- return await this.listPromotionRules({ id: updatedPromotionRules.map((r) => r.id) }, { relations: ["values"] }, sharedContext);
366
+ return this.listPromotionRules({ id: updatedPromotionRules.map((r) => r.id) }, { relations: ["values"] }, sharedContext);
461
367
  }
462
368
  async updatePromotionRules_(data, sharedContext = {}) {
463
369
  const promotionRuleIds = data.map((d) => d.id);
@@ -507,7 +413,9 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
507
413
  return await this.listPromotionRules({ id: createdPromotionRules.map((pr) => pr.id) }, { relations: ["values"] }, sharedContext);
508
414
  }
509
415
  async addPromotionBuyRules(promotionId, rulesData, sharedContext = {}) {
510
- const promotion = await this.promotionService_.retrieve(promotionId, { relations: ["application_method"] }, sharedContext);
416
+ const promotion = await this.promotionService_.retrieve(promotionId, {
417
+ relations: ["application_method"],
418
+ });
511
419
  const applicationMethod = promotion.application_method;
512
420
  if (!applicationMethod) {
513
421
  throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `application_method for promotion not found`);
@@ -583,19 +491,22 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
583
491
  const campaignBudgetsData = [];
584
492
  const campaignIdentifierBudgetMap = new Map();
585
493
  for (const createCampaignData of data) {
586
- const { budget: campaignBudgetData, ...campaignData } = createCampaignData;
494
+ const { budget: campaignBudgetData, promotions, ...campaignData } = createCampaignData;
495
+ const promotionsToAdd = promotions
496
+ ? await this.list({ id: promotions.map((p) => p.id) }, { take: null }, sharedContext)
497
+ : [];
587
498
  if (campaignBudgetData) {
588
499
  campaignIdentifierBudgetMap.set(campaignData.campaign_identifier, campaignBudgetData);
589
500
  }
590
501
  campaignsData.push({
591
502
  ...campaignData,
503
+ promotions: promotionsToAdd,
592
504
  });
593
505
  }
594
506
  const createdCampaigns = await this.campaignService_.create(campaignsData, sharedContext);
595
507
  for (const createdCampaign of createdCampaigns) {
596
508
  const campaignBudgetData = campaignIdentifierBudgetMap.get(createdCampaign.campaign_identifier);
597
509
  if (campaignBudgetData) {
598
- this.validateCampaignBudgetData(campaignBudgetData);
599
510
  campaignBudgetsData.push({
600
511
  ...campaignBudgetData,
601
512
  campaign: createdCampaign.id,
@@ -607,15 +518,6 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
607
518
  }
608
519
  return createdCampaigns;
609
520
  }
610
- validateCampaignBudgetData(data) {
611
- if (!data.type) {
612
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Campaign Budget type is a required field`);
613
- }
614
- if (data.type === utils_1.CampaignBudgetType.SPEND &&
615
- !(0, utils_1.isPresent)(data.currency_code)) {
616
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Campaign Budget type is a required field`);
617
- }
618
- }
619
521
  async updateCampaigns(data, sharedContext = {}) {
620
522
  const input = Array.isArray(data) ? data : [data];
621
523
  const updatedCampaigns = await this.updateCampaigns_(input, sharedContext);
@@ -628,109 +530,36 @@ class PromotionModuleService extends (0, utils_1.MedusaService)({
628
530
  async updateCampaigns_(data, sharedContext = {}) {
629
531
  const campaignIds = data.map((d) => d.id);
630
532
  const campaignsData = [];
631
- const updateBudgetData = [];
632
- const createBudgetData = [];
533
+ const campaignBudgetsData = [];
633
534
  const existingCampaigns = await this.listCampaigns({ id: campaignIds }, { relations: ["budget"], take: null }, sharedContext);
634
535
  const existingCampaignsMap = new Map(existingCampaigns.map((campaign) => [campaign.id, campaign]));
635
536
  for (const updateCampaignData of data) {
636
- const { budget: budgetData, ...campaignData } = updateCampaignData;
537
+ const { budget: campaignBudgetData, ...campaignData } = updateCampaignData;
637
538
  const existingCampaign = existingCampaignsMap.get(campaignData.id);
539
+ const existingCampaignBudget = existingCampaign?.budget;
638
540
  campaignsData.push(campaignData);
639
- // Type & currency code of the budget is immutable, we don't allow for it to be updated.
640
- // If an existing budget is present, we remove the type and currency from being updated
641
- if ((existingCampaign?.budget && budgetData?.type) ||
642
- budgetData?.currency_code) {
643
- delete budgetData?.type;
644
- delete budgetData?.currency_code;
645
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Campaign budget attributes (type, currency_code) are immutable`);
646
- }
647
- if (budgetData) {
648
- if (existingCampaign?.budget) {
649
- updateBudgetData.push({
650
- id: existingCampaign.budget.id,
651
- ...budgetData,
652
- });
653
- }
654
- else {
655
- createBudgetData.push({
656
- ...budgetData,
657
- campaign: existingCampaign.id,
658
- });
659
- }
541
+ if (existingCampaignBudget && campaignBudgetData) {
542
+ campaignBudgetsData.push({
543
+ id: existingCampaignBudget.id,
544
+ ...campaignBudgetData,
545
+ });
660
546
  }
661
547
  }
662
548
  const updatedCampaigns = await this.campaignService_.update(campaignsData, sharedContext);
663
- if (updateBudgetData.length) {
664
- await this.campaignBudgetService_.update(updateBudgetData, sharedContext);
665
- }
666
- if (createBudgetData.length) {
667
- await this.campaignBudgetService_.create(createBudgetData, sharedContext);
549
+ if (campaignBudgetsData.length) {
550
+ await this.campaignBudgetService_.update(campaignBudgetsData, sharedContext);
668
551
  }
669
552
  return updatedCampaigns;
670
553
  }
671
- async addPromotionsToCampaign(data, sharedContext) {
672
- const ids = await this.addPromotionsToCampaign_(data, sharedContext);
673
- return { ids };
674
- }
675
- // TODO:
676
- // - introduce currency_code to promotion
677
- // - allow promotions to be queried by currency code
678
- // - when the above is present, validate adding promotion to campaign based on currency code
679
- async addPromotionsToCampaign_(data, sharedContext = {}) {
680
- const { id, promotion_ids: promotionIds = [] } = data;
681
- const campaign = await this.campaignService_.retrieve(id, {}, sharedContext);
682
- const promotionsToAdd = await this.promotionService_.list({ id: promotionIds, campaign_id: null }, { take: null, relations: ["application_method"] }, sharedContext);
683
- const diff = (0, utils_1.arrayDifference)(promotionsToAdd.map((p) => p.id), promotionIds);
684
- if (diff.length > 0) {
685
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, `Cannot add promotions (${diff.join(",")}) to campaign. These promotions are either already part of a campaign or not found.`);
686
- }
687
- const promotionsWithInvalidCurrency = promotionsToAdd.filter((promotion) => campaign.budget?.type === utils_1.CampaignBudgetType.SPEND &&
688
- promotion.application_method?.currency_code !==
689
- campaign?.budget?.currency_code);
690
- if (promotionsWithInvalidCurrency.length > 0) {
691
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Cannot add promotions to campaign where currency_code don't match.`);
692
- }
693
- await this.promotionService_.update(promotionsToAdd.map((promotion) => ({
694
- id: promotion.id,
695
- campaign_id: campaign.id,
696
- })), sharedContext);
697
- return promotionsToAdd.map((promo) => promo.id);
698
- }
699
- async removePromotionsFromCampaign(data, sharedContext) {
700
- const ids = await this.removePromotionsFromCampaign_(data, sharedContext);
701
- return { ids };
702
- }
703
- async removePromotionsFromCampaign_(data, sharedContext = {}) {
704
- const { id, promotion_ids: promotionIds = [] } = data;
705
- await this.campaignService_.retrieve(id, {}, sharedContext);
706
- const promotionsToRemove = await this.promotionService_.list({ id: promotionIds }, { take: null }, sharedContext);
707
- const diff = (0, utils_1.arrayDifference)(promotionsToRemove.map((p) => p.id), promotionIds);
708
- if (diff.length > 0) {
709
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, `Promotions with ids (${diff.join(",")}) not found.`);
710
- }
711
- await this.promotionService_.update(promotionsToRemove.map((promotion) => ({
712
- id: promotion.id,
713
- campaign_id: null,
714
- })), sharedContext);
715
- return promotionsToRemove.map((promo) => promo.id);
716
- }
717
554
  }
718
555
  exports.default = PromotionModuleService;
719
556
  __decorate([
720
557
  (0, utils_1.InjectManager)("baseRepository_"),
721
558
  __param(1, (0, utils_1.MedusaContext)()),
722
- __param(1, (0, utils_1.MedusaContext)()),
723
559
  __metadata("design:type", Function),
724
560
  __metadata("design:paramtypes", [Array, Object]),
725
561
  __metadata("design:returntype", Promise)
726
562
  ], PromotionModuleService.prototype, "registerUsage", null);
727
- __decorate([
728
- (0, utils_1.InjectManager)("baseRepository_"),
729
- __param(1, (0, utils_1.MedusaContext)()),
730
- __metadata("design:type", Function),
731
- __metadata("design:paramtypes", [Array, Object]),
732
- __metadata("design:returntype", Promise)
733
- ], PromotionModuleService.prototype, "revertUsage", null);
734
563
  __decorate([
735
564
  (0, utils_1.InjectManager)("baseRepository_"),
736
565
  __param(3, (0, utils_1.MedusaContext)()),
@@ -744,32 +573,30 @@ __decorate([
744
573
  __metadata("design:type", Function),
745
574
  __metadata("design:paramtypes", [Object, Object]),
746
575
  __metadata("design:returntype", Promise)
747
- ], PromotionModuleService.prototype, "createPromotions", null);
576
+ ], PromotionModuleService.prototype, "create", null);
748
577
  __decorate([
749
578
  (0, utils_1.InjectTransactionManager)("baseRepository_"),
750
579
  __param(1, (0, utils_1.MedusaContext)()),
751
580
  __metadata("design:type", Function),
752
581
  __metadata("design:paramtypes", [Array, Object]),
753
582
  __metadata("design:returntype", Promise)
754
- ], PromotionModuleService.prototype, "createPromotions_", null);
583
+ ], PromotionModuleService.prototype, "create_", null);
755
584
  __decorate([
756
585
  (0, utils_1.InjectManager)("baseRepository_"),
757
586
  __param(1, (0, utils_1.MedusaContext)()),
758
587
  __metadata("design:type", Function),
759
588
  __metadata("design:paramtypes", [Object, Object]),
760
589
  __metadata("design:returntype", Promise)
761
- ], PromotionModuleService.prototype, "updatePromotions", null);
590
+ ], PromotionModuleService.prototype, "update", null);
762
591
  __decorate([
763
592
  (0, utils_1.InjectTransactionManager)("baseRepository_"),
764
593
  __param(1, (0, utils_1.MedusaContext)()),
765
594
  __metadata("design:type", Function),
766
595
  __metadata("design:paramtypes", [Array, Object]),
767
596
  __metadata("design:returntype", Promise)
768
- ], PromotionModuleService.prototype, "updatePromotions_", null);
597
+ ], PromotionModuleService.prototype, "update_", null);
769
598
  __decorate([
770
- (0, utils_1.InjectManager)("baseRepository_")
771
- // @ts-ignore
772
- ,
599
+ (0, utils_1.InjectManager)("baseRepository_"),
773
600
  __param(1, (0, utils_1.MedusaContext)()),
774
601
  __metadata("design:type", Function),
775
602
  __metadata("design:paramtypes", [Array, Object]),
@@ -873,29 +700,3 @@ __decorate([
873
700
  __metadata("design:paramtypes", [Array, Object]),
874
701
  __metadata("design:returntype", Promise)
875
702
  ], PromotionModuleService.prototype, "updateCampaigns_", null);
876
- __decorate([
877
- (0, utils_1.InjectManager)("baseRepository_"),
878
- __metadata("design:type", Function),
879
- __metadata("design:paramtypes", [Object, Object]),
880
- __metadata("design:returntype", Promise)
881
- ], PromotionModuleService.prototype, "addPromotionsToCampaign", null);
882
- __decorate([
883
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
884
- __param(1, (0, utils_1.MedusaContext)()),
885
- __metadata("design:type", Function),
886
- __metadata("design:paramtypes", [Object, Object]),
887
- __metadata("design:returntype", Promise)
888
- ], PromotionModuleService.prototype, "addPromotionsToCampaign_", null);
889
- __decorate([
890
- (0, utils_1.InjectManager)("baseRepository_"),
891
- __metadata("design:type", Function),
892
- __metadata("design:paramtypes", [Object, Object]),
893
- __metadata("design:returntype", Promise)
894
- ], PromotionModuleService.prototype, "removePromotionsFromCampaign", null);
895
- __decorate([
896
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
897
- __param(1, (0, utils_1.MedusaContext)()),
898
- __metadata("design:type", Function),
899
- __metadata("design:paramtypes", [Object, Object]),
900
- __metadata("design:returntype", Promise)
901
- ], PromotionModuleService.prototype, "removePromotionsFromCampaign_", null);
@@ -1,26 +1,24 @@
1
- import { ApplicationMethodAllocationValues, ApplicationMethodTargetTypeValues, ApplicationMethodTypeValues, BigNumberInput, PromotionDTO } from "@medusajs/types";
1
+ import { ApplicationMethodAllocationValues, ApplicationMethodTargetTypeValues, ApplicationMethodTypeValues, PromotionDTO } from "@medusajs/types";
2
2
  import { Promotion } from "../models";
3
3
  export interface CreateApplicationMethodDTO {
4
4
  type: ApplicationMethodTypeValues;
5
5
  target_type: ApplicationMethodTargetTypeValues;
6
6
  allocation?: ApplicationMethodAllocationValues;
7
- value?: BigNumberInput;
8
- currency_code?: string | null;
7
+ value?: number;
9
8
  promotion: Promotion | string | PromotionDTO;
10
- max_quantity?: BigNumberInput | null;
11
- buy_rules_min_quantity?: BigNumberInput | null;
12
- apply_to_quantity?: BigNumberInput | null;
9
+ max_quantity?: number | null;
10
+ buy_rules_min_quantity?: number | null;
11
+ apply_to_quantity?: number | null;
13
12
  }
14
13
  export interface UpdateApplicationMethodDTO {
15
- id?: string;
14
+ id: string;
16
15
  type?: ApplicationMethodTypeValues;
17
16
  target_type?: ApplicationMethodTargetTypeValues;
18
17
  allocation?: ApplicationMethodAllocationValues;
19
- value?: BigNumberInput;
20
- currency_code?: string | null;
18
+ value?: number;
21
19
  promotion?: Promotion | string | PromotionDTO;
22
- max_quantity?: BigNumberInput | null;
23
- buy_rules_min_quantity?: BigNumberInput | null;
24
- apply_to_quantity?: BigNumberInput | null;
20
+ max_quantity?: number | null;
21
+ buy_rules_min_quantity?: number | null;
22
+ apply_to_quantity?: number | null;
25
23
  }
26
24
  //# sourceMappingURL=application-method.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"application-method.d.ts","sourceRoot":"","sources":["../../src/types/application-method.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,EACjC,iCAAiC,EACjC,2BAA2B,EAC3B,cAAc,EACd,YAAY,EACb,MAAM,iBAAiB,CAAA;AAExB,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAEnC,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,2BAA2B,CAAA;IACjC,WAAW,EAAE,iCAAiC,CAAA;IAC9C,UAAU,CAAC,EAAE,iCAAiC,CAAA;IAC9C,KAAK,CAAC,EAAE,cAAc,CAAA;IACtB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,SAAS,EAAE,SAAS,GAAG,MAAM,GAAG,YAAY,CAAA;IAC5C,YAAY,CAAC,EAAE,cAAc,GAAG,IAAI,CAAA;IACpC,sBAAsB,CAAC,EAAE,cAAc,GAAG,IAAI,CAAA;IAC9C,iBAAiB,CAAC,EAAE,cAAc,GAAG,IAAI,CAAA;CAC1C;AAED,MAAM,WAAW,0BAA0B;IACzC,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,IAAI,CAAC,EAAE,2BAA2B,CAAA;IAClC,WAAW,CAAC,EAAE,iCAAiC,CAAA;IAC/C,UAAU,CAAC,EAAE,iCAAiC,CAAA;IAC9C,KAAK,CAAC,EAAE,cAAc,CAAA;IACtB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,SAAS,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,YAAY,CAAA;IAC7C,YAAY,CAAC,EAAE,cAAc,GAAG,IAAI,CAAA;IACpC,sBAAsB,CAAC,EAAE,cAAc,GAAG,IAAI,CAAA;IAC9C,iBAAiB,CAAC,EAAE,cAAc,GAAG,IAAI,CAAA;CAC1C"}
1
+ {"version":3,"file":"application-method.d.ts","sourceRoot":"","sources":["../../src/types/application-method.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,EACjC,iCAAiC,EACjC,2BAA2B,EAC3B,YAAY,EACb,MAAM,iBAAiB,CAAA;AAExB,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAEnC,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,2BAA2B,CAAA;IACjC,WAAW,EAAE,iCAAiC,CAAA;IAC9C,UAAU,CAAC,EAAE,iCAAiC,CAAA;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,SAAS,GAAG,MAAM,GAAG,YAAY,CAAA;IAC5C,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAClC;AAED,MAAM,WAAW,0BAA0B;IACzC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,2BAA2B,CAAA;IAClC,WAAW,CAAC,EAAE,iCAAiC,CAAA;IAC/C,UAAU,CAAC,EAAE,iCAAiC,CAAA;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,YAAY,CAAA;IAC7C,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAClC"}
@@ -1,17 +1,15 @@
1
- import { BigNumberInput, CampaignBudgetTypeValues } from "@medusajs/types";
1
+ import { CampaignBudgetTypeValues } from "@medusajs/types";
2
2
  import { Campaign } from "../models";
3
3
  export interface CreateCampaignBudgetDTO {
4
- type?: CampaignBudgetTypeValues;
5
- limit?: BigNumberInput | null;
6
- currency_code?: string | null;
7
- used?: BigNumberInput;
4
+ type: CampaignBudgetTypeValues;
5
+ limit: number | null;
6
+ used?: number;
8
7
  campaign?: Campaign | string;
9
8
  }
10
9
  export interface UpdateCampaignBudgetDTO {
11
10
  id: string;
12
11
  type?: CampaignBudgetTypeValues;
13
- limit?: BigNumberInput | null;
14
- currency_code?: string | null;
15
- used?: BigNumberInput;
12
+ limit?: number | null;
13
+ used?: number;
16
14
  }
17
15
  //# sourceMappingURL=campaign-budget.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"campaign-budget.d.ts","sourceRoot":"","sources":["../../src/types/campaign-budget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAA;AAC1E,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAElC,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,EAAE,wBAAwB,CAAA;IAC/B,KAAK,CAAC,EAAE,cAAc,GAAG,IAAI,CAAA;IAC7B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,IAAI,CAAC,EAAE,cAAc,CAAA;IACrB,QAAQ,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAA;CAC7B;AAED,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,wBAAwB,CAAA;IAC/B,KAAK,CAAC,EAAE,cAAc,GAAG,IAAI,CAAA;IAC7B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,IAAI,CAAC,EAAE,cAAc,CAAA;CACtB"}
1
+ {"version":3,"file":"campaign-budget.d.ts","sourceRoot":"","sources":["../../src/types/campaign-budget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAA;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAElC,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,wBAAwB,CAAA;IAC9B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAA;CAC7B;AAED,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,wBAAwB,CAAA;IAC/B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd"}