@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.
- package/lib/db/OrderDeliveriesCollection.d.ts +21 -2
- package/lib/db/OrderDeliveriesCollection.d.ts.map +1 -1
- package/lib/db/OrderDeliveriesCollection.js +6 -0
- package/lib/db/OrderDeliveriesCollection.js.map +1 -1
- package/lib/db/OrderDiscountsCollection.d.ts +16 -2
- package/lib/db/OrderDiscountsCollection.d.ts.map +1 -1
- package/lib/db/OrderDiscountsCollection.js +5 -0
- package/lib/db/OrderDiscountsCollection.js.map +1 -1
- package/lib/db/OrderPaymentsCollection.d.ts +22 -2
- package/lib/db/OrderPaymentsCollection.d.ts.map +1 -1
- package/lib/db/OrderPaymentsCollection.js +6 -0
- package/lib/db/OrderPaymentsCollection.js.map +1 -1
- package/lib/db/OrderPositionsCollection.d.ts +22 -2
- package/lib/db/OrderPositionsCollection.d.ts.map +1 -1
- package/lib/db/OrderPositionsCollection.js.map +1 -1
- package/lib/db/OrdersCollection.d.ts +33 -2
- package/lib/db/OrdersCollection.d.ts.map +1 -1
- package/lib/db/OrdersCollection.js +8 -1
- package/lib/db/OrdersCollection.js.map +1 -1
- package/lib/module/buildFindSelector.d.ts +5 -0
- package/lib/module/buildFindSelector.d.ts.map +1 -0
- package/lib/module/buildFindSelector.js +18 -0
- package/lib/module/buildFindSelector.js.map +1 -0
- package/lib/module/configureOrderDeliveriesModule.d.ts +14 -27
- package/lib/module/configureOrderDeliveriesModule.d.ts.map +1 -1
- package/lib/module/configureOrderDeliveriesModule.js +8 -69
- package/lib/module/configureOrderDeliveriesModule.js.map +1 -1
- package/lib/module/configureOrderDiscountsModule.d.ts +17 -18
- package/lib/module/configureOrderDiscountsModule.d.ts.map +1 -1
- package/lib/module/configureOrderDiscountsModule.js +34 -143
- package/lib/module/configureOrderDiscountsModule.js.map +1 -1
- package/lib/module/configureOrderPaymentsModule.d.ts +17 -37
- package/lib/module/configureOrderPaymentsModule.d.ts.map +1 -1
- package/lib/module/configureOrderPaymentsModule.js +16 -124
- package/lib/module/configureOrderPaymentsModule.js.map +1 -1
- package/lib/module/configureOrderPositionsModule.d.ts +22 -41
- package/lib/module/configureOrderPositionsModule.d.ts.map +1 -1
- package/lib/module/configureOrderPositionsModule.js +22 -85
- package/lib/module/configureOrderPositionsModule.js.map +1 -1
- package/lib/module/configureOrdersModule-mutations.d.ts +5 -11
- package/lib/module/configureOrdersModule-mutations.d.ts.map +1 -1
- package/lib/module/configureOrdersModule-mutations.js +11 -50
- package/lib/module/configureOrdersModule-mutations.js.map +1 -1
- package/lib/module/configureOrdersModule-queries.d.ts +18 -6
- package/lib/module/configureOrdersModule-queries.d.ts.map +1 -1
- package/lib/module/configureOrdersModule-queries.js +35 -22
- package/lib/module/configureOrdersModule-queries.js.map +1 -1
- package/lib/module/configureOrdersModule.d.ts +11 -8
- package/lib/module/configureOrdersModule.d.ts.map +1 -1
- package/lib/module/configureOrdersModule.js +134 -154
- package/lib/module/configureOrdersModule.js.map +1 -1
- package/lib/orders-index.d.ts +11 -8
- package/lib/orders-index.d.ts.map +1 -1
- package/lib/orders-index.js +11 -8
- package/lib/orders-index.js.map +1 -1
- package/lib/orders-settings.d.ts +4 -8
- package/lib/orders-settings.d.ts.map +1 -1
- package/lib/orders-settings.js.map +1 -1
- package/package.json +13 -13
- package/src/db/OrderDeliveriesCollection.ts +25 -2
- package/src/db/OrderDiscountsCollection.ts +18 -2
- package/src/db/OrderPaymentsCollection.ts +26 -2
- package/src/db/OrderPositionsCollection.ts +21 -2
- package/src/db/OrdersCollection.ts +44 -2
- package/src/module/buildFindSelector.test.ts +8 -8
- package/src/module/buildFindSelector.ts +24 -0
- package/src/module/configureOrderDeliveriesModule.ts +29 -172
- package/src/module/configureOrderDiscountsModule.ts +46 -213
- package/src/module/configureOrderPaymentsModule.ts +58 -266
- package/src/module/configureOrderPositionsModule.ts +57 -208
- package/src/module/configureOrdersModule-mutations.ts +13 -85
- package/src/module/configureOrdersModule-queries.ts +61 -29
- package/src/module/configureOrdersModule.ts +181 -264
- package/src/orders-index.ts +11 -10
- package/src/orders-settings.ts +5 -7
- package/tsconfig.json +5 -7
- package/lib/db/OrderDiscountTrigger.d.ts +0 -5
- package/lib/db/OrderDiscountTrigger.d.ts.map +0 -1
- package/lib/db/OrderDiscountTrigger.js +0 -6
- package/lib/db/OrderDiscountTrigger.js.map +0 -1
- package/lib/director/OrderDiscountAdapter.d.ts +0 -4
- package/lib/director/OrderDiscountAdapter.d.ts.map +0 -1
- package/lib/director/OrderDiscountAdapter.js +0 -3
- package/lib/director/OrderDiscountAdapter.js.map +0 -1
- package/lib/director/OrderDiscountConfiguration.d.ts +0 -6
- package/lib/director/OrderDiscountConfiguration.d.ts.map +0 -1
- package/lib/director/OrderDiscountConfiguration.js +0 -2
- package/lib/director/OrderDiscountConfiguration.js.map +0 -1
- package/lib/director/OrderDiscountDirector.d.ts +0 -3
- package/lib/director/OrderDiscountDirector.d.ts.map +0 -1
- package/lib/director/OrderDiscountDirector.js +0 -3
- package/lib/director/OrderDiscountDirector.js.map +0 -1
- package/lib/director/OrderPricingAdapter.d.ts +0 -22
- package/lib/director/OrderPricingAdapter.d.ts.map +0 -1
- package/lib/director/OrderPricingAdapter.js +0 -25
- package/lib/director/OrderPricingAdapter.js.map +0 -1
- package/lib/director/OrderPricingDirector.d.ts +0 -18
- package/lib/director/OrderPricingDirector.d.ts.map +0 -1
- package/lib/director/OrderPricingDirector.js +0 -39
- package/lib/director/OrderPricingDirector.js.map +0 -1
- package/lib/director/OrderPricingSheet.d.ts +0 -36
- package/lib/director/OrderPricingSheet.d.ts.map +0 -1
- package/lib/director/OrderPricingSheet.js +0 -108
- package/lib/director/OrderPricingSheet.js.map +0 -1
- package/lib/module/configureOrdersModule-processing.d.ts +0 -32
- package/lib/module/configureOrdersModule-processing.d.ts.map +0 -1
- package/lib/module/configureOrdersModule-processing.js +0 -339
- package/lib/module/configureOrdersModule-processing.js.map +0 -1
- package/lib/module/configureOrdersModule-transformations.d.ts +0 -20
- package/lib/module/configureOrdersModule-transformations.d.ts.map +0 -1
- package/lib/module/configureOrdersModule-transformations.js +0 -111
- package/lib/module/configureOrdersModule-transformations.js.map +0 -1
- package/lib/service/migrateOrderCartService.d.ts +0 -10
- package/lib/service/migrateOrderCartService.d.ts.map +0 -1
- package/lib/service/migrateOrderCartService.js +0 -32
- package/lib/service/migrateOrderCartService.js.map +0 -1
- package/lib/service/nextUserCartService.d.ts +0 -11
- package/lib/service/nextUserCartService.d.ts.map +0 -1
- package/lib/service/nextUserCartService.js +0 -34
- package/lib/service/nextUserCartService.js.map +0 -1
- package/lib/service/orderServices.d.ts +0 -8
- package/lib/service/orderServices.d.ts.map +0 -1
- package/lib/service/orderServices.js +0 -7
- package/lib/service/orderServices.js.map +0 -1
- package/lib/types.d.ts +0 -116
- package/lib/types.d.ts.map +0 -1
- package/lib/types.js +0 -25
- package/lib/types.js.map +0 -1
- package/src/db/OrderDiscountTrigger.ts +0 -4
- package/src/director/OrderDiscountAdapter.ts +0 -8
- package/src/director/OrderDiscountConfiguration.ts +0 -5
- package/src/director/OrderDiscountDirector.ts +0 -5
- package/src/director/OrderPricingAdapter.ts +0 -61
- package/src/director/OrderPricingDirector.ts +0 -72
- package/src/director/OrderPricingSheet.ts +0 -146
- package/src/module/configureOrdersModule-processing.ts +0 -508
- package/src/module/configureOrdersModule-transformations.ts +0 -171
- package/src/service/migrateOrderCartService.ts +0 -53
- package/src/service/nextUserCartService.ts +0 -54
- package/src/service/orderServices.ts +0 -12
- package/src/types.ts +0 -129
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
26
|
-
|
|
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
|
-
|
|
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
|
};
|
package/src/orders-index.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
export * from './types.js';
|
|
2
1
|
export * from './module/configureOrdersModule.js';
|
|
3
|
-
export * from './
|
|
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';
|
package/src/orders-settings.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { generateRandomHash } from '@unchainedshop/utils';
|
|
2
|
-
import { Order } from './
|
|
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
|
-
|
|
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
|
-
"
|
|
5
|
-
"
|
|
4
|
+
"declarationDir": "./lib",
|
|
5
|
+
"rootDir": "./src",
|
|
6
|
+
"outDir": "./lib"
|
|
6
7
|
},
|
|
7
|
-
"exclude": ["**/*.test.ts", "**/*.test.js", "tests"]
|
|
8
|
-
|
|
9
|
-
"./src"
|
|
10
|
-
]
|
|
11
|
-
}
|
|
8
|
+
"exclude": ["**/*.test.ts", "**/*.test.js", "tests", "lib"]
|
|
9
|
+
}
|
|
@@ -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 +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 +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 +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 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"OrderDiscountConfiguration.js","sourceRoot":"","sources":["../../src/director/OrderDiscountConfiguration.ts"],"names":[],"mappings":""}
|
|
@@ -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 +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
|