@unchainedshop/core-orders 3.0.0-alpha7 → 3.0.0-rc10

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 (141) hide show
  1. package/lib/db/OrderDeliveriesCollection.d.ts +21 -2
  2. package/lib/db/OrderDeliveriesCollection.d.ts.map +1 -1
  3. package/lib/db/OrderDeliveriesCollection.js +6 -0
  4. package/lib/db/OrderDeliveriesCollection.js.map +1 -1
  5. package/lib/db/OrderDiscountsCollection.d.ts +16 -2
  6. package/lib/db/OrderDiscountsCollection.d.ts.map +1 -1
  7. package/lib/db/OrderDiscountsCollection.js +5 -0
  8. package/lib/db/OrderDiscountsCollection.js.map +1 -1
  9. package/lib/db/OrderPaymentsCollection.d.ts +22 -2
  10. package/lib/db/OrderPaymentsCollection.d.ts.map +1 -1
  11. package/lib/db/OrderPaymentsCollection.js +6 -0
  12. package/lib/db/OrderPaymentsCollection.js.map +1 -1
  13. package/lib/db/OrderPositionsCollection.d.ts +22 -2
  14. package/lib/db/OrderPositionsCollection.d.ts.map +1 -1
  15. package/lib/db/OrderPositionsCollection.js.map +1 -1
  16. package/lib/db/OrdersCollection.d.ts +33 -2
  17. package/lib/db/OrdersCollection.d.ts.map +1 -1
  18. package/lib/db/OrdersCollection.js +8 -1
  19. package/lib/db/OrdersCollection.js.map +1 -1
  20. package/lib/module/buildFindSelector.d.ts +5 -0
  21. package/lib/module/buildFindSelector.d.ts.map +1 -0
  22. package/lib/module/buildFindSelector.js +18 -0
  23. package/lib/module/buildFindSelector.js.map +1 -0
  24. package/lib/module/configureOrderDeliveriesModule.d.ts +14 -27
  25. package/lib/module/configureOrderDeliveriesModule.d.ts.map +1 -1
  26. package/lib/module/configureOrderDeliveriesModule.js +8 -69
  27. package/lib/module/configureOrderDeliveriesModule.js.map +1 -1
  28. package/lib/module/configureOrderDiscountsModule.d.ts +17 -18
  29. package/lib/module/configureOrderDiscountsModule.d.ts.map +1 -1
  30. package/lib/module/configureOrderDiscountsModule.js +34 -143
  31. package/lib/module/configureOrderDiscountsModule.js.map +1 -1
  32. package/lib/module/configureOrderPaymentsModule.d.ts +17 -37
  33. package/lib/module/configureOrderPaymentsModule.d.ts.map +1 -1
  34. package/lib/module/configureOrderPaymentsModule.js +16 -124
  35. package/lib/module/configureOrderPaymentsModule.js.map +1 -1
  36. package/lib/module/configureOrderPositionsModule.d.ts +22 -41
  37. package/lib/module/configureOrderPositionsModule.d.ts.map +1 -1
  38. package/lib/module/configureOrderPositionsModule.js +22 -85
  39. package/lib/module/configureOrderPositionsModule.js.map +1 -1
  40. package/lib/module/configureOrdersModule-mutations.d.ts +5 -11
  41. package/lib/module/configureOrdersModule-mutations.d.ts.map +1 -1
  42. package/lib/module/configureOrdersModule-mutations.js +11 -50
  43. package/lib/module/configureOrdersModule-mutations.js.map +1 -1
  44. package/lib/module/configureOrdersModule-queries.d.ts +18 -6
  45. package/lib/module/configureOrdersModule-queries.d.ts.map +1 -1
  46. package/lib/module/configureOrdersModule-queries.js +35 -22
  47. package/lib/module/configureOrdersModule-queries.js.map +1 -1
  48. package/lib/module/configureOrdersModule.d.ts +11 -8
  49. package/lib/module/configureOrdersModule.d.ts.map +1 -1
  50. package/lib/module/configureOrdersModule.js +134 -154
  51. package/lib/module/configureOrdersModule.js.map +1 -1
  52. package/lib/orders-index.d.ts +11 -8
  53. package/lib/orders-index.d.ts.map +1 -1
  54. package/lib/orders-index.js +11 -8
  55. package/lib/orders-index.js.map +1 -1
  56. package/lib/orders-settings.d.ts +4 -8
  57. package/lib/orders-settings.d.ts.map +1 -1
  58. package/lib/orders-settings.js.map +1 -1
  59. package/package.json +13 -13
  60. package/src/db/OrderDeliveriesCollection.ts +25 -2
  61. package/src/db/OrderDiscountsCollection.ts +18 -2
  62. package/src/db/OrderPaymentsCollection.ts +26 -2
  63. package/src/db/OrderPositionsCollection.ts +21 -2
  64. package/src/db/OrdersCollection.ts +44 -2
  65. package/src/module/buildFindSelector.test.ts +8 -8
  66. package/src/module/buildFindSelector.ts +24 -0
  67. package/src/module/configureOrderDeliveriesModule.ts +29 -172
  68. package/src/module/configureOrderDiscountsModule.ts +46 -213
  69. package/src/module/configureOrderPaymentsModule.ts +58 -266
  70. package/src/module/configureOrderPositionsModule.ts +57 -208
  71. package/src/module/configureOrdersModule-mutations.ts +13 -85
  72. package/src/module/configureOrdersModule-queries.ts +61 -29
  73. package/src/module/configureOrdersModule.ts +181 -264
  74. package/src/orders-index.ts +11 -10
  75. package/src/orders-settings.ts +5 -7
  76. package/tsconfig.json +5 -7
  77. package/lib/db/OrderDiscountTrigger.d.ts +0 -5
  78. package/lib/db/OrderDiscountTrigger.d.ts.map +0 -1
  79. package/lib/db/OrderDiscountTrigger.js +0 -6
  80. package/lib/db/OrderDiscountTrigger.js.map +0 -1
  81. package/lib/director/OrderDiscountAdapter.d.ts +0 -4
  82. package/lib/director/OrderDiscountAdapter.d.ts.map +0 -1
  83. package/lib/director/OrderDiscountAdapter.js +0 -3
  84. package/lib/director/OrderDiscountAdapter.js.map +0 -1
  85. package/lib/director/OrderDiscountConfiguration.d.ts +0 -6
  86. package/lib/director/OrderDiscountConfiguration.d.ts.map +0 -1
  87. package/lib/director/OrderDiscountConfiguration.js +0 -2
  88. package/lib/director/OrderDiscountConfiguration.js.map +0 -1
  89. package/lib/director/OrderDiscountDirector.d.ts +0 -3
  90. package/lib/director/OrderDiscountDirector.d.ts.map +0 -1
  91. package/lib/director/OrderDiscountDirector.js +0 -3
  92. package/lib/director/OrderDiscountDirector.js.map +0 -1
  93. package/lib/director/OrderPricingAdapter.d.ts +0 -22
  94. package/lib/director/OrderPricingAdapter.d.ts.map +0 -1
  95. package/lib/director/OrderPricingAdapter.js +0 -25
  96. package/lib/director/OrderPricingAdapter.js.map +0 -1
  97. package/lib/director/OrderPricingDirector.d.ts +0 -18
  98. package/lib/director/OrderPricingDirector.d.ts.map +0 -1
  99. package/lib/director/OrderPricingDirector.js +0 -39
  100. package/lib/director/OrderPricingDirector.js.map +0 -1
  101. package/lib/director/OrderPricingSheet.d.ts +0 -36
  102. package/lib/director/OrderPricingSheet.d.ts.map +0 -1
  103. package/lib/director/OrderPricingSheet.js +0 -108
  104. package/lib/director/OrderPricingSheet.js.map +0 -1
  105. package/lib/module/configureOrdersModule-processing.d.ts +0 -32
  106. package/lib/module/configureOrdersModule-processing.d.ts.map +0 -1
  107. package/lib/module/configureOrdersModule-processing.js +0 -339
  108. package/lib/module/configureOrdersModule-processing.js.map +0 -1
  109. package/lib/module/configureOrdersModule-transformations.d.ts +0 -20
  110. package/lib/module/configureOrdersModule-transformations.d.ts.map +0 -1
  111. package/lib/module/configureOrdersModule-transformations.js +0 -111
  112. package/lib/module/configureOrdersModule-transformations.js.map +0 -1
  113. package/lib/service/migrateOrderCartService.d.ts +0 -10
  114. package/lib/service/migrateOrderCartService.d.ts.map +0 -1
  115. package/lib/service/migrateOrderCartService.js +0 -32
  116. package/lib/service/migrateOrderCartService.js.map +0 -1
  117. package/lib/service/nextUserCartService.d.ts +0 -11
  118. package/lib/service/nextUserCartService.d.ts.map +0 -1
  119. package/lib/service/nextUserCartService.js +0 -34
  120. package/lib/service/nextUserCartService.js.map +0 -1
  121. package/lib/service/orderServices.d.ts +0 -8
  122. package/lib/service/orderServices.d.ts.map +0 -1
  123. package/lib/service/orderServices.js +0 -7
  124. package/lib/service/orderServices.js.map +0 -1
  125. package/lib/types.d.ts +0 -116
  126. package/lib/types.d.ts.map +0 -1
  127. package/lib/types.js +0 -25
  128. package/lib/types.js.map +0 -1
  129. package/src/db/OrderDiscountTrigger.ts +0 -4
  130. package/src/director/OrderDiscountAdapter.ts +0 -8
  131. package/src/director/OrderDiscountConfiguration.ts +0 -5
  132. package/src/director/OrderDiscountDirector.ts +0 -5
  133. package/src/director/OrderPricingAdapter.ts +0 -61
  134. package/src/director/OrderPricingDirector.ts +0 -72
  135. package/src/director/OrderPricingSheet.ts +0 -146
  136. package/src/module/configureOrdersModule-processing.ts +0 -508
  137. package/src/module/configureOrdersModule-transformations.ts +0 -171
  138. package/src/service/migrateOrderCartService.ts +0 -53
  139. package/src/service/nextUserCartService.ts +0 -54
  140. package/src/service/orderServices.ts +0 -12
  141. package/src/types.ts +0 -129
@@ -1,16 +1,10 @@
1
- import { UnchainedCore } from '@unchainedshop/core';
2
- import { OrderDelivery } from '@unchainedshop/core-orders';
3
- import { OrderPayment } from '@unchainedshop/core-orders';
4
- import { generateDbFilterById, ModuleInput } from '@unchainedshop/mongodb';
1
+ import { generateDbFilterById, ModuleInput, mongodb } from '@unchainedshop/mongodb';
5
2
  import { createRequire } from 'node:module';
6
3
  import { OrderDeliveriesCollection } from '../db/OrderDeliveriesCollection.js';
7
4
  import { OrderDiscountsCollection } from '../db/OrderDiscountsCollection.js';
8
- import { OrderDiscountTrigger } from '../db/OrderDiscountTrigger.js';
9
5
  import { OrderPaymentsCollection } from '../db/OrderPaymentsCollection.js';
10
6
  import { OrderPositionsCollection } from '../db/OrderPositionsCollection.js';
11
- import { OrdersCollection } from '../db/OrdersCollection.js';
12
- import { OrderDiscountDirector } from '../director/OrderDiscountDirector.js';
13
- import { OrderPricingDirector } from '../director/OrderPricingDirector.js';
7
+ import { OrdersCollection, Order, OrderStatus } from '../db/OrdersCollection.js';
14
8
  import { ordersSettings, OrdersSettingsOptions } from '../orders-settings.js';
15
9
  import {
16
10
  configureOrderDeliveriesModule,
@@ -20,37 +14,45 @@ import { configureOrderDiscountsModule, OrderDiscountsModule } from './configure
20
14
  import { configureOrderPaymentsModule, OrderPaymentsModule } from './configureOrderPaymentsModule.js';
21
15
  import { configureOrderPositionsModule, OrderPositionsModule } from './configureOrderPositionsModule.js';
22
16
  import { configureOrderModuleMutations, OrderMutations } from './configureOrdersModule-mutations.js';
23
- import { configureOrderModuleProcessing, OrderProcessing } from './configureOrdersModule-processing.js';
24
17
  import { configureOrdersModuleQueries, OrderQueries } from './configureOrdersModule-queries.js';
25
- import {
26
- configureOrderModuleTransformations,
27
- OrderTransformations,
28
- } from './configureOrdersModule-transformations.js';
29
- import { Order, OrderPosition } from '../types.js';
18
+
19
+ import { emit, registerEvents } from '@unchainedshop/events';
30
20
 
31
21
  export type OrdersModule = OrderQueries &
32
- OrderTransformations &
33
- OrderProcessing &
34
22
  OrderMutations & {
35
- // Order context recalculations
36
- initProviders: (order: Order, unchainedAPI: UnchainedCore) => Promise<Order>;
37
- updateCalculation: (orderId: string, unchainedAPI: UnchainedCore) => Promise<Order>;
38
- invalidateProviders: (unchainedAPI: UnchainedCore, maxAgeDays: number) => Promise<void>;
39
-
40
23
  // Sub entities
41
24
  deliveries: OrderDeliveriesModule;
42
25
  discounts: OrderDiscountsModule;
43
26
  positions: OrderPositionsModule;
44
27
  payments: OrderPaymentsModule;
28
+
29
+ updateStatus: (orderId: string, params: { status: OrderStatus; info?: string }) => Promise<Order>;
30
+ acquireLock: (
31
+ orderId: string,
32
+ identifier: string,
33
+ timeout?: number,
34
+ ) => Promise<{ release: () => void }>;
35
+ setDeliveryProvider: (orderId: string, deliveryProviderId: string) => Promise<Order>;
36
+ setPaymentProvider: (orderId: string, paymentProviderId: string) => Promise<Order>;
45
37
  };
46
38
 
39
+ // @kontsedal/locco uses a deprecated way of importing files in ESM (node16 behavior)
47
40
  const require = createRequire(import.meta.url);
48
41
  const { Locker, MongoAdapter } = require('@kontsedal/locco');
49
42
 
43
+ const ORDER_EVENTS: string[] = [
44
+ 'ORDER_CHECKOUT',
45
+ 'ORDER_CONFIRMED',
46
+ 'ORDER_REJECTED',
47
+ 'ORDER_FULLFILLED',
48
+ ];
49
+
50
50
  export const configureOrdersModule = async ({
51
51
  db,
52
52
  options: orderOptions = {},
53
53
  }: ModuleInput<OrdersSettingsOptions>): Promise<OrdersModule> => {
54
+ registerEvents(ORDER_EVENTS);
55
+
54
56
  ordersSettings.configureSettings(orderOptions);
55
57
 
56
58
  const Orders = await OrdersCollection(db);
@@ -69,246 +71,10 @@ export const configureOrdersModule = async ({
69
71
  retrySettings: { retryDelay: 200, retryTimes: 10 },
70
72
  });
71
73
 
72
- const findOrderPositions = async (order: Order) =>
73
- OrderPositions.find(
74
- {
75
- orderId: order._id,
76
- quantity: { $gt: 0 },
77
- },
78
- {},
79
- ).toArray();
80
-
81
- const findOrderDelivery = async (order: Order) =>
82
- OrderDeliveries.findOne(generateDbFilterById(order.deliveryId), {});
83
-
84
- const findOrderPayment = async (order: Order) =>
85
- OrderPayments.findOne(generateDbFilterById(order.paymentId), {});
86
-
87
- const updateDiscounts = async (order: Order, unchainedAPI: UnchainedCore) => {
88
- const { modules } = unchainedAPI;
89
-
90
- // 1. go through existing order-discounts and check if discount still valid,
91
- // those who are not valid anymore should get removed
92
- const discounts = await modules.orders.discounts.findOrderDiscounts({
93
- orderId: order._id,
94
- });
95
-
96
- await Promise.all(
97
- discounts.map(async (discount) => {
98
- const isValid = await modules.orders.discounts.isValid(discount, unchainedAPI);
99
-
100
- if (!isValid) {
101
- await modules.orders.discounts.delete(discount._id, unchainedAPI);
102
- }
103
- }),
104
- );
105
-
106
- // 2. run auto-system discount
107
- const cleanedDiscounts = await modules.orders.discounts.findOrderDiscounts({
108
- orderId: order._id,
109
- });
110
-
111
- const currentDiscountKeys = cleanedDiscounts.map(({ discountKey }) => discountKey);
112
-
113
- const director = await OrderDiscountDirector.actions({ order, code: null }, unchainedAPI);
114
- const systemDiscounts = await director.findSystemDiscounts();
115
-
116
- await Promise.all(
117
- systemDiscounts
118
- .filter((key) => currentDiscountKeys.indexOf(key) === -1)
119
- .map(async (discountKey) =>
120
- modules.orders.discounts.create({
121
- orderId: order._id,
122
- discountKey,
123
- trigger: OrderDiscountTrigger.SYSTEM,
124
- }),
125
- ),
126
- );
127
- };
128
-
129
- const initProviders = async (order: Order, unchainedAPI: UnchainedCore) => {
130
- const { modules } = unchainedAPI;
131
-
132
- let updatedOrder = order;
133
-
134
- // Init delivery provider
135
- const supportedDeliveryProviders = await modules.delivery.findSupported(
136
- { order: updatedOrder },
137
- unchainedAPI,
138
- );
139
-
140
- const orderDelivery = await modules.orders.deliveries.findDelivery({
141
- orderDeliveryId: updatedOrder.deliveryId,
142
- });
143
- const deliveryProviderId = orderDelivery?.deliveryProviderId;
144
-
145
- const isAlreadyInitializedWithSupportedDeliveryProvider = supportedDeliveryProviders?.some(
146
- (provider) => {
147
- return provider._id === deliveryProviderId;
148
- },
149
- );
150
-
151
- if (supportedDeliveryProviders?.length > 0 && !isAlreadyInitializedWithSupportedDeliveryProvider) {
152
- const defaultOrderDeliveryProvider = await modules.delivery.determineDefault(
153
- supportedDeliveryProviders,
154
- { order: updatedOrder },
155
- unchainedAPI,
156
- );
157
- if (defaultOrderDeliveryProvider) {
158
- updatedOrder = await modules.orders.setDeliveryProvider(
159
- updatedOrder._id,
160
- defaultOrderDeliveryProvider._id,
161
- unchainedAPI,
162
- );
163
- }
164
- }
165
-
166
- // Init payment provider
167
- const supportedPaymentProviders = await modules.payment.paymentProviders.findSupported(
168
- { order: updatedOrder },
169
- unchainedAPI,
170
- );
171
-
172
- const orderPayment = await modules.orders.payments.findOrderPayment({
173
- orderPaymentId: updatedOrder.paymentId,
174
- });
175
- const paymentProviderId = orderPayment?.paymentProviderId;
176
-
177
- const isAlreadyInitializedWithSupportedPaymentProvider = supportedPaymentProviders?.some(
178
- (provider) => {
179
- return provider._id === paymentProviderId;
180
- },
181
- );
182
-
183
- if (supportedPaymentProviders?.length > 0 && !isAlreadyInitializedWithSupportedPaymentProvider) {
184
- const paymentCredentials = await modules.payment.paymentCredentials.findPaymentCredentials(
185
- { userId: updatedOrder.userId, isPreferred: true },
186
- {
187
- sort: {
188
- created: -1,
189
- },
190
- },
191
- );
192
-
193
- const defaultOrderPaymentProvider = await modules.payment.paymentProviders.determineDefault(
194
- supportedPaymentProviders,
195
- { order: updatedOrder, paymentCredentials },
196
- unchainedAPI,
197
- );
198
-
199
- if (defaultOrderPaymentProvider) {
200
- updatedOrder = await modules.orders.setPaymentProvider(
201
- updatedOrder._id,
202
- defaultOrderPaymentProvider._id,
203
- unchainedAPI,
204
- );
205
- }
206
- }
207
- return updatedOrder;
208
- };
209
-
210
- const updateCalculation: OrdersModule['updateCalculation'] = async (orderId, unchainedAPI) => {
211
- const { modules } = unchainedAPI;
212
-
213
- const selector = generateDbFilterById(orderId);
214
- const order = (await Orders.findOne(selector, {})) as Order;
215
-
216
- // Don't recalculate orders, only carts
217
- if (order.status !== null) return order;
218
-
219
- await updateDiscounts(order, unchainedAPI);
220
-
221
- let orderPositions = (await findOrderPositions(order)) as OrderPosition[];
222
- orderPositions = await Promise.all(
223
- orderPositions.map(async (orderPosition) =>
224
- modules.orders.positions.updateCalculation(orderPosition, unchainedAPI),
225
- ),
226
- );
227
-
228
- let orderDelivery = (await findOrderDelivery(order)) as OrderDelivery;
229
- if (orderDelivery) {
230
- orderDelivery = await modules.orders.deliveries.updateCalculation(orderDelivery, unchainedAPI);
231
- }
232
- let orderPayment = (await findOrderPayment(order)) as OrderPayment;
233
- if (orderPayment) {
234
- orderPayment = await modules.orders.payments.updateCalculation(orderPayment, unchainedAPI);
235
- }
236
-
237
- orderPositions = await Promise.all(
238
- orderPositions.map(async (orderPosition) =>
239
- modules.orders.positions.updateScheduling({ order, orderDelivery, orderPosition }, unchainedAPI),
240
- ),
241
- );
242
-
243
- const pricing = await OrderPricingDirector.actions(
244
- { order, orderPositions, orderDelivery, orderPayment },
245
- unchainedAPI,
246
- );
247
-
248
- const calculation = await pricing.calculate();
249
- const updated = new Date();
250
-
251
- await Orders.updateOne(selector, {
252
- $set: {
253
- calculation,
254
- updated,
255
- },
256
- });
257
-
258
- /*
259
- // We have to do initProviders after calculation, only then filterSupportedProviders will work correctly and has access to recent pricing
260
- // initProviders calls updateCalculation anyways recursively when a new payment or delivery provider gets set
261
- // Thus, if for example a discount change leads to a free delivery and free payment due to free items amount, the following happens in the stack:
262
- // 1. create discount
263
- // 2. update calculation -> order pricing updated to items 0
264
- // 3. initProviders with updated order -> filterSupportedProviders -> delivery provider is invalid -> set new delivery provider
265
- // 4. update calculation -> order pricing updated to items 0 and delivery 0
266
- // 5. initProviders with updated order -> filterSupportedProviders -> payment provider is invalid -> set new payment provider
267
- // 6. update calculation -> order pricing updated to items 0, delivery 0, payment 0
268
- // 7. initProviders with updated order -> all providers are valid -> return order
269
- */
270
- return initProviders(
271
- {
272
- ...order,
273
- calculation,
274
- updated,
275
- },
276
- unchainedAPI,
277
- );
278
- };
279
-
280
- const invalidateProviders = async (unchainedAPI, maxAgeDays = 30) => {
281
- const ONE_DAY_IN_MILLISECONDS = 86400000;
282
-
283
- const minValidDate = new Date(new Date().getTime() - maxAgeDays * ONE_DAY_IN_MILLISECONDS);
284
-
285
- const orders = await Orders.find({
286
- status: { $eq: null },
287
- updated: { $gte: minValidDate },
288
- }).toArray();
289
-
290
- await Promise.allSettled(
291
- orders.map(async (order) => {
292
- await updateCalculation(order._id, unchainedAPI);
293
- }),
294
- );
295
- };
296
-
297
74
  const orderQueries = configureOrdersModuleQueries({ Orders });
298
- const orderTransformations = configureOrderModuleTransformations({
299
- Orders,
300
- });
301
- const orderProcessing = configureOrderModuleProcessing({
302
- Orders,
303
- OrderDeliveries,
304
- OrderPayments,
305
- OrderPositions,
306
- locker,
307
- });
75
+
308
76
  const orderMutations = configureOrderModuleMutations({
309
77
  Orders,
310
- OrderDeliveries,
311
- OrderPayments,
312
78
  OrderPositions,
313
79
  });
314
80
 
@@ -328,20 +94,171 @@ export const configureOrdersModule = async ({
328
94
  OrderDeliveries,
329
95
  });
330
96
 
97
+ const findNewOrderNumber = async (order: Order, index = 0) => {
98
+ const newHashID = ordersSettings.orderNumberHashFn(order, index);
99
+ if ((await Orders.countDocuments({ orderNumber: newHashID }, { limit: 1 })) === 0) {
100
+ return newHashID;
101
+ }
102
+ return findNewOrderNumber(order, index + 1);
103
+ };
104
+
331
105
  return {
332
106
  ...orderQueries,
333
- ...orderTransformations,
334
- ...orderProcessing,
335
107
  ...orderMutations,
336
108
 
337
- initProviders,
338
- updateCalculation,
339
- invalidateProviders,
340
-
341
109
  // Subentities
342
110
  deliveries: orderDeliveriesModule,
343
111
  discounts: orderDiscountsModule,
344
112
  positions: orderPositionsModule,
345
113
  payments: orderPaymentsModule,
114
+
115
+ updateStatus: async (orderId, { status, info }) => {
116
+ const selector = generateDbFilterById(orderId);
117
+ const order = await Orders.findOne(selector, {});
118
+
119
+ if (order.status === status) return order;
120
+
121
+ const date = new Date();
122
+ const $set: Partial<Order> = {
123
+ status,
124
+ updated: new Date(),
125
+ };
126
+ switch (status) {
127
+ // explicitly use fallthrough here!
128
+ case OrderStatus.FULLFILLED:
129
+ $set.fullfilled = order.fullfilled || date;
130
+ case OrderStatus.REJECTED: // eslint-disable-line no-fallthrough
131
+ case OrderStatus.CONFIRMED: // eslint-disable-line no-fallthrough
132
+ if (status === OrderStatus.REJECTED) {
133
+ $set.rejected = order.rejected || date;
134
+ } else {
135
+ $set.confirmed = order.confirmed || date;
136
+ }
137
+ case OrderStatus.PENDING: // eslint-disable-line no-fallthrough
138
+ $set.ordered = order.ordered || date;
139
+ $set.orderNumber = order.orderNumber || (await findNewOrderNumber(order));
140
+ break;
141
+ default:
142
+ break;
143
+ }
144
+
145
+ const modifier: mongodb.UpdateFilter<Order> = {
146
+ $set,
147
+ $push: {
148
+ log: {
149
+ date,
150
+ status,
151
+ info,
152
+ },
153
+ },
154
+ };
155
+
156
+ const modificationResult = await Orders.findOneAndUpdate(
157
+ {
158
+ ...selector,
159
+ status: { $ne: status }, // Only update if status is different
160
+ },
161
+ modifier,
162
+ {
163
+ returnDocument: 'after',
164
+ includeResultMetadata: true,
165
+ },
166
+ );
167
+
168
+ if (modificationResult.ok) {
169
+ if (order.status === null) {
170
+ // The first time that an order transitions away from cart is a checkout event
171
+ await emit('ORDER_CHECKOUT', { order: modificationResult.value, oldStatus: order.status });
172
+ }
173
+ switch (status) {
174
+ case OrderStatus.FULLFILLED:
175
+ await emit('ORDER_FULLFILLED', { order: modificationResult.value, oldStatus: order.status });
176
+ break;
177
+ case OrderStatus.REJECTED:
178
+ await emit('ORDER_REJECTED', { order: modificationResult.value, oldStatus: order.status });
179
+ break;
180
+ case OrderStatus.CONFIRMED:
181
+ await emit('ORDER_CONFIRMED', { order: modificationResult.value, oldStatus: order.status });
182
+ break;
183
+ default:
184
+ break;
185
+ }
186
+ }
187
+
188
+ return modificationResult.value || Orders.findOne(selector, {});
189
+ },
190
+
191
+ acquireLock: async (orderId: string, identifier: string, timeout = 5000) => {
192
+ return await locker.lock(`order:${identifier}:${orderId}`, timeout).acquire();
193
+ },
194
+
195
+ setDeliveryProvider: async (orderId, deliveryProviderId) => {
196
+ const delivery = await OrderDeliveries.findOne({
197
+ orderId,
198
+ deliveryProviderId,
199
+ });
200
+ const deliveryId =
201
+ delivery?._id ||
202
+ (
203
+ await orderDeliveriesModule.create({
204
+ calculation: [],
205
+ deliveryProviderId,
206
+ log: [],
207
+ orderId,
208
+ status: null,
209
+ })
210
+ )._id;
211
+
212
+ const order = await Orders.findOneAndUpdate(
213
+ { _id: orderId },
214
+ {
215
+ $set: {
216
+ deliveryId,
217
+ updated: new Date(),
218
+ },
219
+ },
220
+ { returnDocument: 'after' },
221
+ );
222
+
223
+ await emit('ORDER_SET_DELIVERY_PROVIDER', {
224
+ order,
225
+ deliveryProviderId,
226
+ });
227
+
228
+ return order;
229
+ },
230
+
231
+ setPaymentProvider: async (orderId, paymentProviderId) => {
232
+ const payment = await OrderPayments.findOne({
233
+ orderId,
234
+ paymentProviderId,
235
+ });
236
+
237
+ const paymentId =
238
+ payment?._id ||
239
+ (
240
+ await orderPaymentsModule.create({
241
+ calculation: [],
242
+ paymentProviderId,
243
+ log: [],
244
+ orderId,
245
+ status: null,
246
+ })
247
+ )._id;
248
+ const order = await Orders.findOneAndUpdate(
249
+ { _id: orderId },
250
+ {
251
+ $set: { paymentId, updated: new Date() },
252
+ },
253
+ { returnDocument: 'after' },
254
+ );
255
+
256
+ await emit('ORDER_SET_PAYMENT_PROVIDER', {
257
+ order,
258
+ paymentProviderId,
259
+ });
260
+
261
+ return order;
262
+ },
346
263
  };
347
264
  };
@@ -1,12 +1,13 @@
1
- export * from './types.js';
2
1
  export * from './module/configureOrdersModule.js';
3
- export * from './service/orderServices.js';
2
+ export * from './module/configureOrderDeliveriesModule.js';
3
+ export * from './module/configureOrderDiscountsModule.js';
4
+ export * from './module/configureOrderPaymentsModule.js';
5
+ export * from './module/configureOrderPositionsModule.js';
6
+ export * from './module/configureOrdersModule-mutations.js';
7
+ export * from './module/configureOrdersModule-queries.js';
8
+ export * from './db/OrderDeliveriesCollection.js';
9
+ export * from './db/OrderDiscountsCollection.js';
10
+ export * from './db/OrderPaymentsCollection.js';
11
+ export * from './db/OrderPositionsCollection.js';
12
+ export * from './db/OrdersCollection.js';
4
13
  export * from './orders-settings.js';
5
-
6
- export * from './director/OrderDiscountConfiguration.js';
7
- export * from './director/OrderDiscountAdapter.js';
8
- export * from './director/OrderDiscountDirector.js';
9
-
10
- export * from './director/OrderPricingAdapter.js';
11
- export * from './director/OrderPricingDirector.js';
12
- export * from './director/OrderPricingSheet.js';
@@ -1,9 +1,7 @@
1
1
  import { generateRandomHash } from '@unchainedshop/utils';
2
- import { Order } from './types.js';
3
- import { UnchainedCore } from '@unchainedshop/core';
4
- import { Product } from '@unchainedshop/core-products';
2
+ import { Order } from './db/OrdersCollection.js';
5
3
 
6
- export interface OrderSettingsOrderPositionValidation {
4
+ export interface OrderSettingsOrderPositionValidation<Product = unknown> {
7
5
  order: Order;
8
6
  product: Product;
9
7
  quantityDiff?: number;
@@ -13,14 +11,14 @@ export interface OrderSettingsOrderPositionValidation {
13
11
  export interface OrdersSettingsOptions {
14
12
  ensureUserHasCart?: boolean;
15
13
  orderNumberHashFn?: (order: Order, index: number) => string;
16
- validateOrderPosition?: (
14
+ validateOrderPosition?: <UnchainedAPI = unknown>(
17
15
  validationParams: OrderSettingsOrderPositionValidation,
18
- context: UnchainedCore,
16
+ unchainedAPI: UnchainedAPI,
19
17
  ) => Promise<void>;
20
18
  lockOrderDuringCheckout?: boolean;
21
19
  }
22
20
 
23
- export const defaultValidateOrderPosition = async ({ product }, { modules }) => {
21
+ export const defaultValidateOrderPosition = async ({ product }, { modules }: any) => {
24
22
  if (!modules.products.isActive(product)) {
25
23
  throw new Error('This product is inactive');
26
24
  }
package/tsconfig.json CHANGED
@@ -1,11 +1,9 @@
1
1
  {
2
2
  "extends": "../shared/base.tsconfig.json",
3
3
  "compilerOptions": {
4
- "rootDir": "src",
5
- "outDir": "lib",
4
+ "declarationDir": "./lib",
5
+ "rootDir": "./src",
6
+ "outDir": "./lib"
6
7
  },
7
- "exclude": ["**/*.test.ts", "**/*.test.js", "tests"],
8
- "include": [
9
- "./src"
10
- ]
11
- }
8
+ "exclude": ["**/*.test.ts", "**/*.test.js", "tests", "lib"]
9
+ }
@@ -1,5 +0,0 @@
1
- export declare enum OrderDiscountTrigger {
2
- USER = "USER",
3
- SYSTEM = "SYSTEM"
4
- }
5
- //# sourceMappingURL=OrderDiscountTrigger.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"OrderDiscountTrigger.d.ts","sourceRoot":"","sources":["../../src/db/OrderDiscountTrigger.ts"],"names":[],"mappings":"AAAA,oBAAY,oBAAoB;IAC9B,IAAI,SAAS;IACb,MAAM,WAAW;CAClB"}
@@ -1,6 +0,0 @@
1
- export var OrderDiscountTrigger;
2
- (function (OrderDiscountTrigger) {
3
- OrderDiscountTrigger["USER"] = "USER";
4
- OrderDiscountTrigger["SYSTEM"] = "SYSTEM";
5
- })(OrderDiscountTrigger || (OrderDiscountTrigger = {}));
6
- //# sourceMappingURL=OrderDiscountTrigger.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"OrderDiscountTrigger.js","sourceRoot":"","sources":["../../src/db/OrderDiscountTrigger.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,oBAGX;AAHD,WAAY,oBAAoB;IAC9B,qCAAa,CAAA;IACb,yCAAiB,CAAA;AACnB,CAAC,EAHW,oBAAoB,KAApB,oBAAoB,QAG/B"}
@@ -1,4 +0,0 @@
1
- import { OrderDiscountConfiguration } from './OrderDiscountConfiguration.js';
2
- import { IDiscountAdapter } from '@unchainedshop/utils';
3
- export declare const OrderDiscountAdapter: Omit<IDiscountAdapter<OrderDiscountConfiguration>, 'key' | 'label' | 'version'>;
4
- //# sourceMappingURL=OrderDiscountAdapter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"OrderDiscountAdapter.d.ts","sourceRoot":"","sources":["../../src/director/OrderDiscountAdapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,eAAO,MAAM,oBAAoB,EAAE,IAAI,CACrC,gBAAgB,CAAC,0BAA0B,CAAC,EAC5C,KAAK,GAAG,OAAO,GAAG,SAAS,CACN,CAAC"}
@@ -1,3 +0,0 @@
1
- import { BaseDiscountAdapter } from '@unchainedshop/utils';
2
- export const OrderDiscountAdapter = BaseDiscountAdapter;
3
- //# sourceMappingURL=OrderDiscountAdapter.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"OrderDiscountAdapter.js","sourceRoot":"","sources":["../../src/director/OrderDiscountAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAI3D,MAAM,CAAC,MAAM,oBAAoB,GAG7B,mBAAmB,CAAC"}
@@ -1,6 +0,0 @@
1
- export interface OrderDiscountConfiguration {
2
- fixedRate?: number;
3
- rate?: number;
4
- isNetPrice?: boolean;
5
- }
6
- //# sourceMappingURL=OrderDiscountConfiguration.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"OrderDiscountConfiguration.d.ts","sourceRoot":"","sources":["../../src/director/OrderDiscountConfiguration.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,0BAA0B;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=OrderDiscountConfiguration.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"OrderDiscountConfiguration.js","sourceRoot":"","sources":["../../src/director/OrderDiscountConfiguration.ts"],"names":[],"mappings":""}
@@ -1,3 +0,0 @@
1
- import { OrderDiscountConfiguration } from './OrderDiscountConfiguration.js';
2
- export declare const OrderDiscountDirector: import("@unchainedshop/utils").IDiscountDirector<OrderDiscountConfiguration>;
3
- //# sourceMappingURL=OrderDiscountDirector.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"OrderDiscountDirector.d.ts","sourceRoot":"","sources":["../../src/director/OrderDiscountDirector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAE7E,eAAO,MAAM,qBAAqB,8EACyC,CAAC"}
@@ -1,3 +0,0 @@
1
- import { BaseDiscountDirector } from '@unchainedshop/utils';
2
- export const OrderDiscountDirector = BaseDiscountDirector('OrderDiscountDirector');
3
- //# sourceMappingURL=OrderDiscountDirector.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"OrderDiscountDirector.js","sourceRoot":"","sources":["../../src/director/OrderDiscountDirector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAG5D,MAAM,CAAC,MAAM,qBAAqB,GAChC,oBAAoB,CAA6B,uBAAuB,CAAC,CAAC"}
@@ -1,22 +0,0 @@
1
- import { IPricingAdapter, BasePricingAdapterContext } from '@unchainedshop/utils';
2
- import { IOrderPricingSheet, OrderPricingCalculation } from './OrderPricingSheet.js';
3
- import { Order, OrderDelivery, OrderDiscount, OrderPayment, OrderPosition } from '../types.js';
4
- import { User } from '@unchainedshop/core-users';
5
- export interface OrderPricingAdapterContext extends BasePricingAdapterContext {
6
- currency?: string;
7
- discounts: Array<OrderDiscount>;
8
- order: Order;
9
- orderDelivery: OrderDelivery;
10
- orderPositions: Array<OrderPosition>;
11
- orderPayment: OrderPayment;
12
- user: User;
13
- }
14
- export interface OrderPricingContext {
15
- order: Order;
16
- orderDelivery: OrderDelivery;
17
- orderPositions: Array<OrderPosition>;
18
- orderPayment: OrderPayment;
19
- }
20
- export type IOrderPricingAdapter<DiscountConfiguration = unknown> = IPricingAdapter<OrderPricingAdapterContext, OrderPricingCalculation, IOrderPricingSheet, DiscountConfiguration>;
21
- export declare const OrderPricingAdapter: IPricingAdapter<OrderPricingAdapterContext, OrderPricingCalculation, IOrderPricingSheet>;
22
- //# sourceMappingURL=OrderPricingAdapter.d.ts.map