@unchainedshop/core 3.1.13 → 4.0.0-rc.10
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/directors/BaseDiscountAdapter.js +0 -1
- package/lib/directors/BaseDiscountAdapter.js.map +1 -1
- package/lib/directors/BaseDiscountDirector.d.ts +1 -1
- package/lib/directors/BaseDiscountDirector.d.ts.map +1 -1
- package/lib/directors/BasePricingAdapter.d.ts +4 -4
- package/lib/directors/BasePricingAdapter.d.ts.map +1 -1
- package/lib/directors/BasePricingDirector.d.ts +2 -2
- package/lib/directors/BasePricingDirector.d.ts.map +1 -1
- package/lib/directors/BasePricingDirector.js.map +1 -1
- package/lib/directors/BasePricingSheet.d.ts +10 -10
- package/lib/directors/BasePricingSheet.d.ts.map +1 -1
- package/lib/directors/BasePricingSheet.js +2 -2
- package/lib/directors/BasePricingSheet.js.map +1 -1
- package/lib/directors/DeliveryAdapter.d.ts +3 -4
- package/lib/directors/DeliveryAdapter.d.ts.map +1 -1
- package/lib/directors/DeliveryAdapter.js.map +1 -1
- package/lib/directors/DeliveryDirector.d.ts.map +1 -1
- package/lib/directors/DeliveryDirector.js +1 -3
- package/lib/directors/DeliveryDirector.js.map +1 -1
- package/lib/directors/DeliveryPricingAdapter.d.ts +3 -3
- package/lib/directors/DeliveryPricingAdapter.d.ts.map +1 -1
- package/lib/directors/DeliveryPricingAdapter.js +2 -2
- package/lib/directors/DeliveryPricingAdapter.js.map +1 -1
- package/lib/directors/DeliveryPricingDirector.d.ts +3 -3
- package/lib/directors/DeliveryPricingDirector.d.ts.map +1 -1
- package/lib/directors/DeliveryPricingDirector.js +6 -6
- package/lib/directors/DeliveryPricingDirector.js.map +1 -1
- package/lib/directors/DeliveryPricingSheet.js +2 -2
- package/lib/directors/DeliveryPricingSheet.js.map +1 -1
- package/lib/directors/EnrollmentAdapter.d.ts +3 -3
- package/lib/directors/EnrollmentAdapter.d.ts.map +1 -1
- package/lib/directors/EnrollmentAdapter.js.map +1 -1
- package/lib/directors/FailedRescheduler.d.ts +2 -2
- package/lib/directors/FailedRescheduler.d.ts.map +1 -1
- package/lib/directors/FailedRescheduler.js +1 -1
- package/lib/directors/FailedRescheduler.js.map +1 -1
- package/lib/directors/FilterAdapter.d.ts +9 -12
- package/lib/directors/FilterAdapter.d.ts.map +1 -1
- package/lib/directors/FilterAdapter.js +0 -4
- package/lib/directors/FilterAdapter.js.map +1 -1
- package/lib/directors/FilterDirector.d.ts +9 -9
- package/lib/directors/FilterDirector.d.ts.map +1 -1
- package/lib/directors/FilterDirector.js.map +1 -1
- package/lib/directors/MessagingDirector.d.ts +11 -15
- package/lib/directors/MessagingDirector.d.ts.map +1 -1
- package/lib/directors/OrderPricingAdapter.d.ts +3 -3
- package/lib/directors/OrderPricingAdapter.d.ts.map +1 -1
- package/lib/directors/OrderPricingAdapter.js +2 -2
- package/lib/directors/OrderPricingAdapter.js.map +1 -1
- package/lib/directors/OrderPricingDirector.d.ts +2 -2
- package/lib/directors/OrderPricingDirector.d.ts.map +1 -1
- package/lib/directors/OrderPricingDirector.js +4 -4
- package/lib/directors/OrderPricingDirector.js.map +1 -1
- package/lib/directors/OrderPricingSheet.js +2 -2
- package/lib/directors/OrderPricingSheet.js.map +1 -1
- package/lib/directors/PaymentAdapter.d.ts +2 -2
- package/lib/directors/PaymentAdapter.d.ts.map +1 -1
- package/lib/directors/PaymentPricingAdapter.d.ts +2 -2
- package/lib/directors/PaymentPricingAdapter.d.ts.map +1 -1
- package/lib/directors/PaymentPricingAdapter.js +2 -2
- package/lib/directors/PaymentPricingAdapter.js.map +1 -1
- package/lib/directors/PaymentPricingDirector.d.ts +3 -3
- package/lib/directors/PaymentPricingDirector.d.ts.map +1 -1
- package/lib/directors/PaymentPricingDirector.js +6 -6
- package/lib/directors/PaymentPricingDirector.js.map +1 -1
- package/lib/directors/PaymentPricingSheet.js +1 -1
- package/lib/directors/PaymentPricingSheet.js.map +1 -1
- package/lib/directors/ProductDiscountConfiguration.d.ts +1 -1
- package/lib/directors/ProductDiscountConfiguration.d.ts.map +1 -1
- package/lib/directors/ProductPricingAdapter.d.ts +3 -3
- package/lib/directors/ProductPricingAdapter.d.ts.map +1 -1
- package/lib/directors/ProductPricingAdapter.js +2 -2
- package/lib/directors/ProductPricingAdapter.js.map +1 -1
- package/lib/directors/ProductPricingDirector.d.ts +5 -5
- package/lib/directors/ProductPricingDirector.d.ts.map +1 -1
- package/lib/directors/ProductPricingDirector.js +6 -6
- package/lib/directors/ProductPricingDirector.js.map +1 -1
- package/lib/directors/ProductPricingSheet.js +2 -2
- package/lib/directors/ProductPricingSheet.js.map +1 -1
- package/lib/directors/QuotationAdapter.d.ts +2 -2
- package/lib/directors/QuotationAdapter.d.ts.map +1 -1
- package/lib/directors/WarehousingAdapter.d.ts +3 -3
- package/lib/directors/WarehousingAdapter.d.ts.map +1 -1
- package/lib/directors/WarehousingDirector.d.ts +3 -3
- package/lib/directors/WarehousingDirector.d.ts.map +1 -1
- package/lib/directors/WorkerDirector.d.ts +2 -2
- package/lib/directors/WorkerDirector.d.ts.map +1 -1
- package/lib/directors/index.d.ts +4 -0
- package/lib/directors/index.d.ts.map +1 -1
- package/lib/directors/index.js +4 -0
- package/lib/directors/index.js.map +1 -1
- package/lib/services/calculateDiscountTotal.d.ts +1 -1
- package/lib/services/calculateDiscountTotal.js +5 -5
- package/lib/services/calculateDiscountTotal.js.map +1 -1
- package/lib/services/checkoutOrder.js +1 -1
- package/lib/services/checkoutOrder.js.map +1 -1
- package/lib/services/createEnrollmentFromCheckout.d.ts +3 -3
- package/lib/services/createEnrollmentFromCheckout.d.ts.map +1 -1
- package/lib/services/createEnrollmentFromCheckout.js +1 -1
- package/lib/services/createEnrollmentFromCheckout.js.map +1 -1
- package/lib/services/discountedEntities.d.ts +1 -1
- package/lib/services/discountedEntities.d.ts.map +1 -1
- package/lib/services/discountedEntities.js +4 -4
- package/lib/services/discountedEntities.js.map +1 -1
- package/lib/services/ercMetadata.d.ts +5 -3
- package/lib/services/ercMetadata.d.ts.map +1 -1
- package/lib/services/ercMetadata.js +2 -11
- package/lib/services/ercMetadata.js.map +1 -1
- package/lib/services/index.d.ts +1 -3
- package/lib/services/index.d.ts.map +1 -1
- package/lib/services/index.js.map +1 -1
- package/lib/services/loadFilters.d.ts +1 -1
- package/lib/services/loadFilters.d.ts.map +1 -1
- package/lib/services/loadFilters.js.map +1 -1
- package/lib/services/migrateBookmarks.d.ts +1 -1
- package/lib/services/migrateBookmarks.d.ts.map +1 -1
- package/lib/services/migrateOrderCart.d.ts +2 -2
- package/lib/services/migrateOrderCart.d.ts.map +1 -1
- package/lib/services/migrateOrderCart.js +3 -3
- package/lib/services/migrateOrderCart.js.map +1 -1
- package/lib/services/migrateUserData.js +2 -2
- package/lib/services/migrateUserData.js.map +1 -1
- package/lib/services/nextUserCart.js +2 -2
- package/lib/services/nextUserCart.js.map +1 -1
- package/lib/services/processOrder.d.ts.map +1 -1
- package/lib/services/processOrder.js +1 -3
- package/lib/services/processOrder.js.map +1 -1
- package/lib/services/removeFiles.d.ts +1 -1
- package/lib/services/removeFiles.d.ts.map +1 -1
- package/lib/services/removeFiles.js +1 -1
- package/lib/services/removeFiles.js.map +1 -1
- package/lib/services/removeProduct.d.ts.map +1 -1
- package/lib/services/removeProduct.js +1 -0
- package/lib/services/removeProduct.js.map +1 -1
- package/lib/services/searchProducts.d.ts.map +1 -1
- package/lib/services/searchProducts.js +1 -2
- package/lib/services/searchProducts.js.map +1 -1
- package/lib/services/simulateProductDispatching.d.ts +1 -3
- package/lib/services/simulateProductDispatching.d.ts.map +1 -1
- package/lib/services/simulateProductDispatching.js +2 -1
- package/lib/services/simulateProductDispatching.js.map +1 -1
- package/lib/services/simulateProductInventory.d.ts +1 -3
- package/lib/services/simulateProductInventory.d.ts.map +1 -1
- package/lib/services/simulateProductInventory.js +2 -1
- package/lib/services/simulateProductInventory.js.map +1 -1
- package/lib/services/simulateProductPricing.d.ts +3 -3
- package/lib/services/simulateProductPricing.d.ts.map +1 -1
- package/lib/services/supportedDeliveryProviders.js +1 -1
- package/lib/services/supportedDeliveryProviders.js.map +1 -1
- package/lib/services/supportedPaymentProviders.js +1 -1
- package/lib/services/supportedPaymentProviders.js.map +1 -1
- package/lib/services/supportedWarehousingProviders.js +1 -1
- package/lib/services/supportedWarehousingProviders.js.map +1 -1
- package/lib/services/updateCalculation.d.ts.map +1 -1
- package/lib/services/updateCalculation.js +4 -5
- package/lib/services/updateCalculation.js.map +1 -1
- package/lib/services/updateScheduling.js +1 -1
- package/lib/services/updateScheduling.js.map +1 -1
- package/lib/services/uploadFileFromStream.d.ts +2 -2
- package/lib/services/uploadFileFromStream.d.ts.map +1 -1
- package/lib/services/uploadFileFromStream.js +2 -2
- package/lib/services/uploadFileFromStream.js.map +1 -1
- package/package.json +22 -21
- package/src/directors/BaseDiscountAdapter.ts +1 -1
- package/src/directors/BaseDiscountDirector.ts +1 -1
- package/src/directors/BasePricingAdapter.ts +4 -4
- package/src/directors/BasePricingDirector.ts +4 -10
- package/src/directors/BasePricingSheet.ts +12 -12
- package/src/directors/BaseWorker.ts +117 -0
- package/src/directors/DeliveryAdapter.ts +2 -4
- package/src/directors/DeliveryDirector.ts +1 -3
- package/src/directors/DeliveryPricingAdapter.ts +5 -5
- package/src/directors/DeliveryPricingDirector.ts +9 -9
- package/src/directors/DeliveryPricingSheet.ts +2 -2
- package/src/directors/EnrollmentAdapter.ts +3 -6
- package/src/directors/EventListenerWorker.ts +101 -0
- package/src/directors/FailedRescheduler.ts +73 -0
- package/src/directors/FilterAdapter.ts +11 -11
- package/src/directors/FilterDirector.ts +16 -16
- package/src/directors/IntervalWorker.ts +75 -0
- package/src/directors/MessagingDirector.ts +10 -10
- package/src/directors/OrderPricingAdapter.ts +5 -5
- package/src/directors/OrderPricingDirector.ts +6 -6
- package/src/directors/OrderPricingSheet.ts +2 -2
- package/src/directors/PaymentAdapter.ts +2 -2
- package/src/directors/PaymentPricingAdapter.ts +4 -4
- package/src/directors/PaymentPricingDirector.ts +9 -9
- package/src/directors/PaymentPricingSheet.ts +1 -1
- package/src/directors/ProductDiscountConfiguration.ts +1 -1
- package/src/directors/ProductPricingAdapter.ts +5 -5
- package/src/directors/ProductPricingDirector.ts +11 -11
- package/src/directors/ProductPricingSheet.test.ts +22 -13
- package/src/directors/ProductPricingSheet.ts +2 -2
- package/src/directors/QuotationAdapter.ts +2 -2
- package/src/directors/WarehousingAdapter.ts +3 -3
- package/src/directors/WarehousingDirector.ts +3 -3
- package/src/directors/WorkerDirector.ts +2 -2
- package/src/directors/index.ts +4 -0
- package/src/services/calculateDiscountTotal.ts +5 -5
- package/src/services/checkoutOrder.ts +1 -1
- package/src/services/createEnrollmentFromCheckout.ts +4 -4
- package/src/services/discountedEntities.ts +5 -5
- package/src/services/ercMetadata.ts +6 -14
- package/src/services/index.ts +1 -3
- package/src/services/loadFilters.ts +1 -1
- package/src/services/migrateBookmarks.ts +1 -1
- package/src/services/migrateOrderCart.ts +4 -4
- package/src/services/migrateUserData.ts +2 -2
- package/src/services/nextUserCart.ts +2 -2
- package/src/services/processOrder.ts +4 -3
- package/src/services/removeFiles.ts +2 -2
- package/src/services/removeProduct.ts +2 -0
- package/src/services/searchProducts.ts +1 -3
- package/src/services/simulateProductDispatching.ts +3 -4
- package/src/services/simulateProductInventory.ts +3 -4
- package/src/services/simulateProductPricing.ts +3 -3
- package/src/services/supportedDeliveryProviders.ts +1 -1
- package/src/services/supportedPaymentProviders.ts +1 -1
- package/src/services/supportedWarehousingProviders.ts +1 -1
- package/src/services/updateCalculation.ts +4 -5
- package/src/services/updateScheduling.ts +2 -2
- package/src/services/uploadFileFromStream.ts +14 -4
|
@@ -10,13 +10,13 @@ interface IDiscountableItem {
|
|
|
10
10
|
|
|
11
11
|
export interface BasePricingAdapterContext {
|
|
12
12
|
order?: Order;
|
|
13
|
-
discounts:
|
|
13
|
+
discounts: OrderDiscount[];
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
export type BasePricingContext =
|
|
17
17
|
| {
|
|
18
18
|
order?: Order;
|
|
19
|
-
discounts?:
|
|
19
|
+
discounts?: OrderDiscount[];
|
|
20
20
|
}
|
|
21
21
|
| {
|
|
22
22
|
item: IDiscountableItem;
|
|
@@ -26,7 +26,7 @@ export interface IPricingAdapterActions<
|
|
|
26
26
|
Calculation extends PricingCalculation,
|
|
27
27
|
Sheet extends IPricingSheet<Calculation>,
|
|
28
28
|
> {
|
|
29
|
-
calculate: () => Promise<
|
|
29
|
+
calculate: () => Promise<Calculation[]>;
|
|
30
30
|
resultSheet: () => Sheet;
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -43,7 +43,7 @@ export type IPricingAdapter<
|
|
|
43
43
|
actions: (params: {
|
|
44
44
|
context: PricingAdapterContext;
|
|
45
45
|
calculationSheet: Sheet;
|
|
46
|
-
discounts:
|
|
46
|
+
discounts: Discount<DiscountConfiguration>[];
|
|
47
47
|
}) => IPricingAdapterActions<Calculation, Sheet>;
|
|
48
48
|
};
|
|
49
49
|
|
|
@@ -25,15 +25,9 @@ export type IPricingDirector<
|
|
|
25
25
|
unchainedAPI: Context,
|
|
26
26
|
) => Promise<PricingAdapterContext>;
|
|
27
27
|
|
|
28
|
-
rebuildCalculation: (
|
|
29
|
-
pricingContext: PricingContext,
|
|
30
|
-
unchainedAPI: Context,
|
|
31
|
-
) => Promise<Array<Calculation>>;
|
|
28
|
+
rebuildCalculation: (pricingContext: PricingContext, unchainedAPI: Context) => Promise<Calculation[]>;
|
|
32
29
|
|
|
33
|
-
calculationSheet: (
|
|
34
|
-
pricingContext: PricingContext,
|
|
35
|
-
calculation: Array<Calculation>,
|
|
36
|
-
) => PricingAdapterSheet;
|
|
30
|
+
calculationSheet: (pricingContext: PricingContext, calculation: Calculation[]) => PricingAdapterSheet;
|
|
37
31
|
};
|
|
38
32
|
|
|
39
33
|
export const BasePricingDirector = <
|
|
@@ -76,7 +70,7 @@ export const BasePricingDirector = <
|
|
|
76
70
|
async rebuildCalculation(this: typeof director, pricingContext, unchainedAPI) {
|
|
77
71
|
const context = await this.buildPricingContext(pricingContext, unchainedAPI);
|
|
78
72
|
|
|
79
|
-
let calculation:
|
|
73
|
+
let calculation: Calculation[] = [];
|
|
80
74
|
|
|
81
75
|
const Adapters = baseDirector.getAdapters({
|
|
82
76
|
adapterFilter: (Adapter) => {
|
|
@@ -88,7 +82,7 @@ export const BasePricingDirector = <
|
|
|
88
82
|
const resolvedCalculation = await previousPromise;
|
|
89
83
|
if (!resolvedCalculation) return null;
|
|
90
84
|
|
|
91
|
-
const discounts:
|
|
85
|
+
const discounts: Discount<any>[] = await Promise.all(
|
|
92
86
|
context.discounts.map(async (orderDiscount) => {
|
|
93
87
|
const order = await unchainedAPI.modules.orders.findOrder({
|
|
94
88
|
orderId: orderDiscount.orderId,
|
|
@@ -2,22 +2,22 @@ import { PricingCalculation } from '@unchainedshop/utils';
|
|
|
2
2
|
export interface PricingDiscount {
|
|
3
3
|
discountId: string;
|
|
4
4
|
amount: number;
|
|
5
|
-
|
|
5
|
+
currencyCode: string;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export interface IPricingSheet<Calculation extends PricingCalculation>
|
|
9
9
|
extends IBasePricingSheet<Calculation> {
|
|
10
|
-
discountPrices: (discountId?: string) =>
|
|
10
|
+
discountPrices: (discountId?: string) => PricingDiscount[];
|
|
11
11
|
addDiscount: (params: { amount: number; discountId: string; meta?: any }) => void;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export interface IBasePricingSheet<Calculation extends PricingCalculation> {
|
|
15
|
-
calculation:
|
|
16
|
-
|
|
15
|
+
calculation: Calculation[];
|
|
16
|
+
currencyCode?: string;
|
|
17
17
|
quantity?: number;
|
|
18
18
|
|
|
19
|
-
getRawPricingSheet: () =>
|
|
20
|
-
filterBy: (filter?: Partial<Calculation>) =>
|
|
19
|
+
getRawPricingSheet: () => Calculation[];
|
|
20
|
+
filterBy: (filter?: Partial<Calculation>) => Calculation[];
|
|
21
21
|
isValid: () => boolean;
|
|
22
22
|
|
|
23
23
|
gross: () => number;
|
|
@@ -25,17 +25,17 @@ export interface IBasePricingSheet<Calculation extends PricingCalculation> {
|
|
|
25
25
|
sum: (filter?: Partial<Calculation>) => number;
|
|
26
26
|
total: (params?: { category?: string; discountId?: string; useNetPrice?: boolean }) => {
|
|
27
27
|
amount: number;
|
|
28
|
-
|
|
28
|
+
currencyCode: string;
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
taxSum: (filter?: Partial<Calculation>) => number;
|
|
32
32
|
|
|
33
|
-
resetCalculation: (sheetToInvert: IBasePricingSheet<Calculation>) =>
|
|
33
|
+
resetCalculation: (sheetToInvert: IBasePricingSheet<Calculation>) => Calculation[];
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
export interface PricingSheetParams<Calculation extends PricingCalculation> {
|
|
37
|
-
calculation?:
|
|
38
|
-
|
|
37
|
+
calculation?: Calculation[];
|
|
38
|
+
currencyCode?: string;
|
|
39
39
|
quantity?: number;
|
|
40
40
|
}
|
|
41
41
|
|
|
@@ -44,7 +44,7 @@ export const BasePricingSheet = <Calculation extends PricingCalculation>(
|
|
|
44
44
|
): IBasePricingSheet<Calculation> => {
|
|
45
45
|
const pricingSheet: IBasePricingSheet<Calculation> = {
|
|
46
46
|
calculation: params.calculation || [],
|
|
47
|
-
|
|
47
|
+
currencyCode: params.currencyCode,
|
|
48
48
|
quantity: params.quantity,
|
|
49
49
|
|
|
50
50
|
getRawPricingSheet() {
|
|
@@ -84,7 +84,7 @@ export const BasePricingSheet = <Calculation extends PricingCalculation>(
|
|
|
84
84
|
|
|
85
85
|
return {
|
|
86
86
|
amount: Math.round(useNetPrice ? netAmount : netAmount + taxAmountForCategory),
|
|
87
|
-
|
|
87
|
+
currencyCode: this.currencyCode,
|
|
88
88
|
};
|
|
89
89
|
},
|
|
90
90
|
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import later from '@breejs/later';
|
|
2
|
+
import { Work, WorkData } from '@unchainedshop/core-worker';
|
|
3
|
+
import { WorkerDirector } from './WorkerDirector.js';
|
|
4
|
+
|
|
5
|
+
export interface IWorker<P extends { workerId?: string }> {
|
|
6
|
+
key: string;
|
|
7
|
+
label: string;
|
|
8
|
+
version: string;
|
|
9
|
+
type: string;
|
|
10
|
+
external: boolean;
|
|
11
|
+
|
|
12
|
+
getFloorDate: (date?: Date) => Date;
|
|
13
|
+
|
|
14
|
+
actions: (
|
|
15
|
+
params: P,
|
|
16
|
+
unchainedAPI,
|
|
17
|
+
) => {
|
|
18
|
+
autorescheduleTypes: (options: { referenceDate: Date }) => Promise<(Work | null)[]>;
|
|
19
|
+
process: (options: { maxWorkItemCount?: number; referenceDate?: Date }) => Promise<void>;
|
|
20
|
+
reset: () => Promise<void> | void;
|
|
21
|
+
start: () => Promise<void> | void;
|
|
22
|
+
stop: () => Promise<void> | void;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface WorkerParams {
|
|
27
|
+
workerId?: string;
|
|
28
|
+
worker: IWorker<any>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const BaseWorker: IWorker<WorkerParams> = {
|
|
32
|
+
key: 'shop.unchained.worker.base',
|
|
33
|
+
label: 'Base worker. Do not use this directly.',
|
|
34
|
+
version: '1.0.0',
|
|
35
|
+
type: 'BASE',
|
|
36
|
+
external: false,
|
|
37
|
+
|
|
38
|
+
getFloorDate: (date = new Date()) => {
|
|
39
|
+
const floored = new Date(Math.floor(date.getTime() / 1000) * 1000);
|
|
40
|
+
return floored;
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
actions: ({ workerId }: WorkerParams, unchainedAPI) => {
|
|
44
|
+
const workerActions = {
|
|
45
|
+
async start() {
|
|
46
|
+
throw new Error(`Not implemented on ${this.constructor.key}`);
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
async stop() {
|
|
50
|
+
throw new Error(`Not implemented on ${this.constructor.key}`);
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
reset: async (referenceDate = new Date()) => {
|
|
54
|
+
await unchainedAPI.modules.worker.markOldWorkAsFailed({
|
|
55
|
+
types: WorkerDirector.getActivePluginTypes({ external: false }),
|
|
56
|
+
worker: workerId,
|
|
57
|
+
referenceDate,
|
|
58
|
+
});
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
autorescheduleTypes: async ({ referenceDate }) => {
|
|
62
|
+
return Promise.all(
|
|
63
|
+
WorkerDirector.getAutoSchedules().map(async ([scheduleId, workConfig]) => {
|
|
64
|
+
if (!workConfig.schedule) {
|
|
65
|
+
await unchainedAPI.modules.worker.ensureNoWork({
|
|
66
|
+
type: workConfig.type,
|
|
67
|
+
priority: workConfig.priority || 0,
|
|
68
|
+
scheduleId,
|
|
69
|
+
});
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const fixedSchedule = { ...workConfig.schedule };
|
|
74
|
+
fixedSchedule.schedules[0].s = [0]; // ignore seconds, always run on second 0
|
|
75
|
+
const nextDate = later.schedule(fixedSchedule).next(1, referenceDate) as Date;
|
|
76
|
+
nextDate.setMilliseconds(0);
|
|
77
|
+
const workData: WorkData = {
|
|
78
|
+
type: workConfig.type,
|
|
79
|
+
scheduleId,
|
|
80
|
+
scheduled: nextDate,
|
|
81
|
+
timeout: workConfig.timeout,
|
|
82
|
+
priority: workConfig.priority || 0,
|
|
83
|
+
retries: workConfig.retries || 0,
|
|
84
|
+
};
|
|
85
|
+
if (workConfig.input) {
|
|
86
|
+
workData.input = await workConfig.input(workData);
|
|
87
|
+
// A work input fn can skip auto scheduling a new record
|
|
88
|
+
// when it explicitly returns a falsish input instead of a dictionary
|
|
89
|
+
if (!workData.input) return null;
|
|
90
|
+
}
|
|
91
|
+
return unchainedAPI.modules.worker.ensureOneWork(workData);
|
|
92
|
+
}),
|
|
93
|
+
);
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
process: async ({ maxWorkItemCount = 10, referenceDate }) => {
|
|
97
|
+
await workerActions.autorescheduleTypes({
|
|
98
|
+
referenceDate,
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
let processedCount = 0;
|
|
102
|
+
while (true) {
|
|
103
|
+
if (maxWorkItemCount && maxWorkItemCount <= processedCount) break;
|
|
104
|
+
|
|
105
|
+
const doneWork = await WorkerDirector.processNextWork(unchainedAPI, workerId);
|
|
106
|
+
if (!doneWork) break;
|
|
107
|
+
|
|
108
|
+
processedCount++;
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
workerActions.reset();
|
|
114
|
+
|
|
115
|
+
return workerActions;
|
|
116
|
+
},
|
|
117
|
+
};
|
|
@@ -7,7 +7,6 @@ import type { User } from '@unchainedshop/core-users';
|
|
|
7
7
|
import {
|
|
8
8
|
DeliveryConfiguration,
|
|
9
9
|
DeliveryLocation,
|
|
10
|
-
DeliveryProvider,
|
|
11
10
|
DeliveryProviderType,
|
|
12
11
|
} from '@unchainedshop/core-delivery';
|
|
13
12
|
import { Modules } from '../modules.js';
|
|
@@ -25,13 +24,12 @@ export interface DeliveryAdapterActions {
|
|
|
25
24
|
isActive: () => boolean;
|
|
26
25
|
isAutoReleaseAllowed: () => boolean;
|
|
27
26
|
pickUpLocationById: (locationId: string) => Promise<DeliveryLocation>;
|
|
28
|
-
pickUpLocations: () => Promise<
|
|
27
|
+
pickUpLocations: () => Promise<DeliveryLocation[]>;
|
|
29
28
|
send: () => Promise<boolean | Work>;
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
export interface DeliveryContext {
|
|
33
|
-
|
|
34
|
-
deliveryProvider?: DeliveryProvider;
|
|
32
|
+
countryCode?: string;
|
|
35
33
|
order?: Order;
|
|
36
34
|
orderDelivery?: OrderDelivery;
|
|
37
35
|
orderPosition?: OrderPosition;
|
|
@@ -103,12 +103,10 @@ export const DeliveryDirector: IDeliveryDirector = {
|
|
|
103
103
|
const deliveryProvider = await unchainedAPI.modules.delivery.findProvider({
|
|
104
104
|
deliveryProviderId: orderDelivery.deliveryProviderId,
|
|
105
105
|
});
|
|
106
|
-
const deliveryProviderId = deliveryProvider._id;
|
|
107
106
|
const address = orderDelivery.context?.address || order || order.billingAddress;
|
|
108
|
-
const provider = await await unchainedAPI.modules.delivery.findProvider({ deliveryProviderId });
|
|
109
107
|
|
|
110
108
|
const adapter = await DeliveryDirector.actions(
|
|
111
|
-
|
|
109
|
+
deliveryProvider,
|
|
112
110
|
{
|
|
113
111
|
order,
|
|
114
112
|
orderDelivery,
|
|
@@ -37,14 +37,14 @@ export type IDeliveryPricingSheet = IPricingSheet<DeliveryPricingCalculation> &
|
|
|
37
37
|
};
|
|
38
38
|
|
|
39
39
|
export interface DeliveryPricingAdapterContext extends BasePricingAdapterContext {
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
countryCode?: string;
|
|
41
|
+
currencyCode?: string;
|
|
42
42
|
provider: DeliveryProvider;
|
|
43
43
|
providerContext?: any;
|
|
44
44
|
order: Order;
|
|
45
45
|
orderDelivery: OrderDelivery;
|
|
46
46
|
user: User;
|
|
47
|
-
discounts:
|
|
47
|
+
discounts: OrderDiscount[];
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
export type IDeliveryPricingAdapter<DiscountConfiguration = unknown> = IPricingAdapter<
|
|
@@ -68,9 +68,9 @@ export const DeliveryPricingAdapter: IDeliveryPricingAdapter = {
|
|
|
68
68
|
|
|
69
69
|
actions: (params) => {
|
|
70
70
|
const { context } = params;
|
|
71
|
-
const {
|
|
71
|
+
const { currencyCode } = context;
|
|
72
72
|
const baseActions = basePricingAdapter.actions(params);
|
|
73
|
-
const resultSheet = DeliveryPricingSheet({
|
|
73
|
+
const resultSheet = DeliveryPricingSheet({ currencyCode });
|
|
74
74
|
|
|
75
75
|
return {
|
|
76
76
|
...baseActions,
|
|
@@ -14,14 +14,14 @@ import type { OrderDelivery } from '@unchainedshop/core-orders';
|
|
|
14
14
|
|
|
15
15
|
export type DeliveryPricingContext =
|
|
16
16
|
| {
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
currencyCode: string;
|
|
18
|
+
countryCode?: string;
|
|
19
19
|
provider: DeliveryProvider;
|
|
20
20
|
providerContext?: any;
|
|
21
21
|
order: Order;
|
|
22
22
|
user: User;
|
|
23
23
|
}
|
|
24
|
-
| {
|
|
24
|
+
| { currencyCode: string; item: OrderDelivery };
|
|
25
25
|
|
|
26
26
|
export type IDeliveryPricingDirector<DiscountConfiguration = unknown> = IPricingDirector<
|
|
27
27
|
DeliveryPricingContext,
|
|
@@ -45,7 +45,7 @@ export const DeliveryPricingDirector: IDeliveryPricingDirector<any> = {
|
|
|
45
45
|
const { modules } = unchainedAPI;
|
|
46
46
|
|
|
47
47
|
if ('item' in context) {
|
|
48
|
-
const { item,
|
|
48
|
+
const { item, currencyCode } = context;
|
|
49
49
|
const order = await modules.orders.findOrder({
|
|
50
50
|
orderId: item.orderId,
|
|
51
51
|
});
|
|
@@ -59,8 +59,8 @@ export const DeliveryPricingDirector: IDeliveryPricingDirector<any> = {
|
|
|
59
59
|
|
|
60
60
|
return {
|
|
61
61
|
...unchainedAPI,
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
countryCode: order.countryCode,
|
|
63
|
+
currencyCode,
|
|
64
64
|
order,
|
|
65
65
|
provider,
|
|
66
66
|
user,
|
|
@@ -72,8 +72,8 @@ export const DeliveryPricingDirector: IDeliveryPricingDirector<any> = {
|
|
|
72
72
|
|
|
73
73
|
return {
|
|
74
74
|
...unchainedAPI,
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
countryCode: context.countryCode,
|
|
76
|
+
currencyCode: context.currencyCode,
|
|
77
77
|
order: context.order,
|
|
78
78
|
provider: context.provider,
|
|
79
79
|
user: context.user,
|
|
@@ -86,7 +86,7 @@ export const DeliveryPricingDirector: IDeliveryPricingDirector<any> = {
|
|
|
86
86
|
calculationSheet(pricingContext, calculation) {
|
|
87
87
|
return DeliveryPricingSheet({
|
|
88
88
|
calculation,
|
|
89
|
-
|
|
89
|
+
currencyCode: pricingContext.currencyCode,
|
|
90
90
|
});
|
|
91
91
|
},
|
|
92
92
|
};
|
|
@@ -65,7 +65,7 @@ export const DeliveryPricingSheet = (
|
|
|
65
65
|
|
|
66
66
|
return [...new Set(discountIds)]
|
|
67
67
|
.map((discountId) => {
|
|
68
|
-
const {
|
|
68
|
+
const { currencyCode, amount } = basePricingSheet.total({
|
|
69
69
|
category: DeliveryPricingRowCategory.Discount,
|
|
70
70
|
discountId,
|
|
71
71
|
});
|
|
@@ -75,7 +75,7 @@ export const DeliveryPricingSheet = (
|
|
|
75
75
|
return {
|
|
76
76
|
discountId,
|
|
77
77
|
amount: Math.round(amount),
|
|
78
|
-
|
|
78
|
+
currencyCode,
|
|
79
79
|
};
|
|
80
80
|
})
|
|
81
81
|
.filter(Boolean);
|
|
@@ -8,15 +8,12 @@ import {
|
|
|
8
8
|
import type { Product, ProductPlan } from '@unchainedshop/core-products';
|
|
9
9
|
import type { OrderPosition } from '@unchainedshop/core-orders';
|
|
10
10
|
|
|
11
|
-
export
|
|
11
|
+
export interface EnrollmentContext {
|
|
12
12
|
enrollment: Enrollment;
|
|
13
|
-
}
|
|
13
|
+
}
|
|
14
14
|
|
|
15
15
|
export interface EnrollmentAdapterActions {
|
|
16
|
-
configurationForOrder: (params: {
|
|
17
|
-
period: EnrollmentPeriod;
|
|
18
|
-
products: Array<Product>;
|
|
19
|
-
}) => Promise<any>;
|
|
16
|
+
configurationForOrder: (params: { period: EnrollmentPeriod; products: Product[] }) => Promise<any>;
|
|
20
17
|
isOverdue: () => Promise<boolean>;
|
|
21
18
|
isValidForActivation: () => Promise<boolean>;
|
|
22
19
|
nextPeriod: () => Promise<EnrollmentPeriod>;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { subscribe } from '@unchainedshop/events';
|
|
2
|
+
import { BaseWorker, IWorker } from './BaseWorker.js';
|
|
3
|
+
import { WorkerEventTypes } from '@unchainedshop/core-worker';
|
|
4
|
+
import { setTimeout } from 'node:timers/promises';
|
|
5
|
+
import { createLogger } from '@unchainedshop/logger';
|
|
6
|
+
|
|
7
|
+
const logger = createLogger('unchained:worker');
|
|
8
|
+
|
|
9
|
+
function debounce<T extends (...args: any[]) => Promise<any>>(
|
|
10
|
+
func: T,
|
|
11
|
+
wait: number,
|
|
12
|
+
): T & { cancel: () => void } {
|
|
13
|
+
let abortController: AbortController | null = null;
|
|
14
|
+
|
|
15
|
+
const debounced = (async (...args: Parameters<T>) => {
|
|
16
|
+
// Cancel any pending execution
|
|
17
|
+
if (abortController) {
|
|
18
|
+
abortController.abort();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Create new abort controller for this execution
|
|
22
|
+
abortController = new AbortController();
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
// Wait for the debounce period
|
|
26
|
+
await setTimeout(wait, undefined, { signal: abortController.signal });
|
|
27
|
+
|
|
28
|
+
// If we reach here, the timeout completed without being aborted
|
|
29
|
+
const result = await func(...args);
|
|
30
|
+
abortController = null;
|
|
31
|
+
return result;
|
|
32
|
+
} catch (error) {
|
|
33
|
+
// If the operation was aborted, don't execute the function
|
|
34
|
+
if (error.name === 'AbortError') {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
// Re-throw any other errors
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
}) as T & { cancel: () => void };
|
|
41
|
+
|
|
42
|
+
debounced.cancel = () => {
|
|
43
|
+
if (abortController) {
|
|
44
|
+
abortController.abort();
|
|
45
|
+
abortController = null;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
return debounced;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface EventListenerWorkerParams {
|
|
53
|
+
workerId?: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export const EventListenerWorker: IWorker<EventListenerWorkerParams> = {
|
|
57
|
+
...BaseWorker,
|
|
58
|
+
|
|
59
|
+
key: 'shop.unchained.worker.event-listener',
|
|
60
|
+
label: 'Allocates work on events. This worker does not make sense on multiple containers.',
|
|
61
|
+
version: '1.0.0',
|
|
62
|
+
type: 'EVENT_LISTENER',
|
|
63
|
+
|
|
64
|
+
actions: ({ workerId }, unchainedAPI) => {
|
|
65
|
+
const baseWorkerActions = BaseWorker.actions(
|
|
66
|
+
{ workerId, worker: EventListenerWorker },
|
|
67
|
+
unchainedAPI,
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
// Debounce in the event of many work queue events conflicting with each other
|
|
71
|
+
const processWorkQueue = debounce<() => Promise<void>>(async () => {
|
|
72
|
+
try {
|
|
73
|
+
await baseWorkerActions.process({
|
|
74
|
+
maxWorkItemCount: 1, // only one work item at a time, else we could end up in a loop
|
|
75
|
+
referenceDate: EventListenerWorker.getFloorDate(),
|
|
76
|
+
});
|
|
77
|
+
} catch (error) {
|
|
78
|
+
// Log error but don't crash the worker
|
|
79
|
+
logger.error(error);
|
|
80
|
+
}
|
|
81
|
+
}, 300);
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
...baseWorkerActions,
|
|
85
|
+
|
|
86
|
+
async start() {
|
|
87
|
+
subscribe(WorkerEventTypes.ADDED, processWorkQueue);
|
|
88
|
+
subscribe(WorkerEventTypes.FINISHED, processWorkQueue);
|
|
89
|
+
|
|
90
|
+
await setTimeout(300);
|
|
91
|
+
await baseWorkerActions.autorescheduleTypes({
|
|
92
|
+
referenceDate: EventListenerWorker.getFloorDate(),
|
|
93
|
+
});
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
stop() {
|
|
97
|
+
processWorkQueue.cancel();
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
},
|
|
101
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { defaultLogger } from '@unchainedshop/logger';
|
|
2
|
+
import { subscribe } from '@unchainedshop/events';
|
|
3
|
+
import { Work, WorkData, WorkerEventTypes } from '@unchainedshop/core-worker';
|
|
4
|
+
|
|
5
|
+
export interface FailedReschedulerParams {
|
|
6
|
+
transformRetry?: (workData: WorkData, lastFailedWork: Work) => Promise<WorkData | null>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface IScheduler<P> {
|
|
10
|
+
key: string;
|
|
11
|
+
label: string;
|
|
12
|
+
version: string;
|
|
13
|
+
|
|
14
|
+
actions: (
|
|
15
|
+
params: P,
|
|
16
|
+
unchainedAPI,
|
|
17
|
+
) => {
|
|
18
|
+
start: () => void;
|
|
19
|
+
stop: () => void;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const FailedRescheduler: IScheduler<FailedReschedulerParams> = {
|
|
24
|
+
key: 'shop.unchained.scheduler.failed',
|
|
25
|
+
label: 'Reschedule failed works',
|
|
26
|
+
version: '1.0.0',
|
|
27
|
+
|
|
28
|
+
actions: ({ transformRetry }, unchainedAPI) => {
|
|
29
|
+
const handleFinishedWork = async ({ payload: work }: { payload: Work }) => {
|
|
30
|
+
if (!work.success && work.retries > 0) {
|
|
31
|
+
const now = new Date();
|
|
32
|
+
const workDelayMs = work.scheduled.getTime() - work.created.getTime();
|
|
33
|
+
|
|
34
|
+
// In short: Double the delay of the old work or delay for 5 seconds
|
|
35
|
+
const scheduled =
|
|
36
|
+
workDelayMs > 1000
|
|
37
|
+
? new Date(now.getTime() + workDelayMs * 2)
|
|
38
|
+
: new Date(now.setSeconds(now.getSeconds() + 5));
|
|
39
|
+
|
|
40
|
+
defaultLogger.error(
|
|
41
|
+
`${FailedRescheduler.key} -> Reschedule failed work ${work._id} ${
|
|
42
|
+
work.type
|
|
43
|
+
} for ${scheduled.toISOString()} (in ${Math.round(workDelayMs / 1000)}). Remaining retries: ${
|
|
44
|
+
work.retries
|
|
45
|
+
}`,
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
const newWorkData = {
|
|
49
|
+
type: work.type,
|
|
50
|
+
priority: work.priority,
|
|
51
|
+
originalWorkId: work.originalWorkId || work._id,
|
|
52
|
+
retries: work.retries - 1,
|
|
53
|
+
timeout: work.timeout,
|
|
54
|
+
input: work.input,
|
|
55
|
+
scheduled,
|
|
56
|
+
};
|
|
57
|
+
await unchainedAPI.modules.worker.addWork(
|
|
58
|
+
transformRetry ? await transformRetry(newWorkData, work) : newWorkData,
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
start() {
|
|
65
|
+
subscribe<Work>(WorkerEventTypes.FINISHED, handleFinishedWork);
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
stop() {
|
|
69
|
+
/* */
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
},
|
|
73
|
+
};
|
|
@@ -5,23 +5,23 @@ import { Product } from '@unchainedshop/core-products';
|
|
|
5
5
|
import { Filter, SearchQuery } from '@unchainedshop/core-filters';
|
|
6
6
|
import { Modules } from '../modules.js';
|
|
7
7
|
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
export interface FilterInputText {
|
|
9
|
+
locale: string;
|
|
10
|
+
title: string;
|
|
11
|
+
subtitle?: string;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
export
|
|
14
|
+
export interface FilterContext {
|
|
15
15
|
filter?: Filter;
|
|
16
16
|
searchQuery: SearchQuery;
|
|
17
|
-
}
|
|
17
|
+
}
|
|
18
18
|
|
|
19
19
|
export interface FilterAdapterActions {
|
|
20
|
-
aggregateProductIds: (params: { productIds:
|
|
20
|
+
aggregateProductIds: (params: { productIds: string[] }) => string[];
|
|
21
21
|
|
|
22
22
|
searchAssortments: (
|
|
23
23
|
params: {
|
|
24
|
-
assortmentIds:
|
|
24
|
+
assortmentIds: string[];
|
|
25
25
|
},
|
|
26
26
|
options: {
|
|
27
27
|
filterSelector: mongodb.Filter<Filter>;
|
|
@@ -29,11 +29,11 @@ export interface FilterAdapterActions {
|
|
|
29
29
|
sortStage: mongodb.FindOptions['sort'];
|
|
30
30
|
locale: Intl.Locale;
|
|
31
31
|
},
|
|
32
|
-
) => Promise<
|
|
32
|
+
) => Promise<string[]>;
|
|
33
33
|
|
|
34
34
|
searchProducts: (
|
|
35
35
|
params: {
|
|
36
|
-
productIds
|
|
36
|
+
productIds?: string[];
|
|
37
37
|
},
|
|
38
38
|
options: {
|
|
39
39
|
filterSelector: mongodb.Filter<Filter>;
|
|
@@ -41,7 +41,7 @@ export interface FilterAdapterActions {
|
|
|
41
41
|
sortStage: mongodb.FindOptions['sort'];
|
|
42
42
|
locale: Intl.Locale;
|
|
43
43
|
},
|
|
44
|
-
) => Promise<
|
|
44
|
+
) => Promise<string[]>;
|
|
45
45
|
|
|
46
46
|
transformFilterSelector: (
|
|
47
47
|
query: mongodb.Filter<Filter>,
|