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