@stamhoofd/backend 2.89.2 → 2.90.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +12 -11
- package/src/boot.ts +2 -0
- package/src/crons/balance-emails.ts +1 -6
- package/src/endpoints/admin/organizations/GetOrganizationsEndpoint.ts +1 -1
- package/src/endpoints/admin/organizations/SearchUitpasOrganizersEndpoint.ts +42 -0
- package/src/endpoints/global/audit-logs/GetAuditLogsEndpoint.ts +4 -4
- package/src/endpoints/global/events/GetEventNotificationsEndpoint.ts +3 -3
- package/src/endpoints/global/events/GetEventsEndpoint.ts +2 -2
- package/src/endpoints/global/events/PatchEventsEndpoint.ts +23 -2
- package/src/endpoints/global/groups/GetGroupsEndpoint.ts +6 -6
- package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.test.ts +8 -6
- package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.ts +2 -2
- package/src/endpoints/global/platform/GetPlatformEndpoint.ts +1 -0
- package/src/endpoints/global/registration/PatchUserMembersEndpoint.test.ts +10 -8
- package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +11 -0
- package/src/endpoints/global/registration-periods/GetRegistrationPeriodsEndpoint.ts +2 -2
- package/src/endpoints/organization/dashboard/documents/GetDocumentsEndpoint.ts +3 -6
- package/src/endpoints/organization/dashboard/organization/GetUitpasClientIdEndpoint.ts +38 -0
- package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.ts +31 -1
- package/src/endpoints/organization/dashboard/organization/SetUitpasClientCredentialsEndpoint.ts +108 -0
- package/src/endpoints/organization/dashboard/payments/GetPaymentsEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/receivable-balances/GetReceivableBalancesEndpoint.ts +1 -2
- package/src/endpoints/organization/dashboard/registration-periods/GetOrganizationRegistrationPeriodsEndpoint.ts +1 -1
- package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.ts +9 -1
- package/src/endpoints/organization/dashboard/webshops/GetWebshopOrdersEndpoint.ts +3 -2
- package/src/endpoints/organization/dashboard/webshops/GetWebshopTicketsEndpoint.ts +1 -1
- package/src/endpoints/organization/webshops/GetWebshopEndpoint.test.ts +2 -9
- package/src/endpoints/organization/webshops/GetWebshopEndpoint.ts +1 -7
- package/src/endpoints/organization/webshops/PlaceOrderEndpoint.ts +68 -1
- package/src/endpoints/organization/webshops/RetrieveUitpasSocialTariffPriceEndpoint.ts +27 -20
- package/src/helpers/AdminPermissionChecker.ts +129 -22
- package/src/helpers/AuthenticatedStructures.ts +13 -10
- package/src/helpers/Context.ts +1 -1
- package/src/helpers/UitpasTokenRepository.ts +125 -35
- package/src/helpers/ViesHelper.ts +2 -1
- package/src/seeds/0000000002-clear-stamhoofd-email-templates.ts +13 -0
- package/src/seeds/0000000003-default-email-templates.ts +20 -0
- package/src/seeds/data/default-email-templates.sql +55 -0
- package/src/services/RegistrationService.ts +6 -4
- package/src/services/uitpas/UitpasService.test.ts +23 -0
- package/src/services/uitpas/UitpasService.ts +222 -0
- package/src/services/uitpas/checkPermissionsFor.ts +111 -0
- package/src/services/uitpas/checkUitpasNumbers.ts +180 -0
- package/src/services/uitpas/getSocialTariffForEvent.ts +90 -0
- package/src/services/uitpas/getSocialTariffForUitpasNumbers.ts +181 -0
- package/src/services/uitpas/searchUitpasOrganizers.ts +93 -0
- package/src/sql-filters/audit-logs.ts +26 -6
- package/src/sql-filters/balance-item-payments.ts +23 -8
- package/src/sql-filters/base-registration-filter-compilers.ts +74 -23
- package/src/sql-filters/documents.ts +46 -13
- package/src/sql-filters/event-notifications.ts +48 -12
- package/src/sql-filters/events.ts +62 -26
- package/src/sql-filters/groups.ts +12 -12
- package/src/sql-filters/members.ts +325 -137
- package/src/sql-filters/orders.ts +96 -48
- package/src/sql-filters/organization-registration-periods.ts +16 -4
- package/src/sql-filters/organizations.ts +105 -99
- package/src/sql-filters/payments.ts +97 -47
- package/src/sql-filters/receivable-balances.ts +56 -19
- package/src/sql-filters/registration-periods.ts +16 -4
- package/src/sql-filters/registrations.ts +2 -2
- package/src/sql-filters/shared/EmailRelationFilterCompilers.ts +14 -8
- package/src/sql-filters/tickets.ts +26 -6
- package/tests/e2e/charge-members.test.ts +1 -0
- package/src/helpers/UitpasNumberValidator.test.ts +0 -23
- package/src/helpers/UitpasNumberValidator.ts +0 -185
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { baseSQLFilterCompilers, createColumnFilter, createExistsFilter, SQL, SQLConcat, SQLFilterDefinitions, SQLValueType, SQLScalar } from '@stamhoofd/sql';
|
|
2
2
|
import { memberFilterCompilers } from './members';
|
|
3
3
|
import { organizationFilterCompilers } from './organizations';
|
|
4
4
|
import { EmailRelationFilterCompilers } from './shared/EmailRelationFilterCompilers';
|
|
@@ -8,23 +8,56 @@ import { EmailRelationFilterCompilers } from './shared/EmailRelationFilterCompil
|
|
|
8
8
|
*/
|
|
9
9
|
export const receivableBalanceFilterCompilers: SQLFilterDefinitions = {
|
|
10
10
|
...baseSQLFilterCompilers,
|
|
11
|
-
id:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
11
|
+
id: createColumnFilter({
|
|
12
|
+
expression: SQL.column('id'),
|
|
13
|
+
type: SQLValueType.String,
|
|
14
|
+
nullable: false,
|
|
15
|
+
}),
|
|
16
|
+
organizationId: createColumnFilter({
|
|
17
|
+
expression: SQL.column('organizationId'),
|
|
18
|
+
type: SQLValueType.String,
|
|
19
|
+
nullable: false,
|
|
20
|
+
}),
|
|
21
|
+
objectType: createColumnFilter({
|
|
22
|
+
expression: SQL.column('objectType'),
|
|
23
|
+
type: SQLValueType.String,
|
|
24
|
+
nullable: false,
|
|
25
|
+
}),
|
|
26
|
+
amountOpen: createColumnFilter({
|
|
27
|
+
expression: SQL.column('amountOpen'),
|
|
28
|
+
type: SQLValueType.Number,
|
|
29
|
+
nullable: false,
|
|
30
|
+
}),
|
|
31
|
+
amountPending: createColumnFilter({
|
|
32
|
+
expression: SQL.column('amountPending'),
|
|
33
|
+
type: SQLValueType.Number,
|
|
34
|
+
nullable: false,
|
|
35
|
+
}),
|
|
36
|
+
nextDueAt: createColumnFilter({
|
|
37
|
+
expression: SQL.column('nextDueAt'),
|
|
38
|
+
type: SQLValueType.Datetime,
|
|
39
|
+
nullable: true,
|
|
40
|
+
}),
|
|
41
|
+
lastReminderEmail: createColumnFilter({
|
|
42
|
+
expression: SQL.column('lastReminderEmail'),
|
|
43
|
+
type: SQLValueType.Datetime,
|
|
44
|
+
nullable: true,
|
|
45
|
+
}),
|
|
46
|
+
reminderEmailCount: createColumnFilter({
|
|
47
|
+
expression: SQL.column('reminderEmailCount'),
|
|
48
|
+
type: SQLValueType.Number,
|
|
49
|
+
nullable: false,
|
|
50
|
+
}),
|
|
51
|
+
reminderAmountIncreased: createColumnFilter({
|
|
52
|
+
expression: SQL.if(
|
|
21
53
|
SQL.column('amountOpen'),
|
|
22
54
|
'>',
|
|
23
55
|
SQL.column('lastReminderAmountOpen'),
|
|
24
56
|
).then(1).else(0),
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
57
|
+
type: SQLValueType.Boolean,
|
|
58
|
+
nullable: false,
|
|
59
|
+
}),
|
|
60
|
+
organizations: createExistsFilter(
|
|
28
61
|
SQL.select()
|
|
29
62
|
.from(SQL.table('organizations'))
|
|
30
63
|
.where(
|
|
@@ -36,9 +69,10 @@ export const receivableBalanceFilterCompilers: SQLFilterDefinitions = {
|
|
|
36
69
|
).where(
|
|
37
70
|
SQL.column('cached_outstanding_balances', 'objectType'),
|
|
38
71
|
'organization'),
|
|
72
|
+
|
|
39
73
|
organizationFilterCompilers,
|
|
40
74
|
),
|
|
41
|
-
members:
|
|
75
|
+
members: createExistsFilter(
|
|
42
76
|
SQL.select()
|
|
43
77
|
.from(SQL.table('members'))
|
|
44
78
|
.where(
|
|
@@ -52,7 +86,7 @@ export const receivableBalanceFilterCompilers: SQLFilterDefinitions = {
|
|
|
52
86
|
'member'),
|
|
53
87
|
memberFilterCompilers,
|
|
54
88
|
),
|
|
55
|
-
users:
|
|
89
|
+
users: createExistsFilter(
|
|
56
90
|
SQL.select()
|
|
57
91
|
.from(SQL.table('users'))
|
|
58
92
|
.where(
|
|
@@ -65,13 +99,16 @@ export const receivableBalanceFilterCompilers: SQLFilterDefinitions = {
|
|
|
65
99
|
SQL.column('cached_outstanding_balances', 'objectType'),
|
|
66
100
|
'user'),
|
|
67
101
|
{
|
|
68
|
-
|
|
69
|
-
|
|
102
|
+
...baseSQLFilterCompilers,
|
|
103
|
+
name: createColumnFilter({
|
|
104
|
+
expression: new SQLConcat(
|
|
70
105
|
SQL.column('firstName'),
|
|
71
106
|
new SQLScalar(' '),
|
|
72
107
|
SQL.column('lastName'),
|
|
73
108
|
),
|
|
74
|
-
|
|
109
|
+
type: SQLValueType.String,
|
|
110
|
+
nullable: false,
|
|
111
|
+
}),
|
|
75
112
|
},
|
|
76
113
|
),
|
|
77
114
|
|
|
@@ -1,8 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { baseSQLFilterCompilers, createColumnFilter, SQL, SQLFilterDefinitions, SQLValueType } from '@stamhoofd/sql';
|
|
2
2
|
|
|
3
3
|
export const registrationPeriodFilterCompilers: SQLFilterDefinitions = {
|
|
4
4
|
...baseSQLFilterCompilers,
|
|
5
|
-
id:
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
id: createColumnFilter({
|
|
6
|
+
expression: SQL.column('id'),
|
|
7
|
+
type: SQLValueType.String,
|
|
8
|
+
nullable: false,
|
|
9
|
+
}),
|
|
10
|
+
startDate: createColumnFilter({
|
|
11
|
+
expression: SQL.column('startDate'),
|
|
12
|
+
type: SQLValueType.Datetime,
|
|
13
|
+
nullable: false,
|
|
14
|
+
}),
|
|
15
|
+
endDate: createColumnFilter({
|
|
16
|
+
expression: SQL.column('endDate'),
|
|
17
|
+
type: SQLValueType.Datetime,
|
|
18
|
+
nullable: false,
|
|
19
|
+
}),
|
|
8
20
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Member, Registration } from '@stamhoofd/models';
|
|
2
|
-
import { baseSQLFilterCompilers,
|
|
2
|
+
import { baseSQLFilterCompilers, createJoinedRelationFilter, SQL, SQLFilterDefinitions } from '@stamhoofd/sql';
|
|
3
3
|
import { baseRegistrationFilterCompilers } from './base-registration-filter-compilers';
|
|
4
4
|
import { memberFilterCompilers } from './members';
|
|
5
5
|
|
|
@@ -8,7 +8,7 @@ export const memberJoin = SQL.join(Member.table).where(SQL.column(Member.table,
|
|
|
8
8
|
export const registrationFilterCompilers: SQLFilterDefinitions = {
|
|
9
9
|
...baseSQLFilterCompilers,
|
|
10
10
|
...baseRegistrationFilterCompilers,
|
|
11
|
-
member:
|
|
11
|
+
member: createJoinedRelationFilter(
|
|
12
12
|
memberJoin,
|
|
13
13
|
memberFilterCompilers,
|
|
14
14
|
),
|
|
@@ -1,19 +1,25 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { baseSQLFilterCompilers, createColumnFilter, createExistsFilter, SQL, SQLFilterDefinitions, SQLValueType } from '@stamhoofd/sql';
|
|
2
2
|
|
|
3
3
|
export const EmailRelationFilterCompilers = {
|
|
4
|
-
emails:
|
|
4
|
+
emails: createExistsFilter(
|
|
5
5
|
SQL.select()
|
|
6
|
-
.from(
|
|
7
|
-
SQL.table('email_recipients'),
|
|
8
|
-
)
|
|
6
|
+
.from(SQL.table('email_recipients'))
|
|
9
7
|
.where(
|
|
10
|
-
SQL.column(SQLParentNamespace, 'id'),
|
|
11
8
|
SQL.column('objectId'),
|
|
9
|
+
SQL.column('id'), // Parent table id
|
|
12
10
|
),
|
|
13
11
|
{
|
|
14
12
|
...baseSQLFilterCompilers,
|
|
15
|
-
emailType:
|
|
16
|
-
|
|
13
|
+
emailType: createColumnFilter({
|
|
14
|
+
expression: SQL.column('emailType'),
|
|
15
|
+
type: SQLValueType.String,
|
|
16
|
+
nullable: false,
|
|
17
|
+
}),
|
|
18
|
+
sentAt: createColumnFilter({
|
|
19
|
+
expression: SQL.column('sentAt'),
|
|
20
|
+
type: SQLValueType.Datetime,
|
|
21
|
+
nullable: true,
|
|
22
|
+
}),
|
|
17
23
|
},
|
|
18
24
|
),
|
|
19
25
|
};
|
|
@@ -1,10 +1,30 @@
|
|
|
1
|
-
import { baseSQLFilterCompilers,
|
|
1
|
+
import { baseSQLFilterCompilers, createColumnFilter, SQL, SQLFilterDefinitions, SQLValueType } from '@stamhoofd/sql';
|
|
2
2
|
|
|
3
3
|
export const ticketFilterCompilers: SQLFilterDefinitions = {
|
|
4
4
|
...baseSQLFilterCompilers,
|
|
5
|
-
organizationId:
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
organizationId: createColumnFilter({
|
|
6
|
+
expression: SQL.column('organizationId'),
|
|
7
|
+
type: SQLValueType.String,
|
|
8
|
+
nullable: false,
|
|
9
|
+
}),
|
|
10
|
+
updatedAt: createColumnFilter({
|
|
11
|
+
expression: SQL.column('updatedAt'),
|
|
12
|
+
type: SQLValueType.Datetime,
|
|
13
|
+
nullable: false,
|
|
14
|
+
}),
|
|
15
|
+
webshopId: createColumnFilter({
|
|
16
|
+
expression: SQL.column('webshopId'),
|
|
17
|
+
type: SQLValueType.String,
|
|
18
|
+
nullable: false,
|
|
19
|
+
}),
|
|
20
|
+
id: createColumnFilter({
|
|
21
|
+
expression: SQL.column('id'),
|
|
22
|
+
type: SQLValueType.String,
|
|
23
|
+
nullable: false,
|
|
24
|
+
}),
|
|
25
|
+
createdAt: createColumnFilter({
|
|
26
|
+
expression: SQL.column('createdAt'),
|
|
27
|
+
type: SQLValueType.Datetime,
|
|
28
|
+
nullable: false,
|
|
29
|
+
}),
|
|
10
30
|
};
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { STExpect } from '@stamhoofd/test-utils';
|
|
2
|
-
import { UitpasNumberValidator } from './UitpasNumberValidator';
|
|
3
|
-
|
|
4
|
-
describe.skip('UitpasNumberValidator', () => {
|
|
5
|
-
it('should validate a correct Uitpas number with kansentarief', async () => {
|
|
6
|
-
const validNumber = '0900000067513';
|
|
7
|
-
await expect(UitpasNumberValidator.checkUitpasNumber(validNumber)).resolves.toBeUndefined();
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
it('should throw an error for an invalid Uitpas number', async () => {
|
|
11
|
-
const invalidNumber = '1234567890123';
|
|
12
|
-
await expect(UitpasNumberValidator.checkUitpasNumber(invalidNumber)).rejects.toThrow(
|
|
13
|
-
STExpect.simpleError({ code: 'unsuccessful_but_expected_response_retrieving_pass_by_uitpas_number' }),
|
|
14
|
-
);
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
it('should throw an error for a Uitpas number with kansentarief expired', async () => {
|
|
18
|
-
const expiredNumber = '0900000058918';
|
|
19
|
-
await expect(UitpasNumberValidator.checkUitpasNumber(expiredNumber)).rejects.toThrow(
|
|
20
|
-
STExpect.simpleError({ code: 'uitpas_number_issue' }),
|
|
21
|
-
);
|
|
22
|
-
});
|
|
23
|
-
});
|
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
import { isSimpleError, isSimpleErrors, SimpleError, SimpleErrors } from '@simonbackx/simple-errors';
|
|
2
|
-
import { UitpasTokenRepository } from './UitpasTokenRepository';
|
|
3
|
-
import { DataValidator } from '@stamhoofd/utility';
|
|
4
|
-
|
|
5
|
-
type UitpasNumberSuccessfulResponse = {
|
|
6
|
-
socialTariff: {
|
|
7
|
-
status: 'ACTIVE' | 'EXPIRED' | 'NONE';
|
|
8
|
-
};
|
|
9
|
-
messages?: Array<{
|
|
10
|
-
text: string;
|
|
11
|
-
}>;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
type UitpasNumberErrorResponse = {
|
|
15
|
-
title: string; // e.g., "Invalid uitpas number"
|
|
16
|
-
endUserMessage?: {
|
|
17
|
-
nl: string;
|
|
18
|
-
};
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
function assertIsUitpasNumberSuccessfulResponse(
|
|
22
|
-
json: unknown,
|
|
23
|
-
): asserts json is UitpasNumberSuccessfulResponse {
|
|
24
|
-
if (
|
|
25
|
-
typeof json !== 'object'
|
|
26
|
-
|| json === null
|
|
27
|
-
|| !('socialTariff' in json)
|
|
28
|
-
|| typeof json.socialTariff !== 'object'
|
|
29
|
-
|| json.socialTariff === null
|
|
30
|
-
|| !('status' in json.socialTariff)
|
|
31
|
-
|| typeof json.socialTariff.status !== 'string'
|
|
32
|
-
|| (json.socialTariff.status !== 'ACTIVE' && json.socialTariff.status !== 'EXPIRED' && json.socialTariff.status !== 'NONE')
|
|
33
|
-
|| ('messages' in json && (!Array.isArray(json.messages) || !json.messages.every(
|
|
34
|
-
(message: unknown) => typeof message === 'object' && message !== null && 'text' in message && typeof message.text === 'string')))
|
|
35
|
-
) {
|
|
36
|
-
console.error('Invalid response when retrieving pass by UiTPAS number:', json);
|
|
37
|
-
throw new SimpleError({
|
|
38
|
-
code: 'invalid_response_retrieving_pass_by_uitpas_number',
|
|
39
|
-
message: `Invalid response when retrieving pass by UiTPAS number`,
|
|
40
|
-
human: $t(`Er is een fout opgetreden bij het ophalen van je UiTPAS. Kijk je het nummer even na?`),
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function isUitpasNumberErrorResponse(
|
|
46
|
-
json: unknown,
|
|
47
|
-
): json is UitpasNumberErrorResponse {
|
|
48
|
-
return typeof json === 'object'
|
|
49
|
-
&& json !== null
|
|
50
|
-
&& 'title' in json
|
|
51
|
-
&& typeof json.title === 'string'
|
|
52
|
-
&& (!('endUserMessage' in json)
|
|
53
|
-
|| (typeof json.endUserMessage === 'object' && json.endUserMessage !== null && 'nl' in json.endUserMessage && typeof json.endUserMessage.nl === 'string')
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export class UitpasNumberValidatorStatic {
|
|
58
|
-
async checkUitpasNumber(uitpasNumber: string) {
|
|
59
|
-
// static check (using regex)
|
|
60
|
-
if (!DataValidator.isUitpasNumberValid(uitpasNumber)) {
|
|
61
|
-
throw new SimpleError({
|
|
62
|
-
code: 'invalid_uitpas_number',
|
|
63
|
-
message: `Invalid UiTPAS number: ${uitpasNumber}`,
|
|
64
|
-
human: $t(
|
|
65
|
-
`Het opgegeven UiTPAS-nummer is ongeldig. Controleer het nummer en probeer het opnieuw.`,
|
|
66
|
-
),
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
const access_token = await UitpasTokenRepository.getAccessTokenFor(); // for nothing, means for platform
|
|
70
|
-
const baseUrl = 'https://api-test.uitpas.be'; // TO DO: Use the URL from environment variables
|
|
71
|
-
|
|
72
|
-
const url = `${baseUrl}/passes/${uitpasNumber}`;
|
|
73
|
-
const myHeaders = new Headers();
|
|
74
|
-
myHeaders.append('Authorization', 'Bearer ' + access_token);
|
|
75
|
-
const requestOptions = {
|
|
76
|
-
method: 'GET',
|
|
77
|
-
headers: myHeaders,
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
const response = await fetch(url, requestOptions).catch(() => {
|
|
81
|
-
// Handle network errors
|
|
82
|
-
throw new SimpleError({
|
|
83
|
-
code: 'uitpas_unreachable_retrieving_pass_by_uitpas_number',
|
|
84
|
-
message: `Network issue when retrieving pass by UiTPAS number`,
|
|
85
|
-
human: $t(
|
|
86
|
-
`We konden UiTPAS niet bereiken om jouw UiTPAS-nummer te valideren. Probeer het later opnieuw.`,
|
|
87
|
-
),
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
if (!response.ok) {
|
|
91
|
-
const json: unknown = await response.json().catch(() => { /* ignore */ });
|
|
92
|
-
let endUserMessage = '';
|
|
93
|
-
|
|
94
|
-
if (json) {
|
|
95
|
-
console.error(`UiTPAS API returned an error for UiTPAS number ${uitpasNumber}:`, json);
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
console.error(`UiTPAS API returned an error for UiTPAS number ${uitpasNumber}:`, response.statusText);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (isUitpasNumberErrorResponse(json)) {
|
|
102
|
-
endUserMessage = json.endUserMessage ? json.endUserMessage.nl : '';
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (endUserMessage) {
|
|
106
|
-
throw new SimpleError({
|
|
107
|
-
code: 'unsuccessful_but_expected_response_retrieving_pass_by_uitpas_number',
|
|
108
|
-
message: `Unsuccesful response with message when retrieving pass by UiTPAS number, message: ${endUserMessage}`,
|
|
109
|
-
human: endUserMessage,
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
throw new SimpleError({
|
|
114
|
-
code: 'unsuccessful_and_unexpected_response_retrieving_pass_by_uitpas_number',
|
|
115
|
-
message: `Unsuccesful response without message when retrieving pass by UiTPAS number`,
|
|
116
|
-
human: $t(`Er is een fout opgetreden bij het ophalen van je UiTPAS. Kijk je het nummer even na?`),
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const json = await response.json().catch(() => {
|
|
121
|
-
// Handle JSON parsing errors
|
|
122
|
-
throw new SimpleError({
|
|
123
|
-
code: 'invalid_json_retrieving_pass_by_uitpas_number',
|
|
124
|
-
message: `Invalid json when retrieving pass by UiTPAS number`,
|
|
125
|
-
human: $t(
|
|
126
|
-
`Er is een fout opgetreden bij het communiceren met UiTPAS. Probeer het later opnieuw.`,
|
|
127
|
-
),
|
|
128
|
-
});
|
|
129
|
-
});
|
|
130
|
-
assertIsUitpasNumberSuccessfulResponse(json);
|
|
131
|
-
if (json.messages) {
|
|
132
|
-
const humanMessage = json.messages[0].text; // only display the first message
|
|
133
|
-
|
|
134
|
-
// alternatively, join all messages
|
|
135
|
-
// const text = json.messages.map((message: any) => message.text).join(', ');
|
|
136
|
-
|
|
137
|
-
throw new SimpleError({
|
|
138
|
-
code: 'uitpas_number_issue',
|
|
139
|
-
message: `UiTPAS API returned an error: ${humanMessage}`,
|
|
140
|
-
human: humanMessage,
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
if (json.socialTariff.status !== 'ACTIVE') {
|
|
144
|
-
// THIS SHOULD NOT HAPPEN, as in that case json.messages should be present
|
|
145
|
-
throw new SimpleError({
|
|
146
|
-
code: 'non_active_social_tariff',
|
|
147
|
-
message: `UiTPAS social tariff is not ACTIVE but ${json.socialTariff.status}`,
|
|
148
|
-
human: $t(
|
|
149
|
-
`Het opgegeven UiTPAS-nummer heeft geen actief kansentarief. Neem contact op met de UiTPAS-organisatie voor meer informatie.`,
|
|
150
|
-
),
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
// no errors -> the uitpas number is valid and social tariff is applicable
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Checks multiple uitpas numbers
|
|
158
|
-
* If any of the uitpas numbers is invalid, it will throw a SimpleErrors instance with all errors.
|
|
159
|
-
* The field of the error will be the index of the uitpas number in the array.
|
|
160
|
-
* @param uitpasNumbers The uitpas numbers to check
|
|
161
|
-
*/
|
|
162
|
-
async checkUitpasNumbers(uitpasNumbers: string[]) {
|
|
163
|
-
const simpleErrors = new SimpleErrors();
|
|
164
|
-
for (let i = 0; i < uitpasNumbers.length; i++) {
|
|
165
|
-
const uitpasNumber = uitpasNumbers[i];
|
|
166
|
-
try {
|
|
167
|
-
await this.checkUitpasNumber(uitpasNumber); // Throws if invalid
|
|
168
|
-
}
|
|
169
|
-
catch (e) {
|
|
170
|
-
if (isSimpleError(e) || isSimpleErrors(e)) {
|
|
171
|
-
e.addNamespace(i.toString());
|
|
172
|
-
simpleErrors.addError(e);
|
|
173
|
-
}
|
|
174
|
-
else {
|
|
175
|
-
throw e;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
if (simpleErrors.errors.length > 0) {
|
|
180
|
-
throw simpleErrors;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
export const UitpasNumberValidator = new UitpasNumberValidatorStatic();
|