@unchainedshop/core-orders 3.0.0-alpha2 → 3.0.0-alpha4

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 (131) hide show
  1. package/lib/db/OrderDeliveriesCollection.d.ts +1 -1
  2. package/lib/db/OrderDeliveriesCollection.d.ts.map +1 -1
  3. package/lib/db/OrderDiscountsCollection.d.ts +1 -1
  4. package/lib/db/OrderDiscountsCollection.d.ts.map +1 -1
  5. package/lib/db/OrderPaymentsCollection.d.ts +1 -1
  6. package/lib/db/OrderPaymentsCollection.d.ts.map +1 -1
  7. package/lib/db/OrderPositionsCollection.d.ts +1 -1
  8. package/lib/db/OrderPositionsCollection.d.ts.map +1 -1
  9. package/lib/db/OrdersCollection.d.ts +1 -1
  10. package/lib/db/OrdersCollection.d.ts.map +1 -1
  11. package/lib/director/OrderDiscountAdapter.d.ts +1 -1
  12. package/lib/director/OrderDiscountAdapter.d.ts.map +1 -1
  13. package/lib/director/OrderDiscountAdapter.js.map +1 -1
  14. package/lib/director/OrderDiscountDirector.d.ts +1 -1
  15. package/lib/director/OrderDiscountDirector.d.ts.map +1 -1
  16. package/lib/director/OrderPricingAdapter.d.ts +20 -2
  17. package/lib/director/OrderPricingAdapter.d.ts.map +1 -1
  18. package/lib/director/OrderPricingAdapter.js.map +1 -1
  19. package/lib/director/OrderPricingDirector.d.ts +16 -1
  20. package/lib/director/OrderPricingDirector.d.ts.map +1 -1
  21. package/lib/director/OrderPricingDirector.js.map +1 -1
  22. package/lib/director/OrderPricingSheet.d.ts +34 -2
  23. package/lib/director/OrderPricingSheet.d.ts.map +1 -1
  24. package/lib/director/OrderPricingSheet.js +9 -2
  25. package/lib/director/OrderPricingSheet.js.map +1 -1
  26. package/lib/module/configureOrderDeliveriesModule.d.ts +31 -1
  27. package/lib/module/configureOrderDeliveriesModule.d.ts.map +1 -1
  28. package/lib/module/configureOrderDeliveriesModule.js +15 -9
  29. package/lib/module/configureOrderDeliveriesModule.js.map +1 -1
  30. package/lib/module/configureOrderDiscountsModule.d.ts +21 -1
  31. package/lib/module/configureOrderDiscountsModule.d.ts.map +1 -1
  32. package/lib/module/configureOrderDiscountsModule.js +19 -15
  33. package/lib/module/configureOrderDiscountsModule.js.map +1 -1
  34. package/lib/module/configureOrderPaymentsModule.d.ts +45 -1
  35. package/lib/module/configureOrderPaymentsModule.d.ts.map +1 -1
  36. package/lib/module/configureOrderPaymentsModule.js +5 -8
  37. package/lib/module/configureOrderPaymentsModule.js.map +1 -1
  38. package/lib/module/configureOrderPositionsModule.d.ts +57 -1
  39. package/lib/module/configureOrderPositionsModule.d.ts.map +1 -1
  40. package/lib/module/configureOrderPositionsModule.js.map +1 -1
  41. package/lib/module/configureOrdersModule-mutations.d.ts +31 -5
  42. package/lib/module/configureOrdersModule-mutations.d.ts.map +1 -1
  43. package/lib/module/configureOrdersModule-mutations.js +5 -9
  44. package/lib/module/configureOrdersModule-mutations.js.map +1 -1
  45. package/lib/module/configureOrdersModule-processing.d.ts +22 -4
  46. package/lib/module/configureOrdersModule-processing.d.ts.map +1 -1
  47. package/lib/module/configureOrdersModule-processing.js +15 -20
  48. package/lib/module/configureOrdersModule-processing.js.map +1 -1
  49. package/lib/module/configureOrdersModule-queries.d.ts +23 -3
  50. package/lib/module/configureOrdersModule-queries.d.ts.map +1 -1
  51. package/lib/module/configureOrdersModule-queries.js +89 -5
  52. package/lib/module/configureOrdersModule-queries.js.map +1 -1
  53. package/lib/module/configureOrdersModule-transformations.d.ts +15 -1
  54. package/lib/module/configureOrdersModule-transformations.d.ts.map +1 -1
  55. package/lib/module/configureOrdersModule-transformations.js +4 -5
  56. package/lib/module/configureOrdersModule-transformations.js.map +1 -1
  57. package/lib/module/configureOrdersModule.d.ts +21 -2
  58. package/lib/module/configureOrdersModule.d.ts.map +1 -1
  59. package/lib/module/configureOrdersModule.js +2 -2
  60. package/lib/module/configureOrdersModule.js.map +1 -1
  61. package/lib/orders-index.d.ts +10 -12
  62. package/lib/orders-index.d.ts.map +1 -1
  63. package/lib/orders-index.js +10 -11
  64. package/lib/orders-index.js.map +1 -1
  65. package/lib/orders-settings.d.ts +18 -1
  66. package/lib/orders-settings.d.ts.map +1 -1
  67. package/lib/orders-settings.js.map +1 -1
  68. package/lib/service/migrateOrderCartService.d.ts +8 -1
  69. package/lib/service/migrateOrderCartService.d.ts.map +1 -1
  70. package/lib/service/migrateOrderCartService.js.map +1 -1
  71. package/lib/service/nextUserCartService.d.ts +9 -1
  72. package/lib/service/nextUserCartService.d.ts.map +1 -1
  73. package/lib/service/nextUserCartService.js.map +1 -1
  74. package/lib/service/orderServices.d.ts +6 -1
  75. package/lib/service/orderServices.d.ts.map +1 -1
  76. package/lib/service/orderServices.js.map +1 -1
  77. package/lib/types.d.ts +116 -0
  78. package/lib/types.d.ts.map +1 -0
  79. package/lib/types.js +25 -0
  80. package/lib/types.js.map +1 -0
  81. package/package.json +7 -9
  82. package/src/db/OrderDeliveriesCollection.ts +1 -1
  83. package/src/db/OrderDiscountsCollection.ts +1 -1
  84. package/src/db/OrderPaymentsCollection.ts +1 -1
  85. package/src/db/OrderPositionsCollection.ts +1 -1
  86. package/src/db/OrdersCollection.ts +1 -1
  87. package/src/director/OrderDiscountAdapter.ts +1 -1
  88. package/src/director/OrderPricingAdapter.ts +26 -6
  89. package/src/director/OrderPricingDirector.ts +21 -5
  90. package/src/director/OrderPricingSheet.ts +25 -6
  91. package/src/module/buildFindSelector.test.ts +77 -72
  92. package/src/module/configureOrderDeliveriesModule.ts +81 -15
  93. package/src/module/configureOrderDiscountsModule.ts +70 -19
  94. package/src/module/configureOrderPaymentsModule.ts +93 -14
  95. package/src/module/configureOrderPositionsModule.ts +72 -1
  96. package/src/module/configureOrdersModule-mutations.ts +47 -14
  97. package/src/module/configureOrdersModule-processing.ts +53 -26
  98. package/src/module/configureOrdersModule-queries.ts +121 -13
  99. package/src/module/configureOrdersModule-transformations.ts +28 -6
  100. package/src/module/configureOrdersModule.ts +36 -15
  101. package/src/orders-index.ts +12 -16
  102. package/src/orders-settings.ts +20 -1
  103. package/src/service/migrateOrderCartService.ts +12 -1
  104. package/src/service/nextUserCartService.ts +13 -1
  105. package/src/service/orderServices.ts +7 -3
  106. package/src/types.ts +129 -0
  107. package/lib/db/OrderDeliveriesSchema.d.ts +0 -3
  108. package/lib/db/OrderDeliveriesSchema.d.ts.map +0 -1
  109. package/lib/db/OrderDeliveriesSchema.js +0 -20
  110. package/lib/db/OrderDeliveriesSchema.js.map +0 -1
  111. package/lib/db/OrderDiscountsSchema.d.ts +0 -3
  112. package/lib/db/OrderDiscountsSchema.d.ts.map +0 -1
  113. package/lib/db/OrderDiscountsSchema.js +0 -12
  114. package/lib/db/OrderDiscountsSchema.js.map +0 -1
  115. package/lib/db/OrderPaymentsSchema.d.ts +0 -3
  116. package/lib/db/OrderPaymentsSchema.d.ts.map +0 -1
  117. package/lib/db/OrderPaymentsSchema.js +0 -20
  118. package/lib/db/OrderPaymentsSchema.js.map +0 -1
  119. package/lib/db/OrderPositionsSchema.d.ts +0 -3
  120. package/lib/db/OrderPositionsSchema.d.ts.map +0 -1
  121. package/lib/db/OrderPositionsSchema.js +0 -37
  122. package/lib/db/OrderPositionsSchema.js.map +0 -1
  123. package/lib/db/OrdersSchema.d.ts +0 -3
  124. package/lib/db/OrdersSchema.d.ts.map +0 -1
  125. package/lib/db/OrdersSchema.js +0 -30
  126. package/lib/db/OrdersSchema.js.map +0 -1
  127. package/src/db/OrderDeliveriesSchema.ts +0 -24
  128. package/src/db/OrderDiscountsSchema.ts +0 -15
  129. package/src/db/OrderPaymentsSchema.ts +0 -24
  130. package/src/db/OrderPositionsSchema.ts +0 -41
  131. package/src/db/OrdersSchema.ts +0 -34
@@ -1,12 +1,94 @@
1
- import { ModuleMutations } from '@unchainedshop/types/core.js';
2
- import {
3
- OrderPayment,
4
- OrderPaymentsModule,
5
- OrderPaymentStatus,
6
- } from '@unchainedshop/types/orders.payments.js';
1
+ import { UnchainedCore } from '@unchainedshop/core';
7
2
  import { emit, registerEvents } from '@unchainedshop/events';
8
- import { generateDbFilterById, generateDbMutations, mongodb } from '@unchainedshop/mongodb';
9
- import { OrderPaymentsSchema } from '../db/OrderPaymentsSchema.js';
3
+ import { generateDbFilterById, generateDbObjectId, mongodb } from '@unchainedshop/mongodb';
4
+ import { Order, OrderDiscount, OrderPayment, OrderPaymentStatus } from '../types.js';
5
+ import { IPaymentPricingSheet } from '@unchainedshop/core-payment';
6
+ import { OrderPricingDiscount } from '../director/OrderPricingDirector.js';
7
+
8
+ export type OrderPaymentsModule = {
9
+ // Queries
10
+ findOrderPayment: (
11
+ params: {
12
+ orderPaymentId: string;
13
+ },
14
+ options?: mongodb.FindOptions,
15
+ ) => Promise<OrderPayment>;
16
+
17
+ findOrderPaymentByContextData: (
18
+ params: {
19
+ context: any;
20
+ },
21
+ options?: mongodb.FindOptions,
22
+ ) => Promise<OrderPayment>;
23
+
24
+ countOrderPaymentsByContextData: (
25
+ params: {
26
+ context: any;
27
+ },
28
+ options?: mongodb.FindOptions,
29
+ ) => Promise<number>;
30
+
31
+ // Transformations
32
+ discounts: (
33
+ orderPayment: OrderPayment,
34
+ params: { order: Order; orderDiscount: OrderDiscount },
35
+ unchainedAPI: UnchainedCore,
36
+ ) => Array<OrderPricingDiscount>;
37
+ isBlockingOrderConfirmation: (
38
+ orderPayment: OrderPayment,
39
+ unchainedAPI: UnchainedCore,
40
+ ) => Promise<boolean>;
41
+ isBlockingOrderFullfillment: (orderPayment: OrderPayment) => boolean;
42
+ normalizedStatus: (orderPayment: OrderPayment) => string;
43
+ pricingSheet: (
44
+ orderPayment: OrderPayment,
45
+ currency: string,
46
+ unchainedAPI: UnchainedCore,
47
+ ) => IPaymentPricingSheet;
48
+
49
+ // Mutations
50
+ create: (doc: OrderPayment) => Promise<OrderPayment>;
51
+
52
+ cancel: (
53
+ orderPayment: OrderPayment,
54
+ paymentContext: {
55
+ transactionContext: any;
56
+ userId: string;
57
+ },
58
+ unchainedAPI: UnchainedCore,
59
+ ) => Promise<OrderPayment>;
60
+
61
+ confirm: (
62
+ orderPayment: OrderPayment,
63
+ paymentContext: {
64
+ transactionContext: any;
65
+ userId: string;
66
+ },
67
+ unchainedAPI: UnchainedCore,
68
+ ) => Promise<OrderPayment>;
69
+
70
+ charge: (
71
+ orderPayment: OrderPayment,
72
+ paymentContext: {
73
+ transactionContext: any;
74
+ userId: string;
75
+ },
76
+ unchainedAPI: UnchainedCore,
77
+ ) => Promise<OrderPayment>;
78
+
79
+ logEvent: (orderPaymentId: string, event: any) => Promise<boolean>;
80
+
81
+ markAsPaid: (payment: OrderPayment, meta: any) => Promise<void>;
82
+
83
+ updateContext: (orderPaymentId: string, context: any) => Promise<OrderPayment | null>;
84
+
85
+ updateStatus: (
86
+ orderPaymentId: string,
87
+ params: { transactionId?: string; status: OrderPaymentStatus; info?: string },
88
+ ) => Promise<OrderPayment>;
89
+
90
+ updateCalculation: (orderPayment: OrderPayment, unchainedAPI: UnchainedCore) => Promise<OrderPayment>;
91
+ };
10
92
 
11
93
  const ORDER_PAYMENT_EVENTS: string[] = ['ORDER_UPDATE_PAYMENT', 'ORDER_SIGN_PAYMENT', 'ORDER_PAY'];
12
94
 
@@ -38,11 +120,6 @@ export const configureOrderPaymentsModule = ({
38
120
  }): OrderPaymentsModule => {
39
121
  registerEvents(ORDER_PAYMENT_EVENTS);
40
122
 
41
- const mutations = generateDbMutations<OrderPayment>(OrderPayments, OrderPaymentsSchema, {
42
- permanentlyDeleteByDefault: true,
43
- hasCreateOnly: false,
44
- }) as ModuleMutations<OrderPayment>;
45
-
46
123
  const normalizedStatus: OrderPaymentsModule['normalizedStatus'] = (orderPayment) => {
47
124
  return orderPayment.status === null
48
125
  ? OrderPaymentStatus.OPEN
@@ -149,7 +226,9 @@ export const configureOrderPaymentsModule = ({
149
226
  // Mutations
150
227
 
151
228
  create: async (doc) => {
152
- const orderPaymentId = await mutations.create({
229
+ const { insertedId: orderPaymentId } = await OrderPayments.insertOne({
230
+ _id: generateDbObjectId(),
231
+ created: new Date(),
153
232
  ...doc,
154
233
  status: null,
155
234
  context: doc.context || {},
@@ -1,7 +1,78 @@
1
- import { OrderPosition, OrderPositionsModule } from '@unchainedshop/types/orders.positions.js';
1
+ import type { OrderDiscount } from '@unchainedshop/core-orders';
2
+ import type { UnchainedCore } from '@unchainedshop/core';
3
+ import { IProductPricingSheet, Product } from '@unchainedshop/core-products';
4
+
5
+ import { Order, OrderPosition } from '../types.js';
2
6
  import { emit, registerEvents } from '@unchainedshop/events';
3
7
  import { generateDbFilterById, generateDbObjectId, mongodb } from '@unchainedshop/mongodb';
4
8
  import { ordersSettings } from '../orders-settings.js';
9
+ import { OrderDelivery } from '@unchainedshop/core-orders';
10
+ import { OrderPricingDiscount } from '../director/OrderPricingDirector.js';
11
+
12
+ export type OrderPositionsModule = {
13
+ // Queries
14
+ findOrderPosition: (
15
+ params: { itemId: string },
16
+ options?: mongodb.FindOptions,
17
+ ) => Promise<OrderPosition>;
18
+ findOrderPositions: (params: { orderId: string }) => Promise<Array<OrderPosition>>;
19
+
20
+ // Transformations
21
+ discounts: (
22
+ orderPosition: OrderPosition,
23
+ params: { order: Order; orderDiscount: OrderDiscount },
24
+ unchainedAPI: UnchainedCore,
25
+ ) => Array<OrderPricingDiscount>;
26
+
27
+ pricingSheet: (
28
+ orderPosition: OrderPosition,
29
+ currency: string,
30
+ unchainedAPI: UnchainedCore,
31
+ ) => IProductPricingSheet;
32
+
33
+ delete: (orderPositionId: string) => Promise<OrderPosition>;
34
+
35
+ removePositions: ({ orderId }: { orderId: string }) => Promise<number>;
36
+ removeProductByIdFromAllOpenPositions: (productId: string) => Promise<Array<string>>;
37
+
38
+ updateProductItem: (
39
+ doc: {
40
+ context?: any;
41
+ configuration?: Array<{ key: string; value: string }>;
42
+ quantity?: number;
43
+ },
44
+ params: { order: Order; product: Product; orderPosition: OrderPosition },
45
+ unchainedAPI: UnchainedCore,
46
+ ) => Promise<OrderPosition>;
47
+
48
+ updateScheduling: (
49
+ params: {
50
+ order: Order;
51
+ orderDelivery: OrderDelivery;
52
+ orderPosition: OrderPosition;
53
+ },
54
+ unchainedAPI: UnchainedCore,
55
+ ) => Promise<OrderPosition>;
56
+
57
+ updateCalculation: (
58
+ orderPosition: OrderPosition,
59
+ unchainedAPI: UnchainedCore,
60
+ ) => Promise<OrderPosition>;
61
+
62
+ addProductItem: (
63
+ doc: {
64
+ context?: any;
65
+ configuration?: Array<{ key: string; value: string }>;
66
+ orderId?: string;
67
+ originalProductId?: string;
68
+ productId?: string;
69
+ quantity: number;
70
+ quotationId?: string;
71
+ },
72
+ params: { order: Order; product: Product },
73
+ unchainedAPI: UnchainedCore,
74
+ ) => Promise<OrderPosition>;
75
+ };
5
76
 
6
77
  const ORDER_POSITION_EVENTS: string[] = [
7
78
  'ORDER_UPDATE_CART_ITEM',
@@ -1,11 +1,48 @@
1
- import { ModuleMutations } from '@unchainedshop/types/core.js';
2
- import { Order, OrderStatus, OrderMutations } from '@unchainedshop/types/orders.js';
3
- import { OrderDelivery } from '@unchainedshop/types/orders.deliveries.js';
4
- import { OrderPayment } from '@unchainedshop/types/orders.payments.js';
1
+ import { UnchainedCore } from '@unchainedshop/core';
2
+ import { Order, OrderStatus } from '../types.js';
3
+ import { OrderDelivery } from '@unchainedshop/core-orders';
4
+ import { OrderPayment } from '@unchainedshop/core-orders';
5
5
  import { emit, registerEvents } from '@unchainedshop/events';
6
- import { generateDbFilterById, generateDbMutations, mongodb } from '@unchainedshop/mongodb';
7
- import { OrderPosition } from '@unchainedshop/types/orders.positions.js';
8
- import { OrdersSchema } from '../db/OrdersSchema.js';
6
+ import {
7
+ Address,
8
+ Contact,
9
+ generateDbFilterById,
10
+ generateDbObjectId,
11
+ mongodb,
12
+ } from '@unchainedshop/mongodb';
13
+ import { OrderPosition } from '@unchainedshop/core-orders';
14
+
15
+ export interface OrderMutations {
16
+ create: (doc: {
17
+ userId: string;
18
+ billingAddress?: Address;
19
+ contact?: Contact;
20
+ countryCode: string;
21
+ currency: string;
22
+ orderNumber?: string;
23
+ originEnrollmentId?: string;
24
+ }) => Promise<Order>;
25
+
26
+ delete: (orderId: string) => Promise<number>;
27
+
28
+ setCartOwner: (params: { orderId: string; userId: string }) => Promise<void>;
29
+ moveCartPositions: (params: { fromOrderId: string; toOrderId: string }) => Promise<void>;
30
+
31
+ setDeliveryProvider: (
32
+ orderId: string,
33
+ deliveryProviderId: string,
34
+ unchainedAPI: UnchainedCore,
35
+ ) => Promise<Order>;
36
+ setPaymentProvider: (
37
+ orderId: string,
38
+ paymentProviderId: string,
39
+ unchainedAPI: UnchainedCore,
40
+ ) => Promise<Order>;
41
+
42
+ updateBillingAddress: (orderId: string, billingAddress: Address) => Promise<Order>;
43
+ updateContact: (orderId: string, contact: Contact) => Promise<Order>;
44
+ updateContext: (orderId: string, context: any) => Promise<Order | null>;
45
+ }
9
46
 
10
47
  const ORDER_EVENTS: string[] = [
11
48
  'ORDER_CREATE',
@@ -28,14 +65,10 @@ export const configureOrderModuleMutations = ({
28
65
  }): OrderMutations => {
29
66
  registerEvents(ORDER_EVENTS);
30
67
 
31
- const mutations = generateDbMutations<Order>(Orders, OrdersSchema, {
32
- permanentlyDeleteByDefault: true,
33
- hasCreateOnly: false,
34
- }) as ModuleMutations<Order>;
35
-
36
68
  return {
37
69
  create: async ({ userId, orderNumber, currency, countryCode, billingAddress, contact }) => {
38
- const orderId = await mutations.create({
70
+ const { insertedId: orderId } = await Orders.insertOne({
71
+ _id: generateDbObjectId(),
39
72
  created: new Date(),
40
73
  status: null,
41
74
  billingAddress,
@@ -55,7 +88,7 @@ export const configureOrderModuleMutations = ({
55
88
  },
56
89
 
57
90
  delete: async (orderId) => {
58
- const deletedCount = await mutations.delete(orderId);
91
+ const { deletedCount } = await Orders.deleteOne({ _id: orderId });
59
92
  await emit('ORDER_REMOVE', { orderId });
60
93
  return deletedCount;
61
94
  },
@@ -1,14 +1,41 @@
1
1
  import { mongodb, generateDbFilterById } from '@unchainedshop/mongodb';
2
- import { Order, OrderStatus, OrderProcessing, OrdersModule } from '@unchainedshop/types/orders.js';
3
- import type { Locker } from '@kontsedal/locco';
4
- import { OrderDelivery } from '@unchainedshop/types/orders.deliveries.js';
5
- import { OrderPayment } from '@unchainedshop/types/orders.payments.js';
6
- import { OrderPosition } from '@unchainedshop/types/orders.positions.js';
2
+ import { ProductTypes } from '@unchainedshop/core-products';
7
3
  import { emit, registerEvents } from '@unchainedshop/events';
8
- import { ProductType } from '@unchainedshop/types/products.js';
9
- import { UnchainedCore } from '@unchainedshop/types/core.js';
4
+
5
+ import type { Locker } from '@kontsedal/locco';
6
+ import { Order, OrderStatus } from '../types.js';
7
+ import { OrderDelivery } from '@unchainedshop/core-orders';
8
+ import { OrderPayment } from '@unchainedshop/core-orders';
9
+ import { OrderPosition } from '@unchainedshop/core-orders';
10
+ import { UnchainedCore } from '@unchainedshop/core';
11
+
10
12
  import { ordersSettings } from '../orders-settings.js';
11
13
 
14
+ export type OrderContextParams<P> = (
15
+ order: Order,
16
+ params: P,
17
+ unchainedAPI: UnchainedCore,
18
+ ) => Promise<Order>;
19
+
20
+ export type OrderTransactionContext = {
21
+ paymentContext?: any;
22
+ deliveryContext?: any;
23
+ comment?: string;
24
+ nextStatus?: OrderStatus;
25
+ };
26
+
27
+ export interface OrderProcessing {
28
+ checkout: (
29
+ orderId: string,
30
+ params: OrderTransactionContext,
31
+ unchainedAPI: UnchainedCore,
32
+ ) => Promise<Order>;
33
+ confirm: OrderContextParams<OrderTransactionContext>;
34
+ reject: OrderContextParams<OrderTransactionContext>;
35
+ processOrder: OrderContextParams<OrderTransactionContext>;
36
+ updateStatus: (orderId: string, params: { status: OrderStatus; info?: string }) => Promise<Order>;
37
+ }
38
+
12
39
  const ORDER_PROCESSING_EVENTS: string[] = [
13
40
  'ORDER_CHECKOUT',
14
41
  'ORDER_CONFIRMED',
@@ -39,7 +66,7 @@ export const configureOrderModuleProcessing = ({
39
66
  return findNewOrderNumber(order, index + 1);
40
67
  };
41
68
 
42
- const updateStatus: OrdersModule['updateStatus'] = async (orderId, { status, info }) => {
69
+ const updateStatus: OrderProcessing['updateStatus'] = async (orderId, { status, info }) => {
43
70
  const selector = generateDbFilterById(orderId);
44
71
  const order = await Orders.findOne(selector, {});
45
72
 
@@ -249,7 +276,7 @@ export const configureOrderModuleProcessing = ({
249
276
  };
250
277
 
251
278
  return {
252
- checkout: async (orderId, { paymentContext, deliveryContext }, unchainedAPI) => {
279
+ checkout: async (orderId, transactionContext, unchainedAPI) => {
253
280
  const { modules, services } = unchainedAPI;
254
281
 
255
282
  const order = await Orders.findOne(generateDbFilterById(orderId), {});
@@ -268,10 +295,7 @@ export const configureOrderModuleProcessing = ({
268
295
  try {
269
296
  const processedOrder = await modules.orders.processOrder(
270
297
  order,
271
- {
272
- paymentContext,
273
- deliveryContext,
274
- },
298
+ transactionContext,
275
299
  unchainedAPI,
276
300
  );
277
301
 
@@ -288,7 +312,7 @@ export const configureOrderModuleProcessing = ({
288
312
  await services.orders.nextUserCart(
289
313
  {
290
314
  user,
291
- countryCode: locale.country,
315
+ countryCode: locale.region,
292
316
  },
293
317
  unchainedAPI,
294
318
  );
@@ -299,7 +323,7 @@ export const configureOrderModuleProcessing = ({
299
323
  }
300
324
  },
301
325
 
302
- confirm: async (order, { paymentContext, deliveryContext }, unchainedAPI) => {
326
+ confirm: async (order, transactionContext, unchainedAPI) => {
303
327
  const { modules } = unchainedAPI;
304
328
 
305
329
  if (order.status !== OrderStatus.PENDING) return order;
@@ -309,8 +333,7 @@ export const configureOrderModuleProcessing = ({
309
333
  return await modules.orders.processOrder(
310
334
  order,
311
335
  {
312
- paymentContext,
313
- deliveryContext,
336
+ ...transactionContext,
314
337
  nextStatus: OrderStatus.CONFIRMED,
315
338
  },
316
339
  unchainedAPI,
@@ -320,7 +343,7 @@ export const configureOrderModuleProcessing = ({
320
343
  }
321
344
  },
322
345
 
323
- reject: async (order, { paymentContext, deliveryContext }, unchainedAPI) => {
346
+ reject: async (order, transactionContext, unchainedAPI) => {
324
347
  const { modules } = unchainedAPI;
325
348
 
326
349
  if (order.status !== OrderStatus.PENDING) return order;
@@ -330,8 +353,7 @@ export const configureOrderModuleProcessing = ({
330
353
  return await modules.orders.processOrder(
331
354
  order,
332
355
  {
333
- paymentContext,
334
- deliveryContext,
356
+ ...transactionContext,
335
357
  nextStatus: OrderStatus.REJECTED,
336
358
  },
337
359
  unchainedAPI,
@@ -341,9 +363,14 @@ export const configureOrderModuleProcessing = ({
341
363
  }
342
364
  },
343
365
 
344
- processOrder: async (initialOrder, params, unchainedAPI) => {
366
+ processOrder: async (initialOrder, orderTransactionContext, unchainedAPI) => {
345
367
  const { modules } = unchainedAPI;
346
- const { paymentContext, deliveryContext, nextStatus: forceNextStatus } = params;
368
+ const {
369
+ paymentContext,
370
+ deliveryContext,
371
+ nextStatus: forceNextStatus,
372
+ comment,
373
+ } = orderTransactionContext;
347
374
 
348
375
  const orderId = initialOrder._id;
349
376
  let order = initialOrder;
@@ -393,7 +420,7 @@ export const configureOrderModuleProcessing = ({
393
420
  // numbers that are needed for delivery
394
421
  order = await updateStatus(orderId, {
395
422
  status: OrderStatus.CONFIRMED,
396
- info: 'before delivery',
423
+ info: comment,
397
424
  });
398
425
 
399
426
  const orderDelivery = await modules.orders.deliveries.findDelivery({
@@ -421,7 +448,7 @@ export const configureOrderModuleProcessing = ({
421
448
  }),
422
449
  );
423
450
  const tokenizedItems = mappedProductOrderPositions.filter(
424
- (item) => item.product?.type === ProductType.TokenizedProduct,
451
+ (item) => item.product?.type === ProductTypes.TokenizedProduct,
425
452
  );
426
453
  if (tokenizedItems.length > 0) {
427
454
  // Give virtual warehouse a chance to instantiate new virtual objects
@@ -436,7 +463,7 @@ export const configureOrderModuleProcessing = ({
436
463
 
437
464
  // Enrollments: Generate enrollments for plan products
438
465
  const planItems = mappedProductOrderPositions.filter(
439
- (item) => item.product?.type === ProductType.PlanProduct && !order.originEnrollmentId,
466
+ (item) => item.product?.type === ProductTypes.PlanProduct && !order.originEnrollmentId,
440
467
  );
441
468
  if (planItems.length > 0) {
442
469
  await modules.enrollments.createFromCheckout(
@@ -473,7 +500,7 @@ export const configureOrderModuleProcessing = ({
473
500
  nextStatus = await findNextStatus(nextStatus, order, unchainedAPI);
474
501
  }
475
502
 
476
- return updateStatus(order._id, { status: nextStatus, info: 'order processed' });
503
+ return updateStatus(order._id, { status: nextStatus, info: comment });
477
504
  },
478
505
 
479
506
  updateStatus,
@@ -1,5 +1,5 @@
1
- import { SortDirection, SortOption } from '@unchainedshop/types/api.js';
2
- import { Order, OrderQueries, OrderQuery, OrderStatus } from '@unchainedshop/types/orders.js';
1
+ import { SortDirection, SortOption } from '@unchainedshop/utils';
2
+ import { Order, OrderQuery, OrderReport } from '../types.js';
3
3
  import { generateDbFilterById, buildSortOptions, mongodb } from '@unchainedshop/mongodb';
4
4
 
5
5
  export const buildFindSelector = ({ includeCarts, status, userId, queryString }: OrderQuery) => {
@@ -9,8 +9,8 @@ export const buildFindSelector = ({ includeCarts, status, userId, queryString }:
9
9
  selector.userId = userId;
10
10
  }
11
11
 
12
- if (status) {
13
- selector.status = status as OrderStatus;
12
+ if (Array.isArray(status) && status?.length) {
13
+ selector.status = { $in: status };
14
14
  } else if (!includeCarts) {
15
15
  selector.status = { $ne: null }; // TODO: Slow performance! IDXSCAN in common query!
16
16
  }
@@ -22,23 +22,56 @@ export const buildFindSelector = ({ includeCarts, status, userId, queryString }:
22
22
  return selector;
23
23
  };
24
24
 
25
- export const configureOrdersModuleQueries = ({
26
- Orders,
27
- }: {
28
- Orders: mongodb.Collection<Order>;
29
- }): OrderQueries => {
25
+ const normalizeOrderAggregateResult = (data = {}): OrderReport => {
26
+ const statusToFieldMap = {
27
+ newCount: 0,
28
+ checkoutCount: 0,
29
+ rejectCount: 0,
30
+ confirmCount: 0,
31
+ fulfillCount: 0,
32
+ };
33
+
34
+ Object.entries(data).forEach(([key, value]) => {
35
+ statusToFieldMap[key] = value;
36
+ });
37
+ return statusToFieldMap;
38
+ };
39
+
40
+ export const configureOrdersModuleQueries = ({ Orders }: { Orders: mongodb.Collection<Order> }) => {
30
41
  return {
31
- count: async (query) => {
42
+ count: async (query: OrderQuery): Promise<number> => {
32
43
  const orderCount = await Orders.countDocuments(buildFindSelector(query));
33
44
  return orderCount;
34
45
  },
35
46
 
36
- findOrder: async ({ orderId, orderNumber }, options) => {
47
+ findOrder: async (
48
+ {
49
+ orderId,
50
+ orderNumber,
51
+ }: {
52
+ orderId?: string;
53
+ orderNumber?: string;
54
+ },
55
+ options?: mongodb.FindOptions,
56
+ ): Promise<Order> => {
37
57
  const selector = orderId ? generateDbFilterById(orderId) : { orderNumber };
38
58
  return Orders.findOne(selector, options);
39
59
  },
40
60
 
41
- findOrders: async ({ limit, offset, queryString, sort, ...query }, options) => {
61
+ findOrders: async (
62
+ {
63
+ limit,
64
+ offset,
65
+ queryString,
66
+ sort,
67
+ ...query
68
+ }: OrderQuery & {
69
+ limit?: number;
70
+ offset?: number;
71
+ sort?: Array<SortOption>;
72
+ },
73
+ options?: mongodb.FindOptions,
74
+ ): Promise<Array<Order>> => {
42
75
  const defaultSortOption: Array<SortOption> = [{ key: 'created', value: SortDirection.DESC }];
43
76
  const findOptions: mongodb.FindOptions = {
44
77
  skip: offset,
@@ -58,7 +91,80 @@ export const configureOrdersModuleQueries = ({
58
91
  return Orders.find(selector, findOptions).toArray();
59
92
  },
60
93
 
61
- orderExists: async ({ orderId }) => {
94
+ getReport: async (params?: { from?: Date; to?: Date }): Promise<OrderReport> => {
95
+ const { from, to } = params || {};
96
+ const selector: any = { $exists: true };
97
+ if (from || to) {
98
+ if (from) {
99
+ const fromDate = new Date(from);
100
+ selector.$gte = fromDate;
101
+ }
102
+ if (to) {
103
+ const toDate = new Date(to);
104
+ selector.$lte = toDate;
105
+ }
106
+ }
107
+
108
+ const pipeline = [
109
+ {
110
+ $facet: {
111
+ checkoutCount: [
112
+ {
113
+ $match: {
114
+ ordered: selector,
115
+ },
116
+ },
117
+ { $count: 'count' },
118
+ ],
119
+ fulfillCount: [
120
+ {
121
+ $match: {
122
+ fullfilled: selector,
123
+ },
124
+ },
125
+ { $count: 'count' },
126
+ ],
127
+ rejectCount: [
128
+ {
129
+ $match: {
130
+ rejected: selector,
131
+ },
132
+ },
133
+ { $count: 'count' },
134
+ ],
135
+ newCount: [
136
+ {
137
+ $match: {
138
+ created: selector,
139
+ },
140
+ },
141
+ { $count: 'count' },
142
+ ],
143
+ confirmCount: [
144
+ {
145
+ $match: {
146
+ confirmed: selector,
147
+ },
148
+ },
149
+ { $count: 'count' },
150
+ ],
151
+ },
152
+ },
153
+ {
154
+ $project: {
155
+ checkoutCount: { $arrayElemAt: ['$checkoutCount.count', 0] },
156
+ fulfillCount: { $arrayElemAt: ['$fulfillCount.count', 0] },
157
+ rejectCount: { $arrayElemAt: ['$rejectCount.count', 0] },
158
+ newCount: { $arrayElemAt: ['$newCount.count', 0] },
159
+ confirmCount: { $arrayElemAt: ['$confirmCount.count', 0] },
160
+ },
161
+ },
162
+ ];
163
+ const [facetedResult] = await Orders.aggregate(pipeline).toArray();
164
+ return normalizeOrderAggregateResult(facetedResult);
165
+ },
166
+
167
+ orderExists: async ({ orderId }: { orderId: string }): Promise<boolean> => {
62
168
  const orderCount = await Orders.countDocuments(generateDbFilterById(orderId), {
63
169
  limit: 1,
64
170
  });
@@ -66,3 +172,5 @@ export const configureOrdersModuleQueries = ({
66
172
  },
67
173
  };
68
174
  };
175
+
176
+ export type OrderQueries = ReturnType<typeof configureOrdersModuleQueries>;
@@ -1,10 +1,32 @@
1
- import { Order, OrderTransformations } from '@unchainedshop/types/orders.js';
1
+ import { Order, OrderDiscount } from '../types.js';
2
2
  import { mongodb } from '@unchainedshop/mongodb';
3
- import { DeliveryPricingRowCategory } from '@unchainedshop/types/delivery.pricing.js';
4
- import { PaymentPricingRowCategory } from '@unchainedshop/types/payments.pricing.js';
5
- import { ProductPricingRowCategory } from '@unchainedshop/types/products.pricing.js';
6
- import { OrderPricingRowCategory } from '@unchainedshop/types/orders.pricing.js';
7
- import { OrderPricingSheet } from '../director/OrderPricingSheet.js';
3
+ import { PaymentPricingRowCategory } from '@unchainedshop/core-payment';
4
+ import {
5
+ IOrderPricingSheet,
6
+ OrderPricingRowCategory,
7
+ OrderPricingSheet,
8
+ } from '../director/OrderPricingSheet.js';
9
+ import { UnchainedCore } from '@unchainedshop/core';
10
+ import { ProductPricingRowCategory } from '@unchainedshop/core-products';
11
+ import { DeliveryPricingRowCategory } from '@unchainedshop/core-delivery';
12
+ import { OrderPrice, OrderPricingDiscount } from '../director/OrderPricingDirector.js';
13
+
14
+ export interface OrderTransformations {
15
+ discounted: (
16
+ order: Order,
17
+ orderDiscount: OrderDiscount,
18
+ unchainedAPI: UnchainedCore,
19
+ ) => Promise<Array<OrderPricingDiscount>>;
20
+ discountTotal: (
21
+ order: Order,
22
+ orderDiscount: OrderDiscount,
23
+ unchainedAPI: UnchainedCore,
24
+ ) => Promise<OrderPrice>;
25
+
26
+ isCart: (order: Order) => boolean;
27
+ cart: (order: { countryContext?: string; orderNumber?: string; userId: string }) => Promise<Order>;
28
+ pricingSheet: (order: Order) => IOrderPricingSheet;
29
+ }
8
30
 
9
31
  export const configureOrderModuleTransformations = ({
10
32
  Orders,