@medusajs/pricing 0.2.0-snapshot-20240429113131 → 1.0.0-rc-20241003153304

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 +2 -1
  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 +651 -638
  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 +25 -26
  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,121 +218,113 @@ 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);
229
+ const priceListPrices = await this.priceService_.list({
230
+ price_set_id: normalizedData.map(({ id }) => id),
231
+ price_list_id: { $ne: null },
232
+ });
224
233
  const prices = normalizedData.flatMap((priceSet) => priceSet.prices || []);
225
- const upsertedPrices = await this.priceService_.upsertWithReplace(prices, {
226
- relations: ["price_rules"],
227
- }, sharedContext);
234
+ const { entities: upsertedPrices } = await this.priceService_.upsertWithReplace(prices, { relations: ["price_rules"] }, sharedContext);
228
235
  const priceSetsToUpsert = normalizedData.map((priceSet) => {
229
236
  const { prices, ...rest } = priceSet;
230
237
  return {
231
238
  ...rest,
232
- prices: upsertedPrices
233
- .filter((p) => p.price_set_id === priceSet.id)
234
- .map((price) => {
235
- // @ts-ignore
236
- delete price.price_rules;
237
- return price;
238
- }),
239
+ prices: [
240
+ ...upsertedPrices
241
+ .filter((p) => p.price_set_id === priceSet.id)
242
+ .map((price) => {
243
+ // @ts-ignore
244
+ delete price.price_rules;
245
+ return price;
246
+ }),
247
+ ...priceListPrices
248
+ .filter((p) => p.price_set_id === priceSet.id)
249
+ .map((price) => ({
250
+ id: price.id,
251
+ amount: price.amount,
252
+ price_set_id: price.price_set_id,
253
+ price_list_id: price.price_list_id,
254
+ })),
255
+ ],
239
256
  };
240
257
  });
241
- return await this.priceSetService_.upsertWithReplace(priceSetsToUpsert, { relations: ["prices"] }, sharedContext);
258
+ const { entities: priceSets } = await this.priceSetService_.upsertWithReplace(priceSetsToUpsert, { relations: ["prices"] }, sharedContext);
259
+ return priceSets.map((ps) => {
260
+ if (ps.prices) {
261
+ ps.prices = ps.prices.filter((p) => !p.price_list_id);
262
+ }
263
+ return ps;
264
+ });
242
265
  }
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);
266
+ async normalizeUpdateData(data) {
267
+ return data.map((priceSet) => {
268
+ return {
269
+ ...priceSet,
270
+ prices: this.normalizePrices(priceSet.prices?.map((p) => ({ ...p, price_set_id: priceSet.id })), []),
271
+ };
249
272
  });
250
- return Array.isArray(data) ? orderedPriceSets : orderedPriceSets[0];
273
+ }
274
+ normalizePrices(data, existingPrices, priceListId) {
275
+ const pricesToUpsert = new Map();
276
+ const existingPricesMap = new Map();
277
+ existingPrices?.forEach((price) => {
278
+ existingPricesMap.set(hashPrice(price), price);
279
+ });
280
+ data?.forEach((price) => {
281
+ const cleanRules = price.rules ? (0, utils_1.removeNullish)(price.rules) : {};
282
+ const ruleEntries = Object.entries(cleanRules);
283
+ const rules = ruleEntries.map(([attribute, value]) => {
284
+ return {
285
+ attribute,
286
+ value,
287
+ };
288
+ });
289
+ const hasRulesInput = (0, utils_1.isPresent)(price.rules);
290
+ const entry = {
291
+ ...price,
292
+ price_list_id: priceListId,
293
+ price_rules: hasRulesInput ? rules : undefined,
294
+ rules_count: hasRulesInput ? ruleEntries.length : undefined,
295
+ };
296
+ delete entry.rules;
297
+ const entryHash = hashPrice(entry);
298
+ // We want to keep the existing rules as they might already have ids, but any other data should come from the updated input
299
+ const existing = existingPricesMap.get(entryHash);
300
+ pricesToUpsert.set(entryHash, {
301
+ ...entry,
302
+ id: existing?.id ?? entry.id,
303
+ price_rules: existing?.price_rules ?? entry.price_rules,
304
+ });
305
+ return entry;
306
+ });
307
+ return Array.from(pricesToUpsert.values());
251
308
  }
252
309
  async addPrices(data, sharedContext = {}) {
253
310
  const input = Array.isArray(data) ? data : [data];
254
311
  await this.addPrices_(input, sharedContext);
255
- const dbPrices = await this.list({ id: input.map((d) => d.priceSetId) }, { relations: ["prices"] }, sharedContext);
312
+ const dbPrices = await this.listPriceSets({ id: input.map((d) => d.priceSetId) }, { relations: ["prices"] }, sharedContext);
256
313
  const orderedPriceSets = input.map((inputItem) => {
257
314
  return dbPrices.find((p) => p.id === inputItem.priceSetId);
258
315
  });
259
316
  return Array.isArray(data) ? orderedPriceSets : orderedPriceSets[0];
260
317
  }
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
- }
318
+ // @ts-ignore
273
319
  async createPriceLists(data, sharedContext = {}) {
274
320
  const priceLists = await this.createPriceLists_(data, sharedContext);
275
321
  return await this.baseRepository_.serialize(priceLists);
276
322
  }
323
+ // @ts-ignore
277
324
  async updatePriceLists(data, sharedContext = {}) {
278
325
  const priceLists = await this.updatePriceLists_(data, sharedContext);
279
326
  return await this.baseRepository_.serialize(priceLists);
280
327
  }
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
328
  async updatePriceListPrices(data, sharedContext = {}) {
297
329
  const prices = await this.updatePriceListPrices_(data, sharedContext);
298
330
  return await this.baseRepository_.serialize(prices);
@@ -312,693 +344,674 @@ class PricingModuleService extends utils_1.ModulesSdkUtils.abstractModuleService
312
344
  const [priceList] = await this.removePriceListRules_([data], sharedContext);
313
345
  return await this.baseRepository_.serialize(priceList);
314
346
  }
315
- async create_(data, sharedContext = {}) {
347
+ async createPricePreferences(data, sharedContext = {}) {
348
+ const normalized = Array.isArray(data) ? data : [data];
349
+ const preferences = await this.createPricePreferences_(normalized, sharedContext);
350
+ const serialized = await this.baseRepository_.serialize(preferences);
351
+ return Array.isArray(data) ? serialized : serialized[0];
352
+ }
353
+ async upsertPricePreferences(data, sharedContext = {}) {
316
354
  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(", ")}`);
355
+ const forUpdate = input.filter((pricePreference) => !!pricePreference.id);
356
+ const forCreate = input.filter((pricePreference) => !pricePreference.id);
357
+ const operations = [];
358
+ if (forCreate.length) {
359
+ operations.push(this.createPricePreferences_(forCreate, sharedContext));
328
360
  }
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(", ")}`);
361
+ if (forUpdate.length) {
362
+ operations.push(this.updatePricePreferences_(forUpdate, sharedContext));
335
363
  }
336
- const ruleSetRuleTypeToCreateMap = new Map();
364
+ const result = (await (0, utils_1.promiseAll)(operations)).flat();
365
+ return await this.baseRepository_.serialize(Array.isArray(data) ? result : result[0]);
366
+ }
367
+ async updatePricePreferences(idOrSelector, data, sharedContext = {}) {
368
+ let normalizedInput = [];
369
+ if ((0, utils_1.isString)(idOrSelector)) {
370
+ // Check if the ID exists, it will throw if not.
371
+ await this.pricePreferenceService_.retrieve(idOrSelector, {}, sharedContext);
372
+ normalizedInput = [{ id: idOrSelector, ...data }];
373
+ }
374
+ else {
375
+ const pricePreferences = await this.pricePreferenceService_.list(idOrSelector, {}, sharedContext);
376
+ normalizedInput = pricePreferences.map((pricePreference) => ({
377
+ id: pricePreference.id,
378
+ ...data,
379
+ }));
380
+ }
381
+ const updateResult = await this.updatePricePreferences_(normalizedInput, sharedContext);
382
+ const pricePreferences = await this.baseRepository_.serialize(updateResult);
383
+ return (0, utils_1.isString)(idOrSelector) ? pricePreferences[0] : pricePreferences;
384
+ }
385
+ async createPricePreferences_(data, sharedContext = {}) {
386
+ const preferences = await this.pricePreferenceService_.create(data.map((d) => ({
387
+ ...d,
388
+ is_tax_inclusive: d.is_tax_inclusive ?? false,
389
+ })), sharedContext);
390
+ return preferences;
391
+ }
392
+ async updatePricePreferences_(data, sharedContext = {}) {
393
+ const preferences = await this.pricePreferenceService_.update(data, sharedContext);
394
+ return preferences;
395
+ }
396
+ async createPriceSets_(data, sharedContext = {}) {
397
+ const input = Array.isArray(data) ? data : [data];
337
398
  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,
399
+ const entry = {
400
+ ...inputData,
401
+ prices: this.normalizePrices(inputData.prices, []),
379
402
  };
403
+ return entry;
380
404
  });
381
405
  // Bulk create price sets
382
406
  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,
407
+ const eventsData = createdPriceSets.reduce((eventsData, priceSet) => {
408
+ eventsData.priceSets.push({
409
+ id: priceSet.id,
410
+ });
411
+ priceSet.prices.map((price) => {
412
+ eventsData.prices.push({
413
+ id: price.id,
425
414
  });
426
- }
415
+ price.price_rules.map((priceRule) => {
416
+ eventsData.priceRules.push({
417
+ id: priceRule.id,
418
+ });
419
+ });
420
+ });
421
+ return eventsData;
422
+ }, {
423
+ priceSets: [],
424
+ priceRules: [],
425
+ prices: [],
427
426
  });
428
- await this.priceSetRuleTypeService_.create(priceSetRuleTypesCreate, sharedContext);
429
- return priceSets;
427
+ _utils_1.eventBuilders.createdPriceSet({
428
+ data: eventsData.priceSets,
429
+ sharedContext,
430
+ });
431
+ _utils_1.eventBuilders.createdPrice({
432
+ data: eventsData.prices,
433
+ sharedContext,
434
+ });
435
+ _utils_1.eventBuilders.createdPriceRule({
436
+ data: eventsData.priceRules,
437
+ sharedContext,
438
+ });
439
+ return createdPriceSets;
430
440
  }
431
441
  async addPrices_(input, sharedContext = {}) {
432
- const priceSets = await this.list({ id: input.map((d) => d.priceSetId) }, { relations: ["rule_types"] }, sharedContext);
442
+ const priceSets = await this.listPriceSets({ id: input.map((d) => d.priceSetId) }, { relations: ["prices", "prices.price_rules"] }, sharedContext);
443
+ const existingPrices = priceSets
444
+ .map((p) => p.prices)
445
+ .flat();
446
+ const pricesToUpsert = input
447
+ .map((addPrice) => this.normalizePrices(addPrice.prices?.map((p) => ({
448
+ ...p,
449
+ price_set_id: addPrice.priceSetId,
450
+ })), existingPrices))
451
+ .filter(Boolean)
452
+ .flat();
433
453
  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);
454
+ pricesToUpsert.forEach((price) => {
455
+ const priceSet = priceSetMap.get(price.price_set_id);
440
456
  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(", ")}`);
457
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Price set with id: ${price.price_set_id} not found`);
449
458
  }
450
459
  });
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);
460
+ const { entities, performedActions } = await this.priceService_.upsertWithReplace(pricesToUpsert, { relations: ["price_rules"] }, sharedContext);
461
+ _utils_1.eventBuilders.createdPrice({
462
+ data: performedActions.created[_models_1.Price.name] ?? [],
463
+ sharedContext,
464
+ });
465
+ _utils_1.eventBuilders.updatedPrice({
466
+ data: performedActions.updated[_models_1.Price.name] ?? [],
467
+ sharedContext,
468
+ });
469
+ _utils_1.eventBuilders.deletedPrice({
470
+ data: performedActions.deleted[_models_1.Price.name] ?? [],
471
+ sharedContext,
472
+ });
473
+ _utils_1.eventBuilders.createdPriceRule({
474
+ data: performedActions.created[_models_1.PriceRule.name] ?? [],
475
+ sharedContext,
476
+ });
477
+ _utils_1.eventBuilders.updatedPriceRule({
478
+ data: performedActions.updated[_models_1.PriceRule.name] ?? [],
479
+ sharedContext,
480
+ });
481
+ _utils_1.eventBuilders.deletedPriceRule({
482
+ data: performedActions.deleted[_models_1.PriceRule.name] ?? [],
483
+ sharedContext,
484
+ });
485
+ return entities;
467
486
  }
468
487
  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));
488
+ const normalized = this.normalizePriceListDate(data);
489
+ const priceListsToCreate = normalized.map((priceListData) => {
490
+ const entry = {
491
+ ...priceListData,
492
+ rules: undefined,
493
+ };
494
+ if (priceListData.prices) {
495
+ entry.prices = this.normalizePrices(priceListData.prices, []);
476
496
  }
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,
497
+ if (priceListData.rules) {
498
+ const cleanRules = priceListData.rules
499
+ ? (0, utils_1.removeNullish)(priceListData.rules)
500
+ : {};
501
+ const rules = Object.entries(cleanRules);
502
+ const numberOfRules = rules.length;
503
+ const rulesDataMap = new Map();
504
+ rules.map(([attribute, value]) => {
505
+ const rule = {
506
+ attribute,
507
+ value,
502
508
  };
509
+ rulesDataMap.set(JSON.stringify(rule), rule);
503
510
  });
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
- };
511
+ entry.price_list_rules = Array.from(rulesDataMap.values());
512
+ entry.rules_count = numberOfRules;
513
+ }
514
+ return entry;
515
+ });
516
+ const priceLists = await this.priceListService_.create(priceListsToCreate, sharedContext);
517
+ /**
518
+ * Preparing data for emitting events
519
+ */
520
+ const eventsData = priceLists.reduce((eventsData, priceList) => {
521
+ eventsData.priceList.push({
522
+ id: priceList.id,
511
523
  });
512
- return {
513
- id,
514
- ...rest,
515
- rules_count: Object.keys(rules).length,
516
- price_list_rules: priceListRules,
517
- prices: pricesData,
518
- };
524
+ priceList.price_list_rules.map((listRule) => {
525
+ eventsData.priceListRules.push({
526
+ id: listRule.id,
527
+ });
528
+ });
529
+ priceList.prices.map((price) => {
530
+ eventsData.prices.push({
531
+ id: price.id,
532
+ });
533
+ price.price_rules.map((priceRule) => {
534
+ eventsData.priceRules.push({
535
+ id: priceRule.id,
536
+ });
537
+ });
538
+ });
539
+ return eventsData;
540
+ }, {
541
+ priceList: [],
542
+ priceListRules: [],
543
+ priceRules: [],
544
+ prices: [],
545
+ });
546
+ /**
547
+ * Emitting events for all created entities
548
+ */
549
+ _utils_1.eventBuilders.createdPriceList({
550
+ data: eventsData.priceList,
551
+ sharedContext,
552
+ });
553
+ _utils_1.eventBuilders.createdPriceListRule({
554
+ data: eventsData.priceListRules,
555
+ sharedContext,
556
+ });
557
+ _utils_1.eventBuilders.createdPrice({
558
+ data: eventsData.prices,
559
+ sharedContext,
519
560
  });
520
- return await this.priceListService_.create(priceListsToCreate, sharedContext);
561
+ _utils_1.eventBuilders.createdPriceRule({
562
+ data: eventsData.priceRules,
563
+ sharedContext,
564
+ });
565
+ return priceLists;
521
566
  }
522
567
  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
- }
568
+ const existingPriceLists = await this.priceListService_.list({ id: data.map((d) => d.id) }, {}, sharedContext);
569
+ if (existingPriceLists.length !== data.length) {
570
+ const diff = (0, utils_1.arrayDifference)(data.map((d) => d.id), existingPriceLists.map((p) => p.id));
571
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Price lists with ids: '${diff.join(", ")}' not found`);
531
572
  }
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);
539
- }
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,
573
+ const normalizedData = this.normalizePriceListDate(data).map((priceList) => {
574
+ const entry = {
575
+ ...priceList,
576
+ rules: undefined,
577
+ price_list_rules: undefined,
546
578
  };
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
- }
579
+ if (typeof priceList.rules === "object") {
580
+ const cleanRules = priceList.rules
581
+ ? (0, utils_1.removeNullish)(priceList.rules)
582
+ : {};
583
+ const rules = Object.entries(cleanRules);
584
+ const numberOfRules = rules.length;
585
+ const rulesDataMap = new Map();
586
+ rules.map(([attribute, value]) => {
587
+ const rule = {
588
+ attribute,
589
+ value,
590
+ };
591
+ rulesDataMap.set(JSON.stringify(rule), rule);
592
+ });
593
+ entry.price_list_rules = Array.from(rulesDataMap.values());
594
+ entry.rules_count = numberOfRules;
569
595
  }
570
- }
571
- return updatedPriceLists;
596
+ return entry;
597
+ });
598
+ const { entities } = await this.priceListService_.upsertWithReplace(normalizedData, {
599
+ relations: ["price_list_rules"],
600
+ });
601
+ return entities;
572
602
  }
573
603
  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))
604
+ const priceLists = await this.listPriceLists({ id: data.map((p) => p.price_list_id) }, { relations: ["prices", "prices.price_rules"] }, sharedContext);
605
+ const existingPrices = priceLists
606
+ .map((p) => p.prices ?? [])
607
+ .flat();
608
+ const pricesToUpsert = data
609
+ .map((addPrice) => this.normalizePrices(addPrice.prices, existingPrices, addPrice.price_list_id))
610
+ .filter(Boolean)
579
611
  .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
612
  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) {
613
+ for (const { price_list_id: priceListId } of data) {
619
614
  const priceList = priceListMap.get(priceListId);
620
615
  if (!priceList) {
621
616
  throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Price list with id: ${priceListId} not found`);
622
617
  }
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
618
  }
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;
619
+ const { entities } = await this.priceService_.upsertWithReplace(pricesToUpsert, { relations: ["price_rules"] }, sharedContext);
620
+ return entities;
646
621
  }
647
622
  async removePrices_(ids, sharedContext = {}) {
648
623
  await this.priceService_.delete(ids, sharedContext);
649
624
  }
650
625
  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);
626
+ const priceLists = await this.listPriceLists({ id: data.map((p) => p.price_list_id) }, { relations: ["prices", "prices.price_rules"] }, sharedContext);
627
+ const existingPrices = priceLists
628
+ .map((p) => p.prices ?? [])
629
+ .flat();
630
+ const pricesToUpsert = data
631
+ .map((addPrice) => this.normalizePrices(addPrice.prices, existingPrices, addPrice.price_list_id))
632
+ .filter(Boolean)
633
+ .flat();
686
634
  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);
635
+ pricesToUpsert.forEach((price) => {
636
+ const priceList = priceListMap.get(price.price_list_id);
690
637
  if (!priceList) {
691
- throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Price list with id: ${priceListId} not found`);
638
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Price list with id: ${price.price_list_id} not found`);
692
639
  }
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);
640
+ });
641
+ const { entities, performedActions } = await this.priceService_.upsertWithReplace(pricesToUpsert, { relations: ["price_rules"] }, sharedContext);
642
+ _utils_1.eventBuilders.createdPrice({
643
+ data: performedActions.created[_models_1.Price.name] ?? [],
644
+ sharedContext,
645
+ });
646
+ _utils_1.eventBuilders.updatedPrice({
647
+ data: performedActions.updated[_models_1.Price.name] ?? [],
648
+ sharedContext,
649
+ });
650
+ _utils_1.eventBuilders.deletedPrice({
651
+ data: performedActions.deleted[_models_1.Price.name] ?? [],
652
+ sharedContext,
653
+ });
654
+ _utils_1.eventBuilders.createdPriceRule({
655
+ data: performedActions.created[_models_1.PriceRule.name] ?? [],
656
+ sharedContext,
657
+ });
658
+ _utils_1.eventBuilders.updatedPriceRule({
659
+ data: performedActions.updated[_models_1.PriceRule.name] ?? [],
660
+ sharedContext,
661
+ });
662
+ _utils_1.eventBuilders.deletedPriceRule({
663
+ data: performedActions.deleted[_models_1.PriceRule.name] ?? [],
664
+ sharedContext,
665
+ });
666
+ return entities;
715
667
  }
716
668
  async setPriceListRules_(data, sharedContext = {}) {
717
669
  // 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`);
670
+ const priceLists = await this.priceListService_.list({ id: data.map((d) => d.price_list_id) }, {
671
+ relations: ["price_list_rules"],
672
+ }, sharedContext);
673
+ const rulesMap = new Map();
674
+ data.forEach((rule) => {
675
+ if (!rulesMap.has(rule.price_list_id)) {
676
+ rulesMap.set(rule.price_list_id, []);
729
677
  }
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
- }
678
+ Object.entries(rule.rules).forEach(([key, value]) => {
679
+ rulesMap.get(rule.price_list_id).push([key, value]);
748
680
  });
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;
681
+ });
682
+ const priceListsUpsert = priceLists
683
+ .map((priceList) => {
684
+ const allRules = new Map(priceList.price_list_rules
685
+ .toArray()
686
+ .map((r) => [r.attribute, r.value]));
687
+ const rules = rulesMap.get(priceList.id);
688
+ if (!rules?.length) {
689
+ return;
764
690
  }
765
- values.forEach((v) => {
766
- priceListRuleValuesToCreate.push({
767
- price_list_rule_id: id,
768
- value: v,
769
- });
691
+ rules.forEach(([key, value]) => {
692
+ allRules.set(key, value);
770
693
  });
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;
694
+ return {
695
+ ...priceList,
696
+ rules_count: allRules.size,
697
+ price_list_rules: Array.from(allRules).map(([attribute, value]) => ({
698
+ attribute,
699
+ value,
700
+ })),
701
+ };
702
+ })
703
+ .filter(Boolean);
704
+ const { entities } = await this.priceListService_.upsertWithReplace(priceListsUpsert, { relations: ["price_list_rules"] }, sharedContext);
705
+ return entities;
777
706
  }
778
707
  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`);
708
+ // TODO: re think this method
709
+ const priceLists = await this.priceListService_.list({ id: data.map((d) => d.price_list_id) }, {
710
+ relations: ["price_list_rules"],
711
+ }, sharedContext);
712
+ const rulesMap = new Map();
713
+ data.forEach((rule) => {
714
+ if (!rulesMap.has(rule.price_list_id)) {
715
+ rulesMap.set(rule.price_list_id, []);
786
716
  }
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
- }
717
+ rule.rules.forEach((key) => {
718
+ rulesMap.get(rule.price_list_id).push([key, undefined]);
793
719
  });
794
- }
795
- await this.priceListRuleService_.delete(idsToDelete);
796
- return priceLists;
720
+ });
721
+ const priceListsUpsert = priceLists
722
+ .map((priceList) => {
723
+ const allRules = new Map(priceList.price_list_rules
724
+ .toArray()
725
+ .map((r) => [r.attribute, r.value]));
726
+ const rules = rulesMap.get(priceList.id);
727
+ if (!rules?.length) {
728
+ return;
729
+ }
730
+ rules.forEach(([key, value]) => {
731
+ allRules.set(key, value);
732
+ });
733
+ return {
734
+ ...priceList,
735
+ rules_count: allRules.size,
736
+ price_list_rules: Array.from(allRules)
737
+ .map(([attribute, value]) => ({
738
+ attribute,
739
+ value,
740
+ }))
741
+ .filter((r) => !!r.value),
742
+ };
743
+ })
744
+ .filter(Boolean);
745
+ const { entities } = await this.priceListService_.upsertWithReplace(priceListsUpsert, { relations: ["price_list_rules"] }, sharedContext);
746
+ return entities;
747
+ }
748
+ normalizePriceListDate(data) {
749
+ return data.map((priceListData) => {
750
+ (0, _utils_1.validatePriceListDates)(priceListData);
751
+ if (!!priceListData.starts_at) {
752
+ priceListData.starts_at = (0, utils_1.GetIsoStringFromDate)(priceListData.starts_at);
753
+ }
754
+ if (!!priceListData.ends_at) {
755
+ priceListData.ends_at = (0, utils_1.GetIsoStringFromDate)(priceListData.ends_at);
756
+ }
757
+ return priceListData;
758
+ });
759
+ }
760
+ normalizePriceSetConfig(config) {
761
+ return {
762
+ options: {
763
+ populateWhere: { prices: { price_list_id: null } },
764
+ },
765
+ ...config,
766
+ };
797
767
  }
798
768
  }
799
769
  exports.default = PricingModuleService;
800
770
  __decorate([
801
- (0, utils_1.InjectManager)("baseRepository_"),
771
+ (0, utils_1.InjectManager)()
772
+ // @ts-expect-error
773
+ ,
774
+ __metadata("design:type", Function),
775
+ __metadata("design:paramtypes", [String, Object, Object]),
776
+ __metadata("design:returntype", Promise)
777
+ ], PricingModuleService.prototype, "retrievePriceSet", null);
778
+ __decorate([
779
+ (0, utils_1.InjectManager)()
780
+ // @ts-expect-error
781
+ ,
802
782
  __param(2, (0, utils_1.MedusaContext)()),
803
783
  __metadata("design:type", Function),
804
784
  __metadata("design:paramtypes", [Object, Object, Object]),
805
785
  __metadata("design:returntype", Promise)
806
- ], PricingModuleService.prototype, "list", null);
786
+ ], PricingModuleService.prototype, "listPriceSets", null);
807
787
  __decorate([
808
- (0, utils_1.InjectManager)("baseRepository_"),
788
+ (0, utils_1.InjectManager)()
789
+ // @ts-expect-error
790
+ ,
809
791
  __param(2, (0, utils_1.MedusaContext)()),
810
792
  __metadata("design:type", Function),
811
793
  __metadata("design:paramtypes", [Object, Object, Object]),
812
794
  __metadata("design:returntype", Promise)
813
- ], PricingModuleService.prototype, "listAndCount", null);
795
+ ], PricingModuleService.prototype, "listAndCountPriceSets", null);
814
796
  __decorate([
815
- (0, utils_1.InjectManager)("baseRepository_"),
797
+ (0, utils_1.InjectManager)(),
816
798
  __param(2, (0, utils_1.MedusaContext)()),
817
799
  __metadata("design:type", Function),
818
800
  __metadata("design:paramtypes", [Object, Object, Object]),
819
801
  __metadata("design:returntype", Promise)
820
802
  ], PricingModuleService.prototype, "calculatePrices", null);
821
803
  __decorate([
822
- (0, utils_1.InjectManager)("baseRepository_"),
804
+ (0, utils_1.InjectManager)(),
805
+ (0, utils_1.EmitEvents)(),
823
806
  __param(1, (0, utils_1.MedusaContext)()),
824
807
  __metadata("design:type", Function),
825
808
  __metadata("design:paramtypes", [Object, Object]),
826
809
  __metadata("design:returntype", Promise)
827
- ], PricingModuleService.prototype, "create", null);
810
+ ], PricingModuleService.prototype, "createPriceSets", null);
828
811
  __decorate([
829
- (0, utils_1.InjectManager)("baseRepository_"),
812
+ (0, utils_1.InjectManager)(),
830
813
  __param(1, (0, utils_1.MedusaContext)()),
831
814
  __metadata("design:type", Function),
832
815
  __metadata("design:paramtypes", [Object, Object]),
833
816
  __metadata("design:returntype", Promise)
834
- ], PricingModuleService.prototype, "upsert", null);
817
+ ], PricingModuleService.prototype, "upsertPriceSets", null);
835
818
  __decorate([
836
- (0, utils_1.InjectManager)("baseRepository_"),
819
+ (0, utils_1.InjectManager)(),
837
820
  __param(2, (0, utils_1.MedusaContext)()),
838
821
  __metadata("design:type", Function),
839
822
  __metadata("design:paramtypes", [Object, Object, Object]),
840
823
  __metadata("design:returntype", Promise)
841
- ], PricingModuleService.prototype, "update", null);
824
+ ], PricingModuleService.prototype, "updatePriceSets", null);
842
825
  __decorate([
843
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
826
+ (0, utils_1.InjectTransactionManager)(),
844
827
  __param(1, (0, utils_1.MedusaContext)()),
845
828
  __metadata("design:type", Function),
846
829
  __metadata("design:paramtypes", [Array, Object]),
847
830
  __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);
831
+ ], PricingModuleService.prototype, "updatePriceSets_", null);
856
832
  __decorate([
857
- (0, utils_1.InjectManager)("baseRepository_"),
833
+ (0, utils_1.InjectManager)(),
834
+ (0, utils_1.EmitEvents)(),
858
835
  __param(1, (0, utils_1.MedusaContext)()),
859
836
  __metadata("design:type", Function),
860
837
  __metadata("design:paramtypes", [Object, Object]),
861
838
  __metadata("design:returntype", Promise)
862
839
  ], PricingModuleService.prototype, "addPrices", null);
863
840
  __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_"),
841
+ (0, utils_1.InjectManager)(),
842
+ (0, utils_1.EmitEvents)()
843
+ // @ts-ignore
844
+ ,
872
845
  __param(1, (0, utils_1.MedusaContext)()),
873
846
  __metadata("design:type", Function),
874
847
  __metadata("design:paramtypes", [Array, Object]),
875
848
  __metadata("design:returntype", Promise)
876
849
  ], PricingModuleService.prototype, "createPriceLists", null);
877
850
  __decorate([
878
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
851
+ (0, utils_1.InjectTransactionManager)()
852
+ // @ts-ignore
853
+ ,
879
854
  __param(1, (0, utils_1.MedusaContext)()),
880
855
  __metadata("design:type", Function),
881
856
  __metadata("design:paramtypes", [Array, Object]),
882
857
  __metadata("design:returntype", Promise)
883
858
  ], PricingModuleService.prototype, "updatePriceLists", null);
884
859
  __decorate([
885
- (0, utils_1.InjectManager)("baseRepository_"),
860
+ (0, utils_1.InjectManager)(),
886
861
  __param(1, (0, utils_1.MedusaContext)()),
887
862
  __metadata("design:type", Function),
888
863
  __metadata("design:paramtypes", [Array, Object]),
889
864
  __metadata("design:returntype", Promise)
890
- ], PricingModuleService.prototype, "createPriceListRules", null);
865
+ ], PricingModuleService.prototype, "updatePriceListPrices", null);
891
866
  __decorate([
892
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
867
+ (0, utils_1.InjectManager)(),
893
868
  __param(1, (0, utils_1.MedusaContext)()),
894
869
  __metadata("design:type", Function),
895
870
  __metadata("design:paramtypes", [Array, Object]),
896
871
  __metadata("design:returntype", Promise)
897
- ], PricingModuleService.prototype, "createPriceListRules_", null);
872
+ ], PricingModuleService.prototype, "removePrices", null);
898
873
  __decorate([
899
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
874
+ (0, utils_1.InjectManager)(),
875
+ (0, utils_1.EmitEvents)(),
900
876
  __param(1, (0, utils_1.MedusaContext)()),
901
877
  __metadata("design:type", Function),
902
878
  __metadata("design:paramtypes", [Array, Object]),
903
879
  __metadata("design:returntype", Promise)
904
- ], PricingModuleService.prototype, "updatePriceListRules", null);
880
+ ], PricingModuleService.prototype, "addPriceListPrices", null);
905
881
  __decorate([
906
- (0, utils_1.InjectManager)("baseRepository_"),
882
+ (0, utils_1.InjectManager)(),
907
883
  __param(1, (0, utils_1.MedusaContext)()),
908
884
  __metadata("design:type", Function),
909
- __metadata("design:paramtypes", [Array, Object]),
885
+ __metadata("design:paramtypes", [Object, Object]),
910
886
  __metadata("design:returntype", Promise)
911
- ], PricingModuleService.prototype, "updatePriceListPrices", null);
887
+ ], PricingModuleService.prototype, "setPriceListRules", null);
912
888
  __decorate([
913
- (0, utils_1.InjectManager)("baseRepository_"),
889
+ (0, utils_1.InjectManager)(),
914
890
  __param(1, (0, utils_1.MedusaContext)()),
915
891
  __metadata("design:type", Function),
916
- __metadata("design:paramtypes", [Array, Object]),
892
+ __metadata("design:paramtypes", [Object, Object]),
917
893
  __metadata("design:returntype", Promise)
918
- ], PricingModuleService.prototype, "removePrices", null);
894
+ ], PricingModuleService.prototype, "removePriceListRules", null);
919
895
  __decorate([
920
- (0, utils_1.InjectManager)("baseRepository_"),
896
+ (0, utils_1.InjectManager)(),
897
+ (0, utils_1.EmitEvents)(),
921
898
  __param(1, (0, utils_1.MedusaContext)()),
922
899
  __metadata("design:type", Function),
923
- __metadata("design:paramtypes", [Array, Object]),
900
+ __metadata("design:paramtypes", [Object, Object]),
924
901
  __metadata("design:returntype", Promise)
925
- ], PricingModuleService.prototype, "addPriceListPrices", null);
902
+ ], PricingModuleService.prototype, "createPricePreferences", null);
926
903
  __decorate([
927
- (0, utils_1.InjectManager)("baseRepository_"),
904
+ (0, utils_1.InjectManager)(),
928
905
  __param(1, (0, utils_1.MedusaContext)()),
929
906
  __metadata("design:type", Function),
930
907
  __metadata("design:paramtypes", [Object, Object]),
931
908
  __metadata("design:returntype", Promise)
932
- ], PricingModuleService.prototype, "setPriceListRules", null);
909
+ ], PricingModuleService.prototype, "upsertPricePreferences", null);
910
+ __decorate([
911
+ (0, utils_1.InjectManager)(),
912
+ __param(2, (0, utils_1.MedusaContext)()),
913
+ __metadata("design:type", Function),
914
+ __metadata("design:paramtypes", [Object, Object, Object]),
915
+ __metadata("design:returntype", Promise)
916
+ ], PricingModuleService.prototype, "updatePricePreferences", null);
933
917
  __decorate([
934
- (0, utils_1.InjectManager)("baseRepository_"),
918
+ (0, utils_1.InjectTransactionManager)(),
935
919
  __param(1, (0, utils_1.MedusaContext)()),
936
920
  __metadata("design:type", Function),
937
- __metadata("design:paramtypes", [Object, Object]),
921
+ __metadata("design:paramtypes", [Array, Object]),
938
922
  __metadata("design:returntype", Promise)
939
- ], PricingModuleService.prototype, "removePriceListRules", null);
923
+ ], PricingModuleService.prototype, "createPricePreferences_", null);
940
924
  __decorate([
941
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
925
+ (0, utils_1.InjectTransactionManager)(),
942
926
  __param(1, (0, utils_1.MedusaContext)()),
943
927
  __metadata("design:type", Function),
944
928
  __metadata("design:paramtypes", [Array, Object]),
945
929
  __metadata("design:returntype", Promise)
946
- ], PricingModuleService.prototype, "create_", null);
930
+ ], PricingModuleService.prototype, "updatePricePreferences_", null);
947
931
  __decorate([
948
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
932
+ (0, utils_1.InjectTransactionManager)(),
949
933
  __param(1, (0, utils_1.MedusaContext)()),
950
934
  __metadata("design:type", Function),
951
935
  __metadata("design:paramtypes", [Array, Object]),
952
936
  __metadata("design:returntype", Promise)
953
- ], PricingModuleService.prototype, "addRules_", null);
937
+ ], PricingModuleService.prototype, "createPriceSets_", null);
954
938
  __decorate([
955
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
939
+ (0, utils_1.InjectTransactionManager)(),
956
940
  __param(1, (0, utils_1.MedusaContext)()),
957
941
  __metadata("design:type", Function),
958
942
  __metadata("design:paramtypes", [Array, Object]),
959
943
  __metadata("design:returntype", Promise)
960
944
  ], PricingModuleService.prototype, "addPrices_", null);
961
945
  __decorate([
962
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
946
+ (0, utils_1.InjectTransactionManager)(),
963
947
  __param(1, (0, utils_1.MedusaContext)()),
964
948
  __metadata("design:type", Function),
965
949
  __metadata("design:paramtypes", [Array, Object]),
966
950
  __metadata("design:returntype", Promise)
967
951
  ], PricingModuleService.prototype, "createPriceLists_", null);
968
952
  __decorate([
969
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
953
+ (0, utils_1.InjectTransactionManager)(),
970
954
  __param(1, (0, utils_1.MedusaContext)()),
971
955
  __metadata("design:type", Function),
972
956
  __metadata("design:paramtypes", [Array, Object]),
973
957
  __metadata("design:returntype", Promise)
974
958
  ], PricingModuleService.prototype, "updatePriceLists_", null);
975
959
  __decorate([
976
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
960
+ (0, utils_1.InjectTransactionManager)(),
977
961
  __metadata("design:type", Function),
978
962
  __metadata("design:paramtypes", [Array, Object]),
979
963
  __metadata("design:returntype", Promise)
980
964
  ], PricingModuleService.prototype, "updatePriceListPrices_", null);
981
965
  __decorate([
982
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
966
+ (0, utils_1.InjectTransactionManager)(),
983
967
  __metadata("design:type", Function),
984
968
  __metadata("design:paramtypes", [Array, Object]),
985
969
  __metadata("design:returntype", Promise)
986
970
  ], PricingModuleService.prototype, "removePrices_", null);
987
971
  __decorate([
988
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
972
+ (0, utils_1.InjectTransactionManager)(),
989
973
  __metadata("design:type", Function),
990
974
  __metadata("design:paramtypes", [Array, Object]),
991
975
  __metadata("design:returntype", Promise)
992
976
  ], PricingModuleService.prototype, "addPriceListPrices_", null);
993
977
  __decorate([
994
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
978
+ (0, utils_1.InjectTransactionManager)(),
995
979
  __metadata("design:type", Function),
996
980
  __metadata("design:paramtypes", [Array, Object]),
997
981
  __metadata("design:returntype", Promise)
998
982
  ], PricingModuleService.prototype, "setPriceListRules_", null);
999
983
  __decorate([
1000
- (0, utils_1.InjectTransactionManager)("baseRepository_"),
984
+ (0, utils_1.InjectTransactionManager)(),
1001
985
  __metadata("design:type", Function),
1002
986
  __metadata("design:paramtypes", [Array, Object]),
1003
987
  __metadata("design:returntype", Promise)
1004
988
  ], PricingModuleService.prototype, "removePriceListRules_", null);
989
+ const isTaxInclusive = (priceRules, preferences, currencyCode, regionId) => {
990
+ const regionRule = priceRules?.find((rule) => rule.attribute === "region_id" && rule.value === regionId);
991
+ const regionPreference = preferences.find((p) => p.attribute === "region_id" && p.value === regionId);
992
+ const currencyPreference = preferences.find((p) => p.attribute === "currency_code" && p.value === currencyCode);
993
+ if (regionRule && regionPreference) {
994
+ return regionPreference.is_tax_inclusive;
995
+ }
996
+ if (currencyPreference) {
997
+ return currencyPreference.is_tax_inclusive;
998
+ }
999
+ return false;
1000
+ };
1001
+ const hashPrice = (price) => {
1002
+ const data = Object.entries({
1003
+ currency_code: price.currency_code,
1004
+ price_set_id: "price_set_id" in price ? price.price_set_id ?? null : null,
1005
+ price_list_id: "price_list_id" in price ? price.price_list_id ?? null : null,
1006
+ min_quantity: price.min_quantity ? price.min_quantity.toString() : null,
1007
+ max_quantity: price.max_quantity ? price.max_quantity.toString() : null,
1008
+ ...("price_rules" in price
1009
+ ? price.price_rules?.reduce((agg, pr) => {
1010
+ agg[pr.attribute] = pr.value;
1011
+ return agg;
1012
+ }, {})
1013
+ : {}),
1014
+ }).sort(([a], [b]) => a.localeCompare(b));
1015
+ return (0, utils_1.simpleHash)(JSON.stringify(data));
1016
+ };
1017
+ //# sourceMappingURL=pricing-module.js.map