@stamhoofd/backend 2.80.1 → 2.81.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/index.ts +1 -4
- package/package.json +10 -10
- package/src/excel-loaders/event-notifications.ts +133 -0
- package/src/excel-loaders/index.ts +5 -0
- package/src/excel-loaders/members.ts +15 -38
- package/src/excel-loaders/organizations.ts +2 -2
- package/src/excel-loaders/payments.ts +2 -2
- package/src/helpers/{xlsxAddressTransformerColumnFactory.ts → XlsxTransformerColumnHelper.ts} +68 -2
package/index.ts
CHANGED
|
@@ -111,10 +111,7 @@ const start = async () => {
|
|
|
111
111
|
console.log('Loading loaders...');
|
|
112
112
|
|
|
113
113
|
// Register Excel loaders
|
|
114
|
-
await import('./src/excel-loaders
|
|
115
|
-
await import('./src/excel-loaders/payments');
|
|
116
|
-
await import('./src/excel-loaders/organizations');
|
|
117
|
-
await import('./src/excel-loaders/receivable-balances');
|
|
114
|
+
await import('./src/excel-loaders');
|
|
118
115
|
|
|
119
116
|
// Register Email Recipient loaders
|
|
120
117
|
await import('./src/email-recipient-loaders/members');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stamhoofd/backend",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.81.0",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -38,14 +38,14 @@
|
|
|
38
38
|
"@simonbackx/simple-encoding": "2.22.0",
|
|
39
39
|
"@simonbackx/simple-endpoints": "1.19.1",
|
|
40
40
|
"@simonbackx/simple-logging": "^1.0.1",
|
|
41
|
-
"@stamhoofd/backend-i18n": "2.
|
|
42
|
-
"@stamhoofd/backend-middleware": "2.
|
|
43
|
-
"@stamhoofd/email": "2.
|
|
44
|
-
"@stamhoofd/models": "2.
|
|
45
|
-
"@stamhoofd/queues": "2.
|
|
46
|
-
"@stamhoofd/sql": "2.
|
|
47
|
-
"@stamhoofd/structures": "2.
|
|
48
|
-
"@stamhoofd/utility": "2.
|
|
41
|
+
"@stamhoofd/backend-i18n": "2.81.0",
|
|
42
|
+
"@stamhoofd/backend-middleware": "2.81.0",
|
|
43
|
+
"@stamhoofd/email": "2.81.0",
|
|
44
|
+
"@stamhoofd/models": "2.81.0",
|
|
45
|
+
"@stamhoofd/queues": "2.81.0",
|
|
46
|
+
"@stamhoofd/sql": "2.81.0",
|
|
47
|
+
"@stamhoofd/structures": "2.81.0",
|
|
48
|
+
"@stamhoofd/utility": "2.81.0",
|
|
49
49
|
"archiver": "^7.0.1",
|
|
50
50
|
"aws-sdk": "^2.885.0",
|
|
51
51
|
"axios": "1.6.8",
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
"publishConfig": {
|
|
66
66
|
"access": "public"
|
|
67
67
|
},
|
|
68
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "5a0faf4813aeb5c3d7216536278acb65ba2361e0"
|
|
69
69
|
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { XlsxBuiltInNumberFormat, XlsxTransformerSheet } from '@stamhoofd/excel-writer';
|
|
2
|
+
import { EventNotification, EventNotificationStatus, EventNotificationStatusHelper, ExcelExportType, LimitedFilteredRequest, Platform as PlatformStruct } from '@stamhoofd/structures';
|
|
3
|
+
import { Formatter } from '@stamhoofd/utility';
|
|
4
|
+
import { GetEventNotificationsEndpoint } from '../endpoints/global/events/GetEventNotificationsEndpoint';
|
|
5
|
+
import { ExportToExcelEndpoint } from '../endpoints/global/files/ExportToExcelEndpoint';
|
|
6
|
+
import { XlsxTransformerColumnHelper } from '../helpers/XlsxTransformerColumnHelper';
|
|
7
|
+
|
|
8
|
+
// Assign to a typed variable to assure we have correct type checking in place
|
|
9
|
+
const sheet: XlsxTransformerSheet<EventNotification, EventNotification> = {
|
|
10
|
+
id: 'event-notifications',
|
|
11
|
+
name: 'Meldingen',
|
|
12
|
+
columns: [
|
|
13
|
+
{
|
|
14
|
+
id: 'id',
|
|
15
|
+
name: 'ID',
|
|
16
|
+
width: 40,
|
|
17
|
+
getValue: (notification: EventNotification) => ({
|
|
18
|
+
value: notification.id,
|
|
19
|
+
}),
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: 'name',
|
|
23
|
+
name: 'Naam activiteit',
|
|
24
|
+
width: 40,
|
|
25
|
+
getValue: (notification: EventNotification) => ({
|
|
26
|
+
value: notification.events.map(e => e.name).join(', '),
|
|
27
|
+
}),
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: 'organization.name',
|
|
31
|
+
name: 'Groep',
|
|
32
|
+
width: 40,
|
|
33
|
+
getValue: (notification: EventNotification) => ({
|
|
34
|
+
value: notification.organization.name,
|
|
35
|
+
}),
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
id: 'organization.uri',
|
|
39
|
+
name: 'Groepsnummer',
|
|
40
|
+
width: 30,
|
|
41
|
+
getValue: (notification: EventNotification) => ({
|
|
42
|
+
value: notification.organization.uri,
|
|
43
|
+
}),
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: 'status',
|
|
47
|
+
name: 'Status',
|
|
48
|
+
width: 30,
|
|
49
|
+
getValue: (notification: EventNotification) => ({
|
|
50
|
+
value: Formatter.capitalizeFirstLetter(EventNotificationStatusHelper.getName(notification.status)),
|
|
51
|
+
}),
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: 'feedbackText',
|
|
55
|
+
name: 'Opmerkingen',
|
|
56
|
+
width: 80,
|
|
57
|
+
getValue: (notification: EventNotification) => ({
|
|
58
|
+
value: notification.status !== EventNotificationStatus.Accepted ? notification.feedbackText : null,
|
|
59
|
+
style: {
|
|
60
|
+
alignment: {
|
|
61
|
+
wrapText: true,
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
}),
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: 'startDate',
|
|
68
|
+
name: 'Startdatum',
|
|
69
|
+
width: 20,
|
|
70
|
+
getValue: (notification: EventNotification) => ({
|
|
71
|
+
value: notification.startDate,
|
|
72
|
+
style: {
|
|
73
|
+
numberFormat: {
|
|
74
|
+
id: XlsxBuiltInNumberFormat.DateSlash,
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
}),
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
id: 'endDate',
|
|
81
|
+
name: 'Einddatum',
|
|
82
|
+
width: 20,
|
|
83
|
+
getValue: (notification: EventNotification) => ({
|
|
84
|
+
value: notification.endDate,
|
|
85
|
+
style: {
|
|
86
|
+
numberFormat: {
|
|
87
|
+
id: XlsxBuiltInNumberFormat.DateSlash,
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
}),
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
id: 'submittedAt',
|
|
94
|
+
name: 'Ingediend op',
|
|
95
|
+
width: 20,
|
|
96
|
+
getValue: (notification: EventNotification) => ({
|
|
97
|
+
value: notification.submittedAt,
|
|
98
|
+
style: {
|
|
99
|
+
numberFormat: {
|
|
100
|
+
id: XlsxBuiltInNumberFormat.DateSlash,
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
}),
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
id: 'submittedBy',
|
|
107
|
+
name: 'Ingediend door',
|
|
108
|
+
width: 40,
|
|
109
|
+
getValue: (notification: EventNotification) => ({
|
|
110
|
+
value: notification.submittedBy?.name ?? '',
|
|
111
|
+
}),
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
// Dynamic records
|
|
115
|
+
XlsxTransformerColumnHelper.createRecordAnswersColumns({
|
|
116
|
+
matchId: 'recordAnswers',
|
|
117
|
+
getRecordAnswers: (notification: EventNotification) => notification.recordAnswers,
|
|
118
|
+
getRecordCategories: () => {
|
|
119
|
+
const platform = PlatformStruct.shared;
|
|
120
|
+
return platform.config.eventNotificationTypes.flatMap(r => r.recordCategories);
|
|
121
|
+
},
|
|
122
|
+
}),
|
|
123
|
+
],
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
ExportToExcelEndpoint.loaders.set(ExcelExportType.EventNotifications, {
|
|
127
|
+
fetch: async (query: LimitedFilteredRequest) => {
|
|
128
|
+
return await GetEventNotificationsEndpoint.buildData(query);
|
|
129
|
+
},
|
|
130
|
+
sheets: [
|
|
131
|
+
sheet,
|
|
132
|
+
],
|
|
133
|
+
});
|
|
@@ -6,7 +6,7 @@ import { ExportToExcelEndpoint } from '../endpoints/global/files/ExportToExcelEn
|
|
|
6
6
|
import { GetMembersEndpoint } from '../endpoints/global/members/GetMembersEndpoint';
|
|
7
7
|
import { AuthenticatedStructures } from '../helpers/AuthenticatedStructures';
|
|
8
8
|
import { Context } from '../helpers/Context';
|
|
9
|
-
import { XlsxTransformerColumnHelper } from '../helpers/
|
|
9
|
+
import { XlsxTransformerColumnHelper } from '../helpers/XlsxTransformerColumnHelper';
|
|
10
10
|
|
|
11
11
|
// Assign to a typed variable to assure we have correct type checking in place
|
|
12
12
|
const sheet: XlsxTransformerSheet<PlatformMember, PlatformMember> = {
|
|
@@ -16,7 +16,7 @@ const sheet: XlsxTransformerSheet<PlatformMember, PlatformMember> = {
|
|
|
16
16
|
{
|
|
17
17
|
id: 'id',
|
|
18
18
|
name: 'ID',
|
|
19
|
-
width:
|
|
19
|
+
width: 40,
|
|
20
20
|
getValue: ({ patchedMember: object }: PlatformMember) => ({
|
|
21
21
|
value: object.id,
|
|
22
22
|
}),
|
|
@@ -89,7 +89,7 @@ const sheet: XlsxTransformerSheet<PlatformMember, PlatformMember> = {
|
|
|
89
89
|
{
|
|
90
90
|
id: 'email',
|
|
91
91
|
name: 'E-mailadres',
|
|
92
|
-
width:
|
|
92
|
+
width: 40,
|
|
93
93
|
getValue: ({ patchedMember: object }: PlatformMember) => ({
|
|
94
94
|
value: object.details.email,
|
|
95
95
|
}),
|
|
@@ -247,42 +247,19 @@ const sheet: XlsxTransformerSheet<PlatformMember, PlatformMember> = {
|
|
|
247
247
|
},
|
|
248
248
|
|
|
249
249
|
// Dynamic records
|
|
250
|
-
{
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
const recordSettingId = id.split('.')[1];
|
|
262
|
-
console.log('recordSettingId', recordSettingId);
|
|
263
|
-
const recordSetting = recordSettings.find(r => r.id === recordSettingId);
|
|
264
|
-
|
|
265
|
-
if (!recordSetting) {
|
|
266
|
-
// Will throw a proper error itself
|
|
267
|
-
console.log('recordSetting not found', recordSettings);
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
const columns = recordSetting.excelColumns;
|
|
272
|
-
|
|
273
|
-
return columns.map((columnName, index) => {
|
|
274
|
-
return {
|
|
275
|
-
id: `recordAnswers.${recordSettingId}.${index}`,
|
|
276
|
-
name: columnName,
|
|
277
|
-
width: 20,
|
|
278
|
-
getValue: ({ patchedMember: object }: PlatformMember) => ({
|
|
279
|
-
value: object.details.recordAnswers.get(recordSettingId)?.excelValues[index]?.value ?? '',
|
|
280
|
-
}),
|
|
281
|
-
};
|
|
282
|
-
});
|
|
283
|
-
}
|
|
250
|
+
XlsxTransformerColumnHelper.createRecordAnswersColumns({
|
|
251
|
+
matchId: 'recordAnswers',
|
|
252
|
+
getRecordAnswers: ({ patchedMember: object }: PlatformMember) => object.details.recordAnswers,
|
|
253
|
+
getRecordCategories: () => {
|
|
254
|
+
const platform = PlatformStruct.shared;
|
|
255
|
+
const organization = Context.organization;
|
|
256
|
+
|
|
257
|
+
return [
|
|
258
|
+
...(organization?.meta.recordsConfiguration.recordCategories ?? []),
|
|
259
|
+
...platform.config.recordsConfiguration.recordCategories,
|
|
260
|
+
];
|
|
284
261
|
},
|
|
285
|
-
},
|
|
262
|
+
}),
|
|
286
263
|
|
|
287
264
|
// Registration records
|
|
288
265
|
{
|
|
@@ -2,7 +2,7 @@ import { XlsxTransformerSheet } from '@stamhoofd/excel-writer';
|
|
|
2
2
|
import { Platform as PlatformStruct, ExcelExportType, LimitedFilteredRequest, Organization as OrganizationStruct, MemberResponsibilityRecord as MemberResponsibilityRecordStruct, PaginatedResponse, MemberWithRegistrationsBlob, Premise } from '@stamhoofd/structures';
|
|
3
3
|
import { GetOrganizationsEndpoint } from '../endpoints/admin/organizations/GetOrganizationsEndpoint';
|
|
4
4
|
import { ExportToExcelEndpoint } from '../endpoints/global/files/ExportToExcelEndpoint';
|
|
5
|
-
import { XlsxTransformerColumnHelper } from '../helpers/
|
|
5
|
+
import { XlsxTransformerColumnHelper } from '../helpers/XlsxTransformerColumnHelper';
|
|
6
6
|
import { Group, Member, MemberResponsibilityRecord } from '@stamhoofd/models';
|
|
7
7
|
import { Formatter, Sorter } from '@stamhoofd/utility';
|
|
8
8
|
import { ArrayDecoder, field } from '@simonbackx/simple-encoding';
|
|
@@ -33,7 +33,7 @@ const sheet: XlsxTransformerSheet<Object, Object> = {
|
|
|
33
33
|
{
|
|
34
34
|
id: 'id',
|
|
35
35
|
name: 'ID',
|
|
36
|
-
width:
|
|
36
|
+
width: 40,
|
|
37
37
|
getValue: (object: Object) => ({
|
|
38
38
|
value: object.id,
|
|
39
39
|
}),
|
|
@@ -5,7 +5,7 @@ import { BalanceItemPaymentDetailed, BalanceItemRelationType, ExcelExportType, g
|
|
|
5
5
|
import { Formatter } from '@stamhoofd/utility';
|
|
6
6
|
import { ExportToExcelEndpoint } from '../endpoints/global/files/ExportToExcelEndpoint';
|
|
7
7
|
import { GetPaymentsEndpoint } from '../endpoints/organization/dashboard/payments/GetPaymentsEndpoint';
|
|
8
|
-
import { XlsxTransformerColumnHelper } from '../helpers/
|
|
8
|
+
import { XlsxTransformerColumnHelper } from '../helpers/XlsxTransformerColumnHelper';
|
|
9
9
|
|
|
10
10
|
type PaymentWithItem = {
|
|
11
11
|
payment: PaymentGeneral;
|
|
@@ -475,7 +475,7 @@ function getPayingOrganizationColumns(): XlsxTransformerColumn<PaymentGeneral>[]
|
|
|
475
475
|
{
|
|
476
476
|
id: 'payingOrganization.id',
|
|
477
477
|
name: 'ID betalende groep',
|
|
478
|
-
width:
|
|
478
|
+
width: 40,
|
|
479
479
|
getValue: (object: PaymentGeneralWithStripeAccount) => {
|
|
480
480
|
return {
|
|
481
481
|
value: object.payingOrganization?.id || '',
|
package/src/helpers/{xlsxAddressTransformerColumnFactory.ts → XlsxTransformerColumnHelper.ts}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { XlsxTransformerColumn } from '@stamhoofd/excel-writer';
|
|
2
|
-
import { Address, CountryHelper, Parent, ParentTypeHelper, PlatformMember } from '@stamhoofd/structures';
|
|
2
|
+
import { Address, CountryHelper, Parent, ParentTypeHelper, PlatformMember, RecordAnswer, RecordCategory, RecordSettings, RecordType } from '@stamhoofd/structures';
|
|
3
3
|
|
|
4
4
|
export class XlsxTransformerColumnHelper {
|
|
5
5
|
static formatBoolean(value: boolean | undefined | null): string {
|
|
@@ -115,7 +115,8 @@ export class XlsxTransformerColumnHelper {
|
|
|
115
115
|
{
|
|
116
116
|
id: getId('street'),
|
|
117
117
|
name: `Straat`,
|
|
118
|
-
|
|
118
|
+
defaultCategory: 'Adres', // Ignore this name
|
|
119
|
+
width: 40,
|
|
119
120
|
getValue: (object: T) => {
|
|
120
121
|
const address = getAddress(object);
|
|
121
122
|
return {
|
|
@@ -126,6 +127,7 @@ export class XlsxTransformerColumnHelper {
|
|
|
126
127
|
{
|
|
127
128
|
id: getId('number'),
|
|
128
129
|
name: 'Nummer',
|
|
130
|
+
defaultCategory: 'Adres', // Ignore this name
|
|
129
131
|
width: 20,
|
|
130
132
|
getValue: (object: T) => {
|
|
131
133
|
const address = getAddress(object);
|
|
@@ -137,6 +139,7 @@ export class XlsxTransformerColumnHelper {
|
|
|
137
139
|
{
|
|
138
140
|
id: getId('postalCode'),
|
|
139
141
|
name: 'Postcode',
|
|
142
|
+
defaultCategory: 'Adres', // Ignore this name
|
|
140
143
|
width: 20,
|
|
141
144
|
getValue: (object: T) => {
|
|
142
145
|
const address = getAddress(object);
|
|
@@ -148,6 +151,7 @@ export class XlsxTransformerColumnHelper {
|
|
|
148
151
|
{
|
|
149
152
|
id: getId('city'),
|
|
150
153
|
name: 'Stad',
|
|
154
|
+
defaultCategory: 'Adres', // Ignore this name
|
|
151
155
|
width: 20,
|
|
152
156
|
getValue: (object: T) => {
|
|
153
157
|
const address = getAddress(object);
|
|
@@ -159,6 +163,7 @@ export class XlsxTransformerColumnHelper {
|
|
|
159
163
|
{
|
|
160
164
|
id: getId('country'),
|
|
161
165
|
name: 'Land',
|
|
166
|
+
defaultCategory: 'Adres', // Ignore this name
|
|
162
167
|
width: 20,
|
|
163
168
|
getValue: (object: T) => {
|
|
164
169
|
const address = getAddress(object);
|
|
@@ -173,4 +178,65 @@ export class XlsxTransformerColumnHelper {
|
|
|
173
178
|
},
|
|
174
179
|
};
|
|
175
180
|
}
|
|
181
|
+
|
|
182
|
+
static createRecordAnswersColumns<T>({ matchId, getRecordCategories, getRecordAnswers }: { matchId: string; getRecordCategories: () => RecordCategory[]; getRecordAnswers: (object: T) => Map<string, RecordAnswer> }): XlsxTransformerColumn<T> {
|
|
183
|
+
return {
|
|
184
|
+
match(id) {
|
|
185
|
+
if (id.startsWith(matchId + '.')) {
|
|
186
|
+
const recordCategories = getRecordCategories();
|
|
187
|
+
const flattenedCategories = RecordCategory.flattenCategoriesWith(recordCategories, r => r.excelColumns.length > 0);
|
|
188
|
+
|
|
189
|
+
let recordCategory: RecordCategory | undefined;
|
|
190
|
+
let recordSetting: RecordSettings | undefined;
|
|
191
|
+
const recordSettingId = id.split('.')[1];
|
|
192
|
+
|
|
193
|
+
for (const category of flattenedCategories) {
|
|
194
|
+
const recordSettings = category.getAllRecords();
|
|
195
|
+
const rr = recordSettings.find(r => r.id === recordSettingId);
|
|
196
|
+
|
|
197
|
+
if (rr) {
|
|
198
|
+
recordSetting = rr;
|
|
199
|
+
recordCategory = category;
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (!recordSetting || !recordCategory) {
|
|
205
|
+
// Will throw a proper error itself
|
|
206
|
+
console.log('recordSetting not found');
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const columns = recordSetting.excelColumns;
|
|
211
|
+
|
|
212
|
+
return columns.map(({ name, width, defaultCategory }, index) => {
|
|
213
|
+
return {
|
|
214
|
+
id: `${matchId}.${recordSettingId}.${index}`,
|
|
215
|
+
name,
|
|
216
|
+
width: width ?? 20,
|
|
217
|
+
defaultCategory,
|
|
218
|
+
category: recordCategory.name,
|
|
219
|
+
getValue: (object: T) => {
|
|
220
|
+
const answers = getRecordAnswers(object);
|
|
221
|
+
const b = (answers.get(recordSettingId)?.excelValues[index] ?? {
|
|
222
|
+
value: '',
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
return {
|
|
226
|
+
...b,
|
|
227
|
+
style: {
|
|
228
|
+
...b.style,
|
|
229
|
+
alignment: {
|
|
230
|
+
...b.style?.alignment,
|
|
231
|
+
wrapText: recordSetting.type === RecordType.Textarea,
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
};
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
}
|
|
176
242
|
}
|