@unchainedshop/core-enrollments 3.0.0-alpha7 → 3.0.0-rc.12
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/addToDate.d.ts +2 -0
- package/lib/addToDate.d.ts.map +1 -0
- package/lib/addToDate.js +39 -0
- package/lib/addToDate.js.map +1 -0
- package/lib/db/EnrollmentsCollection.d.ts +50 -1
- package/lib/db/EnrollmentsCollection.d.ts.map +1 -1
- package/lib/db/EnrollmentsCollection.js +7 -0
- package/lib/db/EnrollmentsCollection.js.map +1 -1
- package/lib/enrollments-index.d.ts +2 -4
- package/lib/enrollments-index.d.ts.map +1 -1
- package/lib/enrollments-index.js +2 -4
- package/lib/enrollments-index.js.map +1 -1
- package/lib/enrollments-settings.d.ts +3 -3
- package/lib/enrollments-settings.d.ts.map +1 -1
- package/lib/enrollments-settings.js.map +1 -1
- package/lib/module/configureEnrollmentsModule.d.ts +41 -54
- package/lib/module/configureEnrollmentsModule.d.ts.map +1 -1
- package/lib/module/configureEnrollmentsModule.js +22 -143
- package/lib/module/configureEnrollmentsModule.js.map +1 -1
- package/package.json +14 -14
- package/src/addToDate.ts +58 -0
- package/src/db/EnrollmentsCollection.ts +49 -1
- package/src/enrollments-index.ts +2 -6
- package/src/enrollments-settings.ts +2 -3
- package/src/module/buildFindSelector.test.ts +1 -1
- package/src/module/configureEnrollmentsModule.ts +77 -339
- package/tsconfig.json +5 -7
- package/lib/db/EnrollmentStatus.d.ts +0 -7
- package/lib/db/EnrollmentStatus.d.ts.map +0 -1
- package/lib/db/EnrollmentStatus.js +0 -8
- package/lib/db/EnrollmentStatus.js.map +0 -1
- package/lib/director/EnrollmentAdapter.d.ts +0 -7
- package/lib/director/EnrollmentAdapter.d.ts.map +0 -1
- package/lib/director/EnrollmentAdapter.js +0 -73
- package/lib/director/EnrollmentAdapter.js.map +0 -1
- package/lib/director/EnrollmentDirector.d.ts +0 -3
- package/lib/director/EnrollmentDirector.d.ts.map +0 -1
- package/lib/director/EnrollmentDirector.js +0 -46
- package/lib/director/EnrollmentDirector.js.map +0 -1
- package/lib/director/EnrollmentError.d.ts +0 -7
- package/lib/director/EnrollmentError.d.ts.map +0 -1
- package/lib/director/EnrollmentError.js +0 -8
- package/lib/director/EnrollmentError.js.map +0 -1
- package/lib/types.d.ts +0 -100
- package/lib/types.d.ts.map +0 -1
- package/lib/types.js +0 -8
- package/lib/types.js.map +0 -1
- package/src/db/EnrollmentStatus.ts +0 -6
- package/src/director/EnrollmentAdapter.ts +0 -82
- package/src/director/EnrollmentDirector.ts +0 -60
- package/src/director/EnrollmentError.ts +0 -6
- package/src/module/periodForReferenceDate.test.ts +0 -23
- package/src/types.ts +0 -113
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { log, LogLevel } from '@unchainedshop/logger';
|
|
2
|
-
import { BaseDirector } from '@unchainedshop/utils';
|
|
3
|
-
const baseDirector = BaseDirector('EnrollmentDirector', {
|
|
4
|
-
adapterSortKey: 'orderIndex',
|
|
5
|
-
});
|
|
6
|
-
const findAppropriateAdapters = (productPlan) => baseDirector.getAdapters({
|
|
7
|
-
adapterFilter: (Adapter) => {
|
|
8
|
-
const activated = Adapter.isActivatedFor(productPlan);
|
|
9
|
-
if (!activated) {
|
|
10
|
-
log(`Enrollment Director -> ${Adapter.key} (${Adapter.version}) skipped`, {
|
|
11
|
-
level: LogLevel.Warning,
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
return activated;
|
|
15
|
-
},
|
|
16
|
-
});
|
|
17
|
-
export const EnrollmentDirector = {
|
|
18
|
-
...baseDirector,
|
|
19
|
-
transformOrderItemToEnrollment: async ({ orderPosition, product }, doc, unchainedAPI) => {
|
|
20
|
-
const Adapter = findAppropriateAdapters(product.plan)?.[0];
|
|
21
|
-
if (!Adapter) {
|
|
22
|
-
throw new Error('No suitable enrollment plugin available for this item');
|
|
23
|
-
}
|
|
24
|
-
const enrollmentPlan = await Adapter.transformOrderItemToEnrollmentPlan(orderPosition, unchainedAPI);
|
|
25
|
-
const enrollmentData = {
|
|
26
|
-
...doc,
|
|
27
|
-
...enrollmentPlan,
|
|
28
|
-
configuration: [],
|
|
29
|
-
};
|
|
30
|
-
return enrollmentData;
|
|
31
|
-
},
|
|
32
|
-
actions: async (enrollmentContext, unchainedAPI) => {
|
|
33
|
-
const context = { ...enrollmentContext, ...unchainedAPI };
|
|
34
|
-
// Resolve adapter
|
|
35
|
-
const product = await context.modules.products.findProduct({
|
|
36
|
-
productId: context.enrollment.productId,
|
|
37
|
-
});
|
|
38
|
-
const Adapter = findAppropriateAdapters(product?.plan)?.[0];
|
|
39
|
-
if (!Adapter) {
|
|
40
|
-
throw new Error('No suitable enrollment plugin available for this plan configuration');
|
|
41
|
-
}
|
|
42
|
-
const adapter = Adapter.actions(context);
|
|
43
|
-
return adapter;
|
|
44
|
-
},
|
|
45
|
-
};
|
|
46
|
-
//# sourceMappingURL=EnrollmentDirector.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"EnrollmentDirector.js","sourceRoot":"","sources":["../../src/director/EnrollmentDirector.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,MAAM,YAAY,GAAG,YAAY,CAAqB,oBAAoB,EAAE;IAC1E,cAAc,EAAE,YAAY;CAC7B,CAAC,CAAC;AAEH,MAAM,uBAAuB,GAAG,CAAC,WAAyB,EAAE,EAAE,CAC5D,YAAY,CAAC,WAAW,CAAC;IACvB,aAAa,EAAE,CAAC,OAA2B,EAAE,EAAE;QAC7C,MAAM,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QACtD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,GAAG,CAAC,0BAA0B,OAAO,CAAC,GAAG,KAAK,OAAO,CAAC,OAAO,WAAW,EAAE;gBACxE,KAAK,EAAE,QAAQ,CAAC,OAAO;aACxB,CAAC,CAAC;QACL,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;CACF,CAAC,CAAC;AAEL,MAAM,CAAC,MAAM,kBAAkB,GAAwB;IACrD,GAAG,YAAY;IAEf,8BAA8B,EAAE,KAAK,EAAE,EAAE,aAAa,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,YAAY,EAAE,EAAE;QACtF,MAAM,OAAO,GAAG,uBAAuB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;QAC3E,CAAC;QAED,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,kCAAkC,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;QAErG,MAAM,cAAc,GAAmB;YACrC,GAAG,GAAG;YACN,GAAG,cAAc;YACjB,aAAa,EAAE,EAAE;SAClB,CAAC;QAEF,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,EAAE;QACjD,MAAM,OAAO,GAAG,EAAE,GAAG,iBAAiB,EAAE,GAAG,YAAY,EAAE,CAAC;QAE1D,kBAAkB;QAClB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;YACzD,SAAS,EAAE,OAAO,CAAC,UAAU,CAAC,SAAS;SACxC,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,uBAAuB,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAE5D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAC;QACzF,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAEzC,OAAO,OAAO,CAAC;IACjB,CAAC;CACF,CAAC"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export declare enum EnrollmentError {
|
|
2
|
-
ADAPTER_NOT_FOUND = "ADAPTER_NOT_FOUND",
|
|
3
|
-
NOT_IMPLEMENTED = "NOT_IMPLEMENTED",
|
|
4
|
-
INCOMPLETE_CONFIGURATION = "INCOMPLETE_CONFIGURATION",
|
|
5
|
-
WRONG_CREDENTIALS = "WRONG_CREDENTIALS"
|
|
6
|
-
}
|
|
7
|
-
//# sourceMappingURL=EnrollmentError.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"EnrollmentError.d.ts","sourceRoot":"","sources":["../../src/director/EnrollmentError.ts"],"names":[],"mappings":"AAAA,oBAAY,eAAe;IACzB,iBAAiB,sBAAsB;IACvC,eAAe,oBAAoB;IACnC,wBAAwB,6BAA6B;IACrD,iBAAiB,sBAAsB;CACxC"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export var EnrollmentError;
|
|
2
|
-
(function (EnrollmentError) {
|
|
3
|
-
EnrollmentError["ADAPTER_NOT_FOUND"] = "ADAPTER_NOT_FOUND";
|
|
4
|
-
EnrollmentError["NOT_IMPLEMENTED"] = "NOT_IMPLEMENTED";
|
|
5
|
-
EnrollmentError["INCOMPLETE_CONFIGURATION"] = "INCOMPLETE_CONFIGURATION";
|
|
6
|
-
EnrollmentError["WRONG_CREDENTIALS"] = "WRONG_CREDENTIALS";
|
|
7
|
-
})(EnrollmentError || (EnrollmentError = {}));
|
|
8
|
-
//# sourceMappingURL=EnrollmentError.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"EnrollmentError.js","sourceRoot":"","sources":["../../src/director/EnrollmentError.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,eAKX;AALD,WAAY,eAAe;IACzB,0DAAuC,CAAA;IACvC,sDAAmC,CAAA;IACnC,wEAAqD,CAAA;IACrD,0DAAuC,CAAA;AACzC,CAAC,EALW,eAAe,KAAf,eAAe,QAK1B"}
|
package/lib/types.d.ts
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import type { IBaseAdapter, IBaseDirector } from '@unchainedshop/utils';
|
|
2
|
-
import type { TimestampFields, LogFields, Address, Contact } from '@unchainedshop/mongodb';
|
|
3
|
-
import { Product, ProductPlan } from '@unchainedshop/core-products';
|
|
4
|
-
import { OrderPosition } from '@unchainedshop/core-orders';
|
|
5
|
-
import { UnchainedCore } from '@unchainedshop/core';
|
|
6
|
-
export declare enum EnrollmentStatus {
|
|
7
|
-
INITIAL = "INITIAL",
|
|
8
|
-
ACTIVE = "ACTIVE",
|
|
9
|
-
PAUSED = "PAUSED",
|
|
10
|
-
TERMINATED = "TERMINATED"
|
|
11
|
-
}
|
|
12
|
-
export interface EnrollmentPeriod {
|
|
13
|
-
start: Date;
|
|
14
|
-
end: Date;
|
|
15
|
-
orderId?: string;
|
|
16
|
-
isTrial?: boolean;
|
|
17
|
-
}
|
|
18
|
-
export interface EnrollmentPlan {
|
|
19
|
-
configuration: Array<{
|
|
20
|
-
key: string;
|
|
21
|
-
value: string;
|
|
22
|
-
}>;
|
|
23
|
-
productId: string;
|
|
24
|
-
quantity: number;
|
|
25
|
-
}
|
|
26
|
-
export type EnrollmentQuery = {
|
|
27
|
-
status?: Array<EnrollmentStatus>;
|
|
28
|
-
userId?: string;
|
|
29
|
-
queryString?: string;
|
|
30
|
-
};
|
|
31
|
-
export type Enrollment = {
|
|
32
|
-
_id?: string;
|
|
33
|
-
billingAddress: Address;
|
|
34
|
-
configuration: Array<{
|
|
35
|
-
key: string;
|
|
36
|
-
value: string;
|
|
37
|
-
}>;
|
|
38
|
-
contact: Contact;
|
|
39
|
-
context?: any;
|
|
40
|
-
countryCode?: string;
|
|
41
|
-
currencyCode?: string;
|
|
42
|
-
delivery: {
|
|
43
|
-
deliveryProviderId?: string;
|
|
44
|
-
context?: any;
|
|
45
|
-
};
|
|
46
|
-
enrollmentNumber?: string;
|
|
47
|
-
expires?: Date;
|
|
48
|
-
meta?: any;
|
|
49
|
-
payment: {
|
|
50
|
-
paymentProviderId?: string;
|
|
51
|
-
context?: any;
|
|
52
|
-
};
|
|
53
|
-
periods: Array<EnrollmentPeriod>;
|
|
54
|
-
productId: string;
|
|
55
|
-
quantity?: number;
|
|
56
|
-
status: string;
|
|
57
|
-
userId: string;
|
|
58
|
-
} & LogFields & TimestampFields;
|
|
59
|
-
export type EnrollmentContext = {
|
|
60
|
-
enrollment: Enrollment;
|
|
61
|
-
};
|
|
62
|
-
export interface EnrollmentAdapterActions {
|
|
63
|
-
configurationForOrder: (params: {
|
|
64
|
-
period: EnrollmentPeriod;
|
|
65
|
-
products: Array<Product>;
|
|
66
|
-
}) => Promise<any>;
|
|
67
|
-
isOverdue: () => Promise<boolean>;
|
|
68
|
-
isValidForActivation: () => Promise<boolean>;
|
|
69
|
-
nextPeriod: () => Promise<EnrollmentPeriod>;
|
|
70
|
-
}
|
|
71
|
-
export type IEnrollmentAdapter = IBaseAdapter & {
|
|
72
|
-
isActivatedFor: (productPlan?: ProductPlan) => boolean;
|
|
73
|
-
transformOrderItemToEnrollmentPlan: (orderPosition: OrderPosition, unchainedAPI: UnchainedCore) => Promise<EnrollmentPlan>;
|
|
74
|
-
actions: (params: EnrollmentContext & UnchainedCore) => EnrollmentAdapterActions;
|
|
75
|
-
};
|
|
76
|
-
export interface EnrollmentData {
|
|
77
|
-
billingAddress: Address;
|
|
78
|
-
configuration?: Array<{
|
|
79
|
-
key: string;
|
|
80
|
-
value: string;
|
|
81
|
-
}>;
|
|
82
|
-
contact: Contact;
|
|
83
|
-
countryCode?: string;
|
|
84
|
-
currencyCode?: string;
|
|
85
|
-
delivery: Enrollment['delivery'];
|
|
86
|
-
meta?: any;
|
|
87
|
-
orderIdForFirstPeriod?: string;
|
|
88
|
-
payment: Enrollment['payment'];
|
|
89
|
-
productId: string;
|
|
90
|
-
quantity: number;
|
|
91
|
-
userId: string;
|
|
92
|
-
}
|
|
93
|
-
export type IEnrollmentDirector = IBaseDirector<IEnrollmentAdapter> & {
|
|
94
|
-
transformOrderItemToEnrollment: (item: {
|
|
95
|
-
orderPosition: OrderPosition;
|
|
96
|
-
product: Product;
|
|
97
|
-
}, doc: Omit<EnrollmentData, 'configuration' | 'productId' | 'quantity'>, unchainedAPI: UnchainedCore) => Promise<EnrollmentData>;
|
|
98
|
-
actions: (enrollmentContext: EnrollmentContext, unchainedAPI: UnchainedCore) => Promise<EnrollmentAdapterActions>;
|
|
99
|
-
};
|
|
100
|
-
//# sourceMappingURL=types.d.ts.map
|
package/lib/types.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/lib/types.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export var EnrollmentStatus;
|
|
2
|
-
(function (EnrollmentStatus) {
|
|
3
|
-
EnrollmentStatus["INITIAL"] = "INITIAL";
|
|
4
|
-
EnrollmentStatus["ACTIVE"] = "ACTIVE";
|
|
5
|
-
EnrollmentStatus["PAUSED"] = "PAUSED";
|
|
6
|
-
EnrollmentStatus["TERMINATED"] = "TERMINATED";
|
|
7
|
-
})(EnrollmentStatus || (EnrollmentStatus = {}));
|
|
8
|
-
//# sourceMappingURL=types.js.map
|
package/lib/types.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAMA,MAAM,CAAN,IAAY,gBAKX;AALD,WAAY,gBAAgB;IAC1B,uCAAmB,CAAA;IACnB,qCAAiB,CAAA;IACjB,qCAAiB,CAAA;IACjB,6CAAyB,CAAA;AAC3B,CAAC,EALW,gBAAgB,KAAhB,gBAAgB,QAK3B"}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { log, LogLevel } from '@unchainedshop/logger';
|
|
2
|
-
import { add } from 'date-fns/add';
|
|
3
|
-
import { IEnrollmentAdapter } from '../types.js';
|
|
4
|
-
|
|
5
|
-
export const periodForReferenceDate = (referenceDate: Date, intervalCount = 1, interval = 'WEEKS') => {
|
|
6
|
-
const lowerCaseInterval = interval.toLowerCase();
|
|
7
|
-
|
|
8
|
-
const start = new Date(referenceDate);
|
|
9
|
-
if (lowerCaseInterval === 'hours') {
|
|
10
|
-
start.setMinutes(0, 0, 0);
|
|
11
|
-
} else {
|
|
12
|
-
start.setSeconds(0, 0);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
return {
|
|
16
|
-
start,
|
|
17
|
-
end: add(start, {
|
|
18
|
-
[lowerCaseInterval]: intervalCount,
|
|
19
|
-
}),
|
|
20
|
-
};
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export const EnrollmentAdapter: Omit<IEnrollmentAdapter, 'key' | 'label' | 'version'> = {
|
|
24
|
-
isActivatedFor: () => {
|
|
25
|
-
return false;
|
|
26
|
-
},
|
|
27
|
-
|
|
28
|
-
transformOrderItemToEnrollmentPlan: async (item) => {
|
|
29
|
-
return {
|
|
30
|
-
configuration: item.configuration,
|
|
31
|
-
productId: item.productId,
|
|
32
|
-
quantity: item.quantity,
|
|
33
|
-
};
|
|
34
|
-
},
|
|
35
|
-
|
|
36
|
-
actions: (context) => {
|
|
37
|
-
return {
|
|
38
|
-
configurationForOrder: async () => {
|
|
39
|
-
throw new Error(`Not implemented on EnrollmentAdapter`);
|
|
40
|
-
},
|
|
41
|
-
|
|
42
|
-
isOverdue: async () => false,
|
|
43
|
-
isValidForActivation: async () => false,
|
|
44
|
-
|
|
45
|
-
nextPeriod: async () => {
|
|
46
|
-
const { enrollment } = context;
|
|
47
|
-
const product = await context.modules.products.findProduct({
|
|
48
|
-
productId: enrollment.productId,
|
|
49
|
-
});
|
|
50
|
-
const plan = product?.plan;
|
|
51
|
-
const referenceDate = new Date();
|
|
52
|
-
if (!plan) return null;
|
|
53
|
-
|
|
54
|
-
if (plan.trialIntervalCount && !enrollment?.periods?.length) {
|
|
55
|
-
return {
|
|
56
|
-
...periodForReferenceDate(referenceDate, plan.trialIntervalCount, plan.trialInterval),
|
|
57
|
-
isTrial: true,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const lastEnd = enrollment?.periods?.reduce((acc, item) => {
|
|
62
|
-
if (!acc) return item.end;
|
|
63
|
-
const endDate = new Date(item.end);
|
|
64
|
-
if (acc.getTime() < endDate.getTime()) {
|
|
65
|
-
return endDate;
|
|
66
|
-
}
|
|
67
|
-
return acc;
|
|
68
|
-
}, referenceDate);
|
|
69
|
-
|
|
70
|
-
return {
|
|
71
|
-
...periodForReferenceDate(lastEnd, plan.billingIntervalCount, plan.billingInterval),
|
|
72
|
-
isTrial: false,
|
|
73
|
-
};
|
|
74
|
-
},
|
|
75
|
-
};
|
|
76
|
-
},
|
|
77
|
-
|
|
78
|
-
// eslint-disable-next-line
|
|
79
|
-
log(message: string, { level = LogLevel.Debug, ...options } = {}) {
|
|
80
|
-
return log(message, { level, ...options });
|
|
81
|
-
},
|
|
82
|
-
};
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { EnrollmentData, IEnrollmentAdapter, IEnrollmentDirector } from '../types.js';
|
|
2
|
-
import { ProductPlan } from '@unchainedshop/core-products';
|
|
3
|
-
import { log, LogLevel } from '@unchainedshop/logger';
|
|
4
|
-
import { BaseDirector } from '@unchainedshop/utils';
|
|
5
|
-
|
|
6
|
-
const baseDirector = BaseDirector<IEnrollmentAdapter>('EnrollmentDirector', {
|
|
7
|
-
adapterSortKey: 'orderIndex',
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
const findAppropriateAdapters = (productPlan?: ProductPlan) =>
|
|
11
|
-
baseDirector.getAdapters({
|
|
12
|
-
adapterFilter: (Adapter: IEnrollmentAdapter) => {
|
|
13
|
-
const activated = Adapter.isActivatedFor(productPlan);
|
|
14
|
-
if (!activated) {
|
|
15
|
-
log(`Enrollment Director -> ${Adapter.key} (${Adapter.version}) skipped`, {
|
|
16
|
-
level: LogLevel.Warning,
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
return activated;
|
|
20
|
-
},
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
export const EnrollmentDirector: IEnrollmentDirector = {
|
|
24
|
-
...baseDirector,
|
|
25
|
-
|
|
26
|
-
transformOrderItemToEnrollment: async ({ orderPosition, product }, doc, unchainedAPI) => {
|
|
27
|
-
const Adapter = findAppropriateAdapters(product.plan)?.[0];
|
|
28
|
-
if (!Adapter) {
|
|
29
|
-
throw new Error('No suitable enrollment plugin available for this item');
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const enrollmentPlan = await Adapter.transformOrderItemToEnrollmentPlan(orderPosition, unchainedAPI);
|
|
33
|
-
|
|
34
|
-
const enrollmentData: EnrollmentData = {
|
|
35
|
-
...doc,
|
|
36
|
-
...enrollmentPlan,
|
|
37
|
-
configuration: [],
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
return enrollmentData;
|
|
41
|
-
},
|
|
42
|
-
|
|
43
|
-
actions: async (enrollmentContext, unchainedAPI) => {
|
|
44
|
-
const context = { ...enrollmentContext, ...unchainedAPI };
|
|
45
|
-
|
|
46
|
-
// Resolve adapter
|
|
47
|
-
const product = await context.modules.products.findProduct({
|
|
48
|
-
productId: context.enrollment.productId,
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
const Adapter = findAppropriateAdapters(product?.plan)?.[0];
|
|
52
|
-
|
|
53
|
-
if (!Adapter) {
|
|
54
|
-
throw new Error('No suitable enrollment plugin available for this plan configuration');
|
|
55
|
-
}
|
|
56
|
-
const adapter = Adapter.actions(context);
|
|
57
|
-
|
|
58
|
-
return adapter;
|
|
59
|
-
},
|
|
60
|
-
};
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { periodForReferenceDate } from '../director/EnrollmentAdapter.js';
|
|
2
|
-
|
|
3
|
-
describe('periodForReferenceDate', () => {
|
|
4
|
-
it('Should return 1 week interval from When passed a given date', () => {
|
|
5
|
-
expect(periodForReferenceDate(new Date('2022-12-03T17:00:00.000Z'))).toEqual({
|
|
6
|
-
start: new Date('2022-12-03T17:00:00.000Z'),
|
|
7
|
-
end: new Date('2022-12-10T17:00:00.000Z'),
|
|
8
|
-
});
|
|
9
|
-
});
|
|
10
|
-
it('Should return 2 week interval from When passed 2 as interval', () => {
|
|
11
|
-
expect(periodForReferenceDate(new Date('2022-12-03T17:00:00.000Z'), 2)).toEqual({
|
|
12
|
-
start: new Date('2022-12-03T17:00:00.000Z'),
|
|
13
|
-
end: new Date('2022-12-17T17:00:00.000Z'),
|
|
14
|
-
});
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
it('Should return 2 HOURS when interval is set to HOURS', () => {
|
|
18
|
-
expect(periodForReferenceDate(new Date('2022-12-03T17:00:00.000Z'), 2, 'HOURS')).toEqual({
|
|
19
|
-
start: new Date('2022-12-03T17:00:00.000Z'),
|
|
20
|
-
end: new Date('2022-12-03T19:00:00.000Z'),
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
});
|
package/src/types.ts
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import type { IBaseAdapter, IBaseDirector } from '@unchainedshop/utils';
|
|
2
|
-
import type { TimestampFields, LogFields, Address, Contact } from '@unchainedshop/mongodb';
|
|
3
|
-
import { Product, ProductPlan } from '@unchainedshop/core-products';
|
|
4
|
-
import { OrderPosition } from '@unchainedshop/core-orders';
|
|
5
|
-
import { UnchainedCore } from '@unchainedshop/core';
|
|
6
|
-
|
|
7
|
-
export enum EnrollmentStatus {
|
|
8
|
-
INITIAL = 'INITIAL',
|
|
9
|
-
ACTIVE = 'ACTIVE',
|
|
10
|
-
PAUSED = 'PAUSED',
|
|
11
|
-
TERMINATED = 'TERMINATED',
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface EnrollmentPeriod {
|
|
15
|
-
start: Date;
|
|
16
|
-
end: Date;
|
|
17
|
-
orderId?: string;
|
|
18
|
-
isTrial?: boolean;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface EnrollmentPlan {
|
|
22
|
-
configuration: Array<{ key: string; value: string }>;
|
|
23
|
-
productId: string;
|
|
24
|
-
quantity: number;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export type EnrollmentQuery = {
|
|
28
|
-
status?: Array<EnrollmentStatus>;
|
|
29
|
-
userId?: string;
|
|
30
|
-
queryString?: string;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
export type Enrollment = {
|
|
34
|
-
_id?: string;
|
|
35
|
-
billingAddress: Address;
|
|
36
|
-
configuration: Array<{ key: string; value: string }>;
|
|
37
|
-
contact: Contact;
|
|
38
|
-
context?: any;
|
|
39
|
-
countryCode?: string;
|
|
40
|
-
currencyCode?: string;
|
|
41
|
-
delivery: {
|
|
42
|
-
deliveryProviderId?: string;
|
|
43
|
-
context?: any;
|
|
44
|
-
};
|
|
45
|
-
enrollmentNumber?: string;
|
|
46
|
-
expires?: Date;
|
|
47
|
-
meta?: any;
|
|
48
|
-
payment: {
|
|
49
|
-
paymentProviderId?: string;
|
|
50
|
-
context?: any;
|
|
51
|
-
};
|
|
52
|
-
periods: Array<EnrollmentPeriod>;
|
|
53
|
-
productId: string;
|
|
54
|
-
quantity?: number;
|
|
55
|
-
status: string;
|
|
56
|
-
userId: string;
|
|
57
|
-
} & LogFields &
|
|
58
|
-
TimestampFields;
|
|
59
|
-
|
|
60
|
-
// Director
|
|
61
|
-
|
|
62
|
-
export type EnrollmentContext = {
|
|
63
|
-
enrollment: Enrollment;
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
export interface EnrollmentAdapterActions {
|
|
67
|
-
configurationForOrder: (params: {
|
|
68
|
-
period: EnrollmentPeriod;
|
|
69
|
-
products: Array<Product>;
|
|
70
|
-
}) => Promise<any>;
|
|
71
|
-
isOverdue: () => Promise<boolean>;
|
|
72
|
-
isValidForActivation: () => Promise<boolean>;
|
|
73
|
-
nextPeriod: () => Promise<EnrollmentPeriod>;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export type IEnrollmentAdapter = IBaseAdapter & {
|
|
77
|
-
isActivatedFor: (productPlan?: ProductPlan) => boolean;
|
|
78
|
-
|
|
79
|
-
transformOrderItemToEnrollmentPlan: (
|
|
80
|
-
orderPosition: OrderPosition,
|
|
81
|
-
unchainedAPI: UnchainedCore,
|
|
82
|
-
) => Promise<EnrollmentPlan>;
|
|
83
|
-
|
|
84
|
-
actions: (params: EnrollmentContext & UnchainedCore) => EnrollmentAdapterActions;
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
export interface EnrollmentData {
|
|
88
|
-
billingAddress: Address;
|
|
89
|
-
configuration?: Array<{ key: string; value: string }>;
|
|
90
|
-
contact: Contact;
|
|
91
|
-
countryCode?: string;
|
|
92
|
-
currencyCode?: string;
|
|
93
|
-
delivery: Enrollment['delivery'];
|
|
94
|
-
meta?: any;
|
|
95
|
-
orderIdForFirstPeriod?: string;
|
|
96
|
-
payment: Enrollment['payment'];
|
|
97
|
-
productId: string;
|
|
98
|
-
quantity: number;
|
|
99
|
-
userId: string;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export type IEnrollmentDirector = IBaseDirector<IEnrollmentAdapter> & {
|
|
103
|
-
transformOrderItemToEnrollment: (
|
|
104
|
-
item: { orderPosition: OrderPosition; product: Product },
|
|
105
|
-
doc: Omit<EnrollmentData, 'configuration' | 'productId' | 'quantity'>,
|
|
106
|
-
unchainedAPI: UnchainedCore,
|
|
107
|
-
) => Promise<EnrollmentData>;
|
|
108
|
-
|
|
109
|
-
actions: (
|
|
110
|
-
enrollmentContext: EnrollmentContext,
|
|
111
|
-
unchainedAPI: UnchainedCore,
|
|
112
|
-
) => Promise<EnrollmentAdapterActions>;
|
|
113
|
-
};
|