@stamhoofd/backend 2.74.0 → 2.75.1
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/index.ts +7 -2
- package/package.json +13 -13
- package/src/crons/update-cached-balances.ts +1 -2
- package/src/endpoints/admin/organizations/GetOrganizationsEndpoint.ts +2 -2
- package/src/endpoints/auth/CreateAdminEndpoint.ts +4 -15
- package/src/endpoints/auth/OpenIDConnectStartEndpoint.ts +0 -5
- package/src/endpoints/global/audit-logs/GetAuditLogsEndpoint.ts +2 -2
- package/src/endpoints/global/events/GetEventNotificationsCountEndpoint.ts +43 -0
- package/src/endpoints/global/events/GetEventNotificationsEndpoint.ts +181 -0
- package/src/endpoints/global/events/GetEventsEndpoint.ts +2 -2
- package/src/endpoints/global/events/PatchEventNotificationsEndpoint.ts +288 -0
- package/src/endpoints/global/events/PatchEventsEndpoint.ts +2 -2
- package/src/endpoints/global/files/UploadFile.ts +56 -4
- package/src/endpoints/global/files/UploadImage.ts +9 -3
- package/src/endpoints/global/members/GetMembersEndpoint.ts +2 -2
- package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.ts +10 -1
- package/src/endpoints/global/platform/GetPlatformAdminsEndpoint.ts +1 -5
- package/src/endpoints/global/platform/PatchPlatformEnpoint.ts +7 -0
- package/src/endpoints/global/registration/GetUserDocumentsEndpoint.ts +1 -1
- package/src/endpoints/global/registration/RegisterMembersEndpoint.test.ts +2084 -164
- package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +2 -2
- package/src/endpoints/global/registration-periods/PatchRegistrationPeriodsEndpoint.ts +48 -2
- package/src/endpoints/organization/dashboard/documents/GetDocumentsEndpoint.ts +2 -2
- package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/payments/GetPaymentsEndpoint.ts +2 -2
- package/src/endpoints/organization/dashboard/receivable-balances/GetReceivableBalancesEndpoint.ts +2 -2
- package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.ts +8 -0
- package/src/endpoints/organization/dashboard/users/GetOrganizationAdminsEndpoint.ts +3 -3
- package/src/endpoints/organization/dashboard/webshops/GetWebshopOrdersEndpoint.ts +2 -2
- package/src/endpoints/organization/dashboard/webshops/GetWebshopTicketsEndpoint.ts +2 -2
- package/src/endpoints/organization/webshops/PlaceOrderEndpoint.ts +1 -2
- package/src/helpers/AdminPermissionChecker.ts +80 -2
- package/src/helpers/AuthenticatedStructures.ts +88 -2
- package/src/helpers/FlagMomentCleanup.ts +1 -8
- package/src/helpers/GlobalHelper.ts +15 -0
- package/src/helpers/MembershipCharger.ts +2 -1
- package/src/services/EventNotificationService.ts +201 -0
- package/src/services/FileSignService.ts +217 -0
- package/src/services/SSOService.ts +7 -2
- package/src/sql-filters/event-notifications.ts +39 -0
- package/src/sql-filters/organizations.ts +1 -1
- package/src/sql-sorters/event-notifications.ts +96 -0
- package/src/sql-sorters/events.ts +2 -2
- package/src/sql-sorters/organizations.ts +2 -2
- package/tests/e2e/private-files.test.ts +497 -0
- package/tests/e2e/register.test.ts +1197 -0
- package/tests/helpers/TestServer.ts +3 -0
- package/tests/jest.setup.ts +15 -2
- package/tsconfig.json +1 -0
|
@@ -0,0 +1,1197 @@
|
|
|
1
|
+
import { Request } from '@simonbackx/simple-endpoints';
|
|
2
|
+
import { BalanceItemFactory, GroupFactory, MemberFactory, MemberWithRegistrations, Organization, OrganizationFactory, OrganizationRegistrationPeriod, Platform, RegistrationPeriod, RegistrationPeriodFactory, Token, UserFactory } from '@stamhoofd/models';
|
|
3
|
+
import { AdministrationFeeSettings, BalanceItemCartItem, BalanceItemStatus, BalanceItemType, BooleanStatus, DefaultAgeGroup, FreeContributionSettings, GroupOption, GroupOptionMenu, IDRegisterCart, IDRegisterCheckout, IDRegisterItem, PaymentMethod, PermissionLevel, Permissions, PlatformMembershipType, PlatformMembershipTypeConfig, ReceivableBalanceType, ReduceablePrice, RegisterItemOption, Version } from '@stamhoofd/structures';
|
|
4
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
5
|
+
import { GetMemberFamilyEndpoint } from '../../src/endpoints/global/members/GetMemberFamilyEndpoint';
|
|
6
|
+
import { RegisterMembersEndpoint } from '../../src/endpoints/global/registration/RegisterMembersEndpoint';
|
|
7
|
+
import { GetMemberBalanceEndpoint } from '../../src/endpoints/organization/dashboard/payments/GetMemberBalanceEndpoint';
|
|
8
|
+
import { GetReceivableBalanceEndpoint } from '../../src/endpoints/organization/dashboard/receivable-balances/GetReceivableBalanceEndpoint';
|
|
9
|
+
import { testServer } from '../helpers/TestServer';
|
|
10
|
+
|
|
11
|
+
describe('E2E.Register', () => {
|
|
12
|
+
// #region global
|
|
13
|
+
const registerEndpoint = new RegisterMembersEndpoint();
|
|
14
|
+
const memberBalanceEndpoint = new GetMemberBalanceEndpoint();
|
|
15
|
+
const receivableBalancesEndpoint = new GetReceivableBalanceEndpoint();
|
|
16
|
+
const getMemberFamilyEndpoint = new GetMemberFamilyEndpoint();
|
|
17
|
+
|
|
18
|
+
let period: RegistrationPeriod;
|
|
19
|
+
|
|
20
|
+
// #region helpers
|
|
21
|
+
const register = async (body: IDRegisterCheckout, organization: Organization, token: Token) => {
|
|
22
|
+
const request = Request.buildJson('POST', `/v${Version}/members/register`, organization.getApiHost(), body);
|
|
23
|
+
request.headers.authorization = 'Bearer ' + token.accessToken;
|
|
24
|
+
return await testServer.test(registerEndpoint, request);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const getBalance = async (memberId: string, organization: Organization, token: Token) => {
|
|
28
|
+
const request = Request.buildJson('GET', `/v${Version}/organization/members/${memberId}/balance`, organization.getApiHost());
|
|
29
|
+
request.headers.authorization = 'Bearer ' + token.accessToken;
|
|
30
|
+
return await testServer.test(memberBalanceEndpoint, request);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const getReceivableBalance = async (type: ReceivableBalanceType, id: string, organization: Organization, token: Token) => {
|
|
34
|
+
const request = Request.buildJson('GET', `/v${Version}/receivable-balances/${type}/${id}`, organization.getApiHost());
|
|
35
|
+
request.headers.authorization = 'Bearer ' + token.accessToken;
|
|
36
|
+
return await testServer.test(receivableBalancesEndpoint, request);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const getMemberFamily = async (memberId: string, organization: Organization, token: Token) => {
|
|
40
|
+
const request = Request.buildJson('GET', `/v${Version}/organization/members/${memberId}/family`, organization.getApiHost());
|
|
41
|
+
request.headers.authorization = 'Bearer ' + token.accessToken;
|
|
42
|
+
return await testServer.test(getMemberFamilyEndpoint, request);
|
|
43
|
+
};
|
|
44
|
+
// #endregion
|
|
45
|
+
|
|
46
|
+
// #endregion
|
|
47
|
+
|
|
48
|
+
beforeAll(async () => {
|
|
49
|
+
const previousPeriod = await new RegistrationPeriodFactory({
|
|
50
|
+
startDate: new Date(2022, 0, 1),
|
|
51
|
+
endDate: new Date(2022, 11, 31),
|
|
52
|
+
}).create();
|
|
53
|
+
|
|
54
|
+
period = await new RegistrationPeriodFactory({
|
|
55
|
+
startDate: new Date(2023, 0, 1),
|
|
56
|
+
endDate: new Date(2023, 11, 31),
|
|
57
|
+
}).create();
|
|
58
|
+
|
|
59
|
+
period.previousPeriodId = previousPeriod.id;
|
|
60
|
+
await period.save();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const initData = async ({ otherMemberAmount = 0, permissionLevel = PermissionLevel.Full }: { otherMemberAmount?: number; permissionLevel?: PermissionLevel } = {}) => {
|
|
64
|
+
const organization = await new OrganizationFactory({ period })
|
|
65
|
+
.create();
|
|
66
|
+
|
|
67
|
+
const user = await new UserFactory({
|
|
68
|
+
organization,
|
|
69
|
+
permissions: Permissions.create({
|
|
70
|
+
level: permissionLevel,
|
|
71
|
+
}),
|
|
72
|
+
})
|
|
73
|
+
.create();
|
|
74
|
+
|
|
75
|
+
const token = await Token.createToken(user);
|
|
76
|
+
|
|
77
|
+
const member = await new MemberFactory({ organization, user })
|
|
78
|
+
.create();
|
|
79
|
+
|
|
80
|
+
const otherMembers: MemberWithRegistrations[] = [];
|
|
81
|
+
|
|
82
|
+
for (let i = 0; i < otherMemberAmount; i++) {
|
|
83
|
+
otherMembers.push(await new MemberFactory({ organization, user })
|
|
84
|
+
.create());
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const group = await new GroupFactory({
|
|
88
|
+
organization,
|
|
89
|
+
price: 25,
|
|
90
|
+
reducedPrice: 21,
|
|
91
|
+
stock: 5,
|
|
92
|
+
})
|
|
93
|
+
.create();
|
|
94
|
+
|
|
95
|
+
const groupPrice = group.settings.prices[0];
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
organization,
|
|
99
|
+
user,
|
|
100
|
+
token,
|
|
101
|
+
member,
|
|
102
|
+
otherMembers,
|
|
103
|
+
group,
|
|
104
|
+
groupPrice,
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
beforeEach(async () => {
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
describe('Register', () => {
|
|
112
|
+
test('Register by member should create balance for member', async () => {
|
|
113
|
+
// #region arrange
|
|
114
|
+
const { organization, group, groupPrice, token, member } = await initData();
|
|
115
|
+
|
|
116
|
+
const body = IDRegisterCheckout.create({
|
|
117
|
+
cart: IDRegisterCart.create({
|
|
118
|
+
items: [
|
|
119
|
+
IDRegisterItem.create({
|
|
120
|
+
id: uuidv4(),
|
|
121
|
+
replaceRegistrationIds: [],
|
|
122
|
+
options: [],
|
|
123
|
+
groupPrice,
|
|
124
|
+
organizationId: organization.id,
|
|
125
|
+
groupId: group.id,
|
|
126
|
+
memberId: member.id,
|
|
127
|
+
}),
|
|
128
|
+
],
|
|
129
|
+
balanceItems: [
|
|
130
|
+
],
|
|
131
|
+
deleteRegistrationIds: [],
|
|
132
|
+
}),
|
|
133
|
+
administrationFee: 0,
|
|
134
|
+
freeContribution: 0,
|
|
135
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
136
|
+
totalPrice: 25,
|
|
137
|
+
customer: null,
|
|
138
|
+
});
|
|
139
|
+
// #endregion
|
|
140
|
+
|
|
141
|
+
// #region act and assert
|
|
142
|
+
const balanceBefore = await getBalance(member.id, organization, token);
|
|
143
|
+
expect(balanceBefore).toBeDefined();
|
|
144
|
+
expect(balanceBefore.body.length).toBe(0);
|
|
145
|
+
|
|
146
|
+
await register(body, organization, token);
|
|
147
|
+
|
|
148
|
+
const balance = await getBalance(member.id, organization, token);
|
|
149
|
+
expect(balance).toBeDefined();
|
|
150
|
+
expect(balance.body.length).toBe(1);
|
|
151
|
+
expect(balance.body[0].price).toBe(25);
|
|
152
|
+
expect(balance.body[0].pricePaid).toBe(0);
|
|
153
|
+
// #endregion
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
test('Should create balance items for options', async () => {
|
|
157
|
+
// #region arrange
|
|
158
|
+
const { organization, group, groupPrice, token, member } = await initData();
|
|
159
|
+
|
|
160
|
+
const option1 = GroupOption.create({
|
|
161
|
+
name: 'option 1',
|
|
162
|
+
price: ReduceablePrice.create({
|
|
163
|
+
price: 5,
|
|
164
|
+
reducedPrice: 3,
|
|
165
|
+
}),
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
const option2 = GroupOption.create({
|
|
169
|
+
name: 'option 2',
|
|
170
|
+
price: ReduceablePrice.create({
|
|
171
|
+
price: 3,
|
|
172
|
+
reducedPrice: 1,
|
|
173
|
+
}),
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
const optionMenu = GroupOptionMenu.create({
|
|
177
|
+
name: 'option menu 1',
|
|
178
|
+
multipleChoice: true,
|
|
179
|
+
options: [option1, option2],
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
group.settings.optionMenus = [
|
|
183
|
+
optionMenu,
|
|
184
|
+
];
|
|
185
|
+
|
|
186
|
+
await group.save();
|
|
187
|
+
|
|
188
|
+
const body = IDRegisterCheckout.create({
|
|
189
|
+
cart: IDRegisterCart.create({
|
|
190
|
+
items: [
|
|
191
|
+
IDRegisterItem.create({
|
|
192
|
+
id: uuidv4(),
|
|
193
|
+
replaceRegistrationIds: [],
|
|
194
|
+
options: [
|
|
195
|
+
RegisterItemOption.create({
|
|
196
|
+
option: option1,
|
|
197
|
+
amount: 2,
|
|
198
|
+
optionMenu,
|
|
199
|
+
}),
|
|
200
|
+
RegisterItemOption.create({
|
|
201
|
+
option: option2,
|
|
202
|
+
amount: 5,
|
|
203
|
+
optionMenu,
|
|
204
|
+
}),
|
|
205
|
+
],
|
|
206
|
+
groupPrice,
|
|
207
|
+
organizationId: organization.id,
|
|
208
|
+
groupId: group.id,
|
|
209
|
+
memberId: member.id,
|
|
210
|
+
}),
|
|
211
|
+
],
|
|
212
|
+
balanceItems: [
|
|
213
|
+
],
|
|
214
|
+
deleteRegistrationIds: [],
|
|
215
|
+
}),
|
|
216
|
+
administrationFee: 0,
|
|
217
|
+
freeContribution: 0,
|
|
218
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
219
|
+
totalPrice: 50,
|
|
220
|
+
customer: null,
|
|
221
|
+
});
|
|
222
|
+
// #endregion
|
|
223
|
+
|
|
224
|
+
// #region act and assert
|
|
225
|
+
const balanceBefore = await getBalance(member.id, organization, token);
|
|
226
|
+
expect(balanceBefore).toBeDefined();
|
|
227
|
+
expect(balanceBefore.body.length).toBe(0);
|
|
228
|
+
|
|
229
|
+
await register(body, organization, token);
|
|
230
|
+
|
|
231
|
+
const balance = await getBalance(member.id, organization, token);
|
|
232
|
+
expect(balance).toBeDefined();
|
|
233
|
+
expect(balance.body.length).toBe(3);
|
|
234
|
+
expect(balance.body).toEqual(expect.arrayContaining([
|
|
235
|
+
expect.objectContaining({
|
|
236
|
+
price: 25,
|
|
237
|
+
pricePaid: 0,
|
|
238
|
+
}),
|
|
239
|
+
expect.objectContaining({
|
|
240
|
+
price: 15,
|
|
241
|
+
pricePaid: 0,
|
|
242
|
+
}),
|
|
243
|
+
expect.objectContaining({
|
|
244
|
+
price: 10,
|
|
245
|
+
pricePaid: 0,
|
|
246
|
+
}),
|
|
247
|
+
]));
|
|
248
|
+
// #endregion
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
test('Should reset free contribution if no options on organization', async () => {
|
|
252
|
+
// #region arrange
|
|
253
|
+
const { organization, group, groupPrice, token, member, user } = await initData();
|
|
254
|
+
|
|
255
|
+
const body = IDRegisterCheckout.create({
|
|
256
|
+
cart: IDRegisterCart.create({
|
|
257
|
+
items: [
|
|
258
|
+
IDRegisterItem.create({
|
|
259
|
+
id: uuidv4(),
|
|
260
|
+
replaceRegistrationIds: [],
|
|
261
|
+
options: [],
|
|
262
|
+
groupPrice,
|
|
263
|
+
organizationId: organization.id,
|
|
264
|
+
groupId: group.id,
|
|
265
|
+
memberId: member.id,
|
|
266
|
+
}),
|
|
267
|
+
],
|
|
268
|
+
balanceItems: [
|
|
269
|
+
],
|
|
270
|
+
deleteRegistrationIds: [],
|
|
271
|
+
}),
|
|
272
|
+
administrationFee: 0,
|
|
273
|
+
freeContribution: 31,
|
|
274
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
275
|
+
totalPrice: 25,
|
|
276
|
+
customer: null,
|
|
277
|
+
});
|
|
278
|
+
// #endregion
|
|
279
|
+
|
|
280
|
+
// #region act and assert
|
|
281
|
+
const receivableBalanceBefore = await getReceivableBalance(ReceivableBalanceType.user, user.id, organization, token);
|
|
282
|
+
expect(receivableBalanceBefore).toBeDefined();
|
|
283
|
+
expect(receivableBalanceBefore.body.balanceItems.length).toBe(0);
|
|
284
|
+
expect(receivableBalanceBefore.body.amountOpen).toBe(0);
|
|
285
|
+
|
|
286
|
+
await register(body, organization, token);
|
|
287
|
+
|
|
288
|
+
const receivableBalanceAfter = await getReceivableBalance(ReceivableBalanceType.user, user.id, organization, token);
|
|
289
|
+
expect(receivableBalanceAfter).toBeDefined();
|
|
290
|
+
expect(receivableBalanceAfter.body.balanceItems.length).toBe(1);
|
|
291
|
+
expect(receivableBalanceAfter.body.amountOpen).toBe(0);
|
|
292
|
+
expect(receivableBalanceAfter.body.balanceItems).toEqual(expect.arrayContaining([
|
|
293
|
+
expect.objectContaining({
|
|
294
|
+
price: 25,
|
|
295
|
+
pricePaid: 0,
|
|
296
|
+
}),
|
|
297
|
+
]));
|
|
298
|
+
// #endregion
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
test('Should create balance item for free contribution', async () => {
|
|
302
|
+
// #region arrange
|
|
303
|
+
const { organization, group, groupPrice, token, member, user } = await initData();
|
|
304
|
+
|
|
305
|
+
organization.meta.recordsConfiguration.freeContribution = FreeContributionSettings.create({
|
|
306
|
+
description: 'free contribution settings',
|
|
307
|
+
amounts: [30, 20],
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
await organization.save();
|
|
311
|
+
|
|
312
|
+
const body = IDRegisterCheckout.create({
|
|
313
|
+
cart: IDRegisterCart.create({
|
|
314
|
+
items: [
|
|
315
|
+
IDRegisterItem.create({
|
|
316
|
+
id: uuidv4(),
|
|
317
|
+
replaceRegistrationIds: [],
|
|
318
|
+
options: [],
|
|
319
|
+
groupPrice,
|
|
320
|
+
organizationId: organization.id,
|
|
321
|
+
groupId: group.id,
|
|
322
|
+
memberId: member.id,
|
|
323
|
+
}),
|
|
324
|
+
],
|
|
325
|
+
balanceItems: [
|
|
326
|
+
],
|
|
327
|
+
deleteRegistrationIds: [],
|
|
328
|
+
}),
|
|
329
|
+
administrationFee: 0,
|
|
330
|
+
freeContribution: 30,
|
|
331
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
332
|
+
totalPrice: 55,
|
|
333
|
+
customer: null,
|
|
334
|
+
});
|
|
335
|
+
// #endregion
|
|
336
|
+
|
|
337
|
+
// #region act and assert
|
|
338
|
+
const receivableBalanceBefore = await getReceivableBalance(ReceivableBalanceType.user, user.id, organization, token);
|
|
339
|
+
expect(receivableBalanceBefore).toBeDefined();
|
|
340
|
+
expect(receivableBalanceBefore.body.balanceItems.length).toBe(0);
|
|
341
|
+
expect(receivableBalanceBefore.body.amountOpen).toBe(0);
|
|
342
|
+
|
|
343
|
+
await register(body, organization, token);
|
|
344
|
+
|
|
345
|
+
const receivableBalanceAfter = await getReceivableBalance(ReceivableBalanceType.user, user.id, organization, token);
|
|
346
|
+
expect(receivableBalanceAfter).toBeDefined();
|
|
347
|
+
expect(receivableBalanceAfter.body.balanceItems.length).toBe(2);
|
|
348
|
+
expect(receivableBalanceAfter.body.amountPending).toBe(55);
|
|
349
|
+
|
|
350
|
+
expect(receivableBalanceAfter.body.balanceItems).toEqual(expect.arrayContaining([
|
|
351
|
+
expect.objectContaining({
|
|
352
|
+
price: 30,
|
|
353
|
+
pricePaid: 0,
|
|
354
|
+
type: BalanceItemType.FreeContribution,
|
|
355
|
+
}),
|
|
356
|
+
expect.objectContaining({
|
|
357
|
+
price: 25,
|
|
358
|
+
pricePaid: 0,
|
|
359
|
+
}),
|
|
360
|
+
]));
|
|
361
|
+
// #endregion
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
test('Should create balance item for free administration fee if register by member', async () => {
|
|
365
|
+
// #region arrange
|
|
366
|
+
const { organization, group, groupPrice, token, member, user } = await initData();
|
|
367
|
+
|
|
368
|
+
organization.meta.registrationPaymentConfiguration.administrationFee = AdministrationFeeSettings.create({
|
|
369
|
+
fixed: 33,
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
await organization.save();
|
|
373
|
+
|
|
374
|
+
const body = IDRegisterCheckout.create({
|
|
375
|
+
cart: IDRegisterCart.create({
|
|
376
|
+
items: [
|
|
377
|
+
IDRegisterItem.create({
|
|
378
|
+
id: uuidv4(),
|
|
379
|
+
replaceRegistrationIds: [],
|
|
380
|
+
options: [],
|
|
381
|
+
groupPrice,
|
|
382
|
+
organizationId: organization.id,
|
|
383
|
+
groupId: group.id,
|
|
384
|
+
memberId: member.id,
|
|
385
|
+
}),
|
|
386
|
+
],
|
|
387
|
+
balanceItems: [
|
|
388
|
+
],
|
|
389
|
+
deleteRegistrationIds: [],
|
|
390
|
+
}),
|
|
391
|
+
administrationFee: 33,
|
|
392
|
+
freeContribution: 0,
|
|
393
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
394
|
+
totalPrice: 58,
|
|
395
|
+
});
|
|
396
|
+
// #endregion
|
|
397
|
+
|
|
398
|
+
// #region act and assert
|
|
399
|
+
const receivableBalanceBefore = await getReceivableBalance(ReceivableBalanceType.user, user.id, organization
|
|
400
|
+
, token);
|
|
401
|
+
expect(receivableBalanceBefore).toBeDefined();
|
|
402
|
+
expect(receivableBalanceBefore.body.balanceItems.length).toBe(0);
|
|
403
|
+
expect(receivableBalanceBefore.body.amountOpen).toBe(0);
|
|
404
|
+
|
|
405
|
+
await register(body, organization, token);
|
|
406
|
+
|
|
407
|
+
const receivableBalanceAfter = await getReceivableBalance(ReceivableBalanceType.user, user.id, organization, token);
|
|
408
|
+
expect(receivableBalanceAfter).toBeDefined();
|
|
409
|
+
expect(receivableBalanceAfter.body.balanceItems.length).toBe(2);
|
|
410
|
+
expect(receivableBalanceAfter.body.amountPending).toBe(58);
|
|
411
|
+
|
|
412
|
+
expect(receivableBalanceAfter.body.balanceItems).toEqual(expect.arrayContaining([
|
|
413
|
+
expect.objectContaining({
|
|
414
|
+
price: 25,
|
|
415
|
+
pricePaid: 0,
|
|
416
|
+
type: BalanceItemType.Registration,
|
|
417
|
+
}),
|
|
418
|
+
expect.objectContaining({
|
|
419
|
+
price: 33,
|
|
420
|
+
pricePaid: 0,
|
|
421
|
+
type: BalanceItemType.AdministrationFee,
|
|
422
|
+
}),
|
|
423
|
+
]));
|
|
424
|
+
// #endregion
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
test('Should create balance item for cart item', async () => {
|
|
428
|
+
// #region arrange
|
|
429
|
+
const { organization, group, groupPrice, token, member, user } = await initData();
|
|
430
|
+
|
|
431
|
+
const balanceItem1 = await new BalanceItemFactory({
|
|
432
|
+
organizationId: organization.id,
|
|
433
|
+
memberId: member.id,
|
|
434
|
+
userId: user.id,
|
|
435
|
+
payingOrganizationId: organization.id,
|
|
436
|
+
type: BalanceItemType.Registration,
|
|
437
|
+
amount: 10,
|
|
438
|
+
unitPrice: 2,
|
|
439
|
+
}).create();
|
|
440
|
+
|
|
441
|
+
const cartItem = BalanceItemCartItem.create({
|
|
442
|
+
item: balanceItem1.getStructure(),
|
|
443
|
+
price: 10,
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
const body = IDRegisterCheckout.create({
|
|
447
|
+
cart: IDRegisterCart.create({
|
|
448
|
+
items: [
|
|
449
|
+
IDRegisterItem.create({
|
|
450
|
+
id: uuidv4(),
|
|
451
|
+
replaceRegistrationIds: [],
|
|
452
|
+
options: [],
|
|
453
|
+
groupPrice,
|
|
454
|
+
organizationId: organization.id,
|
|
455
|
+
groupId: group.id,
|
|
456
|
+
memberId: member.id,
|
|
457
|
+
}),
|
|
458
|
+
],
|
|
459
|
+
balanceItems: [
|
|
460
|
+
cartItem,
|
|
461
|
+
],
|
|
462
|
+
deleteRegistrationIds: [],
|
|
463
|
+
}),
|
|
464
|
+
administrationFee: 0,
|
|
465
|
+
freeContribution: 0,
|
|
466
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
467
|
+
totalPrice: 35,
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
// #endregion
|
|
471
|
+
|
|
472
|
+
// #region act and assert
|
|
473
|
+
const response = await register(body, organization, token);
|
|
474
|
+
expect(response.body.registrations.length).toBe(1);
|
|
475
|
+
|
|
476
|
+
const receivableBalanceAfter = await getReceivableBalance(ReceivableBalanceType.user, user.id, organization, token);
|
|
477
|
+
|
|
478
|
+
expect(receivableBalanceAfter.body.balanceItems.length).toBe(2);
|
|
479
|
+
expect(receivableBalanceAfter.body.amountPending).toBe(35);
|
|
480
|
+
expect(receivableBalanceAfter.body.amountOpen).toBe(10);
|
|
481
|
+
|
|
482
|
+
expect(receivableBalanceAfter.body.balanceItems).toEqual(expect.arrayContaining([
|
|
483
|
+
expect.objectContaining({
|
|
484
|
+
pricePending: 10,
|
|
485
|
+
}),
|
|
486
|
+
expect.objectContaining({
|
|
487
|
+
pricePending: 25,
|
|
488
|
+
}),
|
|
489
|
+
]));
|
|
490
|
+
// #endregion
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
test('Should apply reduced price if member requires financial support', async () => {
|
|
494
|
+
// #region arrange
|
|
495
|
+
const { organization, group, groupPrice, token, member } = await initData();
|
|
496
|
+
member.details.requiresFinancialSupport = BooleanStatus.create({
|
|
497
|
+
value: true,
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
await member.save();
|
|
501
|
+
|
|
502
|
+
const body = IDRegisterCheckout.create({
|
|
503
|
+
cart: IDRegisterCart.create({
|
|
504
|
+
items: [
|
|
505
|
+
IDRegisterItem.create({
|
|
506
|
+
id: uuidv4(),
|
|
507
|
+
replaceRegistrationIds: [],
|
|
508
|
+
options: [],
|
|
509
|
+
groupPrice,
|
|
510
|
+
organizationId: organization.id,
|
|
511
|
+
groupId: group.id,
|
|
512
|
+
memberId: member.id,
|
|
513
|
+
}),
|
|
514
|
+
],
|
|
515
|
+
balanceItems: [
|
|
516
|
+
],
|
|
517
|
+
deleteRegistrationIds: [],
|
|
518
|
+
}),
|
|
519
|
+
administrationFee: 0,
|
|
520
|
+
freeContribution: 0,
|
|
521
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
522
|
+
totalPrice: 21,
|
|
523
|
+
customer: null,
|
|
524
|
+
});
|
|
525
|
+
// #endregion
|
|
526
|
+
|
|
527
|
+
// #region act and assert
|
|
528
|
+
const balanceBefore = await getBalance(member.id, organization, token);
|
|
529
|
+
expect(balanceBefore).toBeDefined();
|
|
530
|
+
expect(balanceBefore.body.length).toBe(0);
|
|
531
|
+
|
|
532
|
+
await register(body, organization, token);
|
|
533
|
+
|
|
534
|
+
const balance = await getBalance(member.id, organization, token);
|
|
535
|
+
expect(balance).toBeDefined();
|
|
536
|
+
expect(balance.body.length).toBe(1);
|
|
537
|
+
expect(balance.body[0].price).toBe(21);
|
|
538
|
+
expect(balance.body[0].pricePaid).toBe(0);
|
|
539
|
+
// #endregion
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
test('Should apply reduced price for options if member requires financial support', async () => {
|
|
543
|
+
// #region arrange
|
|
544
|
+
const { organization, group, groupPrice, token, member } = await initData();
|
|
545
|
+
member.details.requiresFinancialSupport = BooleanStatus.create({
|
|
546
|
+
value: true,
|
|
547
|
+
});
|
|
548
|
+
|
|
549
|
+
await member.save();
|
|
550
|
+
|
|
551
|
+
const option1 = GroupOption.create({
|
|
552
|
+
name: 'option 1',
|
|
553
|
+
price: ReduceablePrice.create({
|
|
554
|
+
price: 5,
|
|
555
|
+
reducedPrice: 3,
|
|
556
|
+
}),
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
const option2 = GroupOption.create({
|
|
560
|
+
name: 'option 2',
|
|
561
|
+
price: ReduceablePrice.create({
|
|
562
|
+
price: 3,
|
|
563
|
+
reducedPrice: 1,
|
|
564
|
+
}),
|
|
565
|
+
});
|
|
566
|
+
|
|
567
|
+
const optionMenu = GroupOptionMenu.create({
|
|
568
|
+
name: 'option menu 1',
|
|
569
|
+
multipleChoice: true,
|
|
570
|
+
options: [option1, option2],
|
|
571
|
+
});
|
|
572
|
+
|
|
573
|
+
group.settings.optionMenus = [
|
|
574
|
+
optionMenu,
|
|
575
|
+
];
|
|
576
|
+
|
|
577
|
+
await group.save();
|
|
578
|
+
|
|
579
|
+
const body = IDRegisterCheckout.create({
|
|
580
|
+
cart: IDRegisterCart.create({
|
|
581
|
+
items: [
|
|
582
|
+
IDRegisterItem.create({
|
|
583
|
+
id: uuidv4(),
|
|
584
|
+
replaceRegistrationIds: [],
|
|
585
|
+
options: [
|
|
586
|
+
RegisterItemOption.create({
|
|
587
|
+
option: option1,
|
|
588
|
+
amount: 2,
|
|
589
|
+
optionMenu,
|
|
590
|
+
}),
|
|
591
|
+
RegisterItemOption.create({
|
|
592
|
+
option: option2,
|
|
593
|
+
amount: 5,
|
|
594
|
+
optionMenu,
|
|
595
|
+
}),
|
|
596
|
+
],
|
|
597
|
+
groupPrice,
|
|
598
|
+
organizationId: organization.id,
|
|
599
|
+
groupId: group.id,
|
|
600
|
+
memberId: member.id,
|
|
601
|
+
}),
|
|
602
|
+
],
|
|
603
|
+
balanceItems: [
|
|
604
|
+
],
|
|
605
|
+
deleteRegistrationIds: [],
|
|
606
|
+
}),
|
|
607
|
+
administrationFee: 0,
|
|
608
|
+
freeContribution: 0,
|
|
609
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
610
|
+
totalPrice: 32,
|
|
611
|
+
customer: null,
|
|
612
|
+
});
|
|
613
|
+
// #endregion
|
|
614
|
+
|
|
615
|
+
// #region act and assert
|
|
616
|
+
const balanceBefore = await getBalance(member.id, organization, token);
|
|
617
|
+
expect(balanceBefore).toBeDefined();
|
|
618
|
+
expect(balanceBefore.body.length).toBe(0);
|
|
619
|
+
|
|
620
|
+
await register(body, organization, token);
|
|
621
|
+
|
|
622
|
+
const balance = await getBalance(member.id, organization, token);
|
|
623
|
+
expect(balance).toBeDefined();
|
|
624
|
+
expect(balance.body.length).toBe(3);
|
|
625
|
+
expect.arrayContaining([
|
|
626
|
+
expect.objectContaining({
|
|
627
|
+
price: 6,
|
|
628
|
+
pricePaid: 0,
|
|
629
|
+
status: BalanceItemStatus.Due,
|
|
630
|
+
}),
|
|
631
|
+
expect.objectContaining({
|
|
632
|
+
price: 5,
|
|
633
|
+
pricePaid: 0,
|
|
634
|
+
status: BalanceItemStatus.Due,
|
|
635
|
+
}),
|
|
636
|
+
expect.objectContaining({
|
|
637
|
+
price: 25,
|
|
638
|
+
pricePaid: 0,
|
|
639
|
+
status: BalanceItemStatus.Due,
|
|
640
|
+
}),
|
|
641
|
+
]);
|
|
642
|
+
// #endregion
|
|
643
|
+
});
|
|
644
|
+
});
|
|
645
|
+
|
|
646
|
+
describe('Delete registrations', () => {
|
|
647
|
+
test('Should cancel balance item for deleted registration', async () => {
|
|
648
|
+
// #region arrange
|
|
649
|
+
const { member, group: group1, groupPrice: groupPrice1, organization, token } = await initData();
|
|
650
|
+
|
|
651
|
+
const body1 = IDRegisterCheckout.create({
|
|
652
|
+
cart: IDRegisterCart.create({
|
|
653
|
+
items: [
|
|
654
|
+
IDRegisterItem.create({
|
|
655
|
+
id: uuidv4(),
|
|
656
|
+
replaceRegistrationIds: [],
|
|
657
|
+
options: [],
|
|
658
|
+
groupPrice: groupPrice1,
|
|
659
|
+
organizationId: organization.id,
|
|
660
|
+
groupId: group1.id,
|
|
661
|
+
memberId: member.id,
|
|
662
|
+
}),
|
|
663
|
+
],
|
|
664
|
+
balanceItems: [
|
|
665
|
+
],
|
|
666
|
+
deleteRegistrationIds: [],
|
|
667
|
+
}),
|
|
668
|
+
administrationFee: 0,
|
|
669
|
+
freeContribution: 0,
|
|
670
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
671
|
+
totalPrice: 25,
|
|
672
|
+
customer: null,
|
|
673
|
+
asOrganizationId: organization.id,
|
|
674
|
+
});
|
|
675
|
+
|
|
676
|
+
const response1 = await register(body1, organization, token);
|
|
677
|
+
expect(response1.body).toBeDefined();
|
|
678
|
+
expect(response1.body.registrations.length).toBe(1);
|
|
679
|
+
|
|
680
|
+
const registrationToDelete = response1.body.registrations[0];
|
|
681
|
+
|
|
682
|
+
const group = await new GroupFactory({
|
|
683
|
+
organization,
|
|
684
|
+
price: 30,
|
|
685
|
+
stock: 5,
|
|
686
|
+
}).create();
|
|
687
|
+
|
|
688
|
+
const groupPrice = group.settings.prices[0];
|
|
689
|
+
|
|
690
|
+
const body2 = IDRegisterCheckout.create({
|
|
691
|
+
cart: IDRegisterCart.create({
|
|
692
|
+
items: [
|
|
693
|
+
IDRegisterItem.create({
|
|
694
|
+
id: uuidv4(),
|
|
695
|
+
replaceRegistrationIds: [],
|
|
696
|
+
options: [],
|
|
697
|
+
groupPrice,
|
|
698
|
+
organizationId: organization.id,
|
|
699
|
+
groupId: group.id,
|
|
700
|
+
memberId: member.id,
|
|
701
|
+
}),
|
|
702
|
+
],
|
|
703
|
+
balanceItems: [
|
|
704
|
+
],
|
|
705
|
+
deleteRegistrationIds: [registrationToDelete.id],
|
|
706
|
+
}),
|
|
707
|
+
administrationFee: 0,
|
|
708
|
+
freeContribution: 0,
|
|
709
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
710
|
+
totalPrice: 30,
|
|
711
|
+
customer: null,
|
|
712
|
+
asOrganizationId: organization.id,
|
|
713
|
+
});
|
|
714
|
+
// #endregion
|
|
715
|
+
|
|
716
|
+
// #region act and assert
|
|
717
|
+
const balanceBefore = await getBalance(member.id, organization, token);
|
|
718
|
+
expect(balanceBefore).toBeDefined();
|
|
719
|
+
expect(balanceBefore.body.length).toBe(1);
|
|
720
|
+
expect(balanceBefore.body[0].price).toBe(25);
|
|
721
|
+
expect(balanceBefore.body[0].pricePaid).toBe(0);
|
|
722
|
+
|
|
723
|
+
await register(body2, organization, token);
|
|
724
|
+
|
|
725
|
+
const balance = await getBalance(member.id, organization, token);
|
|
726
|
+
expect(balance).toBeDefined();
|
|
727
|
+
expect(balance.body.length).toBe(2);
|
|
728
|
+
|
|
729
|
+
expect.arrayContaining([
|
|
730
|
+
expect.objectContaining({
|
|
731
|
+
price: 25,
|
|
732
|
+
pricePaid: 0,
|
|
733
|
+
status: BalanceItemStatus.Canceled,
|
|
734
|
+
}),
|
|
735
|
+
expect.objectContaining({
|
|
736
|
+
price: 30,
|
|
737
|
+
pricePaid: 0,
|
|
738
|
+
status: BalanceItemStatus.Due,
|
|
739
|
+
}),
|
|
740
|
+
]);
|
|
741
|
+
// #endregion
|
|
742
|
+
});
|
|
743
|
+
|
|
744
|
+
test('Should cancel all related balance item for deleted registration', async () => {
|
|
745
|
+
// #region arrange
|
|
746
|
+
const { member, group: group1, groupPrice: groupPrice1, organization, token } = await initData();
|
|
747
|
+
|
|
748
|
+
const option1 = GroupOption.create({
|
|
749
|
+
name: 'option 1',
|
|
750
|
+
price: ReduceablePrice.create({
|
|
751
|
+
price: 5,
|
|
752
|
+
reducedPrice: 3,
|
|
753
|
+
}),
|
|
754
|
+
});
|
|
755
|
+
|
|
756
|
+
const option2 = GroupOption.create({
|
|
757
|
+
name: 'option 2',
|
|
758
|
+
price: ReduceablePrice.create({
|
|
759
|
+
price: 3,
|
|
760
|
+
reducedPrice: 1,
|
|
761
|
+
}),
|
|
762
|
+
});
|
|
763
|
+
|
|
764
|
+
const optionMenu = GroupOptionMenu.create({
|
|
765
|
+
name: 'option menu 1',
|
|
766
|
+
multipleChoice: true,
|
|
767
|
+
options: [option1, option2],
|
|
768
|
+
});
|
|
769
|
+
|
|
770
|
+
group1.settings.optionMenus = [
|
|
771
|
+
optionMenu,
|
|
772
|
+
];
|
|
773
|
+
|
|
774
|
+
await group1.save();
|
|
775
|
+
|
|
776
|
+
const body1 = IDRegisterCheckout.create({
|
|
777
|
+
cart: IDRegisterCart.create({
|
|
778
|
+
items: [
|
|
779
|
+
IDRegisterItem.create({
|
|
780
|
+
id: uuidv4(),
|
|
781
|
+
replaceRegistrationIds: [],
|
|
782
|
+
options: [
|
|
783
|
+
RegisterItemOption.create({
|
|
784
|
+
option: option1,
|
|
785
|
+
amount: 2,
|
|
786
|
+
optionMenu,
|
|
787
|
+
}),
|
|
788
|
+
RegisterItemOption.create({
|
|
789
|
+
option: option2,
|
|
790
|
+
amount: 5,
|
|
791
|
+
optionMenu,
|
|
792
|
+
}),
|
|
793
|
+
],
|
|
794
|
+
groupPrice: groupPrice1,
|
|
795
|
+
organizationId: organization.id,
|
|
796
|
+
groupId: group1.id,
|
|
797
|
+
memberId: member.id,
|
|
798
|
+
}),
|
|
799
|
+
],
|
|
800
|
+
balanceItems: [
|
|
801
|
+
],
|
|
802
|
+
deleteRegistrationIds: [],
|
|
803
|
+
}),
|
|
804
|
+
administrationFee: 0,
|
|
805
|
+
freeContribution: 0,
|
|
806
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
807
|
+
totalPrice: 50,
|
|
808
|
+
customer: null,
|
|
809
|
+
asOrganizationId: organization.id,
|
|
810
|
+
});
|
|
811
|
+
|
|
812
|
+
const response1 = await register(body1, organization, token);
|
|
813
|
+
expect(response1.body).toBeDefined();
|
|
814
|
+
expect(response1.body.registrations.length).toBe(1);
|
|
815
|
+
|
|
816
|
+
const registrationToDelete = response1.body.registrations[0];
|
|
817
|
+
|
|
818
|
+
const group = await new GroupFactory({
|
|
819
|
+
organization,
|
|
820
|
+
price: 30,
|
|
821
|
+
stock: 5,
|
|
822
|
+
}).create();
|
|
823
|
+
|
|
824
|
+
const groupPrice = group.settings.prices[0];
|
|
825
|
+
|
|
826
|
+
const body2 = IDRegisterCheckout.create({
|
|
827
|
+
cart: IDRegisterCart.create({
|
|
828
|
+
items: [
|
|
829
|
+
IDRegisterItem.create({
|
|
830
|
+
id: uuidv4(),
|
|
831
|
+
replaceRegistrationIds: [],
|
|
832
|
+
options: [],
|
|
833
|
+
groupPrice,
|
|
834
|
+
organizationId: organization.id,
|
|
835
|
+
groupId: group.id,
|
|
836
|
+
memberId: member.id,
|
|
837
|
+
}),
|
|
838
|
+
],
|
|
839
|
+
balanceItems: [
|
|
840
|
+
],
|
|
841
|
+
deleteRegistrationIds: [registrationToDelete.id],
|
|
842
|
+
}),
|
|
843
|
+
administrationFee: 0,
|
|
844
|
+
freeContribution: 0,
|
|
845
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
846
|
+
totalPrice: 30,
|
|
847
|
+
customer: null,
|
|
848
|
+
asOrganizationId: organization.id,
|
|
849
|
+
});
|
|
850
|
+
// #endregion
|
|
851
|
+
|
|
852
|
+
// #region act and assert
|
|
853
|
+
const balanceBefore = await getBalance(member.id, organization, token);
|
|
854
|
+
expect(balanceBefore).toBeDefined();
|
|
855
|
+
expect(balanceBefore.body.length).toBe(3);
|
|
856
|
+
|
|
857
|
+
await register(body2, organization, token);
|
|
858
|
+
|
|
859
|
+
const balance = await getBalance(member.id, organization, token);
|
|
860
|
+
expect(balance).toBeDefined();
|
|
861
|
+
expect(balance.body.length).toBe(4);
|
|
862
|
+
|
|
863
|
+
expect.arrayContaining([
|
|
864
|
+
expect.objectContaining({
|
|
865
|
+
price: 10,
|
|
866
|
+
pricePaid: 0,
|
|
867
|
+
status: BalanceItemStatus.Canceled,
|
|
868
|
+
}),
|
|
869
|
+
expect.objectContaining({
|
|
870
|
+
price: 15,
|
|
871
|
+
pricePaid: 0,
|
|
872
|
+
status: BalanceItemStatus.Canceled,
|
|
873
|
+
}),
|
|
874
|
+
expect.objectContaining({
|
|
875
|
+
price: 25,
|
|
876
|
+
pricePaid: 0,
|
|
877
|
+
status: BalanceItemStatus.Canceled,
|
|
878
|
+
}),
|
|
879
|
+
expect.objectContaining({
|
|
880
|
+
price: 30,
|
|
881
|
+
pricePaid: 0,
|
|
882
|
+
status: BalanceItemStatus.Due,
|
|
883
|
+
}),
|
|
884
|
+
]);
|
|
885
|
+
// #endregion
|
|
886
|
+
});
|
|
887
|
+
|
|
888
|
+
test('Should apply cancelation fee', async () => {
|
|
889
|
+
// #region arrange
|
|
890
|
+
const { member, group: group1, groupPrice: groupPrice1, organization, token } = await initData();
|
|
891
|
+
|
|
892
|
+
const body1 = IDRegisterCheckout.create({
|
|
893
|
+
cart: IDRegisterCart.create({
|
|
894
|
+
items: [
|
|
895
|
+
IDRegisterItem.create({
|
|
896
|
+
id: uuidv4(),
|
|
897
|
+
replaceRegistrationIds: [],
|
|
898
|
+
options: [],
|
|
899
|
+
groupPrice: groupPrice1,
|
|
900
|
+
organizationId: organization.id,
|
|
901
|
+
groupId: group1.id,
|
|
902
|
+
memberId: member.id,
|
|
903
|
+
}),
|
|
904
|
+
],
|
|
905
|
+
balanceItems: [
|
|
906
|
+
],
|
|
907
|
+
deleteRegistrationIds: [],
|
|
908
|
+
}),
|
|
909
|
+
administrationFee: 0,
|
|
910
|
+
freeContribution: 0,
|
|
911
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
912
|
+
totalPrice: 25,
|
|
913
|
+
customer: null,
|
|
914
|
+
asOrganizationId: organization.id,
|
|
915
|
+
});
|
|
916
|
+
|
|
917
|
+
const response1 = await register(body1, organization, token);
|
|
918
|
+
expect(response1.body).toBeDefined();
|
|
919
|
+
expect(response1.body.registrations.length).toBe(1);
|
|
920
|
+
|
|
921
|
+
const registrationToDelete = response1.body.registrations[0];
|
|
922
|
+
|
|
923
|
+
const group = await new GroupFactory({
|
|
924
|
+
organization,
|
|
925
|
+
price: 30,
|
|
926
|
+
stock: 5,
|
|
927
|
+
}).create();
|
|
928
|
+
|
|
929
|
+
const groupPrice = group.settings.prices[0];
|
|
930
|
+
|
|
931
|
+
const body2 = IDRegisterCheckout.create({
|
|
932
|
+
cart: IDRegisterCart.create({
|
|
933
|
+
items: [
|
|
934
|
+
IDRegisterItem.create({
|
|
935
|
+
id: uuidv4(),
|
|
936
|
+
replaceRegistrationIds: [],
|
|
937
|
+
options: [],
|
|
938
|
+
groupPrice,
|
|
939
|
+
organizationId: organization.id,
|
|
940
|
+
groupId: group.id,
|
|
941
|
+
memberId: member.id,
|
|
942
|
+
}),
|
|
943
|
+
],
|
|
944
|
+
balanceItems: [
|
|
945
|
+
],
|
|
946
|
+
deleteRegistrationIds: [registrationToDelete.id],
|
|
947
|
+
}),
|
|
948
|
+
administrationFee: 0,
|
|
949
|
+
freeContribution: 0,
|
|
950
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
951
|
+
totalPrice: 30,
|
|
952
|
+
customer: null,
|
|
953
|
+
asOrganizationId: organization.id,
|
|
954
|
+
cancellationFeePercentage: 2000,
|
|
955
|
+
});
|
|
956
|
+
// #endregion
|
|
957
|
+
|
|
958
|
+
// #region act and assert
|
|
959
|
+
const balanceBefore = await getBalance(member.id, organization, token);
|
|
960
|
+
expect(balanceBefore).toBeDefined();
|
|
961
|
+
expect(balanceBefore.body.length).toBe(1);
|
|
962
|
+
expect(balanceBefore.body[0].price).toBe(25);
|
|
963
|
+
expect(balanceBefore.body[0].pricePaid).toBe(0);
|
|
964
|
+
|
|
965
|
+
await register(body2, organization, token);
|
|
966
|
+
|
|
967
|
+
const balance = await getBalance(member.id, organization, token);
|
|
968
|
+
expect(balance).toBeDefined();
|
|
969
|
+
expect(balance.body.length).toBe(3);
|
|
970
|
+
|
|
971
|
+
expect.arrayContaining([
|
|
972
|
+
expect.objectContaining({
|
|
973
|
+
price: 25,
|
|
974
|
+
pricePaid: 0,
|
|
975
|
+
status: BalanceItemStatus.Canceled,
|
|
976
|
+
}),
|
|
977
|
+
expect.objectContaining({
|
|
978
|
+
price: 30,
|
|
979
|
+
pricePaid: 0,
|
|
980
|
+
status: BalanceItemStatus.Due,
|
|
981
|
+
}),
|
|
982
|
+
expect.objectContaining({
|
|
983
|
+
price: 5,
|
|
984
|
+
pricePaid: 0,
|
|
985
|
+
type: BalanceItemType.CancellationFee,
|
|
986
|
+
status: BalanceItemStatus.Due,
|
|
987
|
+
}),
|
|
988
|
+
]);
|
|
989
|
+
// #endregion
|
|
990
|
+
});
|
|
991
|
+
});
|
|
992
|
+
|
|
993
|
+
describe('Register for group with default age group', () => {
|
|
994
|
+
test('Should create membership', async () => {
|
|
995
|
+
// #region arrange
|
|
996
|
+
const date = new Date('2023-05-14');
|
|
997
|
+
jest.useFakeTimers().setSystemTime(date);
|
|
998
|
+
|
|
999
|
+
try {
|
|
1000
|
+
const platformMembershipTypeConfig = PlatformMembershipTypeConfig.create({
|
|
1001
|
+
startDate: period.startDate,
|
|
1002
|
+
endDate: period.endDate,
|
|
1003
|
+
});
|
|
1004
|
+
|
|
1005
|
+
const platformMembershipType = PlatformMembershipType.create({
|
|
1006
|
+
name: 'werkjaar',
|
|
1007
|
+
periods: new Map([
|
|
1008
|
+
[period.id, platformMembershipTypeConfig],
|
|
1009
|
+
]),
|
|
1010
|
+
});
|
|
1011
|
+
|
|
1012
|
+
const platform = await Platform.getShared();
|
|
1013
|
+
|
|
1014
|
+
platform.config.membershipTypes = [
|
|
1015
|
+
platformMembershipType,
|
|
1016
|
+
];
|
|
1017
|
+
|
|
1018
|
+
const defaultAgeGroup = DefaultAgeGroup.create({
|
|
1019
|
+
names: ['test groep'],
|
|
1020
|
+
defaultMembershipTypeId: platformMembershipType.id,
|
|
1021
|
+
});
|
|
1022
|
+
|
|
1023
|
+
platform.config.defaultAgeGroups = [defaultAgeGroup];
|
|
1024
|
+
|
|
1025
|
+
await platform.save();
|
|
1026
|
+
|
|
1027
|
+
const { member, group, groupPrice, organization, token } = await initData();
|
|
1028
|
+
|
|
1029
|
+
// todo: remove from initData
|
|
1030
|
+
member.organizationId = null;
|
|
1031
|
+
await member.save();
|
|
1032
|
+
|
|
1033
|
+
group.defaultAgeGroupId = defaultAgeGroup.id;
|
|
1034
|
+
await group.save();
|
|
1035
|
+
|
|
1036
|
+
const organizationPeriod = new OrganizationRegistrationPeriod();
|
|
1037
|
+
organizationPeriod.organizationId = organization.id;
|
|
1038
|
+
organizationPeriod.periodId = period.id;
|
|
1039
|
+
await organizationPeriod.save();
|
|
1040
|
+
|
|
1041
|
+
const body = IDRegisterCheckout.create({
|
|
1042
|
+
cart: IDRegisterCart.create({
|
|
1043
|
+
items: [
|
|
1044
|
+
IDRegisterItem.create({
|
|
1045
|
+
id: uuidv4(),
|
|
1046
|
+
replaceRegistrationIds: [],
|
|
1047
|
+
options: [],
|
|
1048
|
+
groupPrice: groupPrice,
|
|
1049
|
+
organizationId: organization.id,
|
|
1050
|
+
groupId: group.id,
|
|
1051
|
+
memberId: member.id,
|
|
1052
|
+
trial: false,
|
|
1053
|
+
}),
|
|
1054
|
+
],
|
|
1055
|
+
balanceItems: [],
|
|
1056
|
+
deleteRegistrationIds: [],
|
|
1057
|
+
}),
|
|
1058
|
+
administrationFee: 0,
|
|
1059
|
+
freeContribution: 0,
|
|
1060
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
1061
|
+
totalPrice: 25,
|
|
1062
|
+
asOrganizationId: organization.id,
|
|
1063
|
+
customer: null,
|
|
1064
|
+
});
|
|
1065
|
+
// #endregion
|
|
1066
|
+
|
|
1067
|
+
// act and assert
|
|
1068
|
+
const familyBefore = await getMemberFamily(member.id, organization, token);
|
|
1069
|
+
expect(familyBefore).toBeDefined();
|
|
1070
|
+
expect(familyBefore.body.members.length).toBe(1);
|
|
1071
|
+
expect(familyBefore.body.members[0]).toBeDefined();
|
|
1072
|
+
expect(familyBefore.body.members[0].platformMemberships.length).toBe(0);
|
|
1073
|
+
|
|
1074
|
+
const response = await register(body, organization, token);
|
|
1075
|
+
|
|
1076
|
+
expect(response.body).toBeDefined();
|
|
1077
|
+
expect(response.body.registrations.length).toBe(1);
|
|
1078
|
+
|
|
1079
|
+
const familyAfter = await getMemberFamily(member.id, organization, token);
|
|
1080
|
+
expect(familyAfter).toBeDefined();
|
|
1081
|
+
expect(familyAfter.body.members.length).toBe(1);
|
|
1082
|
+
expect(familyAfter.body.members[0]).toBeDefined();
|
|
1083
|
+
expect(familyAfter.body.members[0].platformMemberships.length).toBe(1);
|
|
1084
|
+
expect(familyAfter.body.members[0].platformMemberships[0].membershipTypeId).toBe(platformMembershipType.id);
|
|
1085
|
+
}
|
|
1086
|
+
finally {
|
|
1087
|
+
jest.useFakeTimers().resetAllMocks();
|
|
1088
|
+
}
|
|
1089
|
+
});
|
|
1090
|
+
|
|
1091
|
+
test('Should set trial until on membership if trial', async () => {
|
|
1092
|
+
// #region arrange
|
|
1093
|
+
const date = new Date('2023-05-14');
|
|
1094
|
+
jest.useFakeTimers().setSystemTime(date);
|
|
1095
|
+
|
|
1096
|
+
try {
|
|
1097
|
+
const platformMembershipTypeConfig = PlatformMembershipTypeConfig.create({
|
|
1098
|
+
startDate: period.startDate,
|
|
1099
|
+
endDate: period.endDate,
|
|
1100
|
+
trialDays: 10,
|
|
1101
|
+
});
|
|
1102
|
+
|
|
1103
|
+
const platformMembershipType = PlatformMembershipType.create({
|
|
1104
|
+
name: 'werkjaar',
|
|
1105
|
+
periods: new Map([
|
|
1106
|
+
[period.id, platformMembershipTypeConfig],
|
|
1107
|
+
]),
|
|
1108
|
+
});
|
|
1109
|
+
|
|
1110
|
+
const platform = await Platform.getShared();
|
|
1111
|
+
|
|
1112
|
+
platform.config.membershipTypes = [
|
|
1113
|
+
platformMembershipType,
|
|
1114
|
+
];
|
|
1115
|
+
|
|
1116
|
+
const defaultAgeGroup = DefaultAgeGroup.create({
|
|
1117
|
+
names: ['test groep'],
|
|
1118
|
+
defaultMembershipTypeId: platformMembershipType.id,
|
|
1119
|
+
});
|
|
1120
|
+
|
|
1121
|
+
platform.config.defaultAgeGroups = [defaultAgeGroup];
|
|
1122
|
+
|
|
1123
|
+
await platform.save();
|
|
1124
|
+
|
|
1125
|
+
const { member, group, groupPrice, organization, token } = await initData();
|
|
1126
|
+
|
|
1127
|
+
// todo: remove from initData
|
|
1128
|
+
member.organizationId = null;
|
|
1129
|
+
await member.save();
|
|
1130
|
+
|
|
1131
|
+
group.settings.trialDays = 5;
|
|
1132
|
+
group.defaultAgeGroupId = defaultAgeGroup.id;
|
|
1133
|
+
await group.save();
|
|
1134
|
+
|
|
1135
|
+
const organizationPeriod = new OrganizationRegistrationPeriod();
|
|
1136
|
+
organizationPeriod.organizationId = organization.id;
|
|
1137
|
+
organizationPeriod.periodId = period.id;
|
|
1138
|
+
await organizationPeriod.save();
|
|
1139
|
+
|
|
1140
|
+
const body = IDRegisterCheckout.create({
|
|
1141
|
+
cart: IDRegisterCart.create({
|
|
1142
|
+
items: [
|
|
1143
|
+
IDRegisterItem.create({
|
|
1144
|
+
id: uuidv4(),
|
|
1145
|
+
replaceRegistrationIds: [],
|
|
1146
|
+
options: [],
|
|
1147
|
+
groupPrice: groupPrice,
|
|
1148
|
+
organizationId: organization.id,
|
|
1149
|
+
groupId: group.id,
|
|
1150
|
+
memberId: member.id,
|
|
1151
|
+
trial: true,
|
|
1152
|
+
}),
|
|
1153
|
+
],
|
|
1154
|
+
balanceItems: [],
|
|
1155
|
+
deleteRegistrationIds: [],
|
|
1156
|
+
}),
|
|
1157
|
+
administrationFee: 0,
|
|
1158
|
+
freeContribution: 0,
|
|
1159
|
+
paymentMethod: PaymentMethod.PointOfSale,
|
|
1160
|
+
totalPrice: 0,
|
|
1161
|
+
asOrganizationId: organization.id,
|
|
1162
|
+
customer: null,
|
|
1163
|
+
});
|
|
1164
|
+
// #endregion
|
|
1165
|
+
|
|
1166
|
+
// act and assert
|
|
1167
|
+
const familyBefore = await getMemberFamily(member.id, organization, token);
|
|
1168
|
+
expect(familyBefore).toBeDefined();
|
|
1169
|
+
expect(familyBefore.body.members.length).toBe(1);
|
|
1170
|
+
expect(familyBefore.body.members[0]).toBeDefined();
|
|
1171
|
+
expect(familyBefore.body.members[0].platformMemberships.length).toBe(0);
|
|
1172
|
+
|
|
1173
|
+
const response = await register(body, organization, token);
|
|
1174
|
+
|
|
1175
|
+
expect(response.body).toBeDefined();
|
|
1176
|
+
expect(response.body.registrations.length).toBe(1);
|
|
1177
|
+
|
|
1178
|
+
const familyAfter = await getMemberFamily(member.id, organization, token);
|
|
1179
|
+
expect(familyAfter).toBeDefined();
|
|
1180
|
+
expect(familyAfter.body.members.length).toBe(1);
|
|
1181
|
+
expect(familyAfter.body.members[0]).toBeDefined();
|
|
1182
|
+
expect(familyAfter.body.members[0].platformMemberships.length).toBe(1);
|
|
1183
|
+
expect(familyAfter.body.members[0].platformMemberships[0].membershipTypeId).toBe(platformMembershipType.id);
|
|
1184
|
+
|
|
1185
|
+
const trialUntil = familyAfter.body.members[0].platformMemberships[0].trialUntil;
|
|
1186
|
+
|
|
1187
|
+
expect(trialUntil).not.toBeNull();
|
|
1188
|
+
expect(trialUntil!.getFullYear()).toBe(2023);
|
|
1189
|
+
expect(trialUntil!.getMonth()).toBe(4);
|
|
1190
|
+
expect(trialUntil!.getDate()).toBe(24);
|
|
1191
|
+
}
|
|
1192
|
+
finally {
|
|
1193
|
+
jest.useFakeTimers().resetAllMocks();
|
|
1194
|
+
}
|
|
1195
|
+
});
|
|
1196
|
+
});
|
|
1197
|
+
});
|