@stamhoofd/backend 2.39.1 → 2.40.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.
Files changed (198) hide show
  1. package/eslint.config.mjs +5 -0
  2. package/index.ts +81 -74
  3. package/jest.config.cjs +10 -0
  4. package/migrations.ts +16 -14
  5. package/package.json +11 -11
  6. package/src/crons/clear-excel-cache.test.ts +48 -50
  7. package/src/crons/clear-excel-cache.ts +18 -18
  8. package/src/crons/setup-steps.ts +2 -2
  9. package/src/crons.ts +325 -306
  10. package/src/decoders/StringArrayDecoder.ts +7 -7
  11. package/src/decoders/StringNullableDecoder.ts +1 -2
  12. package/src/email-recipient-loaders/members.ts +22 -22
  13. package/src/endpoints/admin/memberships/ChargeMembershipsEndpoint.ts +8 -9
  14. package/src/endpoints/admin/memberships/GetChargeMembershipsSummaryEndpoint.ts +39 -40
  15. package/src/endpoints/admin/organizations/GetOrganizationsCountEndpoint.ts +8 -8
  16. package/src/endpoints/admin/organizations/GetOrganizationsEndpoint.ts +44 -45
  17. package/src/endpoints/admin/organizations/PatchOrganizationsEndpoint.ts +58 -57
  18. package/src/endpoints/auth/CreateAdminEndpoint.ts +48 -45
  19. package/src/endpoints/auth/CreateTokenEndpoint.test.ts +31 -31
  20. package/src/endpoints/auth/CreateTokenEndpoint.ts +146 -147
  21. package/src/endpoints/auth/DeleteTokenEndpoint.ts +7 -7
  22. package/src/endpoints/auth/DeleteUserEndpoint.ts +15 -15
  23. package/src/endpoints/auth/ForgotPasswordEndpoint.ts +17 -18
  24. package/src/endpoints/auth/GetOtherUserEndpoint.ts +9 -10
  25. package/src/endpoints/auth/GetUserEndpoint.test.ts +32 -35
  26. package/src/endpoints/auth/GetUserEndpoint.ts +5 -6
  27. package/src/endpoints/auth/PatchApiUserEndpoint.ts +35 -33
  28. package/src/endpoints/auth/PatchUserEndpoint.ts +55 -52
  29. package/src/endpoints/auth/PollEmailVerificationEndpoint.ts +9 -9
  30. package/src/endpoints/auth/RetryEmailVerificationEndpoint.ts +8 -8
  31. package/src/endpoints/auth/SignupEndpoint.ts +37 -36
  32. package/src/endpoints/auth/VerifyEmailEndpoint.ts +29 -28
  33. package/src/endpoints/global/addresses/SearchRegionsEndpoint.ts +33 -33
  34. package/src/endpoints/global/addresses/ValidateAddressEndpoint.ts +7 -7
  35. package/src/endpoints/global/caddy/CheckDomainCertEndpoint.ts +37 -37
  36. package/src/endpoints/global/email/CreateEmailEndpoint.ts +30 -30
  37. package/src/endpoints/global/email/GetEmailAddressEndpoint.ts +13 -13
  38. package/src/endpoints/global/email/GetEmailEndpoint.ts +13 -13
  39. package/src/endpoints/global/email/ManageEmailAddressEndpoint.ts +16 -16
  40. package/src/endpoints/global/email/PatchEmailEndpoint.ts +25 -25
  41. package/src/endpoints/global/events/GetEventsEndpoint.ts +43 -44
  42. package/src/endpoints/global/events/PatchEventsEndpoint.ts +127 -172
  43. package/src/endpoints/global/files/ExportToExcelEndpoint.ts +49 -50
  44. package/src/endpoints/global/files/GetFileCache.ts +13 -13
  45. package/src/endpoints/global/files/UploadFile.ts +51 -54
  46. package/src/endpoints/global/files/UploadImage.ts +53 -53
  47. package/src/endpoints/global/groups/GetGroupsEndpoint.ts +25 -25
  48. package/src/endpoints/global/members/GetMemberFamilyEndpoint.ts +24 -23
  49. package/src/endpoints/global/members/GetMembersCountEndpoint.ts +8 -8
  50. package/src/endpoints/global/members/GetMembersEndpoint.ts +105 -102
  51. package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.ts +240 -239
  52. package/src/endpoints/global/organizations/CheckRegisterCodeEndpoint.ts +12 -14
  53. package/src/endpoints/global/organizations/CreateOrganizationEndpoint.test.ts +32 -33
  54. package/src/endpoints/global/organizations/CreateOrganizationEndpoint.ts +48 -57
  55. package/src/endpoints/global/organizations/GetOrganizationFromDomainEndpoint.test.ts +21 -22
  56. package/src/endpoints/global/organizations/GetOrganizationFromDomainEndpoint.ts +28 -28
  57. package/src/endpoints/global/organizations/GetOrganizationFromUriEndpoint.ts +18 -18
  58. package/src/endpoints/global/organizations/SearchOrganizationEndpoint.test.ts +20 -20
  59. package/src/endpoints/global/organizations/SearchOrganizationEndpoint.ts +17 -17
  60. package/src/endpoints/global/payments/StripeWebhookEndpoint.ts +81 -75
  61. package/src/endpoints/global/platform/GetPlatformAdminsEndpoint.ts +14 -14
  62. package/src/endpoints/global/platform/GetPlatformEnpoint.ts +11 -11
  63. package/src/endpoints/global/platform/PatchPlatformEnpoint.ts +71 -68
  64. package/src/endpoints/global/registration/GetPaymentRegistrations.ts +27 -27
  65. package/src/endpoints/global/registration/GetUserBillingStatusEndpoint.ts +30 -30
  66. package/src/endpoints/global/registration/GetUserDetailedBillingStatusEndpoint.ts +34 -34
  67. package/src/endpoints/global/registration/GetUserDocumentsEndpoint.ts +26 -26
  68. package/src/endpoints/global/registration/GetUserMembersEndpoint.ts +12 -12
  69. package/src/endpoints/global/registration/PatchUserMembersEndpoint.ts +90 -90
  70. package/src/endpoints/global/registration/RegisterMembersEndpoint.test.ts +118 -121
  71. package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +362 -350
  72. package/src/endpoints/global/registration-periods/GetRegistrationPeriodsEndpoint.ts +8 -9
  73. package/src/endpoints/global/registration-periods/PatchRegistrationPeriodsEndpoint.ts +21 -21
  74. package/src/endpoints/global/webshops/GetWebshopFromDomainEndpoint.ts +65 -65
  75. package/src/endpoints/organization/dashboard/billing/GetOrganizationBillingStatusEndpoint.ts +9 -9
  76. package/src/endpoints/organization/dashboard/billing/GetOrganizationDetailedBillingStatusEndpoint.ts +14 -14
  77. package/src/endpoints/organization/dashboard/documents/GetDocumentTemplateXML.ts +17 -17
  78. package/src/endpoints/organization/dashboard/documents/GetDocumentTemplatesEndpoint.ts +21 -21
  79. package/src/endpoints/organization/dashboard/documents/GetDocumentsEndpoint.ts +15 -15
  80. package/src/endpoints/organization/dashboard/documents/PatchDocumentEndpoint.ts +52 -52
  81. package/src/endpoints/organization/dashboard/documents/PatchDocumentTemplateEndpoint.ts +37 -37
  82. package/src/endpoints/organization/dashboard/email/CheckEmailBouncesEndpoint.ts +14 -14
  83. package/src/endpoints/organization/dashboard/email/EmailEndpoint.ts +113 -112
  84. package/src/endpoints/organization/dashboard/email-templates/GetEmailTemplatesEndpoint.ts +29 -29
  85. package/src/endpoints/organization/dashboard/email-templates/PatchEmailTemplatesEndpoint.ts +48 -47
  86. package/src/endpoints/organization/dashboard/mollie/CheckMollieEndpoint.ts +22 -21
  87. package/src/endpoints/organization/dashboard/mollie/ConnectMollieEndpoint.ts +13 -14
  88. package/src/endpoints/organization/dashboard/mollie/DisconnectMollieEndpoint.ts +12 -13
  89. package/src/endpoints/organization/dashboard/mollie/GetMollieDashboardEndpoint.ts +24 -24
  90. package/src/endpoints/organization/dashboard/nolt/CreateNoltTokenEndpoint.ts +10 -12
  91. package/src/endpoints/organization/dashboard/organization/GetOrganizationArchivedGroups.ts +14 -14
  92. package/src/endpoints/organization/dashboard/organization/GetOrganizationDeletedGroups.ts +13 -13
  93. package/src/endpoints/organization/dashboard/organization/GetOrganizationSSOEndpoint.ts +12 -12
  94. package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.test.ts +120 -124
  95. package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.ts +172 -173
  96. package/src/endpoints/organization/dashboard/organization/SetOrganizationDomainEndpoint.ts +88 -89
  97. package/src/endpoints/organization/dashboard/organization/SetOrganizationSSOEndpoint.ts +12 -12
  98. package/src/endpoints/organization/dashboard/payments/GetMemberBalanceEndpoint.ts +17 -17
  99. package/src/endpoints/organization/dashboard/payments/GetPaymentsCountEndpoint.ts +8 -8
  100. package/src/endpoints/organization/dashboard/payments/GetPaymentsEndpoint.ts +66 -67
  101. package/src/endpoints/organization/dashboard/payments/PatchBalanceItemsEndpoint.ts +47 -47
  102. package/src/endpoints/organization/dashboard/payments/PatchPaymentsEndpoint.ts +93 -91
  103. package/src/endpoints/organization/dashboard/registration-periods/GetOrganizationRegistrationPeriodsEndpoint.ts +16 -17
  104. package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.ts +170 -167
  105. package/src/endpoints/organization/dashboard/registration-periods/SetupStepReviewEndpoint.ts +25 -24
  106. package/src/endpoints/organization/dashboard/stripe/ConnectStripeEndpoint.ts +22 -23
  107. package/src/endpoints/organization/dashboard/stripe/DeleteStripeAccountEndpoint.ts +22 -22
  108. package/src/endpoints/organization/dashboard/stripe/GetStripeAccountLinkEndpoint.ts +17 -18
  109. package/src/endpoints/organization/dashboard/stripe/GetStripeAccountsEndpoint.ts +8 -9
  110. package/src/endpoints/organization/dashboard/stripe/GetStripeLoginLinkEndpoint.ts +17 -18
  111. package/src/endpoints/organization/dashboard/stripe/UpdateStripeAccountEndpoint.ts +14 -15
  112. package/src/endpoints/organization/dashboard/users/CreateApiUserEndpoint.ts +19 -19
  113. package/src/endpoints/organization/dashboard/users/DeleteUserEndpoint.ts +19 -19
  114. package/src/endpoints/organization/dashboard/users/GetApiUsersEndpoint.ts +14 -14
  115. package/src/endpoints/organization/dashboard/users/GetOrganizationAdminsEndpoint.ts +12 -12
  116. package/src/endpoints/organization/dashboard/webshops/CreateWebshopEndpoint.ts +103 -100
  117. package/src/endpoints/organization/dashboard/webshops/DeleteWebshopEndpoint.ts +11 -12
  118. package/src/endpoints/organization/dashboard/webshops/GetDiscountCodesEndpoint.ts +15 -15
  119. package/src/endpoints/organization/dashboard/webshops/GetWebshopOrdersEndpoint.ts +14 -14
  120. package/src/endpoints/organization/dashboard/webshops/GetWebshopTicketsEndpoint.ts +14 -14
  121. package/src/endpoints/organization/dashboard/webshops/GetWebshopUriAvailabilityEndpoint.ts +23 -23
  122. package/src/endpoints/organization/dashboard/webshops/PatchDiscountCodesEndpoint.ts +54 -52
  123. package/src/endpoints/organization/dashboard/webshops/PatchWebshopEndpoint.ts +84 -81
  124. package/src/endpoints/organization/dashboard/webshops/PatchWebshopOrdersEndpoint.ts +120 -111
  125. package/src/endpoints/organization/dashboard/webshops/PatchWebshopTicketsEndpoint.ts +24 -24
  126. package/src/endpoints/organization/dashboard/webshops/VerifyWebshopDomainEndpoint.ts +18 -18
  127. package/src/endpoints/organization/shared/ExchangePaymentEndpoint.ts +141 -130
  128. package/src/endpoints/organization/shared/GetDocumentHtml.ts +25 -25
  129. package/src/endpoints/organization/shared/GetPaymentEndpoint.ts +18 -18
  130. package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.test.ts +36 -37
  131. package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.ts +9 -9
  132. package/src/endpoints/organization/shared/auth/OpenIDConnectCallbackEndpoint.ts +11 -11
  133. package/src/endpoints/organization/shared/auth/OpenIDConnectStartEndpoint.ts +28 -27
  134. package/src/endpoints/organization/webshops/CheckWebshopDiscountCodesEndpoint.ts +20 -20
  135. package/src/endpoints/organization/webshops/GetOrderByPaymentEndpoint.ts +22 -22
  136. package/src/endpoints/organization/webshops/GetOrderEndpoint.ts +14 -14
  137. package/src/endpoints/organization/webshops/GetTicketsEndpoint.ts +57 -56
  138. package/src/endpoints/organization/webshops/GetWebshopEndpoint.test.ts +65 -66
  139. package/src/endpoints/organization/webshops/GetWebshopEndpoint.ts +18 -17
  140. package/src/endpoints/organization/webshops/PlaceOrderEndpoint.test.ts +124 -128
  141. package/src/endpoints/organization/webshops/PlaceOrderEndpoint.ts +154 -145
  142. package/src/excel-loaders/members.ts +275 -273
  143. package/src/excel-loaders/payments.ts +155 -156
  144. package/src/helpers/AddressValidator.test.ts +32 -32
  145. package/src/helpers/AddressValidator.ts +128 -122
  146. package/src/helpers/AdminPermissionChecker.ts +339 -236
  147. package/src/helpers/AuthenticatedStructures.ts +233 -134
  148. package/src/helpers/BuckarooHelper.ts +134 -134
  149. package/src/helpers/CheckSettlements.ts +94 -88
  150. package/src/helpers/Context.ts +87 -86
  151. package/src/helpers/CookieHelper.ts +23 -22
  152. package/src/helpers/EmailResumer.ts +10 -10
  153. package/src/helpers/FileCache.ts +62 -62
  154. package/src/helpers/ForwardHandler.test.ts +122 -124
  155. package/src/helpers/ForwardHandler.ts +76 -70
  156. package/src/helpers/MemberUserSyncer.ts +101 -96
  157. package/src/helpers/MembershipCharger.ts +69 -69
  158. package/src/helpers/MembershipHelper.ts +11 -12
  159. package/src/helpers/OpenIDConnectHelper.ts +85 -82
  160. package/src/helpers/PeriodHelper.ts +65 -70
  161. package/src/helpers/StripeHelper.ts +146 -137
  162. package/src/helpers/StripePayoutChecker.ts +51 -52
  163. package/src/helpers/ViesHelper.ts +46 -44
  164. package/src/helpers/fetchToAsyncIterator.ts +14 -14
  165. package/src/helpers/xlsxAddressTransformerColumnFactory.ts +58 -60
  166. package/src/middleware/ContextMiddleware.ts +5 -5
  167. package/src/migrations/1646578856-validate-addresses.ts +6 -9
  168. package/src/seeds/0000000000-example.ts +3 -5
  169. package/src/seeds/1715028563-user-permissions.ts +16 -18
  170. package/src/seeds/1722256498-group-update-occupancy.ts +12 -12
  171. package/src/seeds/1722344162-sync-member-users.ts +14 -15
  172. package/src/seeds/1722344162-update-membership.ts +6 -6
  173. package/src/seeds/1726055544-balance-item-paid.ts +4 -4
  174. package/src/seeds/1726055545-balance-item-pending.ts +4 -4
  175. package/src/seeds/1726494419-update-cached-outstanding-balance.ts +16 -16
  176. package/src/seeds/1726494420-update-cached-outstanding-balance-from-items.ts +12 -12
  177. package/src/seeds/1726572303-schedule-stock-updates.ts +12 -12
  178. package/src/seeds/1726847064-setup-steps.ts +16 -0
  179. package/src/sql-filters/balance-item-payments.ts +7 -7
  180. package/src/sql-filters/events.ts +14 -14
  181. package/src/sql-filters/members.ts +96 -96
  182. package/src/sql-filters/organizations.ts +139 -75
  183. package/src/sql-filters/payments.ts +28 -28
  184. package/src/sql-filters/registrations.ts +14 -14
  185. package/src/sql-sorters/events.ts +25 -25
  186. package/src/sql-sorters/members.ts +26 -26
  187. package/src/sql-sorters/organizations.ts +36 -36
  188. package/src/sql-sorters/payments.ts +26 -26
  189. package/tests/e2e/stock.test.ts +616 -621
  190. package/tests/e2e/tickets.test.ts +255 -260
  191. package/tests/helpers/StripeMocker.ts +177 -179
  192. package/tests/helpers/TestServer.ts +9 -9
  193. package/tests/jest.global.setup.ts +14 -13
  194. package/tests/jest.setup.ts +33 -32
  195. package/.eslintrc.js +0 -61
  196. package/jest.config.js +0 -11
  197. package/src/helpers/SetupStepsUpdater.ts +0 -359
  198. package/src/seeds/1724076679-setup-steps.ts +0 -16
@@ -1,302 +1,304 @@
1
- import { XlsxBuiltInNumberFormat } from "@stamhoofd/excel-writer";
2
- import { Platform } from "@stamhoofd/models";
3
- import { ExcelExportType, Gender, GroupType, LimitedFilteredRequest, MemberWithRegistrationsBlob, PlatformFamily, PlatformMember, UnencodeablePaginatedResponse, Platform as PlatformStruct } from "@stamhoofd/structures";
4
- import { ExportToExcelEndpoint } from "../endpoints/global/files/ExportToExcelEndpoint";
5
- import { GetMembersEndpoint } from "../endpoints/global/members/GetMembersEndpoint";
6
- import { Context } from "../helpers/Context";
7
- import { XlsxTransformerColumnHelper } from "../helpers/xlsxAddressTransformerColumnFactory";
8
- import { Formatter } from "@stamhoofd/utility";
9
- import { AuthenticatedStructures } from "../helpers/AuthenticatedStructures";
1
+ import { XlsxBuiltInNumberFormat, XlsxTransformerSheet } from '@stamhoofd/excel-writer';
2
+ import { Platform } from '@stamhoofd/models';
3
+ import { ExcelExportType, Gender, GroupType, LimitedFilteredRequest, PlatformFamily, PlatformMember, Platform as PlatformStruct, UnencodeablePaginatedResponse } from '@stamhoofd/structures';
4
+ import { Formatter } from '@stamhoofd/utility';
5
+ import { ExportToExcelEndpoint } from '../endpoints/global/files/ExportToExcelEndpoint';
6
+ import { GetMembersEndpoint } from '../endpoints/global/members/GetMembersEndpoint';
7
+ import { AuthenticatedStructures } from '../helpers/AuthenticatedStructures';
8
+ import { Context } from '../helpers/Context';
9
+ import { XlsxTransformerColumnHelper } from '../helpers/xlsxAddressTransformerColumnFactory';
10
10
 
11
- ExportToExcelEndpoint.loaders.set(ExcelExportType.Members, {
12
- fetch: async (query: LimitedFilteredRequest) => {
13
- const result = await GetMembersEndpoint.buildData(query)
14
-
15
- return new UnencodeablePaginatedResponse({
16
- results: PlatformFamily.createSingles(result.results, {
17
- contextOrganization: Context.organization ? (await AuthenticatedStructures.organization(Context.organization)) : null,
18
- platform: await Platform.getSharedStruct()
11
+ // Assign to a typed variable to assure we have correct type checking in place
12
+ const sheet: XlsxTransformerSheet<PlatformMember, PlatformMember> = {
13
+ id: 'members',
14
+ name: 'Leden',
15
+ columns: [
16
+ {
17
+ id: 'id',
18
+ name: 'ID',
19
+ width: 20,
20
+ getValue: ({ patchedMember: object }: PlatformMember) => ({
21
+ value: object.id,
19
22
  }),
20
- next: result.next
21
- });
22
- },
23
- sheets: [
23
+ },
24
24
  {
25
- id: 'members',
26
- name: 'Leden',
27
- columns: [
28
- {
29
- id: 'id',
30
- name: 'ID',
31
- width: 20,
32
- getValue: ({patchedMember: object}: PlatformMember) => ({
33
- value: object.id
34
- })
35
- },
36
- {
37
- id: 'memberNumber',
38
- name: 'Nummer',
39
- width: 20,
40
- getValue: ({patchedMember: object}: PlatformMember) => ({
41
- value: object.details.memberNumber
42
- })
43
- },
44
- {
45
- id: 'firstName',
46
- name: 'Voornaam',
47
- width: 20,
48
- getValue: ({patchedMember: object}: PlatformMember) => ({
49
- value: object.details.firstName
50
- })
51
- },
52
- {
53
- id: 'lastName',
54
- name: 'Achternaam',
55
- width: 20,
56
- getValue: ({patchedMember: object}: PlatformMember) => ({
57
- value: object.details.lastName
58
- })
59
- },
60
- {
61
- id: 'birthDay',
62
- name: 'Geboortedatum',
63
- width: 20,
64
- getValue: ({patchedMember: object}: PlatformMember) => ({
65
- value: object.details.birthDay,
66
- style: {
67
- numberFormat: {
68
- id: XlsxBuiltInNumberFormat.DateSlash
69
- }
70
- }
71
- })
72
- },
73
- {
74
- id: 'age',
75
- name: 'Leeftijd',
76
- width: 20,
77
- getValue: ({patchedMember: object}: PlatformMember) => ({
78
- value: object.details.age,
79
- })
80
- },
81
- {
82
- id: 'gender',
83
- name: 'Geslacht',
84
- width: 20,
85
- getValue: ({patchedMember: object}: PlatformMember) => {
86
- const gender = object.details.gender;
87
-
88
- return ({
89
- value: formatGender(gender)
90
- })
91
- }
92
- },
93
- {
94
- id: 'phone',
95
- name: 'Telefoonnummer',
96
- width: 20,
97
- getValue: ({patchedMember: object}: PlatformMember) => ({
98
- value: object.details.phone,
99
- })
100
- },
101
- {
102
- id: 'email',
103
- name: 'E-mailadres',
104
- width: 20,
105
- getValue: ({patchedMember: object}: PlatformMember) => ({
106
- value: object.details.email,
107
- })
25
+ id: 'memberNumber',
26
+ name: 'Nummer',
27
+ width: 20,
28
+ getValue: ({ patchedMember: object }: PlatformMember) => ({
29
+ value: object.details.memberNumber,
30
+ }),
31
+ },
32
+ {
33
+ id: 'firstName',
34
+ name: 'Voornaam',
35
+ width: 20,
36
+ getValue: ({ patchedMember: object }: PlatformMember) => ({
37
+ value: object.details.firstName,
38
+ }),
39
+ },
40
+ {
41
+ id: 'lastName',
42
+ name: 'Achternaam',
43
+ width: 20,
44
+ getValue: ({ patchedMember: object }: PlatformMember) => ({
45
+ value: object.details.lastName,
46
+ }),
47
+ },
48
+ {
49
+ id: 'birthDay',
50
+ name: 'Geboortedatum',
51
+ width: 20,
52
+ getValue: ({ patchedMember: object }: PlatformMember) => ({
53
+ value: object.details.birthDay,
54
+ style: {
55
+ numberFormat: {
56
+ id: XlsxBuiltInNumberFormat.DateSlash,
57
+ },
108
58
  },
109
- XlsxTransformerColumnHelper.createAddressColumns<PlatformMember>({
110
- matchId: 'address',
111
- identifier: 'Adres',
112
- getAddress: ({patchedMember: object}: PlatformMember) => {
113
- // get member address if exists
114
- const memberAddress = object.details.address;
115
- if(memberAddress) {
116
- return memberAddress;
117
- }
59
+ }),
60
+ },
61
+ {
62
+ id: 'age',
63
+ name: 'Leeftijd',
64
+ width: 20,
65
+ getValue: ({ patchedMember: object }: PlatformMember) => ({
66
+ value: object.details.age,
67
+ }),
68
+ },
69
+ {
70
+ id: 'gender',
71
+ name: 'Geslacht',
72
+ width: 20,
73
+ getValue: ({ patchedMember: object }: PlatformMember) => {
74
+ const gender = object.details.gender;
118
75
 
119
- // else get address of first parent with address
120
- for(const parent of object.details.parents) {
121
- if(parent.address) {
122
- return parent.address;
123
- }
124
- }
76
+ return ({
77
+ value: formatGender(gender),
78
+ });
79
+ },
80
+ },
81
+ {
82
+ id: 'phone',
83
+ name: 'Telefoonnummer',
84
+ width: 20,
85
+ getValue: ({ patchedMember: object }: PlatformMember) => ({
86
+ value: object.details.phone,
87
+ }),
88
+ },
89
+ {
90
+ id: 'email',
91
+ name: 'E-mailadres',
92
+ width: 20,
93
+ getValue: ({ patchedMember: object }: PlatformMember) => ({
94
+ value: object.details.email,
95
+ }),
96
+ },
97
+ XlsxTransformerColumnHelper.createAddressColumns<PlatformMember>({
98
+ matchId: 'address',
99
+ identifier: 'Adres',
100
+ getAddress: ({ patchedMember: object }: PlatformMember) => {
101
+ // get member address if exists
102
+ const memberAddress = object.details.address;
103
+ if (memberAddress) {
104
+ return memberAddress;
105
+ }
125
106
 
126
- return null;
107
+ // else get address of first parent with address
108
+ for (const parent of object.details.parents) {
109
+ if (parent.address) {
110
+ return parent.address;
127
111
  }
128
- }),
129
- {
130
- id: 'securityCode',
131
- name: 'Beveiligingscode',
132
- width: 20,
133
- getValue: ({patchedMember: object}: PlatformMember) => ({
134
- value: object.details.securityCode,
135
- })
136
- },
137
- {
138
- id: 'uitpasNumber',
139
- name: 'UiTPAS-nummer',
140
- width: 20,
141
- getValue: ({patchedMember: object}: PlatformMember) => ({
142
- value: object.details.uitpasNumber,
143
- })
144
- },
145
- {
146
- id: 'requiresFinancialSupport',
147
- // todo: use correct term
148
- name: 'Financiële ondersteuning',
149
- width: 20,
150
- getValue: ({patchedMember: object}: PlatformMember) => ({
151
- value: XlsxTransformerColumnHelper.formatBoolean(object.details.requiresFinancialSupport?.value),
152
- })
153
- },
154
- {
155
- id: 'notes',
156
- name: 'Notities',
157
- width: 20,
158
- getValue: ({patchedMember: object}: PlatformMember) => ({
159
- value: object.details.notes,
160
- })
161
- },
112
+ }
113
+
114
+ return null;
115
+ },
116
+ }),
117
+ {
118
+ id: 'securityCode',
119
+ name: 'Beveiligingscode',
120
+ width: 20,
121
+ getValue: ({ patchedMember: object }: PlatformMember) => ({
122
+ value: object.details.securityCode,
123
+ }),
124
+ },
125
+ {
126
+ id: 'uitpasNumber',
127
+ name: 'UiTPAS-nummer',
128
+ width: 20,
129
+ getValue: ({ patchedMember: object }: PlatformMember) => ({
130
+ value: object.details.uitpasNumber,
131
+ }),
132
+ },
133
+ {
134
+ id: 'requiresFinancialSupport',
135
+ // todo: use correct term
136
+ name: 'Financiële ondersteuning',
137
+ width: 20,
138
+ getValue: ({ patchedMember: object }: PlatformMember) => ({
139
+ value: XlsxTransformerColumnHelper.formatBoolean(object.details.requiresFinancialSupport?.value),
140
+ }),
141
+ },
142
+ {
143
+ id: 'notes',
144
+ name: 'Notities',
145
+ width: 20,
146
+ getValue: ({ patchedMember: object }: PlatformMember) => ({
147
+ value: object.details.notes,
148
+ }),
149
+ },
162
150
 
163
- {
164
- id: 'organization',
165
- name: 'Groep',
166
- width: 40,
167
- getValue: (member: PlatformMember) => {
168
- const organizations = member.filterOrganizations({currentPeriod: true, types: [GroupType.Membership]})
169
- const str = Formatter.joinLast(organizations.map(o => o.name).sort(), ', ', ' en ') || Context.i18n.$t('1a16a32a-7ee4-455d-af3d-6073821efa8f')
151
+ {
152
+ id: 'organization',
153
+ name: 'Groep',
154
+ width: 40,
155
+ getValue: (member: PlatformMember) => {
156
+ const organizations = member.filterOrganizations({ currentPeriod: true, types: [GroupType.Membership] });
157
+ const str = Formatter.joinLast(organizations.map(o => o.name).sort(), ', ', ' en ') || Context.i18n.$t('1a16a32a-7ee4-455d-af3d-6073821efa8f');
170
158
 
171
- return {
172
- value: str
173
- }
174
- }
175
- },
159
+ return {
160
+ value: str,
161
+ };
162
+ },
163
+ },
176
164
 
177
- {
178
- id: 'uri',
179
- name: 'Groepsnummer',
180
- width: 30,
181
- getValue: (member: PlatformMember) => {
182
- const organizations = member.filterOrganizations({currentPeriod: true, types: [GroupType.Membership]})
183
- const str = Formatter.joinLast(organizations.map(o => o.uri).sort(), ', ', ' en ') || Context.i18n.$t('1a16a32a-7ee4-455d-af3d-6073821efa8f')
165
+ {
166
+ id: 'uri',
167
+ name: 'Groepsnummer',
168
+ width: 30,
169
+ getValue: (member: PlatformMember) => {
170
+ const organizations = member.filterOrganizations({ currentPeriod: true, types: [GroupType.Membership] });
171
+ const str = Formatter.joinLast(organizations.map(o => o.uri).sort(), ', ', ' en ') || Context.i18n.$t('1a16a32a-7ee4-455d-af3d-6073821efa8f');
184
172
 
185
- return {
186
- value: str
187
- }
188
- }
189
- },
173
+ return {
174
+ value: str,
175
+ };
176
+ },
177
+ },
190
178
 
191
- {
192
- id: 'group',
193
- name: 'Leeftijdsgroep',
194
- width: 40,
195
- getValue: (member: PlatformMember) => {
196
- const groups = member.filterRegistrations({currentPeriod: true, types: [GroupType.Membership], organizationId: Context.organization?.id})
197
- const str = Formatter.joinLast(Formatter.uniqueArray(groups.map(o => o.group.settings.name)).sort(), ', ', ' en ') || Context.i18n.$t('1a16a32a-7ee4-455d-af3d-6073821efa8f')
179
+ {
180
+ id: 'group',
181
+ name: 'Leeftijdsgroep',
182
+ width: 40,
183
+ getValue: (member: PlatformMember) => {
184
+ const groups = member.filterRegistrations({ currentPeriod: true, types: [GroupType.Membership], organizationId: Context.organization?.id });
185
+ const str = Formatter.joinLast(Formatter.uniqueArray(groups.map(o => o.group.settings.name)).sort(), ', ', ' en ') || Context.i18n.$t('1a16a32a-7ee4-455d-af3d-6073821efa8f');
198
186
 
199
- return {
200
- value: str
201
- }
202
- }
203
- },
187
+ return {
188
+ value: str,
189
+ };
190
+ },
191
+ },
204
192
 
205
- {
206
- id: 'defaultAgeGroup',
207
- name: 'Standaard leeftijdsgroep',
208
- width: 40,
209
- getValue: (member: PlatformMember) => {
210
- const groups = member.filterRegistrations({currentPeriod: true, types: [GroupType.Membership], organizationId: Context.organization?.id})
211
- const defaultAgeGroupIds = Formatter.uniqueArray(groups.filter(o => o.group.defaultAgeGroupId))
212
- const defaultAgeGroups = defaultAgeGroupIds.map(o => PlatformStruct.shared.config.defaultAgeGroups.find(g => g.id === o.group.defaultAgeGroupId)?.name ?? 'verwijderde leeftijdsgroep')
213
- const str = Formatter.joinLast(Formatter.uniqueArray(defaultAgeGroups).sort(), ', ', ' en ') || Context.i18n.$t('1a16a32a-7ee4-455d-af3d-6073821efa8f')
193
+ {
194
+ id: 'defaultAgeGroup',
195
+ name: 'Standaard leeftijdsgroep',
196
+ width: 40,
197
+ getValue: (member: PlatformMember) => {
198
+ const groups = member.filterRegistrations({ currentPeriod: true, types: [GroupType.Membership], organizationId: Context.organization?.id });
199
+ const defaultAgeGroupIds = Formatter.uniqueArray(groups.filter(o => o.group.defaultAgeGroupId));
200
+ const defaultAgeGroups = defaultAgeGroupIds.map(o => PlatformStruct.shared.config.defaultAgeGroups.find(g => g.id === o.group.defaultAgeGroupId)?.name ?? 'verwijderde leeftijdsgroep');
201
+ const str = Formatter.joinLast(Formatter.uniqueArray(defaultAgeGroups).sort(), ', ', ' en ') || Context.i18n.$t('1a16a32a-7ee4-455d-af3d-6073821efa8f');
214
202
 
215
- return {
216
- value: str
217
- }
218
- }
219
- },
203
+ return {
204
+ value: str,
205
+ };
206
+ },
207
+ },
220
208
 
221
- ...XlsxTransformerColumnHelper.creatColumnsForParents(),
209
+ ...XlsxTransformerColumnHelper.creatColumnsForParents(),
222
210
 
223
- // unverified data
224
- {
225
- id: 'unverifiedPhones',
226
- name: 'Niet-geverifieerde telefoonnummers',
227
- width: 20,
228
- getValue: ({patchedMember: object}: PlatformMember) => ({
229
- value: object.details.unverifiedPhones.join(', '),
230
- })
231
- },
232
- {
233
- id: 'unverifiedEmails',
234
- name: 'Niet-geverifieerde e-mailadressen',
235
- width: 20,
236
- getValue: ({patchedMember: object}: PlatformMember) => ({
237
- value: object.details.unverifiedEmails.join(', '),
238
- })
239
- },
240
- ...XlsxTransformerColumnHelper.createColumnsForAddresses<MemberWithRegistrationsBlob>({
241
- matchIdStart: 'unverifiedAddresses',
242
- identifier: 'Niet-geverifieerd adres',
243
- getAddresses: (object) => object.details.unverifiedAddresses,
244
- limit: 2
245
- }),
246
- {
247
- id: 'unverifiedAddresses',
248
- name: 'Niet-geverifieerde adressen',
249
- width: 20,
250
- getValue: ({patchedMember: object}: PlatformMember) => ({
251
- value: object.details.unverifiedAddresses.map(a => a.toString()).join('; '),
252
- })
253
- },
211
+ // unverified data
212
+ {
213
+ id: 'unverifiedPhones',
214
+ name: 'Niet-geverifieerde telefoonnummers',
215
+ width: 20,
216
+ getValue: ({ patchedMember: object }: PlatformMember) => ({
217
+ value: object.details.unverifiedPhones.join(', '),
218
+ }),
219
+ },
220
+ {
221
+ id: 'unverifiedEmails',
222
+ name: 'Niet-geverifieerde e-mailadressen',
223
+ width: 20,
224
+ getValue: ({ patchedMember: object }: PlatformMember) => ({
225
+ value: object.details.unverifiedEmails.join(', '),
226
+ }),
227
+ },
228
+ ...XlsxTransformerColumnHelper.createColumnsForAddresses<PlatformMember>({
229
+ matchIdStart: 'unverifiedAddresses',
230
+ identifier: 'Niet-geverifieerd adres',
231
+ getAddresses: object => object.patchedMember.details.unverifiedAddresses,
232
+ limit: 2,
233
+ }),
234
+ {
235
+ id: 'unverifiedAddresses',
236
+ name: 'Niet-geverifieerde adressen',
237
+ width: 20,
238
+ getValue: ({ patchedMember: object }: PlatformMember) => ({
239
+ value: object.details.unverifiedAddresses.map(a => a.toString()).join('; '),
240
+ }),
241
+ },
254
242
 
255
- // Dynamic records
256
- {
257
- match(id) {
258
- if (id.startsWith('recordAnswers.')) {
259
- const platform = PlatformStruct.shared
260
- const organization = Context.organization
243
+ // Dynamic records
244
+ {
245
+ match(id) {
246
+ if (id.startsWith('recordAnswers.')) {
247
+ const platform = PlatformStruct.shared;
248
+ const organization = Context.organization;
261
249
 
262
- const recordSettings = [
263
- ...(organization?.meta.recordsConfiguration.recordCategories.flatMap(category => category.getAllRecords()) ?? []),
264
- ...platform.config.recordsConfiguration.recordCategories.flatMap(category => category.getAllRecords())
265
- ]
250
+ const recordSettings = [
251
+ ...(organization?.meta.recordsConfiguration.recordCategories.flatMap(category => category.getAllRecords()) ?? []),
252
+ ...platform.config.recordsConfiguration.recordCategories.flatMap(category => category.getAllRecords()),
253
+ ];
266
254
 
267
- const recordSettingId = id.split('.')[1];
268
- console.log('recordSettingId', recordSettingId)
269
- const recordSetting = recordSettings.find(r => r.id === recordSettingId)
270
-
255
+ const recordSettingId = id.split('.')[1];
256
+ console.log('recordSettingId', recordSettingId);
257
+ const recordSetting = recordSettings.find(r => r.id === recordSettingId);
271
258
 
272
- if (!recordSetting) {
273
- // Will throw a proper error itself
274
- console.log('recordSetting not found', recordSettings)
275
- return
276
- }
259
+ if (!recordSetting) {
260
+ // Will throw a proper error itself
261
+ console.log('recordSetting not found', recordSettings);
262
+ return;
263
+ }
277
264
 
278
- const columns = recordSetting.excelColumns
265
+ const columns = recordSetting.excelColumns;
279
266
 
280
- return columns.map((columnName, index) => {
281
- return {
282
- id: `recordAnswers.${recordSettingId}.${index}`,
283
- name: columnName,
284
- width: 20,
285
- getValue: ({patchedMember: object}: PlatformMember) => ({
286
- value: object.details.recordAnswers.get(recordSettingId)?.excelValues[index]?.value ?? ''
287
- })
288
- }
289
- })
290
- }
291
- },
267
+ return columns.map((columnName, index) => {
268
+ return {
269
+ id: `recordAnswers.${recordSettingId}.${index}`,
270
+ name: columnName,
271
+ width: 20,
272
+ getValue: ({ patchedMember: object }: PlatformMember) => ({
273
+ value: object.details.recordAnswers.get(recordSettingId)?.excelValues[index]?.value ?? '',
274
+ }),
275
+ };
276
+ });
292
277
  }
293
- ]
294
- }
295
- ]
296
- })
278
+ },
279
+ },
280
+ ],
281
+ };
282
+
283
+ ExportToExcelEndpoint.loaders.set(ExcelExportType.Members, {
284
+ fetch: async (query: LimitedFilteredRequest) => {
285
+ const result = await GetMembersEndpoint.buildData(query);
286
+
287
+ return new UnencodeablePaginatedResponse({
288
+ results: PlatformFamily.createSingles(result.results, {
289
+ contextOrganization: Context.organization ? (await AuthenticatedStructures.organization(Context.organization)) : null,
290
+ platform: await Platform.getSharedStruct(),
291
+ }),
292
+ next: result.next,
293
+ });
294
+ },
295
+ sheets: [
296
+ sheet,
297
+ ],
298
+ });
297
299
 
298
300
  function formatGender(gender: Gender) {
299
- switch(gender) {
301
+ switch (gender) {
300
302
  case Gender.Male: return 'Man';
301
303
  case Gender.Female: return 'Vrouw';
302
304
  default: return 'Andere';