@unchainedshop/core-orders 2.0.0-beta7 → 2.0.0-beta9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/jest.config.js +9 -0
  2. package/lib/director/OrderPricingDirector.js +5 -5
  3. package/lib/director/OrderPricingDirector.js.map +1 -1
  4. package/lib/module/configureOrderDeliveriesModule.d.ts +2 -1
  5. package/lib/module/configureOrderDeliveriesModule.js +30 -28
  6. package/lib/module/configureOrderDeliveriesModule.js.map +1 -1
  7. package/lib/module/configureOrderDiscountsModule.d.ts +2 -1
  8. package/lib/module/configureOrderDiscountsModule.js +40 -40
  9. package/lib/module/configureOrderDiscountsModule.js.map +1 -1
  10. package/lib/module/configureOrderPaymentsModule.d.ts +3 -1
  11. package/lib/module/configureOrderPaymentsModule.js +65 -39
  12. package/lib/module/configureOrderPaymentsModule.js.map +1 -1
  13. package/lib/module/configureOrderPositionsModule.d.ts +2 -1
  14. package/lib/module/configureOrderPositionsModule.js +39 -33
  15. package/lib/module/configureOrderPositionsModule.js.map +1 -1
  16. package/lib/module/configureOrdersModule-mutations.js +28 -33
  17. package/lib/module/configureOrdersModule-mutations.js.map +1 -1
  18. package/lib/module/configureOrdersModule-processing.js +55 -61
  19. package/lib/module/configureOrdersModule-processing.js.map +1 -1
  20. package/lib/module/configureOrdersModule-queries.d.ts +3 -2
  21. package/lib/module/configureOrdersModule-queries.js +1 -1
  22. package/lib/module/configureOrdersModule-queries.js.map +1 -1
  23. package/lib/module/configureOrdersModule-transformations.js +10 -10
  24. package/lib/module/configureOrdersModule-transformations.js.map +1 -1
  25. package/lib/module/configureOrdersModule.js +24 -26
  26. package/lib/module/configureOrdersModule.js.map +1 -1
  27. package/lib/service/createUserCartService.js +8 -8
  28. package/lib/service/createUserCartService.js.map +1 -1
  29. package/lib/service/migrateOrderCartService.js +3 -9
  30. package/lib/service/migrateOrderCartService.js.map +1 -1
  31. package/package.json +10 -9
  32. package/src/director/OrderPricingDirector.ts +5 -5
  33. package/src/module/configureOrderDeliveriesModule.ts +36 -46
  34. package/src/module/configureOrderDiscountsModule.ts +47 -59
  35. package/src/module/configureOrderPaymentsModule.ts +95 -78
  36. package/src/module/configureOrderPositionsModule.ts +61 -50
  37. package/src/module/configureOrdersModule-mutations.ts +50 -65
  38. package/src/module/configureOrdersModule-processing.ts +78 -88
  39. package/src/module/configureOrdersModule-queries.ts +1 -1
  40. package/src/module/configureOrdersModule-transformations.ts +10 -10
  41. package/src/module/configureOrdersModule.ts +29 -42
  42. package/src/service/createUserCartService.ts +20 -24
  43. package/src/service/migrateOrderCartService.ts +3 -11
  44. package/tests/orders-index.test.ts +103 -48
@@ -15,7 +15,7 @@ const ORDER_POSITION_EVENTS: string[] = [
15
15
  'ORDER_ADD_PRODUCT',
16
16
  ];
17
17
 
18
- const buildFindByIdSelector = (orderPositionId: string, orderId?: string) =>
18
+ export const buildFindByIdSelector = (orderPositionId: string, orderId?: string) =>
19
19
  generateDbFilterById(orderPositionId, orderId ? { orderId } : undefined) as Filter<OrderPosition>;
20
20
 
21
21
  export const configureOrderPositionsModule = ({
@@ -44,11 +44,11 @@ export const configureOrderPositionsModule = ({
44
44
  },
45
45
 
46
46
  // Transformations
47
- discounts: (orderPosition, { order, orderDiscount }, requestContext) => {
48
- const pricingSheet = requestContext.modules.orders.positions.pricingSheet(
47
+ discounts: (orderPosition, { order, orderDiscount }, unchainedAPI) => {
48
+ const pricingSheet = unchainedAPI.modules.orders.positions.pricingSheet(
49
49
  orderPosition,
50
50
  order.currency,
51
- requestContext,
51
+ unchainedAPI,
52
52
  );
53
53
 
54
54
  return pricingSheet.discountPrices(orderDiscount._id).map((discount) => ({
@@ -70,7 +70,7 @@ export const configureOrderPositionsModule = ({
70
70
  create: async (
71
71
  { configuration, context, quantity, quotationId },
72
72
  { order, product, originalProduct },
73
- requestContext,
73
+ unchainedAPI,
74
74
  ) => {
75
75
  const orderId = order._id;
76
76
  const productId = product._id;
@@ -80,30 +80,27 @@ export const configureOrderPositionsModule = ({
80
80
  `Create ${quantity}x Position with Product ${productId} ${
81
81
  quotationId ? ` (${quotationId})` : ''
82
82
  }`,
83
- { orderId, productId, originalProductId, userId: requestContext.userId },
83
+ { orderId, productId, originalProductId },
84
84
  );
85
85
 
86
- const positionId = await mutations.create(
87
- {
88
- orderId,
89
- productId,
90
- originalProductId,
91
- quotationId,
92
- quantity,
93
- configuration,
94
- context,
95
- calculation: [],
96
- scheduling: [],
97
- },
98
- requestContext.userId,
99
- );
86
+ const positionId = await mutations.create({
87
+ orderId,
88
+ productId,
89
+ originalProductId,
90
+ quotationId,
91
+ quantity,
92
+ configuration,
93
+ context,
94
+ calculation: [],
95
+ scheduling: [],
96
+ });
100
97
 
101
- await updateCalculation(orderId, requestContext);
98
+ await updateCalculation(orderId, unchainedAPI);
102
99
 
103
100
  return OrderPositions.findOne(buildFindByIdSelector(positionId));
104
101
  },
105
102
 
106
- delete: async (orderPositionId, requestContext) => {
103
+ delete: async (orderPositionId, unchainedAPI) => {
107
104
  const selector = buildFindByIdSelector(orderPositionId);
108
105
  const orderPosition = await OrderPositions.findOne(selector, {});
109
106
 
@@ -113,23 +110,23 @@ export const configureOrderPositionsModule = ({
113
110
 
114
111
  await OrderPositions.deleteOne(selector);
115
112
 
116
- await updateCalculation(orderPosition.orderId, requestContext);
113
+ await updateCalculation(orderPosition.orderId, unchainedAPI);
117
114
 
118
- emit('ORDER_REMOVE_CART_ITEM', {
115
+ await emit('ORDER_REMOVE_CART_ITEM', {
119
116
  orderPosition,
120
117
  });
121
118
 
122
119
  return { ...orderPosition, calculation: [] };
123
120
  },
124
121
 
125
- removePositions: async ({ orderId }, requestContext) => {
122
+ removePositions: async ({ orderId }, unchainedAPI) => {
126
123
  log('Remove Positions', { orderId });
127
124
 
128
125
  const result = await OrderPositions.deleteMany({ orderId });
129
126
 
130
- await updateCalculation(orderId, requestContext);
127
+ await updateCalculation(orderId, unchainedAPI);
131
128
 
132
- emit('ORDER_EMPTY_CART', { orderId, count: result.deletedCount });
129
+ await emit('ORDER_EMPTY_CART', { orderId, count: result.deletedCount });
133
130
 
134
131
  return result.deletedCount;
135
132
  },
@@ -137,13 +134,12 @@ export const configureOrderPositionsModule = ({
137
134
  updateProductItem: async (
138
135
  { quantity, configuration },
139
136
  { order, product, orderPosition },
140
- requestContext,
137
+ unchainedAPI,
141
138
  ) => {
142
139
  const selector = buildFindByIdSelector(orderPosition._id, order._id);
143
140
  const modifier: any = {
144
141
  $set: {
145
142
  updated: new Date(),
146
- updatedBy: requestContext.userId,
147
143
  },
148
144
  };
149
145
 
@@ -152,10 +148,10 @@ export const configureOrderPositionsModule = ({
152
148
  }
153
149
 
154
150
  if (configuration !== null) {
155
- const resolvedProduct = await requestContext.modules.products.resolveOrderableProduct(
151
+ const resolvedProduct = await unchainedAPI.modules.products.resolveOrderableProduct(
156
152
  product,
157
153
  { configuration },
158
- requestContext,
154
+ unchainedAPI,
159
155
  );
160
156
  modifier.$set.productId = resolvedProduct._id;
161
157
  modifier.$set.configuration = configuration;
@@ -168,24 +164,41 @@ export const configureOrderPositionsModule = ({
168
164
  configuration,
169
165
  quantityDiff: quantity - orderPosition.quantity,
170
166
  },
171
- requestContext,
167
+ unchainedAPI,
172
168
  );
173
169
 
174
170
  await OrderPositions.updateOne(selector, modifier);
175
171
 
176
- await updateCalculation(order._id, requestContext);
172
+ await updateCalculation(order._id, unchainedAPI);
177
173
 
178
174
  const updatedOrderPosition = await OrderPositions.findOne(selector, {});
179
175
 
180
- emit('ORDER_UPDATE_CART_ITEM', {
176
+ await emit('ORDER_UPDATE_CART_ITEM', {
181
177
  orderPosition: updatedOrderPosition,
182
178
  });
183
179
 
184
180
  return updatedOrderPosition;
185
181
  },
186
182
 
187
- updateScheduling: async ({ order, orderDelivery, orderPosition }, requestContext) => {
188
- const { modules } = requestContext;
183
+ removeProductByIdFromAllPositions: async ({ productId }, unchainedAPI) => {
184
+ log('Remove Position Product', { productId });
185
+ const positions = await OrderPositions.find(
186
+ { productId },
187
+ { projection: { orderId: 1 } },
188
+ ).toArray();
189
+
190
+ const result = await OrderPositions.deleteMany({ productId });
191
+
192
+ await Promise.all(
193
+ positions.map(async ({ orderId }) => {
194
+ await updateCalculation(orderId, unchainedAPI);
195
+ }),
196
+ );
197
+ return result.deletedCount;
198
+ },
199
+
200
+ updateScheduling: async ({ order, orderDelivery, orderPosition }, unchainedAPI) => {
201
+ const { modules } = unchainedAPI;
189
202
  // scheduling (store in db for auditing)
190
203
  const product = await modules.products.findProduct({
191
204
  productId: orderPosition.productId,
@@ -204,7 +217,7 @@ export const configureOrderPositionsModule = ({
204
217
  product,
205
218
  deliveryProvider,
206
219
  },
207
- requestContext,
220
+ unchainedAPI,
208
221
  )
209
222
  ).map(async (warehousingProvider) => {
210
223
  const context = {
@@ -219,10 +232,10 @@ export const configureOrderPositionsModule = ({
219
232
  referenceDate: order.ordered,
220
233
  quantity: orderPosition.quantity,
221
234
  };
222
- const dispatch = await requestContext.modules.warehousing.estimatedDispatch(
235
+ const dispatch = await unchainedAPI.modules.warehousing.estimatedDispatch(
223
236
  warehousingProvider,
224
237
  context,
225
- requestContext,
238
+ unchainedAPI,
226
239
  );
227
240
 
228
241
  return {
@@ -239,14 +252,14 @@ export const configureOrderPositionsModule = ({
239
252
  return OrderPositions.findOne(generateDbFilterById(orderPosition._id), {});
240
253
  },
241
254
 
242
- updateCalculation: async (orderPosition, requestContext) => {
255
+ updateCalculation: async (orderPosition, unchainedAPI) => {
243
256
  log(`OrderPosition ${orderPosition._id} -> Update Calculation`, {
244
257
  orderId: orderPosition.orderId,
245
258
  });
246
259
 
247
- const calculation = await requestContext.modules.products.calculate(
260
+ const calculation = await unchainedAPI.modules.products.calculate(
248
261
  { item: orderPosition, configuration: orderPosition.configuration },
249
- requestContext,
262
+ unchainedAPI,
250
263
  );
251
264
  const selector = buildFindByIdSelector(orderPosition._id);
252
265
 
@@ -257,8 +270,8 @@ export const configureOrderPositionsModule = ({
257
270
  return OrderPositions.findOne(selector, {});
258
271
  },
259
272
 
260
- addProductItem: async (orderPosition: OrderPosition, { order, product }, requestContext) => {
261
- const { modules } = requestContext;
273
+ addProductItem: async (orderPosition: OrderPosition, { order, product }, unchainedAPI) => {
274
+ const { modules } = unchainedAPI;
262
275
  const { configuration, orderId: positionOrderId, quantity, ...scope } = orderPosition;
263
276
  const orderId = order._id || positionOrderId;
264
277
 
@@ -266,7 +279,7 @@ export const configureOrderPositionsModule = ({
266
279
  const resolvedProduct = await modules.products.resolveOrderableProduct(
267
280
  product,
268
281
  { configuration },
269
- requestContext,
282
+ unchainedAPI,
270
283
  );
271
284
 
272
285
  // Validate add to cart mutation
@@ -277,7 +290,7 @@ export const configureOrderPositionsModule = ({
277
290
  configuration,
278
291
  quantityDiff: quantity,
279
292
  },
280
- requestContext,
293
+ unchainedAPI,
281
294
  );
282
295
 
283
296
  // Search for existing position
@@ -294,13 +307,11 @@ export const configureOrderPositionsModule = ({
294
307
  {
295
308
  $set: {
296
309
  updated: new Date(),
297
- updatedBy: requestContext.userId,
298
310
  },
299
311
  $inc: { quantity },
300
312
  $setOnInsert: {
301
313
  _id: generateDbObjectId(),
302
314
  created: new Date(),
303
- createdBy: requestContext.userId,
304
315
  calculation: [],
305
316
  scheduling: [],
306
317
  orderId,
@@ -313,11 +324,11 @@ export const configureOrderPositionsModule = ({
313
324
  { upsert: true },
314
325
  );
315
326
 
316
- await updateCalculation(orderId, requestContext);
327
+ await updateCalculation(orderId, unchainedAPI);
317
328
 
318
329
  const upsertedOrderPosition = await OrderPositions.findOne(selector);
319
330
 
320
- emit('ORDER_ADD_PRODUCT', { orderPosition: upsertedOrderPosition });
331
+ await emit('ORDER_ADD_PRODUCT', { orderPosition: upsertedOrderPosition });
321
332
 
322
333
  return upsertedOrderPosition;
323
334
  },
@@ -6,7 +6,6 @@ import { OrderPayment } from '@unchainedshop/types/orders.payments';
6
6
  import { emit, registerEvents } from '@unchainedshop/events';
7
7
  import { log, LogLevel } from '@unchainedshop/logger';
8
8
  import { generateDbFilterById, generateDbMutations } from '@unchainedshop/utils';
9
- import { Context } from '@unchainedshop/types/api';
10
9
  import { OrdersSchema } from '../db/OrdersSchema';
11
10
 
12
11
  const ORDER_EVENTS: string[] = [
@@ -40,39 +39,35 @@ export const configureOrderModuleMutations = ({
40
39
  }) as ModuleMutations<Order>;
41
40
 
42
41
  return {
43
- create: async ({ orderNumber, currency, countryCode, billingAddress, contact }, userId) => {
44
- const orderId = await mutations.create(
45
- {
46
- created: new Date(),
47
- createdBy: userId,
48
- status: null,
49
- billingAddress,
50
- contact,
51
- userId,
52
- currency,
53
- countryCode,
54
- calculation: [],
55
- log: [],
56
- orderNumber,
57
- },
42
+ create: async ({ userId, orderNumber, currency, countryCode, billingAddress, contact }) => {
43
+ const orderId = await mutations.create({
44
+ created: new Date(),
45
+ status: null,
46
+ billingAddress,
47
+ contact,
58
48
  userId,
59
- );
49
+ currency,
50
+ countryCode,
51
+ calculation: [],
52
+ log: [],
53
+ orderNumber,
54
+ });
60
55
 
61
56
  const order = await Orders.findOne(generateDbFilterById(orderId), {});
62
57
 
63
- emit('ORDER_CREATE', { order });
58
+ await emit('ORDER_CREATE', { order });
64
59
  return order;
65
60
  },
66
61
 
67
- delete: async (orderId, userId) => {
68
- const deletedCount = await mutations.delete(orderId, userId);
69
- emit('ORDER_REMOVE', { orderId });
62
+ delete: async (orderId) => {
63
+ const deletedCount = await mutations.delete(orderId);
64
+ await emit('ORDER_REMOVE', { orderId });
70
65
  return deletedCount;
71
66
  },
72
67
 
73
68
  initProviders,
74
69
 
75
- invalidateProviders: async (requestContext, maxAgeDays = 30) => {
70
+ invalidateProviders: async (unchainedAPI, maxAgeDays = 30) => {
76
71
  log('Orders: Start invalidating cart providers', {
77
72
  level: LogLevel.Verbose,
78
73
  });
@@ -86,11 +81,11 @@ export const configureOrderModuleMutations = ({
86
81
  updated: { $gte: minValidDate },
87
82
  }).toArray();
88
83
 
89
- await Promise.all(orders.map((order) => initProviders(order, requestContext as Context))); // TODO: Refactor Types
84
+ await Promise.all(orders.map((order) => initProviders(order, unchainedAPI)));
90
85
  },
91
86
 
92
- setDeliveryProvider: async (orderId, deliveryProviderId, requestContext) => {
93
- const { modules } = requestContext;
87
+ setDeliveryProvider: async (orderId, deliveryProviderId, unchainedAPI) => {
88
+ const { modules } = unchainedAPI;
94
89
  const delivery = await OrderDeliveries.findOne({
95
90
  orderId,
96
91
  deliveryProviderId,
@@ -98,16 +93,13 @@ export const configureOrderModuleMutations = ({
98
93
  const deliveryId =
99
94
  delivery?._id ||
100
95
  (
101
- await modules.orders.deliveries.create(
102
- {
103
- calculation: [],
104
- deliveryProviderId,
105
- log: [],
106
- orderId,
107
- status: null,
108
- },
109
- requestContext.userId,
110
- )
96
+ await modules.orders.deliveries.create({
97
+ calculation: [],
98
+ deliveryProviderId,
99
+ log: [],
100
+ orderId,
101
+ status: null,
102
+ })
111
103
  )._id;
112
104
 
113
105
  log(`Set Delivery Provider ${deliveryProviderId}`, { orderId });
@@ -117,13 +109,12 @@ export const configureOrderModuleMutations = ({
117
109
  $set: {
118
110
  deliveryId,
119
111
  updated: new Date(),
120
- updatedBy: requestContext.userId,
121
112
  },
122
113
  });
123
114
 
124
- const order = await updateCalculation(orderId, requestContext);
115
+ const order = await updateCalculation(orderId, unchainedAPI);
125
116
 
126
- emit('ORDER_SET_DELIVERY_PROVIDER', {
117
+ await emit('ORDER_SET_DELIVERY_PROVIDER', {
127
118
  order,
128
119
  deliveryProviderId,
129
120
  });
@@ -131,8 +122,8 @@ export const configureOrderModuleMutations = ({
131
122
  return order;
132
123
  },
133
124
 
134
- setPaymentProvider: async (orderId, paymentProviderId, requestContext) => {
135
- const { modules, userId } = requestContext;
125
+ setPaymentProvider: async (orderId, paymentProviderId, unchainedAPI) => {
126
+ const { modules } = unchainedAPI;
136
127
  const payment = await OrderPayments.findOne({
137
128
  orderId,
138
129
  paymentProviderId,
@@ -141,27 +132,24 @@ export const configureOrderModuleMutations = ({
141
132
  const paymentId =
142
133
  payment?._id ||
143
134
  (
144
- await modules.orders.payments.create(
145
- {
146
- calculation: [],
147
- paymentProviderId,
148
- log: [],
149
- orderId,
150
- status: null,
151
- },
152
- userId,
153
- )
135
+ await modules.orders.payments.create({
136
+ calculation: [],
137
+ paymentProviderId,
138
+ log: [],
139
+ orderId,
140
+ status: null,
141
+ })
154
142
  )._id;
155
143
  log(`Set Payment Provider ${paymentProviderId}`, { orderId });
156
144
 
157
145
  const selector = generateDbFilterById(orderId);
158
146
  await Orders.updateOne(selector, {
159
- $set: { paymentId, updated: new Date(), updatedBy: userId },
147
+ $set: { paymentId, updated: new Date() },
160
148
  });
161
149
 
162
- const order = await updateCalculation(orderId, requestContext);
150
+ const order = await updateCalculation(orderId, unchainedAPI);
163
151
 
164
- emit('ORDER_SET_PAYMENT_PROVIDER', {
152
+ await emit('ORDER_SET_PAYMENT_PROVIDER', {
165
153
  order,
166
154
  paymentProviderId,
167
155
  });
@@ -169,7 +157,7 @@ export const configureOrderModuleMutations = ({
169
157
  return order;
170
158
  },
171
159
 
172
- updateBillingAddress: async (orderId, billingAddress, requestContext) => {
160
+ updateBillingAddress: async (orderId, billingAddress, unchainedAPI) => {
173
161
  log('Update Invoicing Address', { orderId });
174
162
 
175
163
  const selector = generateDbFilterById(orderId);
@@ -177,16 +165,15 @@ export const configureOrderModuleMutations = ({
177
165
  $set: {
178
166
  billingAddress,
179
167
  updated: new Date(),
180
- updatedBy: requestContext.userId,
181
168
  },
182
169
  });
183
170
 
184
- const order = await updateCalculation(orderId, requestContext);
185
- emit('ORDER_UPDATE', { order, field: 'billing' });
171
+ const order = await updateCalculation(orderId, unchainedAPI);
172
+ await emit('ORDER_UPDATE', { order, field: 'billing' });
186
173
  return order;
187
174
  },
188
175
 
189
- updateContact: async (orderId, contact, requestContext) => {
176
+ updateContact: async (orderId, contact, unchainedAPI) => {
190
177
  log('Update Contact', { orderId });
191
178
 
192
179
  const selector = generateDbFilterById(orderId);
@@ -194,16 +181,15 @@ export const configureOrderModuleMutations = ({
194
181
  $set: {
195
182
  contact,
196
183
  updated: new Date(),
197
- updatedBy: requestContext.userId,
198
184
  },
199
185
  });
200
186
 
201
- const order = await updateCalculation(orderId, requestContext);
202
- emit('ORDER_UPDATE', { order, field: 'contact' });
187
+ const order = await updateCalculation(orderId, unchainedAPI);
188
+ await emit('ORDER_UPDATE', { order, field: 'contact' });
203
189
  return order;
204
190
  },
205
191
 
206
- updateContext: async (orderId, context, requestContext) => {
192
+ updateContext: async (orderId, context, unchainedAPI) => {
207
193
  if (!context) return false;
208
194
 
209
195
  log('Update Arbitrary Context', { orderId, context });
@@ -215,13 +201,12 @@ export const configureOrderModuleMutations = ({
215
201
  $set: {
216
202
  context: { ...(order.context || {}), ...context },
217
203
  updated: new Date(),
218
- updatedBy: requestContext.userId,
219
204
  },
220
205
  });
221
206
 
222
207
  if (result.modifiedCount) {
223
- const calculatedOrder = await updateCalculation(orderId, requestContext);
224
- emit('ORDER_UPDATE', { order: calculatedOrder, field: 'context' });
208
+ const calculatedOrder = await updateCalculation(orderId, unchainedAPI);
209
+ await emit('ORDER_UPDATE', { order: calculatedOrder, field: 'context' });
225
210
  return true;
226
211
  }
227
212
  return false;