@unchainedshop/core-orders 4.3.4 → 4.5.0

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 (84) hide show
  1. package/README.md +137 -3
  2. package/lib/db/OrderDeliveriesCollection.d.ts +8 -8
  3. package/lib/db/OrderDeliveriesCollection.js +6 -9
  4. package/lib/db/OrderDiscountsCollection.d.ts +7 -7
  5. package/lib/db/OrderDiscountsCollection.js +5 -8
  6. package/lib/db/OrderPaymentsCollection.d.ts +8 -8
  7. package/lib/db/OrderPaymentsCollection.js +6 -9
  8. package/lib/db/OrderPositionsCollection.d.ts +2 -3
  9. package/lib/db/OrderPositionsCollection.js +1 -3
  10. package/lib/db/OrdersCollection.d.ts +13 -10
  11. package/lib/db/OrdersCollection.js +7 -10
  12. package/lib/migrations/20250502111800-currency-code.d.ts +1 -2
  13. package/lib/migrations/20250502111800-currency-code.js +1 -2
  14. package/lib/module/buildFindSelector.d.ts +2 -3
  15. package/lib/module/buildFindSelector.js +6 -4
  16. package/lib/module/configureOrderDeliveriesModule.d.ts +2 -3
  17. package/lib/module/configureOrderDeliveriesModule.js +2 -7
  18. package/lib/module/configureOrderDiscountsModule.d.ts +1 -2
  19. package/lib/module/configureOrderDiscountsModule.js +2 -4
  20. package/lib/module/configureOrderPaymentsModule.d.ts +2 -3
  21. package/lib/module/configureOrderPaymentsModule.js +2 -9
  22. package/lib/module/configureOrderPositionsModule.d.ts +10 -3
  23. package/lib/module/configureOrderPositionsModule.js +48 -4
  24. package/lib/module/configureOrdersModule-mutations.d.ts +8 -4
  25. package/lib/module/configureOrdersModule-mutations.js +23 -3
  26. package/lib/module/configureOrdersModule-queries.d.ts +28 -4
  27. package/lib/module/configureOrdersModule-queries.js +127 -3
  28. package/lib/module/configureOrdersModule.d.ts +58 -40
  29. package/lib/module/configureOrdersModule.js +17 -23
  30. package/lib/orders-index.d.ts +13 -14
  31. package/lib/orders-index.js +13 -14
  32. package/lib/orders-settings.d.ts +1 -2
  33. package/lib/orders-settings.js +0 -1
  34. package/package.json +12 -10
  35. package/lib/db/OrderDeliveriesCollection.d.ts.map +0 -1
  36. package/lib/db/OrderDeliveriesCollection.js.map +0 -1
  37. package/lib/db/OrderDiscountsCollection.d.ts.map +0 -1
  38. package/lib/db/OrderDiscountsCollection.js.map +0 -1
  39. package/lib/db/OrderPaymentsCollection.d.ts.map +0 -1
  40. package/lib/db/OrderPaymentsCollection.js.map +0 -1
  41. package/lib/db/OrderPositionsCollection.d.ts.map +0 -1
  42. package/lib/db/OrderPositionsCollection.js.map +0 -1
  43. package/lib/db/OrdersCollection.d.ts.map +0 -1
  44. package/lib/db/OrdersCollection.js.map +0 -1
  45. package/lib/migrations/20250502111800-currency-code.d.ts.map +0 -1
  46. package/lib/migrations/20250502111800-currency-code.js.map +0 -1
  47. package/lib/module/buildFindSelector.d.ts.map +0 -1
  48. package/lib/module/buildFindSelector.js.map +0 -1
  49. package/lib/module/configureOrderDeliveriesModule.d.ts.map +0 -1
  50. package/lib/module/configureOrderDeliveriesModule.js.map +0 -1
  51. package/lib/module/configureOrderDiscountsModule.d.ts.map +0 -1
  52. package/lib/module/configureOrderDiscountsModule.js.map +0 -1
  53. package/lib/module/configureOrderPaymentsModule.d.ts.map +0 -1
  54. package/lib/module/configureOrderPaymentsModule.js.map +0 -1
  55. package/lib/module/configureOrderPositionsModule.d.ts.map +0 -1
  56. package/lib/module/configureOrderPositionsModule.js.map +0 -1
  57. package/lib/module/configureOrdersModule-mutations.d.ts.map +0 -1
  58. package/lib/module/configureOrdersModule-mutations.js.map +0 -1
  59. package/lib/module/configureOrdersModule-queries.d.ts.map +0 -1
  60. package/lib/module/configureOrdersModule-queries.js.map +0 -1
  61. package/lib/module/configureOrdersModule.d.ts.map +0 -1
  62. package/lib/module/configureOrdersModule.js.map +0 -1
  63. package/lib/orders-index.d.ts.map +0 -1
  64. package/lib/orders-index.js.map +0 -1
  65. package/lib/orders-settings.d.ts.map +0 -1
  66. package/lib/orders-settings.js.map +0 -1
  67. package/src/db/OrderDeliveriesCollection.ts +0 -34
  68. package/src/db/OrderDiscountsCollection.ts +0 -30
  69. package/src/db/OrderPaymentsCollection.ts +0 -35
  70. package/src/db/OrderPositionsCollection.ts +0 -32
  71. package/src/db/OrdersCollection.ts +0 -87
  72. package/src/migrations/20250502111800-currency-code.ts +0 -18
  73. package/src/module/buildFindSelector.test.ts +0 -121
  74. package/src/module/buildFindSelector.ts +0 -49
  75. package/src/module/configureOrderDeliveriesModule.ts +0 -157
  76. package/src/module/configureOrderDiscountsModule.ts +0 -95
  77. package/src/module/configureOrderPaymentsModule.ts +0 -224
  78. package/src/module/configureOrderPositionsModule.ts +0 -244
  79. package/src/module/configureOrdersModule-mutations.ts +0 -178
  80. package/src/module/configureOrdersModule-queries.ts +0 -159
  81. package/src/module/configureOrdersModule.ts +0 -257
  82. package/src/orders-index.ts +0 -13
  83. package/src/orders-settings.ts +0 -45
  84. package/tsconfig.json +0 -9
@@ -1,5 +1,5 @@
1
1
  import { emit, registerEvents } from '@unchainedshop/events';
2
- import { generateDbFilterById, generateDbObjectId } from '@unchainedshop/mongodb';
2
+ import { generateDbFilterById, generateDbObjectId, mongodb } from '@unchainedshop/mongodb';
3
3
  const ORDER_POSITION_EVENTS = [
4
4
  'ORDER_UPDATE_CART_ITEM',
5
5
  'ORDER_REMOVE_CART_ITEM',
@@ -10,7 +10,6 @@ export const buildFindOrderPositionByIdSelector = (orderPositionId, orderId) =>
10
10
  export const configureOrderPositionsModule = ({ OrderPositions, }) => {
11
11
  registerEvents(ORDER_POSITION_EVENTS);
12
12
  return {
13
- // Queries
14
13
  findOrderPosition: async ({ itemId }, options) => {
15
14
  return OrderPositions.findOne(buildFindOrderPositionByIdSelector(itemId), options);
16
15
  },
@@ -102,7 +101,6 @@ export const configureOrderPositionsModule = ({ OrderPositions, }) => {
102
101
  },
103
102
  addProductItem: async (orderPosition) => {
104
103
  const { configuration, orderId, originalProductId, productId, quantity, ...scope } = orderPosition;
105
- // Search for existing position
106
104
  const selector = {
107
105
  orderId,
108
106
  productId,
@@ -153,6 +151,52 @@ export const configureOrderPositionsModule = ({ OrderPositions, }) => {
153
151
  stages.push({ $limit: limit });
154
152
  return OrderPositions.aggregate(stages).toArray();
155
153
  },
154
+ getTopProducts: async (orderIds, options) => {
155
+ const limit = options?.limit || 10;
156
+ const pipeline = [
157
+ { $match: { orderId: { $in: orderIds } } },
158
+ {
159
+ $project: {
160
+ productId: 1,
161
+ quantity: 1,
162
+ itemAmount: {
163
+ $let: {
164
+ vars: {
165
+ item: {
166
+ $first: {
167
+ $filter: {
168
+ input: '$calculation',
169
+ as: 'c',
170
+ cond: { $eq: ['$$c.category', 'ITEM'] },
171
+ },
172
+ },
173
+ },
174
+ },
175
+ in: '$$item.amount',
176
+ },
177
+ },
178
+ },
179
+ },
180
+ {
181
+ $group: {
182
+ _id: '$productId',
183
+ totalSold: { $sum: '$quantity' },
184
+ totalRevenue: { $sum: '$itemAmount' },
185
+ },
186
+ },
187
+ { $match: { totalSold: { $gt: 0 } } },
188
+ { $sort: { totalSold: -1 } },
189
+ { $limit: limit },
190
+ {
191
+ $project: {
192
+ _id: 0,
193
+ productId: '$_id',
194
+ totalSold: 1,
195
+ totalRevenue: 1,
196
+ },
197
+ },
198
+ ];
199
+ return OrderPositions.aggregate(pipeline, { allowDiskUse: true }).toArray();
200
+ },
156
201
  };
157
202
  };
158
- //# sourceMappingURL=configureOrderPositionsModule.js.map
@@ -1,6 +1,6 @@
1
- import { Address, Contact, mongodb } from '@unchainedshop/mongodb';
2
- import { Order } from '../db/OrdersCollection.js';
3
- import { OrderPosition } from '../db/OrderPositionsCollection.js';
1
+ import { type Address, type Contact, mongodb } from '@unchainedshop/mongodb';
2
+ import { type Order } from '../db/OrdersCollection.ts';
3
+ import type { OrderPosition } from '../db/OrderPositionsCollection.ts';
4
4
  export declare const configureOrderModuleMutations: ({ Orders, OrderPositions, }: {
5
5
  Orders: mongodb.Collection<Order>;
6
6
  OrderPositions: mongodb.Collection<OrderPosition>;
@@ -28,6 +28,10 @@ export declare const configureOrderModuleMutations: ({ Orders, OrderPositions, }
28
28
  updateContact: (orderId: string, contact: Contact) => Promise<mongodb.WithId<Order> | null>;
29
29
  updateCalculationSheet: (orderId: string, calculation: any) => Promise<mongodb.WithId<Order> | null>;
30
30
  updateContext: (orderId: string, context: any) => Promise<mongodb.WithId<Order> | null>;
31
+ updateCartFields: (orderId: string, updates: {
32
+ meta?: any;
33
+ billingAddress?: Address;
34
+ contact?: Contact;
35
+ }) => Promise<Order | null>;
31
36
  };
32
37
  export type OrderMutations = ReturnType<typeof configureOrderModuleMutations>;
33
- //# sourceMappingURL=configureOrdersModule-mutations.d.ts.map
@@ -1,6 +1,6 @@
1
1
  import { emit, registerEvents } from '@unchainedshop/events';
2
- import { generateDbFilterById, generateDbObjectId, } from '@unchainedshop/mongodb';
3
- import { OrderStatus } from '../db/OrdersCollection.js';
2
+ import { generateDbFilterById, generateDbObjectId, mongodb, } from '@unchainedshop/mongodb';
3
+ import { OrderStatus } from "../db/OrdersCollection.js";
4
4
  const ORDER_EVENTS = [
5
5
  'ORDER_CREATE',
6
6
  'ORDER_REMOVE',
@@ -107,6 +107,26 @@ export const configureOrderModuleMutations = ({ Orders, OrderPositions, }) => {
107
107
  await emit('ORDER_UPDATE', { order, field: 'context' });
108
108
  return order;
109
109
  },
110
+ updateCartFields: async (orderId, updates) => {
111
+ const $set = { updated: new Date() };
112
+ if (updates.billingAddress) {
113
+ $set.billingAddress = updates.billingAddress;
114
+ }
115
+ if (updates.contact) {
116
+ $set.contact = updates.contact;
117
+ }
118
+ if (updates.meta && Object.keys(updates.meta).length > 0) {
119
+ const contextSetters = Object.fromEntries(Object.entries(updates.meta).map(([key, value]) => [`context.${key}`, value]));
120
+ Object.assign($set, contextSetters);
121
+ }
122
+ if (Object.keys($set).length === 1) {
123
+ return Orders.findOne(generateDbFilterById(orderId), {});
124
+ }
125
+ const order = await Orders.findOneAndUpdate(generateDbFilterById(orderId), { $set }, { returnDocument: 'after' });
126
+ if (!order)
127
+ return null;
128
+ await emit('ORDER_UPDATE', { order, field: 'cartFields' });
129
+ return order;
130
+ },
110
131
  };
111
132
  };
112
- //# sourceMappingURL=configureOrdersModule-mutations.js.map
@@ -1,6 +1,6 @@
1
- import { SortOption } from '@unchainedshop/utils';
1
+ import { type SortOption } from '@unchainedshop/utils';
2
2
  import { mongodb } from '@unchainedshop/mongodb';
3
- import { Order, OrderQuery } from '../db/OrdersCollection.js';
3
+ import { type Order, type OrderQuery } from '../db/OrdersCollection.ts';
4
4
  export interface OrderReport {
5
5
  newCount: number;
6
6
  checkoutCount: number;
@@ -8,13 +8,27 @@ export interface OrderReport {
8
8
  confirmCount: number;
9
9
  fulfillCount: number;
10
10
  }
11
+ export interface TopCustomerRecord {
12
+ userId: string;
13
+ currencyCode: string;
14
+ totalSpent: number;
15
+ orderCount: number;
16
+ lastOrderDate: Date;
17
+ averageOrderValue: number;
18
+ }
11
19
  export interface OrderStatisticsRecord {
12
20
  date: string;
21
+ count: number;
13
22
  total: {
14
23
  amount: number;
15
- currency: string;
24
+ currencyCode: string;
16
25
  };
17
26
  }
27
+ export interface DateRange {
28
+ start?: string;
29
+ end?: string;
30
+ }
31
+ export type StatisticsDateField = 'created' | 'ordered' | 'rejected' | 'confirmed' | 'fullfilled';
18
32
  export interface OrderAggregateParams {
19
33
  match?: Record<string, any>;
20
34
  matchAfterGroup?: Record<string, any>;
@@ -49,6 +63,16 @@ export declare const configureOrdersModuleQueries: ({ Orders }: {
49
63
  orderId: string;
50
64
  }) => Promise<boolean>;
51
65
  aggregateOrders: ({ match, project, group, sort, limit, addFields, pipeline, }: OrderAggregateParams) => Promise<mongodb.Document[]>;
66
+ statistics: {
67
+ countByDateField(dateField: StatisticsDateField, dateRange?: DateRange, options?: {
68
+ includeCarts?: boolean;
69
+ }): Promise<number>;
70
+ aggregateByDateField(dateField: StatisticsDateField, dateRange?: DateRange, options?: {
71
+ includeCarts?: boolean;
72
+ }): Promise<OrderStatisticsRecord[]>;
73
+ getTopCustomers(orderIds: string[], options?: {
74
+ limit?: number;
75
+ }): Promise<TopCustomerRecord[]>;
76
+ };
52
77
  };
53
78
  export type OrderQueries = ReturnType<typeof configureOrdersModuleQueries>;
54
- //# sourceMappingURL=configureOrdersModule-queries.d.ts.map
@@ -1,6 +1,17 @@
1
1
  import { SortDirection } from '@unchainedshop/utils';
2
- import { generateDbFilterById, buildSortOptions } from '@unchainedshop/mongodb';
3
- import buildFindSelector from './buildFindSelector.js';
2
+ import { generateDbFilterById, buildSortOptions, mongodb } from '@unchainedshop/mongodb';
3
+ import buildFindSelector from "./buildFindSelector.js";
4
+ import {} from "../db/OrdersCollection.js";
5
+ function buildDateMatch(dateField, dateRange) {
6
+ if (!dateRange?.start && !dateRange?.end)
7
+ return { [dateField]: { $exists: true } };
8
+ const rangeMatch = {};
9
+ if (dateRange?.start)
10
+ rangeMatch.$gte = new Date(dateRange.start);
11
+ if (dateRange?.end)
12
+ rangeMatch.$lte = new Date(dateRange.end);
13
+ return { [dateField]: rangeMatch };
14
+ }
4
15
  export const configureOrdersModuleQueries = ({ Orders }) => {
5
16
  return {
6
17
  isCart: (order) => {
@@ -81,6 +92,119 @@ export const configureOrdersModuleQueries = ({ Orders }) => {
81
92
  stages.push({ $limit: limit });
82
93
  return Orders.aggregate(stages, { allowDiskUse: true }).toArray();
83
94
  },
95
+ statistics: {
96
+ async countByDateField(dateField, dateRange, options) {
97
+ const match = buildDateMatch(dateField, dateRange);
98
+ if (options?.includeCarts) {
99
+ match.status = null;
100
+ match.orderNumber = null;
101
+ }
102
+ const pipeline = [{ $match: match }, { $count: 'count' }];
103
+ const result = await Orders.aggregate(pipeline).toArray();
104
+ return result[0]?.count ?? 0;
105
+ },
106
+ async aggregateByDateField(dateField, dateRange, options) {
107
+ const match = buildDateMatch(dateField, dateRange);
108
+ if (options?.includeCarts) {
109
+ match.status = null;
110
+ match.orderNumber = null;
111
+ }
112
+ const pipeline = [
113
+ { $match: match },
114
+ {
115
+ $addFields: {
116
+ orderTotal: {
117
+ $reduce: {
118
+ input: { $ifNull: ['$calculation', []] },
119
+ initialValue: 0,
120
+ in: { $add: ['$$value', { $ifNull: ['$$this.amount', 0] }] },
121
+ },
122
+ },
123
+ },
124
+ },
125
+ {
126
+ $group: {
127
+ _id: {
128
+ date: { $dateToString: { format: '%Y-%m-%d', date: `$${dateField}` } },
129
+ currency: '$currencyCode',
130
+ },
131
+ totalAmount: { $sum: '$orderTotal' },
132
+ count: { $sum: 1 },
133
+ },
134
+ },
135
+ {
136
+ $project: {
137
+ _id: 0,
138
+ date: '$_id.date',
139
+ total: { amount: '$totalAmount', currencyCode: '$_id.currency' },
140
+ count: 1,
141
+ },
142
+ },
143
+ { $sort: { date: 1 } },
144
+ ];
145
+ return Orders.aggregate(pipeline).toArray();
146
+ },
147
+ async getTopCustomers(orderIds, options) {
148
+ const limit = options?.limit || 10;
149
+ const pipeline = [
150
+ { $match: { _id: { $in: orderIds } } },
151
+ {
152
+ $project: {
153
+ userId: 1,
154
+ created: 1,
155
+ currencyCode: 1,
156
+ itemAmount: {
157
+ $let: {
158
+ vars: {
159
+ item: {
160
+ $first: {
161
+ $filter: {
162
+ input: '$calculation',
163
+ as: 'c',
164
+ cond: { $eq: ['$$c.category', 'ITEMS'] },
165
+ },
166
+ },
167
+ },
168
+ },
169
+ in: '$$item.amount',
170
+ },
171
+ },
172
+ },
173
+ },
174
+ {
175
+ $group: {
176
+ _id: { userId: '$userId', currencyCode: '$currencyCode' },
177
+ totalSpent: { $sum: '$itemAmount' },
178
+ orderCount: { $sum: 1 },
179
+ lastOrderDate: { $max: '$created' },
180
+ },
181
+ },
182
+ { $match: { totalSpent: { $gt: 0 } } },
183
+ {
184
+ $addFields: {
185
+ averageOrderValue: {
186
+ $cond: [{ $eq: ['$orderCount', 0] }, 0, { $divide: ['$totalSpent', '$orderCount'] }],
187
+ },
188
+ currencyCode: '$_id.currencyCode',
189
+ userId: '$_id.userId',
190
+ },
191
+ },
192
+ { $sort: { totalSpent: -1 } },
193
+ { $limit: limit },
194
+ {
195
+ $project: {
196
+ _id: 0,
197
+ userId: 1,
198
+ currencyCode: 1,
199
+ totalSpent: 1,
200
+ orderCount: 1,
201
+ lastOrderDate: 1,
202
+ averageOrderValue: 1,
203
+ },
204
+ },
205
+ ];
206
+ return Orders.aggregate(pipeline, { allowDiskUse: true }).toArray();
207
+ },
208
+ },
84
209
  };
85
210
  };
86
- //# sourceMappingURL=configureOrdersModule-queries.js.map
@@ -1,53 +1,53 @@
1
- import { ModuleInput, mongodb } from '@unchainedshop/mongodb';
2
- import { Order, OrderStatus } from '../db/OrdersCollection.js';
3
- import { OrdersSettingsOptions } from '../orders-settings.js';
1
+ import { type ModuleInput, mongodb } from '@unchainedshop/mongodb';
2
+ import { type Order, OrderStatus } from '../db/OrdersCollection.ts';
3
+ import { type OrdersSettingsOptions } from '../orders-settings.ts';
4
4
  export declare const configureOrdersModule: ({ db, migrationRepository, options: orderOptions, }: ModuleInput<OrdersSettingsOptions>) => Promise<{
5
5
  deliveries: {
6
6
  findDelivery: ({ orderDeliveryId }: {
7
7
  orderDeliveryId: string;
8
- }, options?: mongodb.FindOptions) => Promise<import("../db/OrderDeliveriesCollection.js").OrderDelivery | null>;
8
+ }, options?: mongodb.FindOptions) => Promise<import("../db/OrderDeliveriesCollection.ts").OrderDelivery | null>;
9
9
  findDeliveryByProvidersId: ({ deliveryProviderIds }: {
10
10
  deliveryProviderIds: string[];
11
- }, options?: mongodb.FindOptions) => Promise<import("../db/OrderDeliveriesCollection.js").OrderDelivery[]>;
12
- normalizedStatus: (orderDelivery: import("../db/OrderDeliveriesCollection.js").OrderDelivery) => import("../db/OrderDeliveriesCollection.js").OrderDeliveryStatus;
13
- create: (doc: Omit<import("../db/OrderDeliveriesCollection.js").OrderDelivery, "_id" | "created"> & Pick<Partial<import("../db/OrderDeliveriesCollection.js").OrderDelivery>, "_id" | "created">) => Promise<import("../db/OrderDeliveriesCollection.js").OrderDelivery>;
11
+ }, options?: mongodb.FindOptions) => Promise<import("../db/OrderDeliveriesCollection.ts").OrderDelivery[]>;
12
+ normalizedStatus: (orderDelivery: import("../db/OrderDeliveriesCollection.ts").OrderDelivery) => import("../db/OrderDeliveriesCollection.ts").OrderDeliveryStatus;
13
+ create: (doc: Omit<import("../db/OrderDeliveriesCollection.ts").OrderDelivery, "_id" | "created"> & Pick<Partial<import("../db/OrderDeliveriesCollection.ts").OrderDelivery>, "_id" | "created">) => Promise<import("../db/OrderDeliveriesCollection.ts").OrderDelivery>;
14
14
  delete: (orderDeliveryId: string) => Promise<number>;
15
- markAsDelivered: (orderDelivery: import("../db/OrderDeliveriesCollection.js").OrderDelivery) => Promise<mongodb.WithId<import("../db/OrderDeliveriesCollection.js").OrderDelivery> | null | undefined>;
16
- updateContext: (orderDeliveryId: string, context: any) => Promise<mongodb.WithId<import("../db/OrderDeliveriesCollection.js").OrderDelivery> | null>;
15
+ markAsDelivered: (orderDelivery: import("../db/OrderDeliveriesCollection.ts").OrderDelivery) => Promise<mongodb.WithId<import("../db/OrderDeliveriesCollection.ts").OrderDelivery> | null | undefined>;
16
+ updateContext: (orderDeliveryId: string, context: any) => Promise<mongodb.WithId<import("../db/OrderDeliveriesCollection.ts").OrderDelivery> | null>;
17
17
  updateStatus: (orderDeliveryId: string, { status, info }: {
18
- status: import("../db/OrderDeliveriesCollection.js").OrderDeliveryStatus;
18
+ status: import("../db/OrderDeliveriesCollection.ts").OrderDeliveryStatus;
19
19
  info?: string;
20
- }) => Promise<mongodb.WithId<import("../db/OrderDeliveriesCollection.js").OrderDelivery> | null>;
21
- updateCalculation: <T extends import("@unchainedshop/utils").PricingCalculation>(orderDeliveryId: string, calculation: T[]) => Promise<mongodb.WithId<import("../db/OrderDeliveriesCollection.js").OrderDelivery> | null>;
20
+ }) => Promise<mongodb.WithId<import("../db/OrderDeliveriesCollection.ts").OrderDelivery> | null>;
21
+ updateCalculation: <T extends import("@unchainedshop/utils").PricingCalculation>(orderDeliveryId: string, calculation: T[]) => Promise<mongodb.WithId<import("../db/OrderDeliveriesCollection.ts").OrderDelivery> | null>;
22
22
  deleteOrderDeliveries: (orderId: string) => Promise<number>;
23
23
  };
24
24
  discounts: {
25
25
  findOrderDiscount: ({ discountId }: {
26
26
  discountId: string;
27
- }, options?: mongodb.FindOptions) => Promise<import("../db/OrderDiscountsCollection.js").OrderDiscount | null>;
27
+ }, options?: mongodb.FindOptions) => Promise<import("../db/OrderDiscountsCollection.ts").OrderDiscount | null>;
28
28
  findOrderDiscounts: ({ orderId }: {
29
29
  orderId: string;
30
- }) => Promise<import("../db/OrderDiscountsCollection.js").OrderDiscount[]>;
31
- create: (doc: Omit<import("../db/OrderDiscountsCollection.js").OrderDiscount, "_id" | "created" | "trigger"> & Pick<Partial<import("../db/OrderDiscountsCollection.js").OrderDiscount>, "_id" | "created" | "trigger">) => Promise<import("../db/OrderDiscountsCollection.js").OrderDiscount>;
32
- delete: (orderDiscountId: string) => Promise<mongodb.WithId<import("../db/OrderDiscountsCollection.js").OrderDiscount> | null>;
30
+ }) => Promise<import("../db/OrderDiscountsCollection.ts").OrderDiscount[]>;
31
+ create: (doc: Omit<import("../db/OrderDiscountsCollection.ts").OrderDiscount, "_id" | "created" | "trigger"> & Pick<Partial<import("../db/OrderDiscountsCollection.ts").OrderDiscount>, "_id" | "created" | "trigger">) => Promise<import("../db/OrderDiscountsCollection.ts").OrderDiscount>;
32
+ delete: (orderDiscountId: string) => Promise<mongodb.WithId<import("../db/OrderDiscountsCollection.ts").OrderDiscount> | null>;
33
33
  isDiscountCodeUsed: ({ code, orderId }: {
34
34
  code: any;
35
35
  orderId: any;
36
36
  }) => Promise<boolean>;
37
37
  findSpareDiscount: ({ code }: {
38
38
  code: any;
39
- }) => Promise<mongodb.WithId<import("../db/OrderDiscountsCollection.js").OrderDiscount> | null>;
40
- update: (orderDiscountId: string, doc: Partial<import("../db/OrderDiscountsCollection.js").OrderDiscount>) => Promise<mongodb.WithId<import("../db/OrderDiscountsCollection.js").OrderDiscount> | null>;
39
+ }) => Promise<mongodb.WithId<import("../db/OrderDiscountsCollection.ts").OrderDiscount> | null>;
40
+ update: (orderDiscountId: string, doc: Partial<import("../db/OrderDiscountsCollection.ts").OrderDiscount>) => Promise<mongodb.WithId<import("../db/OrderDiscountsCollection.ts").OrderDiscount> | null>;
41
41
  deleteOrderDiscounts: (orderId: string) => Promise<number>;
42
42
  };
43
43
  positions: {
44
44
  findOrderPosition: ({ itemId }: {
45
45
  itemId: string;
46
- }, options?: mongodb.FindOptions) => Promise<import("../db/OrderPositionsCollection.js").OrderPosition | null>;
46
+ }, options?: mongodb.FindOptions) => Promise<import("../db/OrderPositionsCollection.ts").OrderPosition | null>;
47
47
  findOrderPositions: ({ orderId }: {
48
48
  orderId: string;
49
- }) => Promise<import("../db/OrderPositionsCollection.js").OrderPosition[]>;
50
- delete: (orderPositionId: string) => Promise<mongodb.WithId<import("../db/OrderPositionsCollection.js").OrderPosition> | null>;
49
+ }) => Promise<import("../db/OrderPositionsCollection.ts").OrderPosition[]>;
50
+ delete: (orderPositionId: string) => Promise<mongodb.WithId<import("../db/OrderPositionsCollection.ts").OrderPosition> | null>;
51
51
  removePositions: ({ orderId }: {
52
52
  orderId: string;
53
53
  }) => Promise<number>;
@@ -58,10 +58,10 @@ export declare const configureOrdersModule: ({ db, migrationRepository, options:
58
58
  value: string;
59
59
  }[] | null;
60
60
  quantity: number | null;
61
- }) => Promise<mongodb.WithId<import("../db/OrderPositionsCollection.js").OrderPosition> | null>;
61
+ }) => Promise<mongodb.WithId<import("../db/OrderPositionsCollection.ts").OrderPosition> | null>;
62
62
  removeProductByIdFromAllOpenPositions: (productId: string) => Promise<string[]>;
63
- updateScheduling: (orderPositionId: any, scheduling: any) => Promise<mongodb.WithId<import("../db/OrderPositionsCollection.js").OrderPosition> | null>;
64
- updateCalculation: <T extends import("@unchainedshop/utils").PricingCalculation>(orderPositionId: string, calculation: T[]) => Promise<mongodb.WithId<import("../db/OrderPositionsCollection.js").OrderPosition> | null>;
63
+ updateScheduling: (orderPositionId: any, scheduling: any) => Promise<mongodb.WithId<import("../db/OrderPositionsCollection.ts").OrderPosition> | null>;
64
+ updateCalculation: <T extends import("@unchainedshop/utils").PricingCalculation>(orderPositionId: string, calculation: T[]) => Promise<mongodb.WithId<import("../db/OrderPositionsCollection.ts").OrderPosition> | null>;
65
65
  addProductItem: (orderPosition: {
66
66
  context?: any;
67
67
  configuration?: {
@@ -73,34 +73,37 @@ export declare const configureOrdersModule: ({ db, migrationRepository, options:
73
73
  productId: string;
74
74
  quantity: number;
75
75
  quotationId?: string;
76
- }) => Promise<import("../db/OrderPositionsCollection.js").OrderPosition>;
76
+ }) => Promise<import("../db/OrderPositionsCollection.ts").OrderPosition>;
77
77
  deleteOrderPositions: (orderId: string) => Promise<number>;
78
- aggregatePositions: ({ match, project, group, addFields, sort, limit, pipeline, }: import("./configureOrderPositionsModule.js").OrderPositionAggregateParams) => Promise<mongodb.Document[]>;
78
+ aggregatePositions: ({ match, project, group, addFields, sort, limit, pipeline, }: import("./configureOrderPositionsModule.ts").OrderPositionAggregateParams) => Promise<mongodb.Document[]>;
79
+ getTopProducts: (orderIds: string[], options?: {
80
+ limit?: number;
81
+ }) => Promise<import("./configureOrderPositionsModule.ts").TopProductRecord[]>;
79
82
  };
80
83
  payments: {
81
84
  findOrderPayment: ({ orderPaymentId, }: {
82
85
  orderPaymentId: string;
83
- }, options?: mongodb.FindOptions) => Promise<import("../db/OrderPaymentsCollection.js").OrderPayment | null>;
86
+ }, options?: mongodb.FindOptions) => Promise<import("../db/OrderPaymentsCollection.ts").OrderPayment | null>;
84
87
  findOrderPaymentsByProviderIds: ({ paymentProviderIds, }: {
85
88
  paymentProviderIds: string[];
86
- }, options?: mongodb.FindOptions) => Promise<import("../db/OrderPaymentsCollection.js").OrderPayment[]>;
89
+ }, options?: mongodb.FindOptions) => Promise<import("../db/OrderPaymentsCollection.ts").OrderPayment[]>;
87
90
  findOrderPaymentByContextData: ({ context, }: {
88
91
  context: any;
89
- }, options?: mongodb.FindOptions) => Promise<import("../db/OrderPaymentsCollection.js").OrderPayment | null>;
92
+ }, options?: mongodb.FindOptions) => Promise<import("../db/OrderPaymentsCollection.ts").OrderPayment | null>;
90
93
  countOrderPaymentsByContextData: ({ context, }: {
91
94
  context: any;
92
95
  }, options?: mongodb.FindOptions) => Promise<number>;
93
- normalizedStatus: (orderPayment: import("../db/OrderPaymentsCollection.js").OrderPayment) => import("../db/OrderPaymentsCollection.js").OrderPaymentStatus;
94
- create: (doc: Omit<import("../db/OrderPaymentsCollection.js").OrderPayment, "_id" | "created"> & Pick<Partial<import("../db/OrderPaymentsCollection.js").OrderPayment>, "_id" | "created">) => Promise<import("../db/OrderPaymentsCollection.js").OrderPayment>;
96
+ normalizedStatus: (orderPayment: import("../db/OrderPaymentsCollection.ts").OrderPayment) => import("../db/OrderPaymentsCollection.ts").OrderPaymentStatus;
97
+ create: (doc: Omit<import("../db/OrderPaymentsCollection.ts").OrderPayment, "_id" | "created"> & Pick<Partial<import("../db/OrderPaymentsCollection.ts").OrderPayment>, "_id" | "created">) => Promise<import("../db/OrderPaymentsCollection.ts").OrderPayment>;
95
98
  logEvent: (orderPaymentId: string, event: any) => Promise<boolean>;
96
- markAsPaid: (orderPayment: import("../db/OrderPaymentsCollection.js").OrderPayment, meta: any) => Promise<void>;
97
- updateContext: (orderPaymentId: string, context: any) => Promise<mongodb.WithId<import("../db/OrderPaymentsCollection.js").OrderPayment> | null>;
99
+ markAsPaid: (orderPayment: import("../db/OrderPaymentsCollection.ts").OrderPayment, meta: any) => Promise<void>;
100
+ updateContext: (orderPaymentId: string, context: any) => Promise<mongodb.WithId<import("../db/OrderPaymentsCollection.ts").OrderPayment> | null>;
98
101
  updateStatus: (orderPaymentId: string, { transactionId, status, info, }: {
99
102
  transactionId?: string;
100
- status: import("../db/OrderPaymentsCollection.js").OrderPaymentStatus;
103
+ status: import("../db/OrderPaymentsCollection.ts").OrderPaymentStatus;
101
104
  info?: string;
102
- }) => Promise<mongodb.WithId<import("../db/OrderPaymentsCollection.js").OrderPayment> | null>;
103
- updateCalculation: <T extends import("@unchainedshop/utils").PricingCalculation>(orderPaymentId: string, calculation: T[]) => Promise<mongodb.WithId<import("../db/OrderPaymentsCollection.js").OrderPayment> | null>;
105
+ }) => Promise<mongodb.WithId<import("../db/OrderPaymentsCollection.ts").OrderPayment> | null>;
106
+ updateCalculation: <T extends import("@unchainedshop/utils").PricingCalculation>(orderPaymentId: string, calculation: T[]) => Promise<mongodb.WithId<import("../db/OrderPaymentsCollection.ts").OrderPayment> | null>;
104
107
  deleteOrderPayments: (orderId: string) => Promise<number>;
105
108
  };
106
109
  updateStatus: (orderId: string, { status, info }: {
@@ -133,19 +136,24 @@ export declare const configureOrdersModule: ({ db, migrationRepository, options:
133
136
  updateContact: (orderId: string, contact: import("@unchainedshop/mongodb").Contact) => Promise<mongodb.WithId<Order> | null>;
134
137
  updateCalculationSheet: (orderId: string, calculation: any) => Promise<mongodb.WithId<Order> | null>;
135
138
  updateContext: (orderId: string, context: any) => Promise<mongodb.WithId<Order> | null>;
139
+ updateCartFields: (orderId: string, updates: {
140
+ meta?: any;
141
+ billingAddress?: import("@unchainedshop/mongodb").Address;
142
+ contact?: import("@unchainedshop/mongodb").Contact;
143
+ }) => Promise<Order | null>;
136
144
  isCart: (order: Order) => boolean;
137
145
  cart: ({ orderNumber, countryCode, userId, }: {
138
146
  countryCode?: string;
139
147
  orderNumber?: string;
140
148
  userId: string;
141
149
  }) => Promise<mongodb.WithId<Order> | null>;
142
- count: (query: import("../db/OrdersCollection.js").OrderQuery) => Promise<number>;
150
+ count: (query: import("../db/OrdersCollection.ts").OrderQuery) => Promise<number>;
143
151
  findOrder: ({ orderId, orderNumber, }: {
144
152
  orderId?: string;
145
153
  orderNumber?: string;
146
154
  }, options?: mongodb.FindOptions) => Promise<Order | null>;
147
155
  findCartsToInvalidate: (maxAgeDays?: number) => Promise<mongodb.WithId<Order>[]>;
148
- findOrders: ({ limit, offset, queryString, sort, ...query }: import("../db/OrdersCollection.js").OrderQuery & {
156
+ findOrders: ({ limit, offset, queryString, sort, ...query }: import("../db/OrdersCollection.ts").OrderQuery & {
149
157
  limit?: number;
150
158
  offset?: number;
151
159
  sort?: import("@unchainedshop/utils").SortOption[];
@@ -153,7 +161,17 @@ export declare const configureOrdersModule: ({ db, migrationRepository, options:
153
161
  orderExists: ({ orderId }: {
154
162
  orderId: string;
155
163
  }) => Promise<boolean>;
156
- aggregateOrders: ({ match, project, group, sort, limit, addFields, pipeline, }: import("./configureOrdersModule-queries.js").OrderAggregateParams) => Promise<mongodb.Document[]>;
164
+ aggregateOrders: ({ match, project, group, sort, limit, addFields, pipeline, }: import("./configureOrdersModule-queries.ts").OrderAggregateParams) => Promise<mongodb.Document[]>;
165
+ statistics: {
166
+ countByDateField(dateField: import("./configureOrdersModule-queries.ts").StatisticsDateField, dateRange?: import("./configureOrdersModule-queries.ts").DateRange, options?: {
167
+ includeCarts?: boolean;
168
+ }): Promise<number>;
169
+ aggregateByDateField(dateField: import("./configureOrdersModule-queries.ts").StatisticsDateField, dateRange?: import("./configureOrdersModule-queries.ts").DateRange, options?: {
170
+ includeCarts?: boolean;
171
+ }): Promise<import("./configureOrdersModule-queries.ts").OrderStatisticsRecord[]>;
172
+ getTopCustomers(orderIds: string[], options?: {
173
+ limit?: number;
174
+ }): Promise<import("./configureOrdersModule-queries.ts").TopCustomerRecord[]>;
175
+ };
157
176
  }>;
158
177
  export type OrdersModule = Awaited<ReturnType<typeof configureOrdersModule>>;
159
- //# sourceMappingURL=configureOrdersModule.d.ts.map
@@ -1,20 +1,19 @@
1
- import { generateDbFilterById } from '@unchainedshop/mongodb';
1
+ import { generateDbFilterById, mongodb } from '@unchainedshop/mongodb';
2
2
  import { createRequire } from 'node:module';
3
- import { OrderDeliveriesCollection } from '../db/OrderDeliveriesCollection.js';
4
- import { OrderDiscountsCollection } from '../db/OrderDiscountsCollection.js';
5
- import { OrderPaymentsCollection } from '../db/OrderPaymentsCollection.js';
6
- import { OrderPositionsCollection } from '../db/OrderPositionsCollection.js';
7
- import { OrdersCollection, OrderStatus } from '../db/OrdersCollection.js';
8
- import { ordersSettings } from '../orders-settings.js';
9
- import { configureOrderDeliveriesModule } from './configureOrderDeliveriesModule.js';
10
- import { configureOrderDiscountsModule } from './configureOrderDiscountsModule.js';
11
- import { configureOrderPaymentsModule } from './configureOrderPaymentsModule.js';
12
- import { configureOrderPositionsModule } from './configureOrderPositionsModule.js';
13
- import { configureOrderModuleMutations } from './configureOrdersModule-mutations.js';
14
- import { configureOrdersModuleQueries } from './configureOrdersModule-queries.js';
3
+ import { OrderDeliveriesCollection } from "../db/OrderDeliveriesCollection.js";
4
+ import { OrderDiscountsCollection } from "../db/OrderDiscountsCollection.js";
5
+ import { OrderPaymentsCollection } from "../db/OrderPaymentsCollection.js";
6
+ import { OrderPositionsCollection } from "../db/OrderPositionsCollection.js";
7
+ import { OrdersCollection, OrderStatus } from "../db/OrdersCollection.js";
8
+ import { ordersSettings } from "../orders-settings.js";
9
+ import { configureOrderDeliveriesModule } from "./configureOrderDeliveriesModule.js";
10
+ import { configureOrderDiscountsModule } from "./configureOrderDiscountsModule.js";
11
+ import { configureOrderPaymentsModule } from "./configureOrderPaymentsModule.js";
12
+ import { configureOrderPositionsModule } from "./configureOrderPositionsModule.js";
13
+ import { configureOrderModuleMutations } from "./configureOrdersModule-mutations.js";
14
+ import { configureOrdersModuleQueries } from "./configureOrdersModule-queries.js";
15
15
  import { emit, registerEvents } from '@unchainedshop/events';
16
- import renameCurrencyCode from '../migrations/20250502111800-currency-code.js';
17
- // @kontsedal/locco uses a deprecated way of importing files in ESM (node16 behavior)
16
+ import renameCurrencyCode from "../migrations/20250502111800-currency-code.js";
18
17
  const require = createRequire(import.meta.url);
19
18
  const { Locker, MongoAdapter } = require('@kontsedal/locco');
20
19
  const ORDER_EVENTS = [
@@ -24,7 +23,6 @@ const ORDER_EVENTS = [
24
23
  'ORDER_FULLFILLED',
25
24
  ];
26
25
  export const configureOrdersModule = async ({ db, migrationRepository, options: orderOptions = {}, }) => {
27
- // Migration v3 -> v4
28
26
  renameCurrencyCode(migrationRepository);
29
27
  registerEvents(ORDER_EVENTS);
30
28
  ordersSettings.configureSettings(orderOptions);
@@ -69,7 +67,6 @@ export const configureOrdersModule = async ({ db, migrationRepository, options:
69
67
  return {
70
68
  ...orderQueries,
71
69
  ...orderMutations,
72
- // Subentities
73
70
  deliveries: orderDeliveriesModule,
74
71
  discounts: orderDiscountsModule,
75
72
  positions: orderPositionsModule,
@@ -87,10 +84,9 @@ export const configureOrdersModule = async ({ db, migrationRepository, options:
87
84
  updated: new Date(),
88
85
  };
89
86
  switch (status) {
90
- // explicitly use fallthrough here!
91
87
  case OrderStatus.FULLFILLED:
92
88
  $set.fullfilled = order.fullfilled || date;
93
- case OrderStatus.REJECTED: // eslint-disable-line no-fallthrough
89
+ case OrderStatus.REJECTED:
94
90
  case OrderStatus.CONFIRMED:
95
91
  if (status === OrderStatus.REJECTED) {
96
92
  $set.rejected = order.rejected || date;
@@ -98,7 +94,7 @@ export const configureOrdersModule = async ({ db, migrationRepository, options:
98
94
  else {
99
95
  $set.confirmed = order.confirmed || date;
100
96
  }
101
- case OrderStatus.PENDING: // eslint-disable-line no-fallthrough
97
+ case OrderStatus.PENDING:
102
98
  $set.ordered = order.ordered || date;
103
99
  $set.orderNumber = order.orderNumber || (await findNewOrderNumber(order));
104
100
  break;
@@ -117,14 +113,13 @@ export const configureOrdersModule = async ({ db, migrationRepository, options:
117
113
  };
118
114
  const modificationResult = await Orders.findOneAndUpdate({
119
115
  ...selector,
120
- status: { $ne: status }, // Only update if status is different
116
+ status: { $ne: status },
121
117
  }, modifier, {
122
118
  returnDocument: 'after',
123
119
  includeResultMetadata: true,
124
120
  });
125
121
  if (modificationResult.ok) {
126
122
  if (order.status === null) {
127
- // The first time that an order transitions away from cart is a checkout event
128
123
  await emit('ORDER_CHECKOUT', { order: modificationResult.value, oldStatus: order.status });
129
124
  }
130
125
  switch (status) {
@@ -199,4 +194,3 @@ export const configureOrdersModule = async ({ db, migrationRepository, options:
199
194
  },
200
195
  };
201
196
  };
202
- //# sourceMappingURL=configureOrdersModule.js.map