@medusajs/pricing 0.2.0-snapshot-20240429062340 → 1.0.0-rc-20241001083650

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. package/dist/index.d.ts +6 -6
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +6 -9
  4. package/dist/index.js.map +1 -0
  5. package/dist/joiner-config.d.ts +2 -10
  6. package/dist/joiner-config.d.ts.map +1 -0
  7. package/dist/joiner-config.js +6 -48
  8. package/dist/joiner-config.js.map +1 -0
  9. package/dist/migrations/Migration20230929122253.d.ts +1 -0
  10. package/dist/migrations/Migration20230929122253.d.ts.map +1 -0
  11. package/dist/migrations/Migration20230929122253.js +1 -0
  12. package/dist/migrations/Migration20230929122253.js.map +1 -0
  13. package/dist/migrations/Migration20240322094407.d.ts +1 -0
  14. package/dist/migrations/Migration20240322094407.d.ts.map +1 -0
  15. package/dist/migrations/Migration20240322094407.js +1 -0
  16. package/dist/migrations/Migration20240322094407.js.map +1 -0
  17. package/dist/migrations/Migration20240322113359.d.ts +1 -0
  18. package/dist/migrations/Migration20240322113359.d.ts.map +1 -0
  19. package/dist/migrations/Migration20240322113359.js +1 -0
  20. package/dist/migrations/Migration20240322113359.js.map +1 -0
  21. package/dist/migrations/Migration20240322120125.d.ts +1 -0
  22. package/dist/migrations/Migration20240322120125.d.ts.map +1 -0
  23. package/dist/migrations/Migration20240322120125.js +1 -0
  24. package/dist/migrations/Migration20240322120125.js.map +1 -0
  25. package/dist/migrations/Migration20240626133555.d.ts +5 -0
  26. package/dist/migrations/Migration20240626133555.d.ts.map +1 -0
  27. package/dist/migrations/Migration20240626133555.js +34 -0
  28. package/dist/migrations/Migration20240626133555.js.map +1 -0
  29. package/dist/migrations/Migration20240704094505.d.ts +6 -0
  30. package/dist/migrations/Migration20240704094505.d.ts.map +1 -0
  31. package/dist/migrations/Migration20240704094505.js +16 -0
  32. package/dist/migrations/Migration20240704094505.js.map +1 -0
  33. package/dist/models/index.d.ts +2 -3
  34. package/dist/models/index.d.ts.map +1 -0
  35. package/dist/models/index.js +4 -7
  36. package/dist/models/index.js.map +1 -0
  37. package/dist/models/price-list-rule.d.ts +7 -9
  38. package/dist/models/price-list-rule.d.ts.map +1 -0
  39. package/dist/models/price-list-rule.js +10 -30
  40. package/dist/models/price-list-rule.js.map +1 -0
  41. package/dist/models/price-list.d.ts +4 -5
  42. package/dist/models/price-list.d.ts.map +1 -0
  43. package/dist/models/price-list.js +2 -10
  44. package/dist/models/price-list.js.map +1 -0
  45. package/dist/models/price-preference.d.ts +13 -0
  46. package/dist/models/price-preference.d.ts.map +1 -0
  47. package/dist/models/{rule-type.js → price-preference.js} +37 -41
  48. package/dist/models/price-preference.js.map +1 -0
  49. package/dist/models/price-rule.d.ts +6 -10
  50. package/dist/models/price-rule.d.ts.map +1 -0
  51. package/dist/models/price-rule.js +8 -46
  52. package/dist/models/price-rule.js.map +1 -0
  53. package/dist/models/price-set.d.ts +1 -4
  54. package/dist/models/price-set.d.ts.map +1 -0
  55. package/dist/models/price-set.js +2 -20
  56. package/dist/models/price-set.js.map +1 -0
  57. package/dist/models/price.d.ts +7 -6
  58. package/dist/models/price.d.ts.map +1 -0
  59. package/dist/models/price.js +7 -6
  60. package/dist/models/price.js.map +1 -0
  61. package/dist/repositories/index.d.ts +2 -1
  62. package/dist/repositories/index.d.ts.map +1 -0
  63. package/dist/repositories/index.js +2 -1
  64. package/dist/repositories/index.js.map +1 -0
  65. package/dist/repositories/pricing.d.ts +3 -2
  66. package/dist/repositories/pricing.d.ts.map +1 -0
  67. package/dist/repositories/pricing.js +41 -45
  68. package/dist/repositories/pricing.js.map +1 -0
  69. package/dist/schema/index.d.ts +2 -1
  70. package/dist/schema/index.d.ts.map +1 -0
  71. package/dist/schema/index.js +48 -4
  72. package/dist/schema/index.js.map +1 -0
  73. package/dist/services/index.d.ts +1 -2
  74. package/dist/services/index.d.ts.map +1 -0
  75. package/dist/services/index.js +2 -5
  76. package/dist/services/index.js.map +1 -0
  77. package/dist/services/pricing-module.d.ts +66 -53
  78. package/dist/services/pricing-module.d.ts.map +1 -0
  79. package/dist/services/pricing-module.js +625 -631
  80. package/dist/services/pricing-module.js.map +1 -0
  81. package/dist/tsconfig.tsbuildinfo +1 -0
  82. package/dist/types/index.d.ts +2 -1
  83. package/dist/types/index.d.ts.map +1 -0
  84. package/dist/types/index.js +1 -0
  85. package/dist/types/index.js.map +1 -0
  86. package/dist/types/services/index.d.ts +30 -2
  87. package/dist/types/services/index.d.ts.map +1 -0
  88. package/dist/types/services/index.js +1 -16
  89. package/dist/types/services/index.js.map +1 -0
  90. package/dist/utils/events.d.ts +83 -0
  91. package/dist/utils/events.d.ts.map +1 -0
  92. package/dist/utils/events.js +67 -0
  93. package/dist/utils/events.js.map +1 -0
  94. package/dist/utils/index.d.ts +2 -0
  95. package/dist/utils/index.d.ts.map +1 -0
  96. package/dist/utils/index.js +2 -0
  97. package/dist/utils/index.js.map +1 -0
  98. package/dist/utils/validate-price-list-dates.d.ts +1 -0
  99. package/dist/utils/validate-price-list-dates.d.ts.map +1 -0
  100. package/dist/utils/validate-price-list-dates.js +2 -1
  101. package/dist/utils/validate-price-list-dates.js.map +1 -0
  102. package/package.json +20 -21
  103. package/dist/initialize/index.d.ts +0 -4
  104. package/dist/initialize/index.js +0 -17
  105. package/dist/loaders/connection.d.ts +0 -4
  106. package/dist/loaders/connection.js +0 -40
  107. package/dist/loaders/container.d.ts +0 -2
  108. package/dist/loaders/container.js +0 -34
  109. package/dist/loaders/index.d.ts +0 -2
  110. package/dist/loaders/index.js +0 -18
  111. package/dist/models/price-list-rule-value.d.ts +0 -17
  112. package/dist/models/price-list-rule-value.js +0 -102
  113. package/dist/models/price-set-rule-type.d.ts +0 -10
  114. package/dist/models/price-set-rule-type.js +0 -108
  115. package/dist/models/rule-type.d.ts +0 -17
  116. package/dist/module-definition.d.ts +0 -4
  117. package/dist/module-definition.js +0 -50
  118. package/dist/scripts/bin/run-seed.d.ts +0 -3
  119. package/dist/scripts/bin/run-seed.js +0 -38
  120. package/dist/scripts/seed.d.ts +0 -4
  121. package/dist/scripts/seed.js +0 -67
  122. package/dist/services/price-list.d.ts +0 -16
  123. package/dist/services/price-list.js +0 -34
  124. package/dist/services/rule-type.d.ts +0 -15
  125. package/dist/services/rule-type.js +0 -53
  126. package/dist/types/services/price-list.d.ts +0 -18
  127. package/dist/types/services/price-list.js +0 -2
  128. package/dist/types/services/price-set.d.ts +0 -4
  129. package/dist/types/services/price-set.js +0 -2
@@ -12,38 +12,32 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
12
  return function (target, key) { decorator(target, key, paramIndex); }
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- const types_1 = require("@medusajs/types");
16
- const utils_1 = require("@medusajs/utils");
15
+ const types_1 = require("@medusajs/framework/types");
16
+ const utils_1 = require("@medusajs/framework/utils");
17
17
  const _models_1 = require("../models");
18
18
  const _utils_1 = require("../utils");
19
19
  const joiner_config_1 = require("../joiner-config");
20
- const price_list_1 = require("../models/price-list");
21
- const price_set_1 = require("../models/price-set");
22
- const generateMethodForModels = [
23
- _models_1.PriceList,
24
- _models_1.PriceListRule,
25
- _models_1.PriceListRuleValue,
26
- _models_1.PriceRule,
27
- _models_1.Price,
28
- _models_1.PriceSetRuleType,
29
- _models_1.RuleType,
30
- ];
31
- class PricingModuleService extends utils_1.ModulesSdkUtils.abstractModuleServiceFactory(_models_1.PriceSet, generateMethodForModels, joiner_config_1.entityNameToLinkableKeysMap) {
32
- constructor({ baseRepository, pricingRepository, ruleTypeService, priceSetService, priceRuleService, priceSetRuleTypeService, priceService, priceListService, priceListRuleService, priceListRuleValueService, }, moduleDeclaration) {
20
+ const generateMethodForModels = {
21
+ PriceSet: _models_1.PriceSet,
22
+ PriceList: _models_1.PriceList,
23
+ PriceListRule: _models_1.PriceListRule,
24
+ PriceRule: _models_1.PriceRule,
25
+ Price: _models_1.Price,
26
+ PricePreference: _models_1.PricePreference,
27
+ };
28
+ class PricingModuleService extends utils_1.ModulesSdkUtils.MedusaService(generateMethodForModels) {
29
+ constructor({ baseRepository, pricingRepository, priceSetService, priceRuleService, priceService, pricePreferenceService, priceListService, priceListRuleService, }, moduleDeclaration) {
33
30
  // @ts-ignore
34
31
  super(...arguments);
35
32
  this.moduleDeclaration = moduleDeclaration;
36
33
  this.baseRepository_ = baseRepository;
37
34
  this.pricingRepository_ = pricingRepository;
38
- this.ruleTypeService_ = ruleTypeService;
39
35
  this.priceSetService_ = priceSetService;
40
- this.ruleTypeService_ = ruleTypeService;
41
36
  this.priceRuleService_ = priceRuleService;
42
- this.priceSetRuleTypeService_ = priceSetRuleTypeService;
43
37
  this.priceService_ = priceService;
38
+ this.pricePreferenceService_ = pricePreferenceService;
44
39
  this.priceListService_ = priceListService;
45
40
  this.priceListRuleService_ = priceListRuleService;
46
- this.priceListRuleValueService_ = priceListRuleValueService;
47
41
  }
48
42
  __joinerConfig() {
49
43
  return joiner_config_1.joinerConfig;
@@ -51,61 +45,69 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.abstractModuleService
51
45
  setupCalculatedPriceConfig_(filters, config) {
52
46
  const fieldIdx = config.relations?.indexOf("calculated_price");
53
47
  const shouldCalculatePrice = fieldIdx > -1;
48
+ const pricingContext = filters.context ?? {};
49
+ delete filters.context;
54
50
  if (!shouldCalculatePrice) {
55
51
  return;
56
52
  }
57
- let pricingContext = filters.context ?? {};
58
53
  // cleanup virtual field "calculated_price"
59
54
  config.relations?.splice(fieldIdx, 1);
60
- delete filters.context;
61
55
  return pricingContext;
62
56
  }
63
- async list(filters = {}, config = {}, sharedContext = {}) {
64
- const pricingContext = this.setupCalculatedPriceConfig_(filters, config);
65
- const priceSets = await super.list(filters, config, sharedContext);
66
- if (pricingContext && priceSets.length) {
67
- const priceSetIds = [];
68
- const priceSetMap = new Map();
69
- for (const priceSet of priceSets) {
70
- priceSetIds.push(priceSet.id);
71
- priceSetMap.set(priceSet.id, priceSet);
72
- }
73
- const calculatedPrices = await this.calculatePrices({ id: priceSets.map((p) => p.id) }, { context: pricingContext }, sharedContext);
74
- for (const calculatedPrice of calculatedPrices) {
75
- const priceSet = priceSetMap.get(calculatedPrice.id);
76
- priceSet.calculated_price = calculatedPrice;
77
- }
57
+ // @ts-expect-error
58
+ async retrievePriceSet(id, config, sharedContext) {
59
+ const priceSet = await this.priceSetService_.retrieve(id, this.normalizePriceSetConfig(config), sharedContext);
60
+ return await this.baseRepository_.serialize(priceSet);
61
+ }
62
+ // @ts-expect-error
63
+ async listPriceSets(filters = {}, config = {}, sharedContext = {}) {
64
+ const normalizedConfig = this.normalizePriceSetConfig(config);
65
+ const pricingContext = this.setupCalculatedPriceConfig_(filters, normalizedConfig);
66
+ const priceSets = await super.listPriceSets(filters, normalizedConfig, sharedContext);
67
+ if (!pricingContext || !priceSets.length) {
68
+ return priceSets;
69
+ }
70
+ const calculatedPrices = await this.calculatePrices({ id: priceSets.map((p) => p.id) }, { context: pricingContext }, sharedContext);
71
+ const calculatedPricesMap = new Map();
72
+ for (const calculatedPrice of calculatedPrices) {
73
+ calculatedPricesMap.set(calculatedPrice.id, calculatedPrice);
74
+ }
75
+ for (const priceSet of priceSets) {
76
+ const calculatedPrice = calculatedPricesMap.get(priceSet.id);
77
+ priceSet.calculated_price = calculatedPrice ?? null;
78
78
  }
79
79
  return priceSets;
80
80
  }
81
- async listAndCount(filters = {}, config = {}, sharedContext = {}) {
82
- const pricingContext = this.setupCalculatedPriceConfig_(filters, config);
83
- const [priceSets, count] = await super.listAndCount(filters, config, sharedContext);
84
- if (pricingContext && priceSets.length) {
85
- const priceSetIds = [];
86
- const priceSetMap = new Map();
87
- for (const priceSet of priceSets) {
88
- priceSetIds.push(priceSet.id);
89
- priceSetMap.set(priceSet.id, priceSet);
90
- }
91
- const calculatedPrices = await this.calculatePrices({ id: priceSets.map((p) => p.id) }, { context: pricingContext }, sharedContext);
92
- for (const calculatedPrice of calculatedPrices) {
93
- const priceSet = priceSetMap.get(calculatedPrice.id);
94
- priceSet.calculated_price = calculatedPrice;
95
- }
81
+ // @ts-expect-error
82
+ async listAndCountPriceSets(filters = {}, config = {}, sharedContext = {}) {
83
+ const normalizedConfig = this.normalizePriceSetConfig(config);
84
+ const pricingContext = this.setupCalculatedPriceConfig_(filters, normalizedConfig);
85
+ const [priceSets, count] = await super.listAndCountPriceSets(filters, normalizedConfig, sharedContext);
86
+ if (!pricingContext || !priceSets.length) {
87
+ return [priceSets, count];
88
+ }
89
+ const calculatedPrices = await this.calculatePrices({ id: priceSets.map((p) => p.id) }, { context: pricingContext }, sharedContext);
90
+ const calculatedPricesMap = new Map();
91
+ for (const calculatedPrice of calculatedPrices) {
92
+ calculatedPricesMap.set(calculatedPrice.id, calculatedPrice);
93
+ }
94
+ for (const priceSet of priceSets) {
95
+ const calculatedPrice = calculatedPricesMap.get(priceSet.id);
96
+ priceSet.calculated_price = calculatedPrice ?? null;
96
97
  }
97
98
  return [priceSets, count];
98
99
  }
99
100
  async calculatePrices(pricingFilters, pricingContext = { context: {} }, sharedContext = {}) {
100
101
  const results = await this.pricingRepository_.calculatePrices(pricingFilters, pricingContext, sharedContext);
101
102
  const pricesSetPricesMap = (0, utils_1.groupBy)(results, "price_set_id");
102
- const calculatedPrices = pricingFilters.id.map((priceSetId) => {
103
- // This is where we select prices, for now we just do a first match based on the database results
104
- // which is prioritized by rules_count first for exact match and then deafult_priority of the rule_type
105
- // TODO: inject custom price selection here
106
- const prices = pricesSetPricesMap.get(priceSetId) || [];
103
+ const priceIds = [];
104
+ pricesSetPricesMap.forEach((prices, key) => {
107
105
  const priceListPrice = prices.find((p) => p.price_list_id);
108
106
  const defaultPrice = prices?.find((p) => !p.price_list_id);
107
+ if (!prices.length || (!priceListPrice && !defaultPrice)) {
108
+ pricesSetPricesMap.delete(key);
109
+ return;
110
+ }
109
111
  let calculatedPrice = defaultPrice;
110
112
  let originalPrice = defaultPrice;
111
113
  if (priceListPrice) {
@@ -114,12 +116,47 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.abstractModuleService
114
116
  originalPrice = priceListPrice;
115
117
  }
116
118
  }
119
+ pricesSetPricesMap.set(key, { calculatedPrice, originalPrice });
120
+ priceIds.push(...(0, utils_1.deduplicate)([calculatedPrice?.id, originalPrice?.id].filter(Boolean)));
121
+ });
122
+ // We use the price rules to get the right preferences for the price
123
+ const priceRulesForPrices = await this.priceRuleService_.list({ price_id: priceIds }, {});
124
+ const priceRulesPriceMap = (0, utils_1.groupBy)(priceRulesForPrices, "price_id");
125
+ // Note: For now the preferences are intentionally kept very simple and explicit - they use either the region or currency,
126
+ // so we hard-code those as the possible filters here. This can be made more flexible if needed later on.
127
+ const pricingPreferences = await this.pricePreferenceService_.list({
128
+ $or: Object.entries(pricingContext)
129
+ .filter(([key, val]) => {
130
+ return key === "region_id" || key === "currency_code";
131
+ })
132
+ .map(([key, val]) => ({
133
+ attribute: key,
134
+ value: val,
135
+ })),
136
+ }, {}, sharedContext);
137
+ const calculatedPrices = pricingFilters.id
138
+ .map((priceSetId) => {
139
+ const prices = pricesSetPricesMap.get(priceSetId);
140
+ if (!prices) {
141
+ return null;
142
+ }
143
+ const { calculatedPrice, originalPrice, } = prices;
117
144
  return {
118
145
  id: priceSetId,
119
146
  is_calculated_price_price_list: !!calculatedPrice?.price_list_id,
120
- calculated_amount: parseInt(calculatedPrice?.amount || "") || null,
147
+ is_calculated_price_tax_inclusive: isTaxInclusive(priceRulesPriceMap.get(calculatedPrice.id), pricingPreferences, calculatedPrice.currency_code, pricingContext.context?.region_id),
148
+ calculated_amount: (0, utils_1.isPresent)(calculatedPrice?.amount)
149
+ ? parseFloat(calculatedPrice?.amount)
150
+ : null,
151
+ raw_calculated_amount: calculatedPrice?.raw_amount || null,
121
152
  is_original_price_price_list: !!originalPrice?.price_list_id,
122
- original_amount: parseInt(originalPrice?.amount || "") || null,
153
+ is_original_price_tax_inclusive: originalPrice?.id
154
+ ? isTaxInclusive(priceRulesPriceMap.get(originalPrice.id), pricingPreferences, originalPrice.currency_code || calculatedPrice.currency_code, pricingContext.context?.region_id)
155
+ : false,
156
+ original_amount: (0, utils_1.isPresent)(originalPrice?.amount)
157
+ ? parseFloat(originalPrice?.amount)
158
+ : null,
159
+ raw_original_amount: originalPrice?.raw_amount || null,
123
160
  currency_code: calculatedPrice?.currency_code || null,
124
161
  calculated_price: {
125
162
  id: calculatedPrice?.id || null,
@@ -136,35 +173,38 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.abstractModuleService
136
173
  max_quantity: parseInt(originalPrice?.max_quantity || "") || null,
137
174
  },
138
175
  };
139
- });
176
+ })
177
+ .filter(Boolean);
140
178
  return JSON.parse(JSON.stringify(calculatedPrices));
141
179
  }
142
- async create(data, sharedContext = {}) {
180
+ async createPriceSets(data, sharedContext = {}) {
143
181
  const input = Array.isArray(data) ? data : [data];
144
- const priceSets = await this.create_(input, sharedContext);
182
+ const priceSets = await this.createPriceSets_(input, sharedContext);
145
183
  // TODO: Remove the need to refetch the data here
146
- const dbPriceSets = await this.list({ id: priceSets.map((p) => p.id) }, { relations: ["rule_types", "prices", "price_rules"] }, sharedContext);
184
+ const dbPriceSets = await this.listPriceSets({ id: priceSets.map((p) => p.id) }, this.normalizePriceSetConfig({
185
+ relations: ["prices", "prices.price_rules"],
186
+ }), sharedContext);
147
187
  // Ensure the output to be in the same order as the input
148
188
  const results = priceSets.map((priceSet) => {
149
189
  return dbPriceSets.find((p) => p.id === priceSet.id);
150
190
  });
151
191
  return await this.baseRepository_.serialize(Array.isArray(data) ? results : results[0]);
152
192
  }
153
- async upsert(data, sharedContext = {}) {
193
+ async upsertPriceSets(data, sharedContext = {}) {
154
194
  const input = Array.isArray(data) ? data : [data];
155
195
  const forUpdate = input.filter((priceSet) => !!priceSet.id);
156
196
  const forCreate = input.filter((priceSet) => !priceSet.id);
157
197
  const operations = [];
158
198
  if (forCreate.length) {
159
- operations.push(this.create_(forCreate, sharedContext));
199
+ operations.push(this.createPriceSets_(forCreate, sharedContext));
160
200
  }
161
201
  if (forUpdate.length) {
162
- operations.push(this.update_(forUpdate, sharedContext));
202
+ operations.push(this.updatePriceSets_(forUpdate, sharedContext));
163
203
  }
164
204
  const result = (await (0, utils_1.promiseAll)(operations)).flat();
165
205
  return await this.baseRepository_.serialize(Array.isArray(data) ? result : result[0]);
166
206
  }
167
- async update(idOrSelector, data, sharedContext = {}) {
207
+ async updatePriceSets(idOrSelector, data, sharedContext = {}) {
168
208
  let normalizedInput = [];
169
209
  if ((0, utils_1.isString)(idOrSelector)) {
170
210
  // Check if the ID exists, it will throw if not.
@@ -178,53 +218,16 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.abstractModuleService
178
218
  ...data,
179
219
  }));
180
220
  }
181
- const updateResult = await this.update_(normalizedInput, sharedContext);
221
+ const updateResult = await this.updatePriceSets_(normalizedInput, sharedContext);
182
222
  const priceSets = await this.baseRepository_.serialize(updateResult);
183
223
  return (0, utils_1.isString)(idOrSelector) ? priceSets[0] : priceSets;
184
224
  }
185
- async normalizeUpdateData(data, sharedContext) {
186
- const ruleAttributes = data
187
- .map((d) => d.prices?.map((p) => Object.keys(p.rules ?? [])) ?? [])
188
- .flat(Infinity)
189
- .filter(Boolean);
190
- const ruleTypes = await this.ruleTypeService_.list({ rule_attribute: ruleAttributes }, { take: null }, sharedContext);
191
- const ruleTypeMap = ruleTypes.reduce((acc, curr) => {
192
- acc.set(curr.rule_attribute, curr);
193
- return acc;
194
- }, new Map());
195
- return data.map((priceSet) => {
196
- const prices = priceSet.prices?.map((price) => {
197
- const rules = Object.entries(price.rules ?? {}).map(([attribute, value]) => {
198
- return {
199
- price_set_id: priceSet.id,
200
- rule_type_id: ruleTypeMap.get(attribute).id,
201
- value,
202
- };
203
- });
204
- const hasRulesInput = (0, utils_1.isPresent)(price.rules);
205
- delete price.rules;
206
- return {
207
- ...price,
208
- price_set_id: priceSet.id,
209
- price_rules: hasRulesInput ? rules : undefined,
210
- rules_count: hasRulesInput ? rules.length : undefined,
211
- };
212
- });
213
- return {
214
- ...priceSet,
215
- prices,
216
- };
217
- });
218
- }
219
- async update_(data, sharedContext = {}) {
220
- // TODO: We are not handling rule types, rules, etc. here, add support after data models are finalized
225
+ async updatePriceSets_(data, sharedContext = {}) {
221
226
  // TODO: Since money IDs are rarely passed, this will delete all previous data and insert new entries.
222
227
  // We can make the `insert` inside upsertWithReplace do an `upsert` instead to avoid this
223
- const normalizedData = await this.normalizeUpdateData(data, sharedContext);
228
+ const normalizedData = await this.normalizeUpdateData(data);
224
229
  const prices = normalizedData.flatMap((priceSet) => priceSet.prices || []);
225
- const upsertedPrices = await this.priceService_.upsertWithReplace(prices, {
226
- relations: ["price_rules"],
227
- }, sharedContext);
230
+ const { entities: upsertedPrices } = await this.priceService_.upsertWithReplace(prices, { relations: ["price_rules"] }, sharedContext);
228
231
  const priceSetsToUpsert = normalizedData.map((priceSet) => {
229
232
  const { prices, ...rest } = priceSet;
230
233
  return {
@@ -238,61 +241,71 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.abstractModuleService
238
241
  }),
239
242
  };
240
243
  });
241
- return await this.priceSetService_.upsertWithReplace(priceSetsToUpsert, { relations: ["prices"] }, sharedContext);
244
+ const { entities: priceSets } = await this.priceSetService_.upsertWithReplace(priceSetsToUpsert, { relations: ["prices"] }, sharedContext);
245
+ return priceSets;
242
246
  }
243
- async addRules(data, sharedContext = {}) {
244
- const inputs = Array.isArray(data) ? data : [data];
245
- const priceSets = await this.addRules_(inputs, sharedContext);
246
- const dbPriceSets = await this.list({ id: priceSets.map(({ id }) => id) }, { relations: ["rule_types"] });
247
- const orderedPriceSets = priceSets.map((priceSet) => {
248
- return dbPriceSets.find((p) => p.id === priceSet.id);
247
+ async normalizeUpdateData(data) {
248
+ return data.map((priceSet) => {
249
+ return {
250
+ ...priceSet,
251
+ prices: this.normalizePrices(priceSet.prices?.map((p) => ({ ...p, price_set_id: priceSet.id })), []),
252
+ };
249
253
  });
250
- return Array.isArray(data) ? orderedPriceSets : orderedPriceSets[0];
254
+ }
255
+ normalizePrices(data, existingPrices, priceListId) {
256
+ const pricesToUpsert = new Map();
257
+ const existingPricesMap = new Map();
258
+ existingPrices?.forEach((price) => {
259
+ existingPricesMap.set(hashPrice(price), price);
260
+ });
261
+ data?.forEach((price) => {
262
+ const cleanRules = price.rules ? (0, utils_1.removeNullish)(price.rules) : {};
263
+ const ruleEntries = Object.entries(cleanRules);
264
+ const rules = ruleEntries.map(([attribute, value]) => {
265
+ return {
266
+ attribute,
267
+ value,
268
+ };
269
+ });
270
+ const hasRulesInput = (0, utils_1.isPresent)(price.rules);
271
+ const entry = {
272
+ ...price,
273
+ price_list_id: priceListId,
274
+ price_rules: hasRulesInput ? rules : undefined,
275
+ rules_count: hasRulesInput ? ruleEntries.length : undefined,
276
+ };
277
+ delete entry.rules;
278
+ const entryHash = hashPrice(entry);
279
+ // We want to keep the existing rules as they might already have ids, but any other data should come from the updated input
280
+ const existing = existingPricesMap.get(entryHash);
281
+ pricesToUpsert.set(entryHash, {
282
+ ...entry,
283
+ id: existing?.id ?? entry.id,
284
+ price_rules: existing?.price_rules ?? entry.price_rules,
285
+ });
286
+ return entry;
287
+ });
288
+ return Array.from(pricesToUpsert.values());
251
289
  }
252
290
  async addPrices(data, sharedContext = {}) {
253
291
  const input = Array.isArray(data) ? data : [data];
254
292
  await this.addPrices_(input, sharedContext);
255
- const dbPrices = await this.list({ id: input.map((d) => d.priceSetId) }, { relations: ["prices"] }, sharedContext);
293
+ const dbPrices = await this.listPriceSets({ id: input.map((d) => d.priceSetId) }, { relations: ["prices"] }, sharedContext);
256
294
  const orderedPriceSets = input.map((inputItem) => {
257
295
  return dbPrices.find((p) => p.id === inputItem.priceSetId);
258
296
  });
259
297
  return Array.isArray(data) ? orderedPriceSets : orderedPriceSets[0];
260
298
  }
261
- async removeRules(data, sharedContext = {}) {
262
- const priceSets = await this.priceSetService_.list({ id: data.map((d) => d.id) }, {}, sharedContext);
263
- const priceSetIds = priceSets.map((ps) => ps.id);
264
- const ruleTypes = await this.ruleTypeService_.list({
265
- rule_attribute: data.map((d) => d.rules || []).flat(),
266
- }, { take: null }, sharedContext);
267
- const ruleTypeIds = ruleTypes.map((rt) => rt.id);
268
- const priceSetRuleTypes = await this.priceSetRuleTypeService_.list({ price_set_id: priceSetIds, rule_type_id: ruleTypeIds }, { take: null }, sharedContext);
269
- const priceRules = await this.priceRuleService_.list({ price_set_id: priceSetIds, rule_type_id: ruleTypeIds }, { select: ["price"], take: null }, sharedContext);
270
- await this.priceSetRuleTypeService_.delete(priceSetRuleTypes.map((psrt) => psrt.id), sharedContext);
271
- await this.priceService_.delete(priceRules.map((pr) => pr.price.id), sharedContext);
272
- }
299
+ // @ts-ignore
273
300
  async createPriceLists(data, sharedContext = {}) {
274
301
  const priceLists = await this.createPriceLists_(data, sharedContext);
275
302
  return await this.baseRepository_.serialize(priceLists);
276
303
  }
304
+ // @ts-ignore
277
305
  async updatePriceLists(data, sharedContext = {}) {
278
306
  const priceLists = await this.updatePriceLists_(data, sharedContext);
279
307
  return await this.baseRepository_.serialize(priceLists);
280
308
  }
281
- async createPriceListRules(data, sharedContext = {}) {
282
- const priceLists = await this.createPriceListRules_(data, sharedContext);
283
- return await this.baseRepository_.serialize(priceLists, {
284
- populate: true,
285
- });
286
- }
287
- async createPriceListRules_(data, sharedContext = {}) {
288
- return await this.priceListRuleService_.create(data, sharedContext);
289
- }
290
- async updatePriceListRules(data, sharedContext = {}) {
291
- const priceLists = await this.priceListRuleService_.update(data, sharedContext);
292
- return await this.baseRepository_.serialize(priceLists, {
293
- populate: true,
294
- });
295
- }
296
309
  async updatePriceListPrices(data, sharedContext = {}) {
297
310
  const prices = await this.updatePriceListPrices_(data, sharedContext);
298
311
  return await this.baseRepository_.serialize(prices);
@@ -312,693 +325,674 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.abstractModuleService
312
325
  const [priceList] = await this.removePriceListRules_([data], sharedContext);
313
326
  return await this.baseRepository_.serialize(priceList);
314
327
  }
315
- async create_(data, sharedContext = {}) {
328
+ async createPricePreferences(data, sharedContext = {}) {
329
+ const normalized = Array.isArray(data) ? data : [data];
330
+ const preferences = await this.createPricePreferences_(normalized, sharedContext);
331
+ const serialized = await this.baseRepository_.serialize(preferences);
332
+ return Array.isArray(data) ? serialized : serialized[0];
333
+ }
334
+ async upsertPricePreferences(data, sharedContext = {}) {
316
335
  const input = Array.isArray(data) ? data : [data];
317
- const ruleAttributes = data
318
- .map((d) => d.rules?.map((r) => r.rule_attribute) ?? [])
319
- .flat();
320
- const ruleTypes = await this.ruleTypeService_.list({ rule_attribute: ruleAttributes }, { take: null }, sharedContext);
321
- const ruleTypeMap = ruleTypes.reduce((acc, curr) => {
322
- acc.set(curr.rule_attribute, curr);
323
- return acc;
324
- }, new Map());
325
- const invalidRuleAttributes = ruleAttributes.filter((r) => !ruleTypeMap.has(r));
326
- if (invalidRuleAttributes.length > 0) {
327
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, `Rule types don't exist for: ${invalidRuleAttributes.join(", ")}`);
336
+ const forUpdate = input.filter((pricePreference) => !!pricePreference.id);
337
+ const forCreate = input.filter((pricePreference) => !pricePreference.id);
338
+ const operations = [];
339
+ if (forCreate.length) {
340
+ operations.push(this.createPricePreferences_(forCreate, sharedContext));
341
+ }
342
+ if (forUpdate.length) {
343
+ operations.push(this.updatePricePreferences_(forUpdate, sharedContext));
328
344
  }
329
- const invalidMoneyAmountRule = data
330
- .map((d) => d.prices?.map((ma) => Object.keys(ma?.rules ?? {})).flat() ?? [])
331
- .flat()
332
- .filter((r) => !ruleTypeMap.has(r));
333
- if (invalidMoneyAmountRule.length > 0) {
334
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Rule types don't exist for money amounts with rule attribute: ${invalidMoneyAmountRule.join(", ")}`);
345
+ const result = (await (0, utils_1.promiseAll)(operations)).flat();
346
+ return await this.baseRepository_.serialize(Array.isArray(data) ? result : result[0]);
347
+ }
348
+ async updatePricePreferences(idOrSelector, data, sharedContext = {}) {
349
+ let normalizedInput = [];
350
+ if ((0, utils_1.isString)(idOrSelector)) {
351
+ // Check if the ID exists, it will throw if not.
352
+ await this.pricePreferenceService_.retrieve(idOrSelector, {}, sharedContext);
353
+ normalizedInput = [{ id: idOrSelector, ...data }];
335
354
  }
336
- const ruleSetRuleTypeToCreateMap = new Map();
355
+ else {
356
+ const pricePreferences = await this.pricePreferenceService_.list(idOrSelector, {}, sharedContext);
357
+ normalizedInput = pricePreferences.map((pricePreference) => ({
358
+ id: pricePreference.id,
359
+ ...data,
360
+ }));
361
+ }
362
+ const updateResult = await this.updatePricePreferences_(normalizedInput, sharedContext);
363
+ const pricePreferences = await this.baseRepository_.serialize(updateResult);
364
+ return (0, utils_1.isString)(idOrSelector) ? pricePreferences[0] : pricePreferences;
365
+ }
366
+ async createPricePreferences_(data, sharedContext = {}) {
367
+ const preferences = await this.pricePreferenceService_.create(data.map((d) => ({
368
+ ...d,
369
+ is_tax_inclusive: d.is_tax_inclusive ?? false,
370
+ })), sharedContext);
371
+ return preferences;
372
+ }
373
+ async updatePricePreferences_(data, sharedContext = {}) {
374
+ const preferences = await this.pricePreferenceService_.update(data, sharedContext);
375
+ return preferences;
376
+ }
377
+ async createPriceSets_(data, sharedContext = {}) {
378
+ const input = Array.isArray(data) ? data : [data];
337
379
  const toCreate = input.map((inputData) => {
338
- const id = (0, utils_1.generateEntityId)(inputData.id, price_set_1.PriceSetIdPrefix);
339
- const { prices, rules = [], ...rest } = inputData;
340
- let pricesData = [];
341
- rules.forEach((rule) => {
342
- const priceSetRuleType = {
343
- rule_type_id: ruleTypeMap.get(rule.rule_attribute).id,
344
- price_set_id: id,
345
- };
346
- ruleSetRuleTypeToCreateMap.set(JSON.stringify(priceSetRuleType), priceSetRuleType);
347
- });
348
- if (inputData.prices) {
349
- pricesData = inputData.prices.map((price) => {
350
- let { rules: priceRules = {}, ...rest } = price;
351
- const cleanRules = priceRules ? (0, utils_1.removeNullish)(priceRules) : {};
352
- const numberOfRules = Object.keys(cleanRules).length;
353
- const rulesDataMap = new Map();
354
- Object.entries(priceRules).map(([attribute, value]) => {
355
- const rule = {
356
- price_set_id: id,
357
- rule_type_id: ruleTypeMap.get(attribute).id,
358
- value,
359
- };
360
- rulesDataMap.set(JSON.stringify(rule), rule);
361
- const priceSetRuleType = {
362
- rule_type_id: ruleTypeMap.get(attribute).id,
363
- price_set_id: id,
364
- };
365
- ruleSetRuleTypeToCreateMap.set(JSON.stringify(priceSetRuleType), priceSetRuleType);
366
- });
367
- return {
368
- ...rest,
369
- title: "",
370
- rules_count: numberOfRules,
371
- price_rules: Array.from(rulesDataMap.values()),
372
- };
373
- });
374
- }
375
- return {
376
- ...rest,
377
- id,
378
- prices: pricesData,
380
+ const entry = {
381
+ ...inputData,
382
+ prices: this.normalizePrices(inputData.prices, []),
379
383
  };
384
+ return entry;
380
385
  });
381
386
  // Bulk create price sets
382
387
  const createdPriceSets = await this.priceSetService_.create(toCreate, sharedContext);
383
- if (ruleSetRuleTypeToCreateMap.size) {
384
- await this.priceSetRuleTypeService_.create(Array.from(ruleSetRuleTypeToCreateMap.values()), sharedContext);
385
- }
386
- return createdPriceSets;
387
- }
388
- async addRules_(inputs, sharedContext = {}) {
389
- const priceSets = await this.priceSetService_.list({ id: inputs.map((d) => d.priceSetId) }, { relations: ["rule_types"] }, sharedContext);
390
- const priceSetRuleTypeMap = new Map(priceSets.map((priceSet) => [
391
- priceSet.id,
392
- new Map([...priceSet.rule_types].map((rt) => [rt.rule_attribute, rt])),
393
- ]));
394
- const priceSetMap = new Map(priceSets.map((p) => [p.id, p]));
395
- const invalidPriceSetInputs = inputs.filter((d) => !priceSetMap.has(d.priceSetId));
396
- if (invalidPriceSetInputs.length) {
397
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `PriceSets with ids: ${invalidPriceSetInputs
398
- .map((d) => d.priceSetId)
399
- .join(", ")} was not found`);
400
- }
401
- const ruleTypes = await this.ruleTypeService_.list({
402
- rule_attribute: inputs
403
- .map((data) => data.rules.map((r) => r.attribute))
404
- .flat(),
405
- }, { take: null }, sharedContext);
406
- const ruleTypeMap = new Map(ruleTypes.map((rt) => [rt.rule_attribute, rt]));
407
- const invalidRuleAttributeInputs = inputs
408
- .map((d) => d.rules.map((r) => r.attribute))
409
- .flat()
410
- .filter((r) => !ruleTypeMap.has(r));
411
- if (invalidRuleAttributeInputs.length) {
412
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Rule types don't exist for attributes: ${[
413
- ...new Set(invalidRuleAttributeInputs),
414
- ].join(", ")}`);
415
- }
416
- const priceSetRuleTypesCreate = [];
417
- inputs.forEach((data) => {
418
- for (const rule of data.rules) {
419
- if (priceSetRuleTypeMap.get(data.priceSetId).has(rule.attribute)) {
420
- continue;
421
- }
422
- priceSetRuleTypesCreate.push({
423
- rule_type_id: ruleTypeMap.get(rule.attribute).id,
424
- price_set_id: priceSetMap.get(data.priceSetId).id,
388
+ const eventsData = createdPriceSets.reduce((eventsData, priceSet) => {
389
+ eventsData.priceSets.push({
390
+ id: priceSet.id,
391
+ });
392
+ priceSet.prices.map((price) => {
393
+ eventsData.prices.push({
394
+ id: price.id,
425
395
  });
426
- }
396
+ price.price_rules.map((priceRule) => {
397
+ eventsData.priceRules.push({
398
+ id: priceRule.id,
399
+ });
400
+ });
401
+ });
402
+ return eventsData;
403
+ }, {
404
+ priceSets: [],
405
+ priceRules: [],
406
+ prices: [],
427
407
  });
428
- await this.priceSetRuleTypeService_.create(priceSetRuleTypesCreate, sharedContext);
429
- return priceSets;
408
+ _utils_1.eventBuilders.createdPriceSet({
409
+ data: eventsData.priceSets,
410
+ sharedContext,
411
+ });
412
+ _utils_1.eventBuilders.createdPrice({
413
+ data: eventsData.prices,
414
+ sharedContext,
415
+ });
416
+ _utils_1.eventBuilders.createdPriceRule({
417
+ data: eventsData.priceRules,
418
+ sharedContext,
419
+ });
420
+ return createdPriceSets;
430
421
  }
431
422
  async addPrices_(input, sharedContext = {}) {
432
- const priceSets = await this.list({ id: input.map((d) => d.priceSetId) }, { relations: ["rule_types"] }, sharedContext);
423
+ const priceSets = await this.listPriceSets({ id: input.map((d) => d.priceSetId) }, { relations: ["prices", "prices.price_rules"] }, sharedContext);
424
+ const existingPrices = priceSets
425
+ .map((p) => p.prices)
426
+ .flat();
427
+ const pricesToUpsert = input
428
+ .map((addPrice) => this.normalizePrices(addPrice.prices?.map((p) => ({
429
+ ...p,
430
+ price_set_id: addPrice.priceSetId,
431
+ })), existingPrices))
432
+ .filter(Boolean)
433
+ .flat();
433
434
  const priceSetMap = new Map(priceSets.map((p) => [p.id, p]));
434
- const ruleTypeMap = new Map(priceSets.map((priceSet) => [
435
- priceSet.id,
436
- new Map(priceSet.rule_types?.map((rt) => [rt.rule_attribute, rt]) ?? []),
437
- ]));
438
- input.forEach(({ priceSetId, prices }) => {
439
- const priceSet = priceSetMap.get(priceSetId);
435
+ pricesToUpsert.forEach((price) => {
436
+ const priceSet = priceSetMap.get(price.price_set_id);
440
437
  if (!priceSet) {
441
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Price set with id: ${priceSetId} not found`);
442
- }
443
- const ruleAttributes = prices
444
- .map((d) => (d.rules ? Object.keys(d.rules) : []))
445
- .flat();
446
- const invalidRuleAttributes = ruleAttributes.filter((r) => !ruleTypeMap.get(priceSetId).has(r));
447
- if (invalidRuleAttributes.length > 0) {
448
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, `Rule types don't exist for: ${invalidRuleAttributes.join(", ")}`);
438
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Price set with id: ${price.price_set_id} not found`);
449
439
  }
450
440
  });
451
- const pricesToCreate = input.flatMap(({ priceSetId, prices }) => prices.map((price) => {
452
- const numberOfRules = Object.entries(price?.rules ?? {}).length;
453
- const priceRules = Object.entries(price.rules ?? {}).map(([attribute, value]) => ({
454
- rule_type_id: ruleTypeMap.get(priceSetId).get(attribute).id,
455
- price_set_id: priceSetId,
456
- value,
457
- }));
458
- return {
459
- ...price,
460
- price_set_id: priceSetId,
461
- title: "test",
462
- rules_count: numberOfRules,
463
- priceRules,
464
- };
465
- }));
466
- await this.priceService_.create(pricesToCreate, sharedContext);
441
+ const { entities, performedActions } = await this.priceService_.upsertWithReplace(pricesToUpsert, { relations: ["price_rules"] }, sharedContext);
442
+ _utils_1.eventBuilders.createdPrice({
443
+ data: performedActions.created[_models_1.Price.name] ?? [],
444
+ sharedContext,
445
+ });
446
+ _utils_1.eventBuilders.updatedPrice({
447
+ data: performedActions.updated[_models_1.Price.name] ?? [],
448
+ sharedContext,
449
+ });
450
+ _utils_1.eventBuilders.deletedPrice({
451
+ data: performedActions.deleted[_models_1.Price.name] ?? [],
452
+ sharedContext,
453
+ });
454
+ _utils_1.eventBuilders.createdPriceRule({
455
+ data: performedActions.created[_models_1.PriceRule.name] ?? [],
456
+ sharedContext,
457
+ });
458
+ _utils_1.eventBuilders.updatedPriceRule({
459
+ data: performedActions.updated[_models_1.PriceRule.name] ?? [],
460
+ sharedContext,
461
+ });
462
+ _utils_1.eventBuilders.deletedPriceRule({
463
+ data: performedActions.deleted[_models_1.PriceRule.name] ?? [],
464
+ sharedContext,
465
+ });
466
+ return entities;
467
467
  }
468
468
  async createPriceLists_(data, sharedContext = {}) {
469
- const ruleTypeAttributes = [];
470
- for (const priceListData of data) {
471
- const { prices = [], rules: priceListRules = {} } = priceListData;
472
- ruleTypeAttributes.push(...Object.keys(priceListRules));
473
- for (const price of prices) {
474
- const { rules: priceListPriceRules = {} } = price;
475
- ruleTypeAttributes.push(...Object.keys(priceListPriceRules));
469
+ const normalized = this.normalizePriceListDate(data);
470
+ const priceListsToCreate = normalized.map((priceListData) => {
471
+ const entry = {
472
+ ...priceListData,
473
+ rules: undefined,
474
+ };
475
+ if (priceListData.prices) {
476
+ entry.prices = this.normalizePrices(priceListData.prices, []);
476
477
  }
477
- }
478
- const ruleTypes = await this.listRuleTypes({ rule_attribute: ruleTypeAttributes }, { take: null }, sharedContext);
479
- const invalidRuleTypes = (0, utils_1.arrayDifference)((0, utils_1.deduplicate)(ruleTypeAttributes), ruleTypes.map((ruleType) => ruleType.rule_attribute));
480
- if (invalidRuleTypes.length) {
481
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Cannot find RuleTypes with rule_attribute - ${invalidRuleTypes.join(", ")}`);
482
- }
483
- const ruleTypeMap = new Map(ruleTypes.map((rt) => [rt.rule_attribute, rt]));
484
- const priceListsToCreate = data.map((priceListData) => {
485
- const id = (0, utils_1.generateEntityId)(priceListData.id, price_list_1.PriceListIdPrefix);
486
- const { prices = [], rules = {}, ...rest } = priceListData;
487
- (0, _utils_1.validatePriceListDates)(priceListData);
488
- const priceListRules = Object.entries(rules).map(([attribute, value]) => {
489
- const ruleType = ruleTypeMap.get(attribute);
490
- return {
491
- price_list_id: id,
492
- rule_type_id: ruleType.id,
493
- price_list_rule_values: value.map((v) => ({ value: v })),
494
- };
495
- });
496
- const pricesData = prices.map((price) => {
497
- const priceRules = Object.entries(price.rules ?? {}).map(([ruleAttribute, ruleValue]) => {
498
- return {
499
- price_set_id: price.price_set_id,
500
- rule_type_id: ruleTypeMap.get(ruleAttribute)?.id,
501
- value: ruleValue,
478
+ if (priceListData.rules) {
479
+ const cleanRules = priceListData.rules
480
+ ? (0, utils_1.removeNullish)(priceListData.rules)
481
+ : {};
482
+ const rules = Object.entries(cleanRules);
483
+ const numberOfRules = rules.length;
484
+ const rulesDataMap = new Map();
485
+ rules.map(([attribute, value]) => {
486
+ const rule = {
487
+ attribute,
488
+ value,
502
489
  };
490
+ rulesDataMap.set(JSON.stringify(rule), rule);
503
491
  });
504
- return {
505
- price_list_id: id,
506
- title: "test",
507
- rules_count: Object.keys(price.rules ?? {}).length,
508
- price_rules: priceRules,
509
- ...price,
510
- };
492
+ entry.price_list_rules = Array.from(rulesDataMap.values());
493
+ entry.rules_count = numberOfRules;
494
+ }
495
+ return entry;
496
+ });
497
+ const priceLists = await this.priceListService_.create(priceListsToCreate, sharedContext);
498
+ /**
499
+ * Preparing data for emitting events
500
+ */
501
+ const eventsData = priceLists.reduce((eventsData, priceList) => {
502
+ eventsData.priceList.push({
503
+ id: priceList.id,
511
504
  });
512
- return {
513
- id,
514
- ...rest,
515
- rules_count: Object.keys(rules).length,
516
- price_list_rules: priceListRules,
517
- prices: pricesData,
518
- };
505
+ priceList.price_list_rules.map((listRule) => {
506
+ eventsData.priceListRules.push({
507
+ id: listRule.id,
508
+ });
509
+ });
510
+ priceList.prices.map((price) => {
511
+ eventsData.prices.push({
512
+ id: price.id,
513
+ });
514
+ price.price_rules.map((priceRule) => {
515
+ eventsData.priceRules.push({
516
+ id: priceRule.id,
517
+ });
518
+ });
519
+ });
520
+ return eventsData;
521
+ }, {
522
+ priceList: [],
523
+ priceListRules: [],
524
+ priceRules: [],
525
+ prices: [],
519
526
  });
520
- return await this.priceListService_.create(priceListsToCreate, sharedContext);
527
+ /**
528
+ * Emitting events for all created entities
529
+ */
530
+ _utils_1.eventBuilders.createdPriceList({
531
+ data: eventsData.priceList,
532
+ sharedContext,
533
+ });
534
+ _utils_1.eventBuilders.createdPriceListRule({
535
+ data: eventsData.priceListRules,
536
+ sharedContext,
537
+ });
538
+ _utils_1.eventBuilders.createdPrice({
539
+ data: eventsData.prices,
540
+ sharedContext,
541
+ });
542
+ _utils_1.eventBuilders.createdPriceRule({
543
+ data: eventsData.priceRules,
544
+ sharedContext,
545
+ });
546
+ return priceLists;
521
547
  }
522
548
  async updatePriceLists_(data, sharedContext = {}) {
523
- const updatedPriceLists = [];
524
- const ruleAttributes = [];
525
- const priceListIds = [];
526
- for (const priceListData of data) {
527
- if (typeof priceListData.rules === "object") {
528
- ruleAttributes.push(...Object.keys(priceListData.rules));
529
- priceListIds.push(priceListData.id);
530
- }
531
- }
532
- const existingPriceLists = await this.listPriceLists({ id: priceListIds }, { relations: ["price_list_rules"] }, sharedContext);
533
- const priceListRuleIds = existingPriceLists
534
- .map((pl) => (pl.price_list_rules || []).map((plr) => plr.id))
535
- .flat();
536
- const existingPriceListRules = await this.listPriceListRules({ id: priceListRuleIds }, {}, sharedContext);
537
- if (existingPriceListRules.length) {
538
- await this.deletePriceListRules(existingPriceListRules.map((plr) => plr.id), sharedContext);
549
+ const existingPriceLists = await this.priceListService_.list({ id: data.map((d) => d.id) }, {}, sharedContext);
550
+ if (existingPriceLists.length !== data.length) {
551
+ const diff = (0, utils_1.arrayDifference)(data.map((d) => d.id), existingPriceLists.map((p) => p.id));
552
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Price lists with ids: '${diff.join(", ")}' not found`);
539
553
  }
540
- const ruleTypes = await this.listRuleTypes({ rule_attribute: ruleAttributes }, { take: null }, sharedContext);
541
- const ruleTypeMap = new Map(ruleTypes.map((rt) => [rt.rule_attribute, rt]));
542
- for (const priceListData of data) {
543
- const { rules, ...priceListOnlyData } = priceListData;
544
- const updatePriceListData = {
545
- ...priceListOnlyData,
554
+ const normalizedData = this.normalizePriceListDate(data).map((priceList) => {
555
+ const entry = {
556
+ ...priceList,
557
+ rules: undefined,
558
+ price_list_rules: undefined,
546
559
  };
547
- (0, _utils_1.validatePriceListDates)(updatePriceListData);
548
- if (typeof rules === "object") {
549
- updatePriceListData.rules_count = Object.keys(rules).length;
550
- }
551
- const [updatedPriceList] = (await this.priceListService_.update([updatePriceListData], sharedContext));
552
- updatedPriceLists.push(updatedPriceList);
553
- for (const [ruleAttribute, ruleValues = []] of Object.entries(rules || {})) {
554
- let ruleType = ruleTypeMap.get(ruleAttribute);
555
- if (!ruleType) {
556
- ;
557
- [ruleType] = await this.createRuleTypes([{ name: ruleAttribute, rule_attribute: ruleAttribute }], sharedContext);
558
- ruleTypeMap.set(ruleAttribute, ruleType);
559
- }
560
- const [priceListRule] = await this.priceListRuleService_.create([
561
- {
562
- price_list_id: updatedPriceList.id,
563
- rule_type_id: ruleType?.id,
564
- },
565
- ], sharedContext);
566
- for (const ruleValue of ruleValues) {
567
- await this.priceListRuleValueService_.create([{ price_list_rule_id: priceListRule.id, value: ruleValue }], sharedContext);
568
- }
560
+ if (typeof priceList.rules === "object") {
561
+ const cleanRules = priceList.rules
562
+ ? (0, utils_1.removeNullish)(priceList.rules)
563
+ : {};
564
+ const rules = Object.entries(cleanRules);
565
+ const numberOfRules = rules.length;
566
+ const rulesDataMap = new Map();
567
+ rules.map(([attribute, value]) => {
568
+ const rule = {
569
+ attribute,
570
+ value,
571
+ };
572
+ rulesDataMap.set(JSON.stringify(rule), rule);
573
+ });
574
+ entry.price_list_rules = Array.from(rulesDataMap.values());
575
+ entry.rules_count = numberOfRules;
569
576
  }
570
- }
571
- return updatedPriceLists;
577
+ return entry;
578
+ });
579
+ const { entities } = await this.priceListService_.upsertWithReplace(normalizedData, {
580
+ relations: ["price_list_rules"],
581
+ });
582
+ return entities;
572
583
  }
573
584
  async updatePriceListPrices_(data, sharedContext = {}) {
574
- const ruleTypeAttributes = [];
575
- const priceListIds = [];
576
- const priceIds = [];
577
- const priceSetIds = data
578
- .map((d) => d.prices.map((price) => price.price_set_id))
585
+ const priceLists = await this.listPriceLists({ id: data.map((p) => p.price_list_id) }, { relations: ["prices", "prices.price_rules"] }, sharedContext);
586
+ const existingPrices = priceLists
587
+ .map((p) => p.prices ?? [])
588
+ .flat();
589
+ const pricesToUpsert = data
590
+ .map((addPrice) => this.normalizePrices(addPrice.prices, existingPrices, addPrice.price_list_id))
591
+ .filter(Boolean)
579
592
  .flat();
580
- for (const priceListData of data) {
581
- priceListIds.push(priceListData.price_list_id);
582
- for (const price of priceListData.prices) {
583
- priceIds.push(price.id);
584
- ruleTypeAttributes.push(...Object.keys(price.rules || {}));
585
- }
586
- }
587
- const prices = await this.listPrices({ id: priceIds }, { take: null, relations: ["price_rules"] }, sharedContext);
588
- const priceMap = new Map(prices.map((price) => [price.id, price]));
589
- const ruleTypes = await this.listRuleTypes({ rule_attribute: ruleTypeAttributes }, { take: null }, sharedContext);
590
- const ruleTypeMap = new Map(ruleTypes.map((rt) => [rt.rule_attribute, rt]));
591
- const priceSets = await this.list({ id: priceSetIds }, { relations: ["rule_types"] }, sharedContext);
592
- const priceSetRuleTypeMap = priceSets.reduce((acc, curr) => {
593
- const priceSetRuleAttributeSet = acc.get(curr.id) || new Set();
594
- for (const rt of curr.rule_types ?? []) {
595
- priceSetRuleAttributeSet.add(rt.rule_attribute);
596
- }
597
- acc.set(curr.id, priceSetRuleAttributeSet);
598
- return acc;
599
- }, new Map());
600
- const ruleTypeErrors = [];
601
- for (const priceListData of data) {
602
- for (const price of priceListData.prices) {
603
- for (const ruleAttribute of Object.keys(price.rules ?? {})) {
604
- if (!priceSetRuleTypeMap.get(price.price_set_id)?.has(ruleAttribute)) {
605
- ruleTypeErrors.push(`rule_attribute "${ruleAttribute}" in price set ${price.price_set_id}`);
606
- }
607
- }
608
- }
609
- }
610
- if (ruleTypeErrors.length) {
611
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Invalid rule type configuration: Price set rules doesn't exist for ${ruleTypeErrors.join(", ")}`);
612
- }
613
- const priceLists = await this.listPriceLists({ id: priceListIds }, { take: null }, sharedContext);
614
593
  const priceListMap = new Map(priceLists.map((p) => [p.id, p]));
615
- const pricesToUpdate = [];
616
- const priceRuleIdsToDelete = [];
617
- const priceRulesToCreate = [];
618
- for (const { price_list_id: priceListId, prices } of data) {
594
+ for (const { price_list_id: priceListId } of data) {
619
595
  const priceList = priceListMap.get(priceListId);
620
596
  if (!priceList) {
621
597
  throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Price list with id: ${priceListId} not found`);
622
598
  }
623
- for (const priceData of prices) {
624
- const { rules = {}, price_set_id, ...rest } = priceData;
625
- const price = priceMap.get(rest.id);
626
- const priceRules = price.price_rules;
627
- priceRulesToCreate.push(...Object.entries(rules).map(([ruleAttribute, ruleValue]) => ({
628
- price_set_id,
629
- rule_type_id: ruleTypeMap.get(ruleAttribute).id,
630
- value: ruleValue,
631
- price_id: price.id,
632
- })));
633
- pricesToUpdate.push({
634
- ...rest,
635
- rules_count: Object.keys(rules).length,
636
- });
637
- priceRuleIdsToDelete.push(...priceRules.map((pr) => pr.id));
638
- }
639
599
  }
640
- const [_deletedPriceRule, _createdPriceRule, updatedPrices] = await (0, utils_1.promiseAll)([
641
- this.priceRuleService_.delete(priceRuleIdsToDelete),
642
- this.priceRuleService_.create(priceRulesToCreate),
643
- this.priceService_.update(pricesToUpdate),
644
- ]);
645
- return updatedPrices;
600
+ const { entities } = await this.priceService_.upsertWithReplace(pricesToUpsert, { relations: ["price_rules"] }, sharedContext);
601
+ return entities;
646
602
  }
647
603
  async removePrices_(ids, sharedContext = {}) {
648
604
  await this.priceService_.delete(ids, sharedContext);
649
605
  }
650
606
  async addPriceListPrices_(data, sharedContext = {}) {
651
- const ruleTypeAttributes = [];
652
- const priceListIds = [];
653
- const priceSetIds = [];
654
- for (const priceListData of data) {
655
- priceListIds.push(priceListData.price_list_id);
656
- for (const price of priceListData.prices) {
657
- ruleTypeAttributes.push(...Object.keys(price.rules || {}));
658
- priceSetIds.push(price.price_set_id);
659
- }
660
- }
661
- const ruleTypes = await this.listRuleTypes({ rule_attribute: ruleTypeAttributes }, { take: null }, sharedContext);
662
- const priceSets = await this.list({ id: priceSetIds }, { relations: ["rule_types"] }, sharedContext);
663
- const priceSetRuleTypeMap = priceSets.reduce((acc, curr) => {
664
- const priceSetRuleAttributeSet = acc.get(curr.id) || new Set();
665
- for (const rt of curr.rule_types ?? []) {
666
- priceSetRuleAttributeSet.add(rt.rule_attribute);
667
- }
668
- acc.set(curr.id, priceSetRuleAttributeSet);
669
- return acc;
670
- }, new Map());
671
- const ruleTypeErrors = [];
672
- for (const priceListData of data) {
673
- for (const price of priceListData.prices) {
674
- for (const rule_attribute of Object.keys(price.rules ?? {})) {
675
- if (!priceSetRuleTypeMap.get(price.price_set_id)?.has(rule_attribute)) {
676
- ruleTypeErrors.push(`rule_attribute "${rule_attribute}" in price set ${price.price_set_id}`);
677
- }
678
- }
679
- }
680
- }
681
- if (ruleTypeErrors.length) {
682
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Invalid rule type configuration: Price set rules doesn't exist for ${ruleTypeErrors.join(", ")}`);
683
- }
684
- const ruleTypeMap = new Map(ruleTypes.map((rt) => [rt.rule_attribute, rt]));
685
- const priceLists = await this.listPriceLists({ id: priceListIds }, {}, sharedContext);
607
+ const priceLists = await this.listPriceLists({ id: data.map((p) => p.price_list_id) }, { relations: ["prices", "prices.price_rules"] }, sharedContext);
608
+ const existingPrices = priceLists
609
+ .map((p) => p.prices ?? [])
610
+ .flat();
611
+ const pricesToUpsert = data
612
+ .map((addPrice) => this.normalizePrices(addPrice.prices, existingPrices, addPrice.price_list_id))
613
+ .filter(Boolean)
614
+ .flat();
686
615
  const priceListMap = new Map(priceLists.map((p) => [p.id, p]));
687
- const pricesToCreate = [];
688
- for (const { price_list_id: priceListId, prices } of data) {
689
- const priceList = priceListMap.get(priceListId);
616
+ pricesToUpsert.forEach((price) => {
617
+ const priceList = priceListMap.get(price.price_list_id);
690
618
  if (!priceList) {
691
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Price list with id: ${priceListId} not found`);
619
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Price list with id: ${price.price_list_id} not found`);
692
620
  }
693
- const priceListPricesToCreate = prices.map((priceData) => {
694
- const priceRules = priceData.rules || {};
695
- const noOfRules = Object.keys(priceRules).length;
696
- const priceRulesToCreate = Object.entries(priceRules).map(([ruleAttribute, ruleValue]) => {
697
- return {
698
- price_set_id: priceData.price_set_id,
699
- rule_type_id: ruleTypeMap.get(ruleAttribute)?.id,
700
- value: ruleValue,
701
- };
702
- });
703
- return {
704
- ...priceData,
705
- price_set_id: priceData.price_set_id,
706
- title: "test",
707
- price_list_id: priceList.id,
708
- rules_count: noOfRules,
709
- price_rules: priceRulesToCreate,
710
- };
711
- });
712
- pricesToCreate.push(...priceListPricesToCreate);
713
- }
714
- return await this.priceService_.create(pricesToCreate, sharedContext);
621
+ });
622
+ const { entities, performedActions } = await this.priceService_.upsertWithReplace(pricesToUpsert, { relations: ["price_rules"] }, sharedContext);
623
+ _utils_1.eventBuilders.createdPrice({
624
+ data: performedActions.created[_models_1.Price.name] ?? [],
625
+ sharedContext,
626
+ });
627
+ _utils_1.eventBuilders.updatedPrice({
628
+ data: performedActions.updated[_models_1.Price.name] ?? [],
629
+ sharedContext,
630
+ });
631
+ _utils_1.eventBuilders.deletedPrice({
632
+ data: performedActions.deleted[_models_1.Price.name] ?? [],
633
+ sharedContext,
634
+ });
635
+ _utils_1.eventBuilders.createdPriceRule({
636
+ data: performedActions.created[_models_1.PriceRule.name] ?? [],
637
+ sharedContext,
638
+ });
639
+ _utils_1.eventBuilders.updatedPriceRule({
640
+ data: performedActions.updated[_models_1.PriceRule.name] ?? [],
641
+ sharedContext,
642
+ });
643
+ _utils_1.eventBuilders.deletedPriceRule({
644
+ data: performedActions.deleted[_models_1.PriceRule.name] ?? [],
645
+ sharedContext,
646
+ });
647
+ return entities;
715
648
  }
716
649
  async setPriceListRules_(data, sharedContext = {}) {
717
650
  // TODO: re think this method
718
- const priceLists = await this.priceListService_.list({ id: data.map((d) => d.price_list_id) }, { relations: ["price_list_rules", "price_list_rules.rule_type"] }, sharedContext);
719
- const priceListMap = new Map(priceLists.map((p) => [p.id, p]));
720
- const ruleTypes = await this.listRuleTypes({ rule_attribute: data.map((d) => Object.keys(d.rules)).flat() }, { take: null });
721
- const ruleTypeMap = new Map(ruleTypes.map((rt) => [rt.rule_attribute, rt]));
722
- const ruleIdsToUpdate = [];
723
- const rulesToCreate = [];
724
- const priceRuleValues = new Map();
725
- for (const { price_list_id: priceListId, rules } of data) {
726
- const priceList = priceListMap.get(priceListId);
727
- if (!priceList) {
728
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Price list with id: ${priceListId} not found`);
651
+ const priceLists = await this.priceListService_.list({ id: data.map((d) => d.price_list_id) }, {
652
+ relations: ["price_list_rules"],
653
+ }, sharedContext);
654
+ const rulesMap = new Map();
655
+ data.forEach((rule) => {
656
+ if (!rulesMap.has(rule.price_list_id)) {
657
+ rulesMap.set(rule.price_list_id, []);
729
658
  }
730
- const priceListRulesMap = new Map(priceList.price_list_rules.map((p) => [p.rule_type.rule_attribute, p]));
731
- const priceListRuleValues = new Map();
732
- Object.entries(rules).map(async ([key, value]) => {
733
- const ruleType = ruleTypeMap.get(key);
734
- if (!ruleType) {
735
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Rule type with attribute: ${key} not found`);
736
- }
737
- const rule = priceListRulesMap.get(key);
738
- priceListRuleValues.set(ruleType.id, Array.isArray(value) ? value : [value]);
739
- if (!rule) {
740
- rulesToCreate.push({
741
- rule_type_id: ruleType.id,
742
- price_list_id: priceListId,
743
- });
744
- }
745
- else {
746
- ruleIdsToUpdate.push(rule.id);
747
- }
659
+ Object.entries(rule.rules).forEach(([key, value]) => {
660
+ rulesMap.get(rule.price_list_id).push([key, value]);
748
661
  });
749
- priceRuleValues.set(priceListId, priceListRuleValues);
750
- }
751
- const [createdRules, priceListValuesToDelete] = await (0, utils_1.promiseAll)([
752
- this.priceListRuleService_.create(rulesToCreate),
753
- this.priceListRuleValueService_.list({ price_list_rule_id: ruleIdsToUpdate }, { take: null }),
754
- ]);
755
- const priceListRuleValuesToCreate = [];
756
- for (const { id, price_list_id, rule_type_id } of createdRules) {
757
- const ruleValues = priceRuleValues.get(price_list_id);
758
- if (!ruleValues) {
759
- continue;
760
- }
761
- const values = ruleValues.get(rule_type_id);
762
- if (!values) {
763
- continue;
662
+ });
663
+ const priceListsUpsert = priceLists
664
+ .map((priceList) => {
665
+ const allRules = new Map(priceList.price_list_rules
666
+ .toArray()
667
+ .map((r) => [r.attribute, r.value]));
668
+ const rules = rulesMap.get(priceList.id);
669
+ if (!rules?.length) {
670
+ return;
764
671
  }
765
- values.forEach((v) => {
766
- priceListRuleValuesToCreate.push({
767
- price_list_rule_id: id,
768
- value: v,
769
- });
672
+ rules.forEach(([key, value]) => {
673
+ allRules.set(key, value);
770
674
  });
771
- }
772
- await (0, utils_1.promiseAll)([
773
- this.priceListRuleValueService_.delete(priceListValuesToDelete.map((p) => p.id), sharedContext),
774
- this.priceListRuleValueService_.create(priceListRuleValuesToCreate, sharedContext),
775
- ]);
776
- return priceLists;
675
+ return {
676
+ ...priceList,
677
+ rules_count: allRules.size,
678
+ price_list_rules: Array.from(allRules).map(([attribute, value]) => ({
679
+ attribute,
680
+ value,
681
+ })),
682
+ };
683
+ })
684
+ .filter(Boolean);
685
+ const { entities } = await this.priceListService_.upsertWithReplace(priceListsUpsert, { relations: ["price_list_rules"] }, sharedContext);
686
+ return entities;
777
687
  }
778
688
  async removePriceListRules_(data, sharedContext = {}) {
779
- const priceLists = await this.priceListService_.list({ id: data.map((d) => d.price_list_id) }, { relations: ["price_list_rules", "price_list_rules.rule_type"] }, sharedContext);
780
- const priceListMap = new Map(priceLists.map((p) => [p.id, p]));
781
- const idsToDelete = [];
782
- for (const { price_list_id: priceListId, rules } of data) {
783
- const priceList = priceListMap.get(priceListId);
784
- if (!priceList) {
785
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Price list with id: ${priceListId} not found`);
689
+ // TODO: re think this method
690
+ const priceLists = await this.priceListService_.list({ id: data.map((d) => d.price_list_id) }, {
691
+ relations: ["price_list_rules"],
692
+ }, sharedContext);
693
+ const rulesMap = new Map();
694
+ data.forEach((rule) => {
695
+ if (!rulesMap.has(rule.price_list_id)) {
696
+ rulesMap.set(rule.price_list_id, []);
786
697
  }
787
- const priceListRulesMap = new Map(priceList.price_list_rules.map((p) => [p.rule_type.rule_attribute, p]));
788
- rules.map(async (rule_attribute) => {
789
- const rule = priceListRulesMap.get(rule_attribute);
790
- if (rule) {
791
- idsToDelete.push(rule.id);
792
- }
698
+ rule.rules.forEach((key) => {
699
+ rulesMap.get(rule.price_list_id).push([key, undefined]);
793
700
  });
794
- }
795
- await this.priceListRuleService_.delete(idsToDelete);
796
- return priceLists;
701
+ });
702
+ const priceListsUpsert = priceLists
703
+ .map((priceList) => {
704
+ const allRules = new Map(priceList.price_list_rules
705
+ .toArray()
706
+ .map((r) => [r.attribute, r.value]));
707
+ const rules = rulesMap.get(priceList.id);
708
+ if (!rules?.length) {
709
+ return;
710
+ }
711
+ rules.forEach(([key, value]) => {
712
+ allRules.set(key, value);
713
+ });
714
+ return {
715
+ ...priceList,
716
+ rules_count: allRules.size,
717
+ price_list_rules: Array.from(allRules)
718
+ .map(([attribute, value]) => ({
719
+ attribute,
720
+ value,
721
+ }))
722
+ .filter((r) => !!r.value),
723
+ };
724
+ })
725
+ .filter(Boolean);
726
+ const { entities } = await this.priceListService_.upsertWithReplace(priceListsUpsert, { relations: ["price_list_rules"] }, sharedContext);
727
+ return entities;
728
+ }
729
+ normalizePriceListDate(data) {
730
+ return data.map((priceListData) => {
731
+ (0, _utils_1.validatePriceListDates)(priceListData);
732
+ if (!!priceListData.starts_at) {
733
+ priceListData.starts_at = (0, utils_1.GetIsoStringFromDate)(priceListData.starts_at);
734
+ }
735
+ if (!!priceListData.ends_at) {
736
+ priceListData.ends_at = (0, utils_1.GetIsoStringFromDate)(priceListData.ends_at);
737
+ }
738
+ return priceListData;
739
+ });
740
+ }
741
+ normalizePriceSetConfig(config) {
742
+ return {
743
+ options: {
744
+ populateWhere: { prices: { price_list_id: null } },
745
+ },
746
+ ...config,
747
+ };
797
748
  }
798
749
  }
799
750
  exports.default = PricingModuleService;
800
751
  __decorate([
801
- (0, utils_1.InjectManager)("baseRepository_"),
752
+ (0, utils_1.InjectManager)()
753
+ // @ts-expect-error
754
+ ,
755
+ __metadata("design:type", Function),
756
+ __metadata("design:paramtypes", [String, Object, Object]),
757
+ __metadata("design:returntype", Promise)
758
+ ], PricingModuleService.prototype, "retrievePriceSet", null);
759
+ __decorate([
760
+ (0, utils_1.InjectManager)()
761
+ // @ts-expect-error
762
+ ,
802
763
  __param(2, (0, utils_1.MedusaContext)()),
803
764
  __metadata("design:type", Function),
804
765
  __metadata("design:paramtypes", [Object, Object, Object]),
805
766
  __metadata("design:returntype", Promise)
806
- ], PricingModuleService.prototype, "list", null);
767
+ ], PricingModuleService.prototype, "listPriceSets", null);
807
768
  __decorate([
808
- (0, utils_1.InjectManager)("baseRepository_"),
769
+ (0, utils_1.InjectManager)()
770
+ // @ts-expect-error
771
+ ,
809
772
  __param(2, (0, utils_1.MedusaContext)()),
810
773
  __metadata("design:type", Function),
811
774
  __metadata("design:paramtypes", [Object, Object, Object]),
812
775
  __metadata("design:returntype", Promise)
813
- ], PricingModuleService.prototype, "listAndCount", null);
776
+ ], PricingModuleService.prototype, "listAndCountPriceSets", null);
814
777
  __decorate([
815
- (0, utils_1.InjectManager)("baseRepository_"),
778
+ (0, utils_1.InjectManager)(),
816
779
  __param(2, (0, utils_1.MedusaContext)()),
817
780
  __metadata("design:type", Function),
818
781
  __metadata("design:paramtypes", [Object, Object, Object]),
819
782
  __metadata("design:returntype", Promise)
820
783
  ], PricingModuleService.prototype, "calculatePrices", null);
821
784
  __decorate([
822
- (0, utils_1.InjectManager)("baseRepository_"),
785
+ (0, utils_1.InjectManager)(),
786
+ (0, utils_1.EmitEvents)(),
823
787
  __param(1, (0, utils_1.MedusaContext)()),
824
788
  __metadata("design:type", Function),
825
789
  __metadata("design:paramtypes", [Object, Object]),
826
790
  __metadata("design:returntype", Promise)
827
- ], PricingModuleService.prototype, "create", null);
791
+ ], PricingModuleService.prototype, "createPriceSets", null);
828
792
  __decorate([
829
- (0, utils_1.InjectManager)("baseRepository_"),
793
+ (0, utils_1.InjectManager)(),
830
794
  __param(1, (0, utils_1.MedusaContext)()),
831
795
  __metadata("design:type", Function),
832
796
  __metadata("design:paramtypes", [Object, Object]),
833
797
  __metadata("design:returntype", Promise)
834
- ], PricingModuleService.prototype, "upsert", null);
798
+ ], PricingModuleService.prototype, "upsertPriceSets", null);
835
799
  __decorate([
836
- (0, utils_1.InjectManager)("baseRepository_"),
800
+ (0, utils_1.InjectManager)(),
837
801
  __param(2, (0, utils_1.MedusaContext)()),
838
802
  __metadata("design:type", Function),
839
803
  __metadata("design:paramtypes", [Object, Object, Object]),
840
804
  __metadata("design:returntype", Promise)
841
- ], PricingModuleService.prototype, "update", null);
805
+ ], PricingModuleService.prototype, "updatePriceSets", null);
842
806
  __decorate([
843
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
807
+ (0, utils_1.InjectTransactionManager)(),
844
808
  __param(1, (0, utils_1.MedusaContext)()),
845
809
  __metadata("design:type", Function),
846
810
  __metadata("design:paramtypes", [Array, Object]),
847
811
  __metadata("design:returntype", Promise)
848
- ], PricingModuleService.prototype, "update_", null);
849
- __decorate([
850
- (0, utils_1.InjectManager)("baseRepository_"),
851
- __param(1, (0, utils_1.MedusaContext)()),
852
- __metadata("design:type", Function),
853
- __metadata("design:paramtypes", [Object, Object]),
854
- __metadata("design:returntype", Promise)
855
- ], PricingModuleService.prototype, "addRules", null);
812
+ ], PricingModuleService.prototype, "updatePriceSets_", null);
856
813
  __decorate([
857
- (0, utils_1.InjectManager)("baseRepository_"),
814
+ (0, utils_1.InjectManager)(),
815
+ (0, utils_1.EmitEvents)(),
858
816
  __param(1, (0, utils_1.MedusaContext)()),
859
817
  __metadata("design:type", Function),
860
818
  __metadata("design:paramtypes", [Object, Object]),
861
819
  __metadata("design:returntype", Promise)
862
820
  ], PricingModuleService.prototype, "addPrices", null);
863
821
  __decorate([
864
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
865
- __param(1, (0, utils_1.MedusaContext)()),
866
- __metadata("design:type", Function),
867
- __metadata("design:paramtypes", [Array, Object]),
868
- __metadata("design:returntype", Promise)
869
- ], PricingModuleService.prototype, "removeRules", null);
870
- __decorate([
871
- (0, utils_1.InjectManager)("baseRepository_"),
822
+ (0, utils_1.InjectManager)(),
823
+ (0, utils_1.EmitEvents)()
824
+ // @ts-ignore
825
+ ,
872
826
  __param(1, (0, utils_1.MedusaContext)()),
873
827
  __metadata("design:type", Function),
874
828
  __metadata("design:paramtypes", [Array, Object]),
875
829
  __metadata("design:returntype", Promise)
876
830
  ], PricingModuleService.prototype, "createPriceLists", null);
877
831
  __decorate([
878
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
832
+ (0, utils_1.InjectTransactionManager)()
833
+ // @ts-ignore
834
+ ,
879
835
  __param(1, (0, utils_1.MedusaContext)()),
880
836
  __metadata("design:type", Function),
881
837
  __metadata("design:paramtypes", [Array, Object]),
882
838
  __metadata("design:returntype", Promise)
883
839
  ], PricingModuleService.prototype, "updatePriceLists", null);
884
840
  __decorate([
885
- (0, utils_1.InjectManager)("baseRepository_"),
841
+ (0, utils_1.InjectManager)(),
886
842
  __param(1, (0, utils_1.MedusaContext)()),
887
843
  __metadata("design:type", Function),
888
844
  __metadata("design:paramtypes", [Array, Object]),
889
845
  __metadata("design:returntype", Promise)
890
- ], PricingModuleService.prototype, "createPriceListRules", null);
846
+ ], PricingModuleService.prototype, "updatePriceListPrices", null);
891
847
  __decorate([
892
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
848
+ (0, utils_1.InjectManager)(),
893
849
  __param(1, (0, utils_1.MedusaContext)()),
894
850
  __metadata("design:type", Function),
895
851
  __metadata("design:paramtypes", [Array, Object]),
896
852
  __metadata("design:returntype", Promise)
897
- ], PricingModuleService.prototype, "createPriceListRules_", null);
853
+ ], PricingModuleService.prototype, "removePrices", null);
898
854
  __decorate([
899
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
855
+ (0, utils_1.InjectManager)(),
856
+ (0, utils_1.EmitEvents)(),
900
857
  __param(1, (0, utils_1.MedusaContext)()),
901
858
  __metadata("design:type", Function),
902
859
  __metadata("design:paramtypes", [Array, Object]),
903
860
  __metadata("design:returntype", Promise)
904
- ], PricingModuleService.prototype, "updatePriceListRules", null);
861
+ ], PricingModuleService.prototype, "addPriceListPrices", null);
905
862
  __decorate([
906
- (0, utils_1.InjectManager)("baseRepository_"),
863
+ (0, utils_1.InjectManager)(),
907
864
  __param(1, (0, utils_1.MedusaContext)()),
908
865
  __metadata("design:type", Function),
909
- __metadata("design:paramtypes", [Array, Object]),
866
+ __metadata("design:paramtypes", [Object, Object]),
910
867
  __metadata("design:returntype", Promise)
911
- ], PricingModuleService.prototype, "updatePriceListPrices", null);
868
+ ], PricingModuleService.prototype, "setPriceListRules", null);
912
869
  __decorate([
913
- (0, utils_1.InjectManager)("baseRepository_"),
870
+ (0, utils_1.InjectManager)(),
914
871
  __param(1, (0, utils_1.MedusaContext)()),
915
872
  __metadata("design:type", Function),
916
- __metadata("design:paramtypes", [Array, Object]),
873
+ __metadata("design:paramtypes", [Object, Object]),
917
874
  __metadata("design:returntype", Promise)
918
- ], PricingModuleService.prototype, "removePrices", null);
875
+ ], PricingModuleService.prototype, "removePriceListRules", null);
919
876
  __decorate([
920
- (0, utils_1.InjectManager)("baseRepository_"),
877
+ (0, utils_1.InjectManager)(),
878
+ (0, utils_1.EmitEvents)(),
921
879
  __param(1, (0, utils_1.MedusaContext)()),
922
880
  __metadata("design:type", Function),
923
- __metadata("design:paramtypes", [Array, Object]),
881
+ __metadata("design:paramtypes", [Object, Object]),
924
882
  __metadata("design:returntype", Promise)
925
- ], PricingModuleService.prototype, "addPriceListPrices", null);
883
+ ], PricingModuleService.prototype, "createPricePreferences", null);
926
884
  __decorate([
927
- (0, utils_1.InjectManager)("baseRepository_"),
885
+ (0, utils_1.InjectManager)(),
928
886
  __param(1, (0, utils_1.MedusaContext)()),
929
887
  __metadata("design:type", Function),
930
888
  __metadata("design:paramtypes", [Object, Object]),
931
889
  __metadata("design:returntype", Promise)
932
- ], PricingModuleService.prototype, "setPriceListRules", null);
890
+ ], PricingModuleService.prototype, "upsertPricePreferences", null);
891
+ __decorate([
892
+ (0, utils_1.InjectManager)(),
893
+ __param(2, (0, utils_1.MedusaContext)()),
894
+ __metadata("design:type", Function),
895
+ __metadata("design:paramtypes", [Object, Object, Object]),
896
+ __metadata("design:returntype", Promise)
897
+ ], PricingModuleService.prototype, "updatePricePreferences", null);
933
898
  __decorate([
934
- (0, utils_1.InjectManager)("baseRepository_"),
899
+ (0, utils_1.InjectTransactionManager)(),
935
900
  __param(1, (0, utils_1.MedusaContext)()),
936
901
  __metadata("design:type", Function),
937
- __metadata("design:paramtypes", [Object, Object]),
902
+ __metadata("design:paramtypes", [Array, Object]),
938
903
  __metadata("design:returntype", Promise)
939
- ], PricingModuleService.prototype, "removePriceListRules", null);
904
+ ], PricingModuleService.prototype, "createPricePreferences_", null);
940
905
  __decorate([
941
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
906
+ (0, utils_1.InjectTransactionManager)(),
942
907
  __param(1, (0, utils_1.MedusaContext)()),
943
908
  __metadata("design:type", Function),
944
909
  __metadata("design:paramtypes", [Array, Object]),
945
910
  __metadata("design:returntype", Promise)
946
- ], PricingModuleService.prototype, "create_", null);
911
+ ], PricingModuleService.prototype, "updatePricePreferences_", null);
947
912
  __decorate([
948
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
913
+ (0, utils_1.InjectTransactionManager)(),
949
914
  __param(1, (0, utils_1.MedusaContext)()),
950
915
  __metadata("design:type", Function),
951
916
  __metadata("design:paramtypes", [Array, Object]),
952
917
  __metadata("design:returntype", Promise)
953
- ], PricingModuleService.prototype, "addRules_", null);
918
+ ], PricingModuleService.prototype, "createPriceSets_", null);
954
919
  __decorate([
955
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
920
+ (0, utils_1.InjectTransactionManager)(),
956
921
  __param(1, (0, utils_1.MedusaContext)()),
957
922
  __metadata("design:type", Function),
958
923
  __metadata("design:paramtypes", [Array, Object]),
959
924
  __metadata("design:returntype", Promise)
960
925
  ], PricingModuleService.prototype, "addPrices_", null);
961
926
  __decorate([
962
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
927
+ (0, utils_1.InjectTransactionManager)(),
963
928
  __param(1, (0, utils_1.MedusaContext)()),
964
929
  __metadata("design:type", Function),
965
930
  __metadata("design:paramtypes", [Array, Object]),
966
931
  __metadata("design:returntype", Promise)
967
932
  ], PricingModuleService.prototype, "createPriceLists_", null);
968
933
  __decorate([
969
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
934
+ (0, utils_1.InjectTransactionManager)(),
970
935
  __param(1, (0, utils_1.MedusaContext)()),
971
936
  __metadata("design:type", Function),
972
937
  __metadata("design:paramtypes", [Array, Object]),
973
938
  __metadata("design:returntype", Promise)
974
939
  ], PricingModuleService.prototype, "updatePriceLists_", null);
975
940
  __decorate([
976
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
941
+ (0, utils_1.InjectTransactionManager)(),
977
942
  __metadata("design:type", Function),
978
943
  __metadata("design:paramtypes", [Array, Object]),
979
944
  __metadata("design:returntype", Promise)
980
945
  ], PricingModuleService.prototype, "updatePriceListPrices_", null);
981
946
  __decorate([
982
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
947
+ (0, utils_1.InjectTransactionManager)(),
983
948
  __metadata("design:type", Function),
984
949
  __metadata("design:paramtypes", [Array, Object]),
985
950
  __metadata("design:returntype", Promise)
986
951
  ], PricingModuleService.prototype, "removePrices_", null);
987
952
  __decorate([
988
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
953
+ (0, utils_1.InjectTransactionManager)(),
989
954
  __metadata("design:type", Function),
990
955
  __metadata("design:paramtypes", [Array, Object]),
991
956
  __metadata("design:returntype", Promise)
992
957
  ], PricingModuleService.prototype, "addPriceListPrices_", null);
993
958
  __decorate([
994
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
959
+ (0, utils_1.InjectTransactionManager)(),
995
960
  __metadata("design:type", Function),
996
961
  __metadata("design:paramtypes", [Array, Object]),
997
962
  __metadata("design:returntype", Promise)
998
963
  ], PricingModuleService.prototype, "setPriceListRules_", null);
999
964
  __decorate([
1000
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
965
+ (0, utils_1.InjectTransactionManager)(),
1001
966
  __metadata("design:type", Function),
1002
967
  __metadata("design:paramtypes", [Array, Object]),
1003
968
  __metadata("design:returntype", Promise)
1004
969
  ], PricingModuleService.prototype, "removePriceListRules_", null);
970
+ const isTaxInclusive = (priceRules, preferences, currencyCode, regionId) => {
971
+ const regionRule = priceRules?.find((rule) => rule.attribute === "region_id" && rule.value === regionId);
972
+ const regionPreference = preferences.find((p) => p.attribute === "region_id" && p.value === regionId);
973
+ const currencyPreference = preferences.find((p) => p.attribute === "currency_code" && p.value === currencyCode);
974
+ if (regionRule && regionPreference) {
975
+ return regionPreference.is_tax_inclusive;
976
+ }
977
+ if (currencyPreference) {
978
+ return currencyPreference.is_tax_inclusive;
979
+ }
980
+ return false;
981
+ };
982
+ const hashPrice = (price) => {
983
+ const data = Object.entries({
984
+ currency_code: price.currency_code,
985
+ price_set_id: "price_set_id" in price ? price.price_set_id ?? null : null,
986
+ price_list_id: "price_list_id" in price ? price.price_list_id ?? null : null,
987
+ min_quantity: price.min_quantity ? price.min_quantity.toString() : null,
988
+ max_quantity: price.max_quantity ? price.max_quantity.toString() : null,
989
+ ...("price_rules" in price
990
+ ? price.price_rules?.reduce((agg, pr) => {
991
+ agg[pr.attribute] = pr.value;
992
+ return agg;
993
+ }, {})
994
+ : {}),
995
+ }).sort(([a], [b]) => a.localeCompare(b));
996
+ return (0, utils_1.simpleHash)(JSON.stringify(data));
997
+ };
998
+ //# sourceMappingURL=pricing-module.js.map