@medusajs/pricing 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 (94) hide show
  1. package/dist/joiner-config.d.ts.map +1 -1
  2. package/dist/joiner-config.js +0 -5
  3. package/dist/joiner-config.js.map +1 -1
  4. package/dist/migrations/Migration20230929122253.d.ts +1 -1
  5. package/dist/migrations/Migration20230929122253.d.ts.map +1 -1
  6. package/dist/migrations/Migration20230929122253.js +1 -1
  7. package/dist/migrations/Migration20230929122253.js.map +1 -1
  8. package/dist/migrations/Migration20240322094407.d.ts +1 -1
  9. package/dist/migrations/Migration20240322094407.d.ts.map +1 -1
  10. package/dist/migrations/Migration20240322094407.js +1 -1
  11. package/dist/migrations/Migration20240322094407.js.map +1 -1
  12. package/dist/migrations/Migration20240322113359.d.ts +1 -1
  13. package/dist/migrations/Migration20240322113359.d.ts.map +1 -1
  14. package/dist/migrations/Migration20240322113359.js +1 -1
  15. package/dist/migrations/Migration20240322113359.js.map +1 -1
  16. package/dist/migrations/Migration20240322120125.d.ts +1 -1
  17. package/dist/migrations/Migration20240322120125.d.ts.map +1 -1
  18. package/dist/migrations/Migration20240322120125.js +1 -1
  19. package/dist/migrations/Migration20240322120125.js.map +1 -1
  20. package/dist/migrations/Migration20240626133555.d.ts +1 -1
  21. package/dist/migrations/Migration20240626133555.d.ts.map +1 -1
  22. package/dist/migrations/Migration20240626133555.js +1 -1
  23. package/dist/migrations/Migration20240626133555.js.map +1 -1
  24. package/dist/migrations/Migration20240704094505.d.ts +1 -1
  25. package/dist/migrations/Migration20240704094505.d.ts.map +1 -1
  26. package/dist/migrations/Migration20240704094505.js +1 -1
  27. package/dist/migrations/Migration20240704094505.js.map +1 -1
  28. package/dist/migrations/Migration20241127114534.d.ts +1 -1
  29. package/dist/migrations/Migration20241127114534.d.ts.map +1 -1
  30. package/dist/migrations/Migration20241127114534.js +1 -1
  31. package/dist/migrations/Migration20241127114534.js.map +1 -1
  32. package/dist/migrations/Migration20241127223829.d.ts +1 -1
  33. package/dist/migrations/Migration20241127223829.d.ts.map +1 -1
  34. package/dist/migrations/Migration20241127223829.js +1 -1
  35. package/dist/migrations/Migration20241127223829.js.map +1 -1
  36. package/dist/migrations/Migration20241128055359.d.ts +1 -1
  37. package/dist/migrations/Migration20241128055359.d.ts.map +1 -1
  38. package/dist/migrations/Migration20241128055359.js +1 -1
  39. package/dist/migrations/Migration20241128055359.js.map +1 -1
  40. package/dist/migrations/Migration20241212190401.d.ts +1 -1
  41. package/dist/migrations/Migration20241212190401.d.ts.map +1 -1
  42. package/dist/migrations/Migration20241212190401.js +1 -1
  43. package/dist/migrations/Migration20241212190401.js.map +1 -1
  44. package/dist/migrations/Migration20250408145122.d.ts +1 -1
  45. package/dist/migrations/Migration20250408145122.d.ts.map +1 -1
  46. package/dist/migrations/Migration20250408145122.js +1 -1
  47. package/dist/migrations/Migration20250408145122.js.map +1 -1
  48. package/dist/migrations/Migration20250409122219.d.ts +1 -1
  49. package/dist/migrations/Migration20250409122219.d.ts.map +1 -1
  50. package/dist/migrations/Migration20250409122219.js +1 -1
  51. package/dist/migrations/Migration20250409122219.js.map +1 -1
  52. package/dist/migrations/Migration20251009110625.d.ts +6 -0
  53. package/dist/migrations/Migration20251009110625.d.ts.map +1 -0
  54. package/dist/migrations/Migration20251009110625.js +18 -0
  55. package/dist/migrations/Migration20251009110625.js.map +1 -0
  56. package/dist/models/price-list-rule.d.ts +4 -4
  57. package/dist/models/price-list-rule.d.ts.map +1 -1
  58. package/dist/models/price-list-rule.js +5 -0
  59. package/dist/models/price-list-rule.js.map +1 -1
  60. package/dist/models/price-list.d.ts +4 -4
  61. package/dist/models/price-list.d.ts.map +1 -1
  62. package/dist/models/price-list.js +7 -1
  63. package/dist/models/price-list.js.map +1 -1
  64. package/dist/models/price-rule.d.ts +6 -6
  65. package/dist/models/price-rule.d.ts.map +1 -1
  66. package/dist/models/price-rule.js +4 -0
  67. package/dist/models/price-rule.js.map +1 -1
  68. package/dist/models/price-set.d.ts +6 -6
  69. package/dist/models/price.d.ts +6 -6
  70. package/dist/repositories/pricing.d.ts +2 -0
  71. package/dist/repositories/pricing.d.ts.map +1 -1
  72. package/dist/repositories/pricing.js +104 -69
  73. package/dist/repositories/pricing.js.map +1 -1
  74. package/dist/services/pricing-module.d.ts +34 -21
  75. package/dist/services/pricing-module.d.ts.map +1 -1
  76. package/dist/services/pricing-module.js +479 -271
  77. package/dist/services/pricing-module.js.map +1 -1
  78. package/dist/tsconfig.tsbuildinfo +1 -1
  79. package/dist/types/index.js +17 -7
  80. package/dist/types/index.js.map +1 -1
  81. package/dist/utils/index.d.ts +0 -1
  82. package/dist/utils/index.d.ts.map +1 -1
  83. package/dist/utils/index.js +0 -1
  84. package/dist/utils/index.js.map +1 -1
  85. package/dist/utils/validate-price-list-dates.d.ts.map +1 -1
  86. package/package.json +14 -28
  87. package/dist/schema/index.d.ts +0 -3
  88. package/dist/schema/index.d.ts.map +0 -1
  89. package/dist/schema/index.js +0 -62
  90. package/dist/schema/index.js.map +0 -1
  91. package/dist/utils/events.d.ts +0 -123
  92. package/dist/utils/events.d.ts.map +0 -1
  93. package/dist/utils/events.js +0 -97
  94. package/dist/utils/events.js.map +0 -1
@@ -25,11 +25,13 @@ const generateMethodForModels = {
25
25
  Price: _models_1.Price,
26
26
  PricePreference: _models_1.PricePreference,
27
27
  };
28
- class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generateMethodForModels) {
28
+ const BaseClass = utils_1.ModulesSdkUtils.MedusaService(generateMethodForModels);
29
+ class PricingModuleService extends BaseClass {
29
30
  constructor({ baseRepository, pricingRepository, priceSetService, priceRuleService, priceService, pricePreferenceService, priceListService, priceListRuleService, }, moduleDeclaration) {
30
31
  // @ts-ignore
31
32
  super(...arguments);
32
33
  this.moduleDeclaration = moduleDeclaration;
34
+ this.container_ = arguments[0];
33
35
  this.baseRepository_ = baseRepository;
34
36
  this.pricingRepository_ = pricingRepository;
35
37
  this.priceSetService_ = priceSetService;
@@ -55,6 +57,44 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
55
57
  return pricingContext;
56
58
  }
57
59
  // @ts-expect-error
60
+ async createPriceRules(...args) {
61
+ try {
62
+ return await super.createPriceRules(...args);
63
+ }
64
+ finally {
65
+ this.pricingRepository_.clearAvailableAttributes?.();
66
+ }
67
+ }
68
+ // @ts-expect-error
69
+ async updatePriceRules(...args) {
70
+ try {
71
+ return await super.updatePriceRules(...args);
72
+ }
73
+ finally {
74
+ this.pricingRepository_.clearAvailableAttributes?.();
75
+ }
76
+ }
77
+ // @ts-expect-error
78
+ async createPriceListRules(...args) {
79
+ try {
80
+ // @ts-ignore
81
+ return await super.createPriceListRules(...args);
82
+ }
83
+ finally {
84
+ this.pricingRepository_.clearAvailableAttributes?.();
85
+ }
86
+ }
87
+ // @ts-expect-error
88
+ async updatePriceListRules(...args) {
89
+ try {
90
+ // @ts-ignore
91
+ return await super.updatePriceListRules(...args);
92
+ }
93
+ finally {
94
+ this.pricingRepository_.clearAvailableAttributes?.();
95
+ }
96
+ }
97
+ // @ts-expect-error
58
98
  async retrievePriceSet(id, config, sharedContext) {
59
99
  const priceSet = await this.priceSetService_.retrieve(id, this.normalizePriceSetConfig(config), sharedContext);
60
100
  return await this.baseRepository_.serialize(priceSet);
@@ -76,7 +116,7 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
76
116
  const calculatedPrice = calculatedPricesMap.get(priceSet.id);
77
117
  priceSet.calculated_price = calculatedPrice ?? null;
78
118
  }
79
- return priceSets;
119
+ return await this.baseRepository_.serialize(priceSets);
80
120
  }
81
121
  // @ts-expect-error
82
122
  async listAndCountPriceSets(filters = {}, config = {}, sharedContext = {}) {
@@ -84,7 +124,8 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
84
124
  const pricingContext = this.setupCalculatedPriceConfig_(filters, normalizedConfig);
85
125
  const [priceSets, count] = await super.listAndCountPriceSets(filters, normalizedConfig, sharedContext);
86
126
  if (!pricingContext || !priceSets.length) {
87
- return [priceSets, count];
127
+ const serializedPriceSets = await this.baseRepository_.serialize(priceSets);
128
+ return [serializedPriceSets, count];
88
129
  }
89
130
  const calculatedPrices = await this.calculatePrices({ id: priceSets.map((p) => p.id) }, { context: pricingContext }, sharedContext);
90
131
  const calculatedPricesMap = new Map();
@@ -95,7 +136,24 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
95
136
  const calculatedPrice = calculatedPricesMap.get(priceSet.id);
96
137
  priceSet.calculated_price = calculatedPrice ?? null;
97
138
  }
98
- return [priceSets, count];
139
+ const serializedPriceSets = await this.baseRepository_.serialize(priceSets);
140
+ return [serializedPriceSets, count];
141
+ }
142
+ // @ts-expect-error
143
+ async listPriceRules(filters, config = {}, sharedContext) {
144
+ const priceRules = await this.listPriceRules_(filters, config, sharedContext);
145
+ return await this.baseRepository_.serialize(priceRules);
146
+ }
147
+ async listPriceRules_(filters, config = {}, sharedContext) {
148
+ return await this.priceRuleService_.list(filters, config, sharedContext);
149
+ }
150
+ // @ts-expect-error
151
+ async listPricePreferences(filters, config = {}, sharedContext) {
152
+ const pricePreferences = await this.listPricePreferences_(filters, config, sharedContext);
153
+ return await this.baseRepository_.serialize(pricePreferences);
154
+ }
155
+ async listPricePreferences_(filters, config = {}, sharedContext) {
156
+ return await this.pricePreferenceService_.list(filters, config, sharedContext);
99
157
  }
100
158
  async calculatePrices(pricingFilters, pricingContext = { context: {} }, sharedContext = {}) {
101
159
  const results = await this.pricingRepository_.calculatePrices(pricingFilters, pricingContext, sharedContext);
@@ -113,6 +171,7 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
113
171
  /**
114
172
  * When deciding which price to use we follow the following logic:
115
173
  * - If the price list is of type OVERRIDE, we always use the price list price.
174
+ * - If there are multiple price list prices of type OVERRIDE, we use the one with the lowest amount.
116
175
  * - If the price list is of type SALE, we use the lowest price between the price list price and the default price
117
176
  */
118
177
  if (priceListPrice) {
@@ -137,28 +196,33 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
137
196
  priceIds.push(...(0, utils_1.deduplicate)([calculatedPrice?.id, originalPrice?.id].filter(Boolean)));
138
197
  });
139
198
  // We use the price rules to get the right preferences for the price
140
- const priceRulesForPrices = await this.priceRuleService_.list({ price_id: priceIds }, {});
199
+ const priceRulesForPrices = await this.listPriceRules({ price_id: priceIds }, {}, sharedContext);
141
200
  const priceRulesPriceMap = (0, utils_1.groupBy)(priceRulesForPrices, "price_id");
142
201
  // Note: For now the preferences are intentionally kept very simple and explicit - they use either the region or currency,
143
202
  // so we hard-code those as the possible filters here. This can be made more flexible if needed later on.
144
- const pricingPreferences = await this.pricePreferenceService_.list({
145
- $or: Object.entries(pricingContext)
146
- .filter(([key, val]) => {
147
- return key === "region_id" || key === "currency_code";
148
- })
149
- .map(([key, val]) => ({
150
- attribute: key,
151
- value: val,
152
- })),
153
- }, {}, sharedContext);
154
- const calculatedPrices = pricingFilters.id
155
- .map((priceSetId) => {
203
+ const preferenceContext = Object.entries(pricingContext.context ?? {}).filter(([key, val]) => {
204
+ return key === "region_id" || key === "currency_code";
205
+ });
206
+ let pricingPreferences = [];
207
+ if (preferenceContext.length) {
208
+ const preferenceFilters = preferenceContext.length
209
+ ? {
210
+ $or: preferenceContext.map(([key, val]) => ({
211
+ attribute: key,
212
+ value: val,
213
+ })),
214
+ }
215
+ : {};
216
+ pricingPreferences = await this.listPricePreferences_(preferenceFilters, {}, sharedContext);
217
+ }
218
+ const calculatedPrices = [];
219
+ for (const priceSetId of pricingFilters.id) {
156
220
  const prices = pricesSetPricesMap.get(priceSetId);
157
221
  if (!prices) {
158
- return null;
222
+ continue;
159
223
  }
160
224
  const { calculatedPrice, originalPrice, } = prices;
161
- return {
225
+ const calculatedPrice_ = {
162
226
  id: priceSetId,
163
227
  is_calculated_price_price_list: !!calculatedPrice?.price_list_id,
164
228
  is_calculated_price_tax_inclusive: isTaxInclusive(priceRulesPriceMap.get(calculatedPrice.id), pricingPreferences, calculatedPrice.currency_code, pricingContext.context?.region_id),
@@ -190,9 +254,9 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
190
254
  max_quantity: parseInt(originalPrice?.max_quantity || "") || null,
191
255
  },
192
256
  };
193
- })
194
- .filter(Boolean);
195
- return JSON.parse(JSON.stringify(calculatedPrices));
257
+ calculatedPrices.push(calculatedPrice_);
258
+ }
259
+ return calculatedPrices;
196
260
  }
197
261
  // @ts-expect-error
198
262
  async createPriceSets(data, sharedContext = {}) {
@@ -206,9 +270,23 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
206
270
  const results = priceSets.map((priceSet) => {
207
271
  return dbPriceSets.find((p) => p.id === priceSet.id);
208
272
  });
209
- return await this.baseRepository_.serialize(Array.isArray(data) ? results : results[0]);
273
+ try {
274
+ return await this.baseRepository_.serialize(Array.isArray(data) ? results : results[0]);
275
+ }
276
+ finally {
277
+ this.pricingRepository_.clearAvailableAttributes?.();
278
+ }
210
279
  }
211
280
  async upsertPriceSets(data, sharedContext = {}) {
281
+ const result = await this.upsertPriceSets_(data, sharedContext);
282
+ try {
283
+ return await this.baseRepository_.serialize(Array.isArray(data) ? result : result[0]);
284
+ }
285
+ finally {
286
+ this.pricingRepository_.clearAvailableAttributes?.();
287
+ }
288
+ }
289
+ async upsertPriceSets_(data, sharedContext = {}) {
212
290
  const input = Array.isArray(data) ? data : [data];
213
291
  const forUpdate = input.filter((priceSet) => !!priceSet.id);
214
292
  const forCreate = input.filter((priceSet) => !priceSet.id);
@@ -220,7 +298,7 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
220
298
  operations.push(this.updatePriceSets_(forUpdate, sharedContext));
221
299
  }
222
300
  const result = (await (0, utils_1.promiseAll)(operations)).flat();
223
- return await this.baseRepository_.serialize(Array.isArray(data) ? result : result[0]);
301
+ return result;
224
302
  }
225
303
  // @ts-expect-error
226
304
  async updatePriceSets(idOrSelector, data, sharedContext = {}) {
@@ -238,59 +316,117 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
238
316
  }));
239
317
  }
240
318
  const updateResult = await this.updatePriceSets_(normalizedInput, sharedContext);
241
- const priceSets = await this.baseRepository_.serialize(updateResult);
242
- return (0, utils_1.isString)(idOrSelector) ? priceSets[0] : priceSets;
319
+ const serializedUpdateResult = await this.baseRepository_.serialize((0, utils_1.isString)(idOrSelector) ? updateResult[0] : updateResult);
320
+ try {
321
+ return serializedUpdateResult;
322
+ }
323
+ finally {
324
+ this.pricingRepository_.clearAvailableAttributes?.();
325
+ }
243
326
  }
244
327
  async updatePriceSets_(data, sharedContext = {}) {
245
- // TODO: Since money IDs are rarely passed, this will delete all previous data and insert new entries.
246
- // We can make the `insert` inside upsertWithReplace do an `upsert` instead to avoid this
247
328
  const normalizedData = await this.normalizeUpdateData(data);
248
- const priceListPrices = await this.priceService_.list({
249
- price_set_id: normalizedData.map(({ id }) => id),
250
- price_list_id: { $ne: null },
251
- });
329
+ const priceSetIds = normalizedData.map(({ id }) => id);
330
+ const existingPrices = await this.priceService_.list({
331
+ price_set_id: priceSetIds,
332
+ price_list_id: null,
333
+ }, {
334
+ relations: ["price_rules"],
335
+ take: null,
336
+ }, sharedContext);
337
+ const existingPricesMap = new Map(existingPrices.map((p) => [p.id, p]));
252
338
  const prices = normalizedData.flatMap((priceSet) => priceSet.prices || []);
253
- const { entities: upsertedPrices, performedActions } = await this.priceService_.upsertWithReplace(prices, { relations: ["price_rules"] }, sharedContext);
254
- composeAllEvents({
255
- eventBuilders: _utils_1.eventBuilders,
256
- performedActions,
257
- sharedContext,
258
- });
259
- const priceSetsToUpsert = normalizedData.map((priceSet) => {
260
- const { prices, ...rest } = priceSet;
261
- return {
262
- ...rest,
263
- prices: [
264
- ...upsertedPrices
265
- .filter((p) => p.price_set_id === priceSet.id)
266
- .map((price) => {
267
- // @ts-ignore
268
- delete price.price_rules;
269
- return price;
270
- }),
271
- ...priceListPrices
272
- .filter((p) => p.price_set_id === priceSet.id)
273
- .map((price) => ({
274
- id: price.id,
275
- amount: price.amount,
276
- price_set_id: price.price_set_id,
277
- price_list_id: price.price_list_id,
278
- })),
279
- ],
280
- };
281
- });
282
- const { entities: priceSets, performedActions: priceSetPerformedActions } = await this.priceSetService_.upsertWithReplace(priceSetsToUpsert, { relations: ["prices"] }, sharedContext);
283
- composeAllEvents({
284
- eventBuilders: _utils_1.eventBuilders,
285
- performedActions: priceSetPerformedActions,
286
- sharedContext,
287
- });
288
- return priceSets.map((ps) => {
289
- if (ps.prices) {
290
- ps.prices = ps.prices.filter((p) => !p.price_list_id);
339
+ const pricesToCreate = prices.filter((price) => !price.id || !existingPricesMap.has(price.id));
340
+ const pricesToUpdate = prices.filter((price) => price.id && existingPricesMap.has(price.id));
341
+ const incomingPriceIds = new Set(prices.map((p) => p.id).filter(Boolean));
342
+ const pricesToDelete = existingPrices
343
+ .filter((existingPrice) => !incomingPriceIds.has(existingPrice.id))
344
+ .map((p) => p.id);
345
+ let createdPrices = [];
346
+ let updatedPrices = [];
347
+ if (pricesToCreate.length > 0) {
348
+ createdPrices = await this.priceService_.create(pricesToCreate.map((price) => {
349
+ price.price_rules ??= [];
350
+ return price;
351
+ }), sharedContext);
352
+ }
353
+ if (pricesToUpdate.length > 0) {
354
+ // Handle price rules for updated prices
355
+ for (const priceToUpdate of pricesToUpdate) {
356
+ const existingPrice = existingPricesMap.get(priceToUpdate.id);
357
+ if (priceToUpdate.price_rules?.length) {
358
+ const existingPriceRules = existingPrice?.price_rules || [];
359
+ // Separate price rules for create, update, delete
360
+ const priceRulesToCreate = priceToUpdate.price_rules.filter((rule) => !("id" in rule));
361
+ const priceRulesToUpdate = priceToUpdate.price_rules.filter((rule) => "id" in rule);
362
+ const incomingPriceRuleIds = new Set(priceToUpdate.price_rules
363
+ .map((r) => "id" in r && r.id)
364
+ .filter(Boolean));
365
+ const priceRulesToDelete = existingPriceRules
366
+ .filter((existingRule) => !incomingPriceRuleIds.has(existingRule.id))
367
+ .map((r) => r.id);
368
+ let createdPriceRules = [];
369
+ let updatedPriceRules = [];
370
+ // Bulk operations for price rules
371
+ if (priceRulesToCreate.length > 0) {
372
+ createdPriceRules = await this.priceRuleService_.create(priceRulesToCreate.map((rule) => ({
373
+ ...rule,
374
+ price_id: priceToUpdate.id,
375
+ })), sharedContext);
376
+ }
377
+ if (priceRulesToUpdate.length > 0) {
378
+ updatedPriceRules = await this.priceRuleService_.update(priceRulesToUpdate, sharedContext);
379
+ }
380
+ if (priceRulesToDelete.length > 0) {
381
+ await this.priceRuleService_.delete(priceRulesToDelete, sharedContext);
382
+ }
383
+ const upsertedPriceRules = [
384
+ ...createdPriceRules,
385
+ ...updatedPriceRules,
386
+ ];
387
+ priceToUpdate.price_rules = upsertedPriceRules;
388
+ priceToUpdate.rules_count =
389
+ upsertedPriceRules.length;
390
+ }
391
+ else if (
392
+ // In the case price_rules is provided but without any rules, we delete the existing rules
393
+ (0, utils_1.isDefined)(priceToUpdate.price_rules) &&
394
+ priceToUpdate.price_rules.length === 0) {
395
+ const priceRuleToDelete = existingPrice?.price_rules?.map((r) => r.id);
396
+ if (priceRuleToDelete?.length) {
397
+ await this.priceRuleService_.delete(priceRuleToDelete, sharedContext);
398
+ }
399
+ ;
400
+ priceToUpdate.rules_count = 0;
401
+ }
402
+ else {
403
+ // @ts-expect-error - we want to delete the rules_count property in any case even if provided by mistake
404
+ delete priceToUpdate.rules_count;
405
+ }
406
+ // We don't want to persist the price_rules in the database through the price service as it would not work
407
+ delete priceToUpdate.price_rules;
291
408
  }
292
- return ps;
409
+ updatedPrices = await this.priceService_.update(pricesToUpdate, sharedContext);
410
+ }
411
+ if (pricesToDelete.length > 0) {
412
+ await this.priceService_.delete(pricesToDelete, sharedContext);
413
+ }
414
+ const priceSets = await this.priceSetService_.list({ id: normalizedData.map(({ id }) => id) }, {
415
+ relations: ["prices", "prices.price_rules"],
416
+ }, sharedContext);
417
+ const upsertedPricesMap = new Map();
418
+ const upsertedPrices = [...createdPrices, ...updatedPrices];
419
+ upsertedPrices.forEach((price) => {
420
+ upsertedPricesMap.set(price.price_set_id, [
421
+ ...(upsertedPricesMap.get(price.price_set_id) || []),
422
+ price,
423
+ ]);
293
424
  });
425
+ // re assign the prices to the price sets to not have to refetch after the transaction and keep the bahaviour the same as expected. If the user needs more data, he can still re list the price set with the expected fields and relations that he needs
426
+ priceSets.forEach((ps) => {
427
+ ps.prices = upsertedPricesMap.get(ps.id) || [];
428
+ });
429
+ return priceSets;
294
430
  }
295
431
  async normalizeUpdateData(data) {
296
432
  return data.map((priceSet) => {
@@ -303,18 +439,19 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
303
439
  normalizePrices(data, existingPrices, priceListId) {
304
440
  const pricesToUpsert = new Map();
305
441
  const existingPricesMap = new Map();
306
- existingPrices?.forEach((price) => {
442
+ Array.from(existingPrices ?? []).forEach((price) => {
307
443
  existingPricesMap.set(hashPrice(price), price);
308
444
  });
445
+ const ruleOperatorsSet = new Set(Object.values(utils_1.PricingRuleOperator));
446
+ const validOperatorsList = Array.from(ruleOperatorsSet).join(", ");
447
+ const invalidOperatorError = `operator should be one of ${validOperatorsList}`;
309
448
  data?.forEach((price) => {
310
449
  const cleanRules = price.rules ? (0, utils_1.removeNullish)(price.rules) : {};
311
- const ruleOperators = Object.values(utils_1.PricingRuleOperator);
312
- const rules = Object.entries(cleanRules)
313
- .map(([attribute, value]) => {
450
+ const rules = Object.entries(cleanRules).flatMap(([attribute, value]) => {
314
451
  if (Array.isArray(value)) {
315
452
  return value.map((customRule) => {
316
- if (!ruleOperators.includes(customRule.operator)) {
317
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `operator should be one of ${ruleOperators.join(", ")}`);
453
+ if (!ruleOperatorsSet.has(customRule.operator)) {
454
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, invalidOperatorError);
318
455
  }
319
456
  if (typeof customRule.value !== "number") {
320
457
  throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `value should be a number`);
@@ -322,7 +459,8 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
322
459
  return {
323
460
  attribute,
324
461
  operator: customRule.operator,
325
- value: customRule.value,
462
+ // TODO: we throw above if value is not a number, but the model expect the value to be a string
463
+ value: customRule.value.toString(),
326
464
  };
327
465
  });
328
466
  }
@@ -330,25 +468,23 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
330
468
  attribute,
331
469
  value,
332
470
  };
333
- })
334
- .flat(1);
471
+ });
472
+ const entry = price;
335
473
  const hasRulesInput = (0, utils_1.isPresent)(price.rules);
336
- const entry = {
337
- ...price,
338
- price_list_id: priceListId,
339
- price_rules: hasRulesInput ? rules : undefined,
340
- rules_count: hasRulesInput ? rules.length : undefined,
341
- };
342
- delete entry.rules;
474
+ entry.price_list_id = priceListId;
475
+ if (hasRulesInput) {
476
+ entry.price_rules = rules;
477
+ entry.rules_count = rules.length;
478
+ delete entry.rules;
479
+ }
343
480
  const entryHash = hashPrice(entry);
344
481
  // We want to keep the existing rules as they might already have ids, but any other data should come from the updated input
345
482
  const existing = existingPricesMap.get(entryHash);
346
- pricesToUpsert.set(entryHash, {
347
- ...entry,
348
- id: existing?.id ?? entry.id,
349
- price_rules: existing?.price_rules ?? entry.price_rules,
350
- });
351
- return entry;
483
+ if (existing) {
484
+ entry.id = existing.id ?? entry.id;
485
+ entry.price_rules = existing.price_rules ?? entry.price_rules;
486
+ }
487
+ pricesToUpsert.set(entryHash, entry);
352
488
  });
353
489
  return Array.from(pricesToUpsert.values());
354
490
  }
@@ -359,32 +495,68 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
359
495
  const orderedPriceSets = input.map((inputItem) => {
360
496
  return dbPrices.find((p) => p.id === inputItem.priceSetId);
361
497
  });
362
- return Array.isArray(data) ? orderedPriceSets : orderedPriceSets[0];
498
+ const serializedOrderedPriceSets = await this.baseRepository_.serialize(Array.isArray(data) ? orderedPriceSets : orderedPriceSets[0]);
499
+ try {
500
+ return serializedOrderedPriceSets;
501
+ }
502
+ finally {
503
+ this.pricingRepository_.clearAvailableAttributes?.();
504
+ }
363
505
  }
364
506
  // @ts-ignore
365
507
  async createPriceLists(data, sharedContext = {}) {
366
508
  const priceLists = await this.createPriceLists_(data, sharedContext);
367
- return await this.baseRepository_.serialize(priceLists);
509
+ try {
510
+ return await this.baseRepository_.serialize(priceLists);
511
+ }
512
+ finally {
513
+ this.pricingRepository_.clearAvailableAttributes?.();
514
+ }
368
515
  }
369
516
  // @ts-ignore
370
517
  async updatePriceLists(data, sharedContext = {}) {
371
518
  const priceLists = await this.updatePriceLists_(data, sharedContext);
372
- return await this.baseRepository_.serialize(priceLists);
519
+ try {
520
+ return await this.baseRepository_.serialize(priceLists);
521
+ }
522
+ finally {
523
+ this.pricingRepository_.clearAvailableAttributes?.();
524
+ }
373
525
  }
374
526
  async updatePriceListPrices(data, sharedContext = {}) {
375
527
  const prices = await this.updatePriceListPrices_(data, sharedContext);
376
- return await this.baseRepository_.serialize(prices);
528
+ try {
529
+ return await this.baseRepository_.serialize(prices);
530
+ }
531
+ finally {
532
+ this.pricingRepository_.clearAvailableAttributes?.();
533
+ }
377
534
  }
378
535
  async removePrices(ids, sharedContext = {}) {
379
- await this.removePrices_(ids, sharedContext);
536
+ try {
537
+ await this.removePrices_(ids, sharedContext);
538
+ }
539
+ finally {
540
+ this.pricingRepository_.clearAvailableAttributes?.();
541
+ }
380
542
  }
381
543
  async addPriceListPrices(data, sharedContext = {}) {
382
544
  const prices = await this.addPriceListPrices_(data, sharedContext);
383
- return await this.baseRepository_.serialize(prices);
545
+ try {
546
+ return await this.baseRepository_.serialize(prices);
547
+ }
548
+ finally {
549
+ this.pricingRepository_.clearAvailableAttributes?.();
550
+ }
384
551
  }
385
552
  async setPriceListRules(data, sharedContext = {}) {
386
553
  const [priceList] = await this.setPriceListRules_([data], sharedContext);
387
- return await this.baseRepository_.serialize(priceList);
554
+ try {
555
+ return await this.baseRepository_.serialize(priceList);
556
+ }
557
+ finally {
558
+ this.pricingRepository_.clearAvailableAttributes?.();
559
+ }
388
560
  }
389
561
  async removePriceListRules(data, sharedContext = {}) {
390
562
  const [priceList] = await this.removePriceListRules_([data], sharedContext);
@@ -397,6 +569,10 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
397
569
  return Array.isArray(data) ? serialized : serialized[0];
398
570
  }
399
571
  async upsertPricePreferences(data, sharedContext = {}) {
572
+ const result = await this.upsertPricePreferences_(data, sharedContext);
573
+ return await this.baseRepository_.serialize(Array.isArray(data) ? result : result[0]);
574
+ }
575
+ async upsertPricePreferences_(data, sharedContext = {}) {
400
576
  const input = Array.isArray(data) ? data : [data];
401
577
  const forUpdate = input.filter((pricePreference) => !!pricePreference.id);
402
578
  const forCreate = input.filter((pricePreference) => !pricePreference.id);
@@ -408,7 +584,7 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
408
584
  operations.push(this.updatePricePreferences_(forUpdate, sharedContext));
409
585
  }
410
586
  const result = (await (0, utils_1.promiseAll)(operations)).flat();
411
- return await this.baseRepository_.serialize(Array.isArray(data) ? result : result[0]);
587
+ return result;
412
588
  }
413
589
  // @ts-expect-error
414
590
  async updatePricePreferences(idOrSelector, data, sharedContext = {}) {
@@ -451,52 +627,25 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
451
627
  });
452
628
  // Bulk create price sets
453
629
  const priceSets = await this.priceSetService_.create(toCreate, sharedContext);
454
- const eventsData = priceSets.reduce((eventsData, priceSet) => {
455
- eventsData.priceSets.push({
456
- id: priceSet.id,
457
- });
458
- priceSet.prices.map((price) => {
459
- eventsData.prices.push({
460
- id: price.id,
461
- });
462
- price.price_rules.map((priceRule) => {
463
- eventsData.priceRules.push({
464
- id: priceRule.id,
465
- });
466
- });
467
- });
468
- return eventsData;
469
- }, {
470
- priceSets: [],
471
- priceRules: [],
472
- prices: [],
473
- });
474
- _utils_1.eventBuilders.createdPriceSet({
475
- data: eventsData.priceSets,
476
- sharedContext,
477
- });
478
- _utils_1.eventBuilders.createdPrice({
479
- data: eventsData.prices,
480
- sharedContext,
481
- });
482
- _utils_1.eventBuilders.createdPriceRule({
483
- data: eventsData.priceRules,
484
- sharedContext,
485
- });
486
630
  return priceSets;
487
631
  }
488
632
  async addPrices_(input, sharedContext = {}) {
489
- const priceSets = await this.listPriceSets({ id: input.map((d) => d.priceSetId) }, { relations: ["prices", "prices.price_rules"] }, sharedContext);
490
- const existingPrices = priceSets
491
- .map((p) => p.prices)
492
- .flat();
633
+ const prices = input.flatMap((data) => {
634
+ return data.prices.map((price) => {
635
+ ;
636
+ price.price_set_id = data.priceSetId;
637
+ return price;
638
+ });
639
+ });
640
+ const priceConstraints = buildPreNormalizationPriceConstraintsFromData(prices);
641
+ const [priceSets, priceSetPrices] = await (0, utils_1.promiseAll)([
642
+ this.listPriceSets({ id: input.map((d) => d.priceSetId) }, {}, sharedContext),
643
+ this.priceService_.list(priceConstraints, { relations: ["price_rules"] }, sharedContext),
644
+ ]);
645
+ const existingPrices = priceSetPrices;
493
646
  const pricesToUpsert = input
494
- .map((addPrice) => this.normalizePrices(addPrice.prices?.map((p) => ({
495
- ...p,
496
- price_set_id: addPrice.priceSetId,
497
- })), existingPrices))
498
- .filter(Boolean)
499
- .flat();
647
+ .flatMap((addPrice) => this.normalizePrices(addPrice.prices, existingPrices))
648
+ .filter(Boolean);
500
649
  const priceSetMap = new Map(priceSets.map((p) => [p.id, p]));
501
650
  pricesToUpsert.forEach((price) => {
502
651
  const priceSet = priceSetMap.get(price.price_set_id);
@@ -504,12 +653,7 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
504
653
  throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Price set with id: ${price.price_set_id} not found`);
505
654
  }
506
655
  });
507
- const { entities, performedActions } = await this.priceService_.upsertWithReplace(pricesToUpsert, { relations: ["price_rules"] }, sharedContext);
508
- composeAllEvents({
509
- eventBuilders: _utils_1.eventBuilders,
510
- performedActions,
511
- sharedContext,
512
- });
656
+ const { entities } = await this.priceService_.upsertWithReplace(pricesToUpsert, { relations: ["price_rules"] }, sharedContext);
513
657
  return entities;
514
658
  }
515
659
  async createPriceLists_(data, sharedContext = {}) {
@@ -542,54 +686,6 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
542
686
  return entry;
543
687
  });
544
688
  const priceLists = await this.priceListService_.create(priceListsToCreate, sharedContext);
545
- /**
546
- * Preparing data for emitting events
547
- */
548
- const eventsData = priceLists.reduce((eventsData, priceList) => {
549
- eventsData.priceList.push({
550
- id: priceList.id,
551
- });
552
- priceList.price_list_rules.map((listRule) => {
553
- eventsData.priceListRules.push({
554
- id: listRule.id,
555
- });
556
- });
557
- priceList.prices.map((price) => {
558
- eventsData.prices.push({
559
- id: price.id,
560
- });
561
- price.price_rules.map((priceRule) => {
562
- eventsData.priceRules.push({
563
- id: priceRule.id,
564
- });
565
- });
566
- });
567
- return eventsData;
568
- }, {
569
- priceList: [],
570
- priceListRules: [],
571
- priceRules: [],
572
- prices: [],
573
- });
574
- /**
575
- * Emitting events for all created entities
576
- */
577
- _utils_1.eventBuilders.createdPriceList({
578
- data: eventsData.priceList,
579
- sharedContext,
580
- });
581
- _utils_1.eventBuilders.createdPriceListRule({
582
- data: eventsData.priceListRules,
583
- sharedContext,
584
- });
585
- _utils_1.eventBuilders.createdPrice({
586
- data: eventsData.prices,
587
- sharedContext,
588
- });
589
- _utils_1.eventBuilders.createdPriceRule({
590
- data: eventsData.priceRules,
591
- sharedContext,
592
- });
593
689
  return priceLists;
594
690
  }
595
691
  async updatePriceLists_(data, sharedContext = {}) {
@@ -623,25 +719,23 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
623
719
  }
624
720
  return entry;
625
721
  });
626
- const { entities, performedActions } = await this.priceListService_.upsertWithReplace(normalizedData, {
722
+ const { entities } = await this.priceListService_.upsertWithReplace(normalizedData, {
627
723
  relations: ["price_list_rules"],
628
724
  });
629
- composeAllEvents({
630
- eventBuilders: _utils_1.eventBuilders,
631
- performedActions,
632
- sharedContext,
633
- });
634
725
  return entities;
635
726
  }
636
727
  async updatePriceListPrices_(data, sharedContext = {}) {
637
- const priceLists = await this.listPriceLists({ id: data.map((p) => p.price_list_id) }, { relations: ["prices", "prices.price_rules"] }, sharedContext);
638
- const existingPrices = priceLists
639
- .map((p) => p.prices ?? [])
640
- .flat();
728
+ const priceListIds = data.map((p) => p.price_list_id);
729
+ const prices = data.flatMap((p) => p.prices);
730
+ const priceConstraints = buildPreNormalizationPriceConstraintsFromData(prices, priceListIds);
731
+ const [priceLists, priceListPrices] = await (0, utils_1.promiseAll)([
732
+ this.priceListService_.list({ id: priceListIds }, {}, sharedContext),
733
+ this.priceService_.list(priceConstraints, { relations: ["price_rules"] }, sharedContext),
734
+ ]);
735
+ const existingPrices = priceListPrices;
641
736
  const pricesToUpsert = data
642
- .map((addPrice) => this.normalizePrices(addPrice.prices, existingPrices, addPrice.price_list_id))
643
- .filter(Boolean)
644
- .flat();
737
+ .flatMap((addPrice) => this.normalizePrices(addPrice.prices, existingPrices, addPrice.price_list_id))
738
+ .filter(Boolean);
645
739
  const priceListMap = new Map(priceLists.map((p) => [p.id, p]));
646
740
  for (const { price_list_id: priceListId } of data) {
647
741
  const priceList = priceListMap.get(priceListId);
@@ -649,26 +743,24 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
649
743
  throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Price list with id: ${priceListId} not found`);
650
744
  }
651
745
  }
652
- const { entities, performedActions } = await this.priceService_.upsertWithReplace(pricesToUpsert, { relations: ["price_rules"] }, sharedContext);
653
- composeAllEvents({
654
- eventBuilders: _utils_1.eventBuilders,
655
- performedActions,
656
- sharedContext,
657
- });
746
+ const { entities } = await this.priceService_.upsertWithReplace(pricesToUpsert, { relations: ["price_rules"] }, sharedContext);
658
747
  return entities;
659
748
  }
660
749
  async removePrices_(ids, sharedContext = {}) {
661
750
  await this.priceService_.delete(ids, sharedContext);
662
751
  }
663
752
  async addPriceListPrices_(data, sharedContext = {}) {
664
- const priceLists = await this.listPriceLists({ id: data.map((p) => p.price_list_id) }, { relations: ["prices", "prices.price_rules"] }, sharedContext);
665
- const existingPrices = priceLists
666
- .map((p) => p.prices ?? [])
667
- .flat();
753
+ const priceListIds = data.map((p) => p.price_list_id);
754
+ const prices = data.flatMap((p) => p.prices);
755
+ const priceConstraints = buildPreNormalizationPriceConstraintsFromData(prices, priceListIds);
756
+ const [priceLists, priceListPrices] = await (0, utils_1.promiseAll)([
757
+ this.priceListService_.list({ id: priceListIds }, {}, sharedContext),
758
+ this.priceService_.list(priceConstraints, { relations: ["price_rules"] }, sharedContext),
759
+ ]);
760
+ const existingPrices = priceListPrices;
668
761
  const pricesToUpsert = data
669
- .map((addPrice) => this.normalizePrices(addPrice.prices, existingPrices, addPrice.price_list_id))
670
- .filter(Boolean)
671
- .flat();
762
+ .flatMap((addPrice) => this.normalizePrices(addPrice.prices, existingPrices, addPrice.price_list_id))
763
+ .filter(Boolean);
672
764
  const priceListMap = new Map(priceLists.map((p) => [p.id, p]));
673
765
  pricesToUpsert.forEach((price) => {
674
766
  const priceList = priceListMap.get(price.price_list_id);
@@ -676,12 +768,7 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
676
768
  throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Price list with id: ${price.price_list_id} not found`);
677
769
  }
678
770
  });
679
- const { entities, performedActions } = await this.priceService_.upsertWithReplace(pricesToUpsert, { relations: ["price_rules"] }, sharedContext);
680
- composeAllEvents({
681
- eventBuilders: _utils_1.eventBuilders,
682
- performedActions,
683
- sharedContext,
684
- });
771
+ const { entities } = await this.priceService_.upsertWithReplace(pricesToUpsert, { relations: ["price_rules"] }, sharedContext);
685
772
  return entities;
686
773
  }
687
774
  async setPriceListRules_(data, sharedContext = {}) {
@@ -719,12 +806,7 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
719
806
  };
720
807
  })
721
808
  .filter(Boolean);
722
- const { entities, performedActions } = await this.priceListService_.upsertWithReplace(priceListsUpsert, { relations: ["price_list_rules"] }, sharedContext);
723
- composeAllEvents({
724
- eventBuilders: _utils_1.eventBuilders,
725
- performedActions,
726
- sharedContext,
727
- });
809
+ const { entities } = await this.priceListService_.upsertWithReplace(priceListsUpsert, { relations: ["price_list_rules"] }, sharedContext);
728
810
  return entities;
729
811
  }
730
812
  async removePriceListRules_(data, sharedContext = {}) {
@@ -764,12 +846,7 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
764
846
  };
765
847
  })
766
848
  .filter(Boolean);
767
- const { entities, performedActions } = await this.priceListService_.upsertWithReplace(priceListsUpsert, { relations: ["price_list_rules"] }, sharedContext);
768
- composeAllEvents({
769
- eventBuilders: _utils_1.eventBuilders,
770
- performedActions,
771
- sharedContext,
772
- });
849
+ const { entities } = await this.priceListService_.upsertWithReplace(priceListsUpsert, { relations: ["price_list_rules"] }, sharedContext);
773
850
  return entities;
774
851
  }
775
852
  normalizePriceListDate(data) {
@@ -794,6 +871,42 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generat
794
871
  }
795
872
  }
796
873
  exports.default = PricingModuleService;
874
+ __decorate([
875
+ (0, utils_1.InjectTransactionManager)(),
876
+ (0, utils_1.EmitEvents)()
877
+ // @ts-expect-error
878
+ ,
879
+ __metadata("design:type", Function),
880
+ __metadata("design:paramtypes", [Object]),
881
+ __metadata("design:returntype", Promise)
882
+ ], PricingModuleService.prototype, "createPriceRules", null);
883
+ __decorate([
884
+ (0, utils_1.InjectTransactionManager)(),
885
+ (0, utils_1.EmitEvents)()
886
+ // @ts-expect-error
887
+ ,
888
+ __metadata("design:type", Function),
889
+ __metadata("design:paramtypes", [Object]),
890
+ __metadata("design:returntype", Promise)
891
+ ], PricingModuleService.prototype, "updatePriceRules", null);
892
+ __decorate([
893
+ (0, utils_1.InjectTransactionManager)(),
894
+ (0, utils_1.EmitEvents)()
895
+ // @ts-expect-error
896
+ ,
897
+ __metadata("design:type", Function),
898
+ __metadata("design:paramtypes", [Object]),
899
+ __metadata("design:returntype", Promise)
900
+ ], PricingModuleService.prototype, "createPriceListRules", null);
901
+ __decorate([
902
+ (0, utils_1.InjectTransactionManager)(),
903
+ (0, utils_1.EmitEvents)()
904
+ // @ts-expect-error
905
+ ,
906
+ __metadata("design:type", Function),
907
+ __metadata("design:paramtypes", [Object]),
908
+ __metadata("design:returntype", Promise)
909
+ ], PricingModuleService.prototype, "updatePriceListRules", null);
797
910
  __decorate([
798
911
  (0, utils_1.InjectManager)()
799
912
  // @ts-expect-error
@@ -820,6 +933,22 @@ __decorate([
820
933
  __metadata("design:paramtypes", [Object, Object, Object]),
821
934
  __metadata("design:returntype", Promise)
822
935
  ], PricingModuleService.prototype, "listAndCountPriceSets", null);
936
+ __decorate([
937
+ (0, utils_1.InjectManager)()
938
+ // @ts-expect-error
939
+ ,
940
+ __metadata("design:type", Function),
941
+ __metadata("design:paramtypes", [Object, Object, Object]),
942
+ __metadata("design:returntype", Promise)
943
+ ], PricingModuleService.prototype, "listPriceRules", null);
944
+ __decorate([
945
+ (0, utils_1.InjectManager)()
946
+ // @ts-expect-error
947
+ ,
948
+ __metadata("design:type", Function),
949
+ __metadata("design:paramtypes", [Object, Object, Object]),
950
+ __metadata("design:returntype", Promise)
951
+ ], PricingModuleService.prototype, "listPricePreferences", null);
823
952
  __decorate([
824
953
  (0, utils_1.InjectManager)(),
825
954
  __param(2, (0, utils_1.MedusaContext)()),
@@ -845,6 +974,13 @@ __decorate([
845
974
  __metadata("design:paramtypes", [Object, Object]),
846
975
  __metadata("design:returntype", Promise)
847
976
  ], PricingModuleService.prototype, "upsertPriceSets", null);
977
+ __decorate([
978
+ (0, utils_1.InjectTransactionManager)(),
979
+ __param(1, (0, utils_1.MedusaContext)()),
980
+ __metadata("design:type", Function),
981
+ __metadata("design:paramtypes", [Object, Object]),
982
+ __metadata("design:returntype", Promise)
983
+ ], PricingModuleService.prototype, "upsertPriceSets_", null);
848
984
  __decorate([
849
985
  (0, utils_1.InjectManager)(),
850
986
  (0, utils_1.EmitEvents)()
@@ -881,7 +1017,7 @@ __decorate([
881
1017
  __metadata("design:returntype", Promise)
882
1018
  ], PricingModuleService.prototype, "createPriceLists", null);
883
1019
  __decorate([
884
- (0, utils_1.InjectTransactionManager)(),
1020
+ (0, utils_1.InjectManager)(),
885
1021
  (0, utils_1.EmitEvents)()
886
1022
  // @ts-ignore
887
1023
  ,
@@ -947,7 +1083,15 @@ __decorate([
947
1083
  __metadata("design:returntype", Promise)
948
1084
  ], PricingModuleService.prototype, "upsertPricePreferences", null);
949
1085
  __decorate([
950
- (0, utils_1.InjectManager)()
1086
+ (0, utils_1.InjectTransactionManager)(),
1087
+ __param(1, (0, utils_1.MedusaContext)()),
1088
+ __metadata("design:type", Function),
1089
+ __metadata("design:paramtypes", [Object, Object]),
1090
+ __metadata("design:returntype", Promise)
1091
+ ], PricingModuleService.prototype, "upsertPricePreferences_", null);
1092
+ __decorate([
1093
+ (0, utils_1.InjectManager)(),
1094
+ (0, utils_1.EmitEvents)()
951
1095
  // @ts-expect-error
952
1096
  ,
953
1097
  __param(2, (0, utils_1.MedusaContext)()),
@@ -1027,20 +1171,6 @@ __decorate([
1027
1171
  __metadata("design:paramtypes", [Array, Object]),
1028
1172
  __metadata("design:returntype", Promise)
1029
1173
  ], PricingModuleService.prototype, "removePriceListRules_", null);
1030
- const composeAllEvents = ({ eventBuilders, performedActions, sharedContext, }) => {
1031
- for (const action of Object.keys(performedActions)) {
1032
- for (const entity of Object.keys(performedActions[action])) {
1033
- const eventName = action + (0, utils_1.upperCaseFirst)(entity);
1034
- if (!eventBuilders[eventName]) {
1035
- continue;
1036
- }
1037
- eventBuilders[eventName]({
1038
- data: performedActions[action][entity] ?? [],
1039
- sharedContext,
1040
- });
1041
- }
1042
- }
1043
- };
1044
1174
  const isTaxInclusive = (priceRules, preferences, currencyCode, regionId) => {
1045
1175
  const regionRule = priceRules?.find((rule) => rule.attribute === "region_id" && rule.value === regionId);
1046
1176
  const regionPreference = preferences.find((p) => p.attribute === "region_id" && p.value === regionId);
@@ -1054,19 +1184,97 @@ const isTaxInclusive = (priceRules, preferences, currencyCode, regionId) => {
1054
1184
  return false;
1055
1185
  };
1056
1186
  const hashPrice = (price) => {
1057
- const data = Object.entries({
1058
- currency_code: price.currency_code,
1059
- price_set_id: "price_set_id" in price ? price.price_set_id ?? null : null,
1060
- price_list_id: "price_list_id" in price ? price.price_list_id ?? null : null,
1061
- min_quantity: price.min_quantity ? price.min_quantity.toString() : null,
1062
- max_quantity: price.max_quantity ? price.max_quantity.toString() : null,
1063
- ...("price_rules" in price
1064
- ? price.price_rules?.reduce((agg, pr) => {
1065
- agg[pr.attribute] = pr.value;
1066
- return agg;
1067
- }, {})
1068
- : {}),
1069
- }).sort(([a], [b]) => a.localeCompare(b));
1070
- return (0, utils_1.simpleHash)(JSON.stringify(data));
1187
+ // Build hash using deterministic property order to avoid expensive sort operation
1188
+ // Using a direct string concatenation approach for better performance
1189
+ const parts = [];
1190
+ if ("currency_code" in price) {
1191
+ parts.push(`cc:${price.currency_code ?? ""}`);
1192
+ }
1193
+ if ("price_set_id" in price) {
1194
+ parts.push(`ps:${price.price_set_id ?? ""}`);
1195
+ }
1196
+ if ("price_list_id" in price) {
1197
+ parts.push(`pl:${price.price_list_id ?? ""}`);
1198
+ }
1199
+ if ("min_quantity" in price) {
1200
+ parts.push(`min:${price.min_quantity ?? ""}`);
1201
+ }
1202
+ if ("max_quantity" in price) {
1203
+ parts.push(`max:${price.max_quantity ?? ""}`);
1204
+ }
1205
+ // Add price rules in a deterministic way if present
1206
+ if ("price_rules" in price && price.price_rules) {
1207
+ const sortedRules = price.price_rules.map((pr) => `${pr.attribute}=${pr.value}`);
1208
+ if (sortedRules.length) {
1209
+ parts.push(`rules:${sortedRules.join(",")}`);
1210
+ }
1211
+ }
1212
+ return parts.sort().join("|");
1213
+ };
1214
+ /**
1215
+ * Build targeted database constraints to fetch only prices that could match the incoming data.
1216
+ * Uses the same properties as hashPrice to ensure consistency.
1217
+ */
1218
+ const buildPreNormalizationPriceConstraintsFromData = (prices, priceListIds) => {
1219
+ // Separate prices with explicit IDs from those without
1220
+ const pricesWithIds = prices.filter((p) => p.id).map((p) => p.id);
1221
+ // Build unique constraints based on hash properties
1222
+ const constraintSet = new Set();
1223
+ const constraints = [];
1224
+ for (const price of prices) {
1225
+ // Skip if price has explicit ID (will be queried separately)
1226
+ if (price.id)
1227
+ continue;
1228
+ const constraint = {};
1229
+ if (price.currency_code !== undefined) {
1230
+ constraint.currency_code = price.currency_code;
1231
+ }
1232
+ if ("price_set_id" in price && price.price_set_id !== undefined) {
1233
+ constraint.price_set_id = price.price_set_id;
1234
+ }
1235
+ if ("price_list_id" in price && price.price_list_id !== undefined) {
1236
+ constraint.price_list_id = price.price_list_id;
1237
+ }
1238
+ if (price.min_quantity !== undefined) {
1239
+ constraint.min_quantity = price.min_quantity;
1240
+ }
1241
+ if (price.max_quantity !== undefined) {
1242
+ constraint.max_quantity = price.max_quantity;
1243
+ }
1244
+ // Use hash to deduplicate constraints
1245
+ const constraintHash = JSON.stringify(constraint);
1246
+ if (!constraintSet.has(constraintHash)) {
1247
+ constraintSet.add(constraintHash);
1248
+ constraints.push(constraint);
1249
+ }
1250
+ }
1251
+ // Build final query
1252
+ const query = {};
1253
+ if (priceListIds) {
1254
+ if (Array.isArray(priceListIds) && priceListIds.length > 0) {
1255
+ query.price_list_id = {
1256
+ $in: priceListIds,
1257
+ };
1258
+ }
1259
+ else {
1260
+ query.price_list_id = priceListIds;
1261
+ }
1262
+ }
1263
+ // Combine ID-based and property-based constraints
1264
+ if (pricesWithIds.length && constraints.length) {
1265
+ query.$or = [{ id: pricesWithIds }, ...constraints];
1266
+ }
1267
+ else if (pricesWithIds.length) {
1268
+ query.id = pricesWithIds;
1269
+ }
1270
+ else if (constraints.length) {
1271
+ if (constraints.length === 1) {
1272
+ Object.assign(query, constraints[0]);
1273
+ }
1274
+ else {
1275
+ query.$or = constraints;
1276
+ }
1277
+ }
1278
+ return query;
1071
1279
  };
1072
1280
  //# sourceMappingURL=pricing-module.js.map