@stamhoofd/backend 2.89.1 → 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
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { isSimpleError, isSimpleErrors, SimpleError, SimpleErrors } from '@simonbackx/simple-errors';
|
|
2
|
+
|
|
3
|
+
type SocialTariffReponse = {
|
|
4
|
+
available: Array<{
|
|
5
|
+
price: number;
|
|
6
|
+
remaining: number;
|
|
7
|
+
// other properties ignored
|
|
8
|
+
}>;
|
|
9
|
+
endUserMessage?: {
|
|
10
|
+
nl: string;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type SocialTariffErrorResponse = {
|
|
15
|
+
title: string; // e.g., "Invalid uitpas number"
|
|
16
|
+
endUserMessage?: {
|
|
17
|
+
nl: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
function assertsIsSocialTariffResponse(json: unknown): asserts json is SocialTariffReponse {
|
|
22
|
+
if (
|
|
23
|
+
typeof json !== 'object'
|
|
24
|
+
|| json === null
|
|
25
|
+
|| !('available' in json)
|
|
26
|
+
|| !Array.isArray(json.available)
|
|
27
|
+
|| !json.available.every(
|
|
28
|
+
(item: unknown) => typeof item === 'object' && item !== null && 'price' in item && typeof item.price === 'number' && 'remaining' in item && typeof item.remaining === 'number',
|
|
29
|
+
)
|
|
30
|
+
) {
|
|
31
|
+
console.error('Invalid response when getting UiTPAS social tariff:', json);
|
|
32
|
+
throw new SimpleError({
|
|
33
|
+
code: 'invalid_response_getting_uitpas_social_tariff',
|
|
34
|
+
message: `Invalid response when getting UiTPAS social tariff`,
|
|
35
|
+
human: $t(`Er is een fout opgetreden bij het ophalen van het kansentarief voor jouw UiTPAS-nummer. Probeer het later opnieuw.`),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function isSocialTariffErrorResponse(
|
|
41
|
+
json: unknown,
|
|
42
|
+
): json is SocialTariffErrorResponse {
|
|
43
|
+
return typeof json === 'object'
|
|
44
|
+
&& json !== null
|
|
45
|
+
&& 'title' in json
|
|
46
|
+
&& typeof json.title === 'string'
|
|
47
|
+
&& (!('endUserMessage' in json)
|
|
48
|
+
|| (typeof json.endUserMessage === 'object' && json.endUserMessage !== null && 'nl' in json.endUserMessage && typeof json.endUserMessage.nl === 'string')
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async function getSocialTariffForUitpasNumber(access_token: string, uitpasNumber: string, basePrice: number, uitpasEventUrl: string) {
|
|
53
|
+
const baseUrl = 'https://api-test.uitpas.be/tariffs';
|
|
54
|
+
const params = new URLSearchParams();
|
|
55
|
+
params.append('regularPrice', (basePrice / 100).toFixed(2));
|
|
56
|
+
const eventId = uitpasEventUrl.split('/').pop();
|
|
57
|
+
if (!eventId) {
|
|
58
|
+
throw new SimpleError({
|
|
59
|
+
code: 'invalid_uitpas_event_url',
|
|
60
|
+
message: `Invalid UiTPAS event URL: ${uitpasEventUrl}`,
|
|
61
|
+
human: $t(`De opgegeven UiTPAS-evenement URL is ongeldig.`),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
params.append('eventId', eventId);
|
|
65
|
+
params.append('uitpasNumber', uitpasNumber);
|
|
66
|
+
params.append('type', 'SOCIALTARIFF'); // this ensures we get the social tariff or a message that explains why it's not available
|
|
67
|
+
const url = `${baseUrl}?${params.toString()}`;
|
|
68
|
+
const myHeaders = new Headers();
|
|
69
|
+
myHeaders.append('Authorization', 'Bearer ' + access_token);
|
|
70
|
+
myHeaders.append('Accept', 'application/json');
|
|
71
|
+
const requestOptions = {
|
|
72
|
+
method: 'GET',
|
|
73
|
+
headers: myHeaders,
|
|
74
|
+
};
|
|
75
|
+
const response = await fetch(url, requestOptions).catch(() => {
|
|
76
|
+
// Handle network errors
|
|
77
|
+
throw new SimpleError({
|
|
78
|
+
code: 'uitpas_unreachable_getting_static_uitpas_social_tariff',
|
|
79
|
+
message: `Network issue when getting static UiTPAS social tariff`,
|
|
80
|
+
human: $t(
|
|
81
|
+
`We konden UiTPAS niet bereiken om jouw kansentarief op te zoeken. Probeer het later opnieuw.`,
|
|
82
|
+
),
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
if (!response.ok) {
|
|
86
|
+
const json: unknown = await response.json().catch(() => { /* ignore */ });
|
|
87
|
+
let endUserMessage = '';
|
|
88
|
+
|
|
89
|
+
if (json) {
|
|
90
|
+
console.error(`UiTPAS API returned an error for UiTPAS number ${uitpasNumber} with event id ${eventId}:`, json);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
console.error(`UiTPAS API returned an error for UiTPAS number ${uitpasNumber} with event id ${eventId}:`, response.statusText);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (isSocialTariffErrorResponse(json)) {
|
|
97
|
+
endUserMessage = json.endUserMessage ? json.endUserMessage.nl : '';
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (endUserMessage) {
|
|
101
|
+
throw new SimpleError({
|
|
102
|
+
code: 'unsuccessful_but_expected_response_retrieving_social_tariff_by_uitpas_number',
|
|
103
|
+
message: `Unsuccesful response with message when retrieving social tariff by UiTPAS number, message: ${endUserMessage}`,
|
|
104
|
+
human: endUserMessage,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
throw new SimpleError({
|
|
109
|
+
code: 'unsuccessful_and_unexpected_response_retrieving_social_tariff_by_uitpas_number',
|
|
110
|
+
message: `Unsuccesful response without message when retrieving social tariff by UiTPAS number`,
|
|
111
|
+
human: $t(`Er is een fout opgetreden bij het ophalen van je UiTPAS kansentarief. Kijk je het nummer even na?`),
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
const json = await response.json().catch(() => {
|
|
115
|
+
// Handle JSON parsing errors
|
|
116
|
+
throw new SimpleError({
|
|
117
|
+
code: 'invalid_json_getting_static_uitpas_social_tariff',
|
|
118
|
+
message: `Invalid json when getting static UiTPAS social tariff`,
|
|
119
|
+
human: $t(
|
|
120
|
+
`Er is een fout opgetreden bij het communiceren met UiTPAS. Probeer het later opnieuw.`,
|
|
121
|
+
),
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
assertsIsSocialTariffResponse(json);
|
|
126
|
+
if (json.available.length === 0) {
|
|
127
|
+
if (json.endUserMessage) {
|
|
128
|
+
throw new SimpleError({
|
|
129
|
+
code: 'no_social_tariff_available_with_message',
|
|
130
|
+
message: `No social tariff available for event ${uitpasEventUrl} with message`,
|
|
131
|
+
human: json.endUserMessage.nl,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
throw new SimpleError({
|
|
135
|
+
code: 'no_social_tariff_available',
|
|
136
|
+
message: `No social tariff available for event ${uitpasEventUrl}`,
|
|
137
|
+
human: $t(`Er is geen kansentarief beschikbaar voor dit evenement.`),
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
if (json.available.length > 1) {
|
|
141
|
+
console.warn('Multiple social tariffs available for event', uitpasEventUrl, '(used ', json.available[0].price, ' as base price. All options:', json.available);
|
|
142
|
+
}
|
|
143
|
+
if (json.endUserMessage) {
|
|
144
|
+
console.warn('UiTPAS API returned an end user message for event', uitpasEventUrl, ':', json.endUserMessage.nl);
|
|
145
|
+
console.warn('This message was not shown to the user, as a social tariff wass available.');
|
|
146
|
+
}
|
|
147
|
+
if (json.available[0].remaining < 1) {
|
|
148
|
+
throw new SimpleError({
|
|
149
|
+
code: 'no_remaining_social_tariff',
|
|
150
|
+
message: `No remaining social tariff for event ${uitpasEventUrl} and UiTPAS number ${uitpasNumber}`,
|
|
151
|
+
human: $t(`Je hebt recht op UiTPAS-kansentarief maar het overblijvend aantal is niet voldoende.`),
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
console.log('Social tariff for UiTPAS number', uitpasNumber, 'with event id', uitpasEventUrl, 'is', json.available[0].price, 'euros');
|
|
155
|
+
return Math.round((json.available[0].price) * 100);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export async function getSocialTariffForUitpasNumbers(access_token: string, uitpasNumbers: string[], basePrice: number, uitpasEventUrl: string) {
|
|
159
|
+
const simpleErrors = new SimpleErrors();
|
|
160
|
+
const reducedPrices = new Array<number>(uitpasNumbers.length);
|
|
161
|
+
for (let i = 0; i < uitpasNumbers.length; i++) {
|
|
162
|
+
const uitpasNumber = uitpasNumbers[i];
|
|
163
|
+
try {
|
|
164
|
+
reducedPrices[i] = await getSocialTariffForUitpasNumber(access_token, uitpasNumber, basePrice, uitpasEventUrl); // Throws if invalid
|
|
165
|
+
}
|
|
166
|
+
catch (e) {
|
|
167
|
+
if (isSimpleError(e) || isSimpleErrors(e)) {
|
|
168
|
+
e.addNamespace(i.toString());
|
|
169
|
+
e.addNamespace('uitpasNumbers');
|
|
170
|
+
simpleErrors.addError(e);
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
throw e;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (simpleErrors.errors.length > 0) {
|
|
178
|
+
throw simpleErrors;
|
|
179
|
+
}
|
|
180
|
+
return reducedPrices;
|
|
181
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { UitpasOrganizerResponse, UitpasOrganizersResponse } from '@stamhoofd/structures';
|
|
2
|
+
import { SimpleError } from '@simonbackx/simple-errors';
|
|
3
|
+
|
|
4
|
+
type OrganizersResponse = {
|
|
5
|
+
totalItems: number;
|
|
6
|
+
member: Array<{
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
}>;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
function assertIsOrganizersResponse(json: unknown): asserts json is OrganizersResponse {
|
|
13
|
+
if (
|
|
14
|
+
typeof json !== 'object'
|
|
15
|
+
|| json === null
|
|
16
|
+
|| !('totalItems' in json)
|
|
17
|
+
|| typeof json.totalItems !== 'number'
|
|
18
|
+
|| !('member' in json)
|
|
19
|
+
|| !Array.isArray(json.member)
|
|
20
|
+
|| !json.member.every(
|
|
21
|
+
(member: unknown) => typeof member === 'object' && member !== null && 'id' in member && typeof member.id === 'string' && 'name' in member && typeof member.name === 'string',
|
|
22
|
+
)
|
|
23
|
+
) {
|
|
24
|
+
console.error('Invalid response when searching for UiTPAS organizers:', json);
|
|
25
|
+
throw new SimpleError({
|
|
26
|
+
code: 'invalid_response_searching_uitpas_organizers',
|
|
27
|
+
message: `Invalid response when searching for UiTPAS organizers`,
|
|
28
|
+
human: $t(`Er is een fout opgetreden bij het zoeken naar UiTPAS-organisaties. Probeer het later opnieuw.`),
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function searchUitpasOrganizers(access_token: string, name: string): Promise<UitpasOrganizersResponse> {
|
|
34
|
+
// uses platform credentials
|
|
35
|
+
// https://docs.publiq.be/docs/uitpas/uitpas-api/reference/operations/list-organizers
|
|
36
|
+
if (name === '') {
|
|
37
|
+
throw new SimpleError({
|
|
38
|
+
code: 'empty_uitpas_organizer_name',
|
|
39
|
+
message: `Empty name when searching for UiTPAS organizers`,
|
|
40
|
+
human: $t(`Je moet een naam opgeven om UiTPAS-organisaties te zoeken.`),
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
const baseUrl = 'https://api-test.uitpas.be/organizers';
|
|
44
|
+
const params = new URLSearchParams();
|
|
45
|
+
params.append('name', name);
|
|
46
|
+
params.append('limit', '200');
|
|
47
|
+
const url = `${baseUrl}?${params.toString()}`;
|
|
48
|
+
const myHeaders = new Headers();
|
|
49
|
+
myHeaders.append('Authorization', 'Bearer ' + access_token);
|
|
50
|
+
myHeaders.append('Accept', 'application/json');
|
|
51
|
+
const requestOptions = {
|
|
52
|
+
method: 'GET',
|
|
53
|
+
headers: myHeaders,
|
|
54
|
+
};
|
|
55
|
+
const response = await fetch(url, requestOptions).catch(() => {
|
|
56
|
+
// Handle network errors
|
|
57
|
+
throw new SimpleError({
|
|
58
|
+
code: 'uitpas_unreachable_searching_organizers',
|
|
59
|
+
message: `Network issue when searching for UiTPAS organizers`,
|
|
60
|
+
human: $t(
|
|
61
|
+
`We konden UiTPAS niet bereiken om UiTPAS-organisaties op te zoeken. Probeer het later opnieuw.`,
|
|
62
|
+
),
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
if (!response.ok) {
|
|
66
|
+
throw new SimpleError({
|
|
67
|
+
code: 'unsuccessful_response_searching_uitpas_organizers',
|
|
68
|
+
message: `Unsuccessful response when searching for UiTPAS organizers`,
|
|
69
|
+
human: $t(`Er is een fout opgetreden bij het verbinden met UiTPAS. Probeer het later opnieuw.`),
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
const json = await response.json().catch(() => {
|
|
73
|
+
// Handle JSON parsing errors
|
|
74
|
+
throw new SimpleError({
|
|
75
|
+
code: 'invalid_json_searching_uitpas_organizers',
|
|
76
|
+
message: `Invalid json when searching for UiTPAS organizers`,
|
|
77
|
+
human: $t(
|
|
78
|
+
`Er is een fout opgetreden bij het communiceren met UiTPAS. Probeer het later opnieuw.`,
|
|
79
|
+
),
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
assertIsOrganizersResponse(json);
|
|
84
|
+
const organizersResponse = new UitpasOrganizersResponse();
|
|
85
|
+
organizersResponse.totalItems = json.totalItems;
|
|
86
|
+
organizersResponse.member = json.member.map((member) => {
|
|
87
|
+
const organizer = new UitpasOrganizerResponse();
|
|
88
|
+
organizer.id = member.id;
|
|
89
|
+
organizer.name = member.name;
|
|
90
|
+
return organizer;
|
|
91
|
+
});
|
|
92
|
+
return organizersResponse;
|
|
93
|
+
}
|
|
@@ -1,10 +1,30 @@
|
|
|
1
|
-
import { baseSQLFilterCompilers,
|
|
1
|
+
import { baseSQLFilterCompilers, createColumnFilter, SQL, SQLFilterDefinitions, SQLValueType } from '@stamhoofd/sql';
|
|
2
2
|
|
|
3
3
|
export const auditLogFilterCompilers: SQLFilterDefinitions = {
|
|
4
4
|
...baseSQLFilterCompilers,
|
|
5
|
-
id:
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
id: createColumnFilter({
|
|
6
|
+
expression: SQL.column('id'),
|
|
7
|
+
type: SQLValueType.String,
|
|
8
|
+
nullable: false,
|
|
9
|
+
}),
|
|
10
|
+
organizationId: createColumnFilter({
|
|
11
|
+
expression: SQL.column('organizationId'),
|
|
12
|
+
type: SQLValueType.String,
|
|
13
|
+
nullable: true,
|
|
14
|
+
}),
|
|
15
|
+
type: createColumnFilter({
|
|
16
|
+
expression: SQL.column('type'),
|
|
17
|
+
type: SQLValueType.String,
|
|
18
|
+
nullable: false,
|
|
19
|
+
}),
|
|
20
|
+
objectId: createColumnFilter({
|
|
21
|
+
expression: SQL.column('objectId'),
|
|
22
|
+
type: SQLValueType.String,
|
|
23
|
+
nullable: true,
|
|
24
|
+
}),
|
|
25
|
+
createdAt: createColumnFilter({
|
|
26
|
+
expression: SQL.column('createdAt'),
|
|
27
|
+
type: SQLValueType.Datetime,
|
|
28
|
+
nullable: false,
|
|
29
|
+
}),
|
|
10
30
|
};
|
|
@@ -1,13 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { baseSQLFilterCompilers, createColumnFilter, SQL, SQLFilterDefinitions, SQLValueType } from '@stamhoofd/sql';
|
|
2
2
|
|
|
3
3
|
export const balanceItemPaymentsCompilers: SQLFilterDefinitions = {
|
|
4
4
|
...baseSQLFilterCompilers,
|
|
5
|
-
id:
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
...baseSQLFilterCompilers,
|
|
10
|
-
id: createSQLColumnFilterCompiler(SQL.column('balance_items', 'id')),
|
|
11
|
-
description: createSQLColumnFilterCompiler(SQL.column('balance_items', 'description')),
|
|
5
|
+
id: createColumnFilter({
|
|
6
|
+
expression: SQL.column('balance_item_payments', 'id'),
|
|
7
|
+
type: SQLValueType.String,
|
|
8
|
+
nullable: false,
|
|
12
9
|
}),
|
|
10
|
+
price: createColumnFilter({
|
|
11
|
+
expression: SQL.column('balance_item_payments', 'price'),
|
|
12
|
+
type: SQLValueType.Number,
|
|
13
|
+
nullable: false,
|
|
14
|
+
}),
|
|
15
|
+
balanceItem: {
|
|
16
|
+
...baseSQLFilterCompilers,
|
|
17
|
+
id: createColumnFilter({
|
|
18
|
+
expression: SQL.column('balance_items', 'id'),
|
|
19
|
+
type: SQLValueType.String,
|
|
20
|
+
nullable: false,
|
|
21
|
+
}),
|
|
22
|
+
description: createColumnFilter({
|
|
23
|
+
expression: SQL.column('balance_items', 'description'),
|
|
24
|
+
type: SQLValueType.String,
|
|
25
|
+
nullable: false,
|
|
26
|
+
}),
|
|
27
|
+
},
|
|
13
28
|
};
|
|
@@ -1,37 +1,88 @@
|
|
|
1
|
-
import { baseSQLFilterCompilers,
|
|
1
|
+
import { baseSQLFilterCompilers, createColumnFilter, createExistsFilter, SQL, SQLFilterDefinitions, SQLValueType } from '@stamhoofd/sql';
|
|
2
2
|
import { organizationFilterCompilers } from './organizations';
|
|
3
3
|
|
|
4
4
|
export const baseRegistrationFilterCompilers: SQLFilterDefinitions = {
|
|
5
5
|
...baseSQLFilterCompilers,
|
|
6
|
-
id:
|
|
6
|
+
id: createColumnFilter({
|
|
7
|
+
expression: SQL.column('id'),
|
|
8
|
+
type: SQLValueType.String,
|
|
9
|
+
nullable: false,
|
|
10
|
+
}),
|
|
7
11
|
/**
|
|
8
12
|
* @deprecated
|
|
9
13
|
*/
|
|
10
|
-
price:
|
|
14
|
+
price: createColumnFilter({
|
|
15
|
+
expression: SQL.column('price'),
|
|
16
|
+
type: SQLValueType.Number,
|
|
17
|
+
nullable: true,
|
|
18
|
+
}),
|
|
11
19
|
/**
|
|
12
20
|
* @deprecated
|
|
13
21
|
*/
|
|
14
|
-
pricePaid:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
pricePaid: createColumnFilter({
|
|
23
|
+
expression: SQL.column('pricePaid'),
|
|
24
|
+
type: SQLValueType.Number,
|
|
25
|
+
nullable: false,
|
|
26
|
+
}),
|
|
27
|
+
canRegister: createColumnFilter({
|
|
28
|
+
expression: SQL.column('canRegister'),
|
|
29
|
+
type: SQLValueType.Boolean,
|
|
30
|
+
nullable: false,
|
|
31
|
+
}),
|
|
32
|
+
organizationId: createColumnFilter({
|
|
33
|
+
expression: SQL.column('organizationId'),
|
|
34
|
+
type: SQLValueType.String,
|
|
35
|
+
nullable: false,
|
|
36
|
+
}),
|
|
37
|
+
groupId: createColumnFilter({
|
|
38
|
+
expression: SQL.column('groupId'),
|
|
39
|
+
type: SQLValueType.String,
|
|
40
|
+
nullable: false,
|
|
41
|
+
}),
|
|
42
|
+
registeredAt: createColumnFilter({
|
|
43
|
+
expression: SQL.column('registeredAt'),
|
|
44
|
+
type: SQLValueType.Datetime,
|
|
45
|
+
nullable: true,
|
|
46
|
+
}),
|
|
47
|
+
periodId: createColumnFilter({
|
|
48
|
+
expression: SQL.column('registrations', 'periodId'),
|
|
49
|
+
type: SQLValueType.String,
|
|
50
|
+
nullable: false,
|
|
51
|
+
}),
|
|
52
|
+
deactivatedAt: createColumnFilter({
|
|
53
|
+
expression: SQL.column('registrations', 'deactivatedAt'),
|
|
54
|
+
type: SQLValueType.Datetime,
|
|
55
|
+
nullable: true,
|
|
56
|
+
}),
|
|
57
|
+
group: {
|
|
22
58
|
...baseSQLFilterCompilers,
|
|
23
|
-
id:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
),
|
|
28
|
-
|
|
29
|
-
SQL.column('groups', '
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
59
|
+
id: createColumnFilter({
|
|
60
|
+
expression: SQL.column('groupId'),
|
|
61
|
+
type: SQLValueType.String,
|
|
62
|
+
nullable: false,
|
|
63
|
+
}),
|
|
64
|
+
type: createColumnFilter({
|
|
65
|
+
expression: SQL.column('groups', 'type'),
|
|
66
|
+
type: SQLValueType.String,
|
|
67
|
+
nullable: false,
|
|
68
|
+
}),
|
|
69
|
+
name: createColumnFilter({
|
|
70
|
+
expression: SQL.jsonValue(SQL.column('groups', 'settings'), '$.value.name'),
|
|
71
|
+
type: SQLValueType.JSONString,
|
|
72
|
+
nullable: false,
|
|
73
|
+
}),
|
|
74
|
+
status: createColumnFilter({
|
|
75
|
+
expression: SQL.column('groups', 'status'),
|
|
76
|
+
type: SQLValueType.String,
|
|
77
|
+
nullable: false,
|
|
78
|
+
}),
|
|
79
|
+
defaultAgeGroupId: createColumnFilter({
|
|
80
|
+
expression: SQL.column('groups', 'defaultAgeGroupId'),
|
|
81
|
+
type: SQLValueType.String,
|
|
82
|
+
nullable: true,
|
|
83
|
+
}),
|
|
84
|
+
},
|
|
85
|
+
organization: createExistsFilter(
|
|
35
86
|
SQL.select()
|
|
36
87
|
.from(SQL.table('organizations'))
|
|
37
88
|
.where(
|
|
@@ -1,17 +1,50 @@
|
|
|
1
|
-
import { baseSQLFilterCompilers,
|
|
1
|
+
import { baseSQLFilterCompilers, createColumnFilter, SQL, SQLFilterDefinitions, SQLValueType } from '@stamhoofd/sql';
|
|
2
2
|
|
|
3
3
|
export const documentFilterCompilers: SQLFilterDefinitions = {
|
|
4
4
|
...baseSQLFilterCompilers,
|
|
5
|
-
id:
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
),
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
5
|
+
id: createColumnFilter({
|
|
6
|
+
expression: SQL.column('id'),
|
|
7
|
+
type: SQLValueType.String,
|
|
8
|
+
nullable: false,
|
|
9
|
+
}),
|
|
10
|
+
description: createColumnFilter({
|
|
11
|
+
expression: SQL.jsonValue(SQL.column('data'), '$.value.description'),
|
|
12
|
+
type: SQLValueType.JSONString,
|
|
13
|
+
nullable: false,
|
|
14
|
+
}),
|
|
15
|
+
organizationId: createColumnFilter({
|
|
16
|
+
expression: SQL.column('organizationId'),
|
|
17
|
+
type: SQLValueType.String,
|
|
18
|
+
nullable: false,
|
|
19
|
+
}),
|
|
20
|
+
templateId: createColumnFilter({
|
|
21
|
+
expression: SQL.column('templateId'),
|
|
22
|
+
type: SQLValueType.String,
|
|
23
|
+
nullable: false,
|
|
24
|
+
}),
|
|
25
|
+
memberId: createColumnFilter({
|
|
26
|
+
expression: SQL.column('memberId'),
|
|
27
|
+
type: SQLValueType.String,
|
|
28
|
+
nullable: true,
|
|
29
|
+
}),
|
|
30
|
+
updatedAt: createColumnFilter({
|
|
31
|
+
expression: SQL.column('updatedAt'),
|
|
32
|
+
type: SQLValueType.Datetime,
|
|
33
|
+
nullable: false,
|
|
34
|
+
}),
|
|
35
|
+
createdAt: createColumnFilter({
|
|
36
|
+
expression: SQL.column('createdAt'),
|
|
37
|
+
type: SQLValueType.Datetime,
|
|
38
|
+
nullable: false,
|
|
39
|
+
}),
|
|
40
|
+
number: createColumnFilter({
|
|
41
|
+
expression: SQL.column('number'),
|
|
42
|
+
type: SQLValueType.Number,
|
|
43
|
+
nullable: true,
|
|
44
|
+
}),
|
|
45
|
+
status: createColumnFilter({
|
|
46
|
+
expression: SQL.column('status'),
|
|
47
|
+
type: SQLValueType.String,
|
|
48
|
+
nullable: false,
|
|
49
|
+
}),
|
|
17
50
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { baseSQLFilterCompilers, createColumnFilter, createJoinedRelationFilter, createExistsFilter, SQL, SQLFilterDefinitions, SQLValueType } from '@stamhoofd/sql';
|
|
2
2
|
import { eventFilterCompilers } from './events';
|
|
3
3
|
import { organizationFilterCompilers } from './organizations';
|
|
4
4
|
|
|
@@ -6,20 +6,56 @@ export const organizationJoin = SQL.join('organizations').where(SQL.column('orga
|
|
|
6
6
|
|
|
7
7
|
export const eventNotificationsFilterCompilers: SQLFilterDefinitions = {
|
|
8
8
|
...baseSQLFilterCompilers,
|
|
9
|
-
id:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
9
|
+
id: createColumnFilter({
|
|
10
|
+
expression: SQL.column('id'),
|
|
11
|
+
type: SQLValueType.String,
|
|
12
|
+
nullable: false,
|
|
13
|
+
}),
|
|
14
|
+
typeId: createColumnFilter({
|
|
15
|
+
expression: SQL.column('typeId'),
|
|
16
|
+
type: SQLValueType.String,
|
|
17
|
+
nullable: false,
|
|
18
|
+
}),
|
|
19
|
+
periodId: createColumnFilter({
|
|
20
|
+
expression: SQL.column('periodId'),
|
|
21
|
+
type: SQLValueType.String,
|
|
22
|
+
nullable: false,
|
|
23
|
+
}),
|
|
24
|
+
organizationId: createColumnFilter({
|
|
25
|
+
expression: SQL.column('organizationId'),
|
|
26
|
+
type: SQLValueType.String,
|
|
27
|
+
nullable: false,
|
|
28
|
+
}),
|
|
29
|
+
startDate: createColumnFilter({
|
|
30
|
+
expression: SQL.column('startDate'),
|
|
31
|
+
type: SQLValueType.Datetime,
|
|
32
|
+
nullable: false,
|
|
33
|
+
}),
|
|
34
|
+
endDate: createColumnFilter({
|
|
35
|
+
expression: SQL.column('endDate'),
|
|
36
|
+
type: SQLValueType.Datetime,
|
|
37
|
+
nullable: false,
|
|
38
|
+
}),
|
|
39
|
+
submittedAt: createColumnFilter({
|
|
40
|
+
expression: SQL.column('submittedAt'),
|
|
41
|
+
type: SQLValueType.Datetime,
|
|
42
|
+
nullable: true,
|
|
43
|
+
}),
|
|
44
|
+
createdAt: createColumnFilter({
|
|
45
|
+
expression: SQL.column('createdAt'),
|
|
46
|
+
type: SQLValueType.Datetime,
|
|
47
|
+
nullable: false,
|
|
48
|
+
}),
|
|
49
|
+
status: createColumnFilter({
|
|
50
|
+
expression: SQL.column('status'),
|
|
51
|
+
type: SQLValueType.String,
|
|
52
|
+
nullable: false,
|
|
53
|
+
}),
|
|
54
|
+
organization: createJoinedRelationFilter(
|
|
19
55
|
organizationJoin,
|
|
20
56
|
organizationFilterCompilers,
|
|
21
57
|
),
|
|
22
|
-
events:
|
|
58
|
+
events: createExistsFilter(
|
|
23
59
|
SQL.select()
|
|
24
60
|
.from(
|
|
25
61
|
SQL.table('events'),
|