@stamhoofd/backend 2.39.1 → 2.40.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.
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 +102 -103
  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 +50 -52
  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,15 +1,14 @@
1
- import { AutoEncoderPatchType, Decoder, isPatchableArray, patchObject } from "@simonbackx/simple-encoding";
2
- import { DecodedRequest, Endpoint, Request, Response } from "@simonbackx/simple-endpoints";
3
- import { Organization, Platform, RegistrationPeriod } from "@stamhoofd/models";
4
- import { MemberResponsibility, PlatformConfig, PlatformPremiseType, Platform as PlatformStruct } from "@stamhoofd/structures";
5
-
6
- import { SimpleError } from "@simonbackx/simple-errors";
7
- import { QueueHandler } from "@stamhoofd/queues";
8
- import { Context } from "../../../helpers/Context";
9
- import { MembershipCharger } from "../../../helpers/MembershipCharger";
10
- import { MembershipHelper } from "../../../helpers/MembershipHelper";
11
- import { PeriodHelper } from "../../../helpers/PeriodHelper";
12
- import { SetupStepUpdater } from "../../../helpers/SetupStepsUpdater";
1
+ import { AutoEncoderPatchType, Decoder, isPatchableArray, patchObject } from '@simonbackx/simple-encoding';
2
+ import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
3
+ import { Organization, Platform, RegistrationPeriod, SetupStepUpdater } from '@stamhoofd/models';
4
+ import { MemberResponsibility, PlatformConfig, PlatformPremiseType, Platform as PlatformStruct } from '@stamhoofd/structures';
5
+
6
+ import { SimpleError } from '@simonbackx/simple-errors';
7
+ import { QueueHandler } from '@stamhoofd/queues';
8
+ import { Context } from '../../../helpers/Context';
9
+ import { MembershipCharger } from '../../../helpers/MembershipCharger';
10
+ import { MembershipHelper } from '../../../helpers/MembershipHelper';
11
+ import { PeriodHelper } from '../../../helpers/PeriodHelper';
13
12
 
14
13
  type Params = Record<string, never>;
15
14
  type Query = undefined;
@@ -27,11 +26,11 @@ export class PatchPlatformEndpoint extends Endpoint<
27
26
  >;
28
27
 
29
28
  protected doesMatch(request: Request): [true, Params] | [false] {
30
- if (request.method != "PATCH") {
29
+ if (request.method !== 'PATCH') {
31
30
  return [false];
32
31
  }
33
32
 
34
- const params = Endpoint.parseParameters(request.url, "/platform", {});
33
+ const params = Endpoint.parseParameters(request.url, '/platform', {});
35
34
 
36
35
  if (params) {
37
36
  return [true, params as Params];
@@ -59,7 +58,7 @@ export class PatchPlatformEndpoint extends Endpoint<
59
58
  // Update roles
60
59
  platform.privateConfig.roles = patchObject(
61
60
  platform.privateConfig.roles,
62
- request.body.privateConfig.roles
61
+ request.body.privateConfig.roles,
63
62
  );
64
63
  }
65
64
 
@@ -71,7 +70,7 @@ export class PatchPlatformEndpoint extends Endpoint<
71
70
  // Update roles
72
71
  platform.privateConfig.emails = patchObject(
73
72
  platform.privateConfig.emails,
74
- request.body.privateConfig.emails
73
+ request.body.privateConfig.emails,
75
74
  );
76
75
  }
77
76
  }
@@ -97,9 +96,10 @@ export class PatchPlatformEndpoint extends Endpoint<
97
96
  shouldUpdateSetupSteps = this.shouldUpdateSetupSteps(
98
97
  currentConfig,
99
98
  newConfig,
100
- oldConfig
99
+ oldConfig,
101
100
  );
102
- } else {
101
+ }
102
+ else {
103
103
  platform.config = patchObject(platform.config, newConfig);
104
104
  }
105
105
  }
@@ -118,16 +118,16 @@ export class PatchPlatformEndpoint extends Endpoint<
118
118
  }
119
119
 
120
120
  if (
121
- request.body.period &&
122
- request.body.period.id !== platform.periodId
121
+ request.body.period
122
+ && request.body.period.id !== platform.periodId
123
123
  ) {
124
124
  const period = await RegistrationPeriod.getByID(
125
- request.body.period.id
125
+ request.body.period.id,
126
126
  );
127
127
  if (!period || period.organizationId) {
128
128
  throw new SimpleError({
129
- code: "invalid_period",
130
- message: "Invalid period",
129
+ code: 'invalid_period',
130
+ message: 'Invalid period',
131
131
  });
132
132
  }
133
133
  platform.periodId = period.id;
@@ -137,39 +137,41 @@ export class PatchPlatformEndpoint extends Endpoint<
137
137
 
138
138
  if (request.body.membershipOrganizationId !== undefined) {
139
139
  if (!Context.auth.hasPlatformFullAccess()) {
140
- throw Context.auth.error()
140
+ throw Context.auth.error();
141
141
  }
142
142
 
143
143
  if (request.body.membershipOrganizationId) {
144
- const organization = await Organization.getByID(request.body.membershipOrganizationId)
144
+ const organization = await Organization.getByID(request.body.membershipOrganizationId);
145
145
  if (!organization) {
146
146
  throw new SimpleError({
147
- code: "invalid_organization",
148
- message: "Invalid organization"
149
- })
147
+ code: 'invalid_organization',
148
+ message: 'Invalid organization',
149
+ });
150
150
  }
151
- platform.membershipOrganizationId = organization.id
152
- } else {
153
- platform.membershipOrganizationId = null
151
+ platform.membershipOrganizationId = organization.id;
152
+ }
153
+ else {
154
+ platform.membershipOrganizationId = null;
154
155
  }
155
156
  }
156
157
 
157
158
  if (request.body.membershipOrganizationId !== undefined) {
158
159
  if (!Context.auth.hasPlatformFullAccess()) {
159
- throw Context.auth.error()
160
+ throw Context.auth.error();
160
161
  }
161
162
 
162
163
  if (request.body.membershipOrganizationId) {
163
- const organization = await Organization.getByID(request.body.membershipOrganizationId)
164
+ const organization = await Organization.getByID(request.body.membershipOrganizationId);
164
165
  if (!organization) {
165
166
  throw new SimpleError({
166
- code: "invalid_organization",
167
- message: "Invalid organization"
168
- })
167
+ code: 'invalid_organization',
168
+ message: 'Invalid organization',
169
+ });
169
170
  }
170
- platform.membershipOrganizationId = organization.id
171
- } else {
172
- platform.membershipOrganizationId = null
171
+ platform.membershipOrganizationId = organization.id;
172
+ }
173
+ else {
174
+ platform.membershipOrganizationId = null;
173
175
  }
174
176
  }
175
177
 
@@ -178,15 +180,16 @@ export class PatchPlatformEndpoint extends Endpoint<
178
180
  if (shouldUpdateMemberships) {
179
181
  if (!QueueHandler.isRunning('update-membership-prices')) {
180
182
  QueueHandler.schedule('update-membership-prices', async () => {
181
- await MembershipCharger.updatePrices()
182
- await MembershipHelper.updateAll()
183
+ await MembershipCharger.updatePrices();
184
+ await MembershipHelper.updateAll();
183
185
  }).catch(console.error);
184
186
  }
185
187
  }
186
188
 
187
189
  if (shouldMoveToPeriod) {
188
- PeriodHelper.moveAllOrganizationsToPeriod(shouldMoveToPeriod).catch(console.error)
189
- } else if(shouldUpdateSetupSteps) {
190
+ PeriodHelper.moveAllOrganizationsToPeriod(shouldMoveToPeriod).catch(console.error);
191
+ }
192
+ else if (shouldUpdateSetupSteps) {
190
193
  // Do not call this right away when moving to a period, because this needs to happen AFTER moving to the period
191
194
  SetupStepUpdater.updateSetupStepsForAllOrganizationsInCurrentPeriod().catch(console.error);
192
195
  }
@@ -197,29 +200,29 @@ export class PatchPlatformEndpoint extends Endpoint<
197
200
  private shouldUpdateSetupSteps(
198
201
  currentConfig: PlatformConfig,
199
202
  newConfig: PlatformConfig | AutoEncoderPatchType<PlatformConfig>,
200
- oldConfig: PlatformConfig
203
+ oldConfig: PlatformConfig,
201
204
  ): boolean {
202
205
  let shouldUpdate = false;
203
206
  const premiseTypes: PlatformPremiseType[] = currentConfig.premiseTypes;
204
- const responsibilities: MemberResponsibility[] =
205
- currentConfig.responsibilities;
207
+ const responsibilities: MemberResponsibility[]
208
+ = currentConfig.responsibilities;
206
209
 
207
210
  if (
208
- newConfig.premiseTypes &&
209
- this.shouldUpdateSetupStepPremise(
211
+ newConfig.premiseTypes
212
+ && this.shouldUpdateSetupStepPremise(
210
213
  premiseTypes,
211
- oldConfig.premiseTypes
214
+ oldConfig.premiseTypes,
212
215
  )
213
216
  ) {
214
217
  shouldUpdate = true;
215
218
  }
216
219
 
217
220
  if (
218
- !shouldUpdate &&
219
- newConfig.responsibilities &&
220
- this.shouldUpdateSetupStepFunctions(
221
+ !shouldUpdate
222
+ && newConfig.responsibilities
223
+ && this.shouldUpdateSetupStepFunctions(
221
224
  responsibilities,
222
- oldConfig.responsibilities
225
+ oldConfig.responsibilities,
223
226
  )
224
227
  ) {
225
228
  shouldUpdate = true;
@@ -230,17 +233,17 @@ export class PatchPlatformEndpoint extends Endpoint<
230
233
 
231
234
  private shouldUpdateSetupStepPremise(
232
235
  newPremiseTypes: PlatformPremiseType[],
233
- oldPremiseTypes: PlatformPremiseType[]
236
+ oldPremiseTypes: PlatformPremiseType[],
234
237
  ) {
235
238
  for (const premiseType of newPremiseTypes) {
236
239
  const id = premiseType.id;
237
- const oldVersion = oldPremiseTypes.find((x) => x.id === id);
240
+ const oldVersion = oldPremiseTypes.find(x => x.id === id);
238
241
 
239
242
  // if premise type is not new
240
243
  if (oldVersion) {
241
244
  if (
242
- oldVersion.min !== premiseType.min ||
243
- oldVersion.max !== premiseType.max
245
+ oldVersion.min !== premiseType.min
246
+ || oldVersion.max !== premiseType.max
244
247
  ) {
245
248
  return true;
246
249
  }
@@ -257,7 +260,7 @@ export class PatchPlatformEndpoint extends Endpoint<
257
260
  const id = oldPremiseType.id;
258
261
 
259
262
  // if premise type is removed
260
- if (!newPremiseTypes.some((x) => x.id === id)) {
263
+ if (!newPremiseTypes.some(x => x.id === id)) {
261
264
  if (oldPremiseType.min || oldPremiseType.max) {
262
265
  return true;
263
266
  }
@@ -267,19 +270,19 @@ export class PatchPlatformEndpoint extends Endpoint<
267
270
 
268
271
  private shouldUpdateSetupStepFunctions(
269
272
  newResponsibilities: MemberResponsibility[],
270
- oldResponsibilities: MemberResponsibility[]
273
+ oldResponsibilities: MemberResponsibility[],
271
274
  ) {
272
275
  for (const responsibility of newResponsibilities) {
273
276
  const id = responsibility.id;
274
- const oldVersion = oldResponsibilities.find((x) => x.id === id);
277
+ const oldVersion = oldResponsibilities.find(x => x.id === id);
275
278
 
276
279
  // if responsibility is not new
277
280
  if (oldVersion) {
278
281
  // if restrictions changed
279
282
  if (
280
- oldVersion.minimumMembers !==
281
- responsibility.minimumMembers ||
282
- oldVersion.maximumMembers !== responsibility.maximumMembers
283
+ oldVersion.minimumMembers
284
+ !== responsibility.minimumMembers
285
+ || oldVersion.maximumMembers !== responsibility.maximumMembers
283
286
  ) {
284
287
  return true;
285
288
  }
@@ -288,8 +291,8 @@ export class PatchPlatformEndpoint extends Endpoint<
288
291
 
289
292
  // if responsibility is new
290
293
  if (
291
- responsibility.minimumMembers ||
292
- responsibility.maximumMembers
294
+ responsibility.minimumMembers
295
+ || responsibility.maximumMembers
293
296
  ) {
294
297
  return true;
295
298
  }
@@ -299,11 +302,11 @@ export class PatchPlatformEndpoint extends Endpoint<
299
302
  const id = oldResponsibility.id;
300
303
 
301
304
  // if responsibility is removed
302
- if (!newResponsibilities.some((x) => x.id === id)) {
305
+ if (!newResponsibilities.some(x => x.id === id)) {
303
306
  // if responsibility had restrictions
304
307
  if (
305
- oldResponsibility.minimumMembers ||
306
- oldResponsibility.maximumMembers
308
+ oldResponsibility.minimumMembers
309
+ || oldResponsibility.maximumMembers
307
310
  ) {
308
311
  return true;
309
312
  }
@@ -1,23 +1,23 @@
1
- import { ManyToOneRelation } from "@simonbackx/simple-database";
2
- import { DecodedRequest, Endpoint, Request, Response } from "@simonbackx/simple-endpoints";
3
- import { SimpleError } from "@simonbackx/simple-errors";
1
+ import { ManyToOneRelation } from '@simonbackx/simple-database';
2
+ import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
3
+ import { SimpleError } from '@simonbackx/simple-errors';
4
4
  import { Group, Member, Payment, Registration } from '@stamhoofd/models';
5
- import { PaymentWithRegistrations } from "@stamhoofd/structures";
6
- import { Formatter } from "@stamhoofd/utility";
5
+ import { PaymentWithRegistrations } from '@stamhoofd/structures';
6
+ import { Formatter } from '@stamhoofd/utility';
7
7
 
8
- import { Context } from "../../../helpers/Context";
9
- type Params = {id: string};
10
- type Query = undefined
11
- type Body = undefined
8
+ import { Context } from '../../../helpers/Context';
9
+ type Params = { id: string };
10
+ type Query = undefined;
11
+ type Body = undefined;
12
12
  type ResponseBody = PaymentWithRegistrations | undefined;
13
13
 
14
14
  export class GetPaymentRegistrations extends Endpoint<Params, Query, Body, ResponseBody> {
15
15
  protected doesMatch(request: Request): [true, Params] | [false] {
16
- if (request.method != "GET") {
16
+ if (request.method !== 'GET') {
17
17
  return [false];
18
18
  }
19
19
 
20
- const params = Endpoint.parseParameters(request.url, "/payments/@id/registrations", {id: String});
20
+ const params = Endpoint.parseParameters(request.url, '/payments/@id/registrations', { id: String });
21
21
 
22
22
  if (params) {
23
23
  return [true, params as Params];
@@ -27,30 +27,30 @@ export class GetPaymentRegistrations extends Endpoint<Params, Query, Body, Respo
27
27
 
28
28
  async handle(request: DecodedRequest<Params, Query, Body>) {
29
29
  await Context.setUserOrganizationScope();
30
- const {user} = await Context.authenticate()
31
-
32
- const payment = await Payment.getByID(request.params.id)
30
+ const { user } = await Context.authenticate();
31
+
32
+ const payment = await Payment.getByID(request.params.id);
33
33
  if (!payment) {
34
34
  throw new SimpleError({
35
- code: "",
36
- message: "Deze link is ongeldig"
37
- })
35
+ code: '',
36
+ message: 'Deze link is ongeldig',
37
+ });
38
38
  }
39
- const registrations = await Member.getRegistrationWithMembersForPayment(payment.id)
40
- const authorizedMembers = (await Member.getMembersWithRegistrationForUser(user)).map(m => m.id)
41
- const groups = await Group.getByIDs(...Formatter.uniqueArray(registrations.map(r => r.groupId)))
39
+ const registrations = await Member.getRegistrationWithMembersForPayment(payment.id);
40
+ const authorizedMembers = (await Member.getMembersWithRegistrationForUser(user)).map(m => m.id);
41
+ const groups = await Group.getByIDs(...Formatter.uniqueArray(registrations.map(r => r.groupId)));
42
42
 
43
43
  // Check permissions
44
44
  for (const registration of registrations) {
45
45
  if (!authorizedMembers.includes(registration.member.id)) {
46
46
  throw new SimpleError({
47
- code: "",
48
- message: "Deze link is ongeldig"
49
- })
47
+ code: '',
48
+ message: 'Deze link is ongeldig',
49
+ });
50
50
  }
51
51
  }
52
-
53
- return new Response(
52
+
53
+ return new Response(
54
54
  PaymentWithRegistrations.create({
55
55
  id: payment.id,
56
56
  method: payment.method,
@@ -61,8 +61,8 @@ export class GetPaymentRegistrations extends Endpoint<Params, Query, Body, Respo
61
61
  paidAt: payment.paidAt,
62
62
  createdAt: payment.createdAt,
63
63
  updatedAt: payment.updatedAt,
64
- registrations: registrations.map(r => Member.getRegistrationWithMemberStructure(r.setRelation(Registration.group, groups.find(g => g.id === r.groupId)!)))
65
- })
64
+ registrations: registrations.map(r => Member.getRegistrationWithMemberStructure(r.setRelation(Registration.group, groups.find(g => g.id === r.groupId)!))),
65
+ }),
66
66
  );
67
67
  }
68
68
  }
@@ -1,23 +1,23 @@
1
- import { DecodedRequest, Endpoint, Request, Response } from "@simonbackx/simple-endpoints";
2
- import { CachedOutstandingBalance, Member, Organization } from "@stamhoofd/models";
3
- import { OrganizationBillingStatus, OrganizationBillingStatusItem } from "@stamhoofd/structures";
1
+ import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
2
+ import { CachedOutstandingBalance, Member, Organization } from '@stamhoofd/models';
3
+ import { OrganizationBillingStatus, OrganizationBillingStatusItem } from '@stamhoofd/structures';
4
4
 
5
- import { Formatter } from "@stamhoofd/utility";
6
- import { AuthenticatedStructures } from "../../../helpers/AuthenticatedStructures";
7
- import { Context } from "../../../helpers/Context";
5
+ import { Formatter } from '@stamhoofd/utility';
6
+ import { AuthenticatedStructures } from '../../../helpers/AuthenticatedStructures';
7
+ import { Context } from '../../../helpers/Context';
8
8
 
9
9
  type Params = Record<string, never>;
10
- type Query = undefined
11
- type Body = undefined
12
- type ResponseBody = OrganizationBillingStatus
10
+ type Query = undefined;
11
+ type Body = undefined;
12
+ type ResponseBody = OrganizationBillingStatus;
13
13
 
14
14
  export class GetUserBilingStatusEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
15
15
  protected doesMatch(request: Request): [true, Params] | [false] {
16
- if (request.method != "GET") {
16
+ if (request.method !== 'GET') {
17
17
  return [false];
18
18
  }
19
19
 
20
- const params = Endpoint.parseParameters(request.url, "/user/billing/status", {});
20
+ const params = Endpoint.parseParameters(request.url, '/user/billing/status', {});
21
21
 
22
22
  if (params) {
23
23
  return [true, params as Params];
@@ -27,54 +27,54 @@ export class GetUserBilingStatusEndpoint extends Endpoint<Params, Query, Body, R
27
27
 
28
28
  async handle(_: DecodedRequest<Params, Query, Body>) {
29
29
  const organization = await Context.setUserOrganizationScope();
30
- const {user} = await Context.authenticate()
30
+ const { user } = await Context.authenticate();
31
31
 
32
- const memberIds = await Member.getMemberIdsWithRegistrationForUser(user)
32
+ const memberIds = await Member.getMemberIdsWithRegistrationForUser(user);
33
33
 
34
34
  return new Response(await GetUserBilingStatusEndpoint.getBillingStatusForObjects([user.id, ...memberIds], organization));
35
35
  }
36
36
 
37
- static async getBillingStatusForObjects(objectIds: string[], organization?: Organization|null) {
37
+ static async getBillingStatusForObjects(objectIds: string[], organization?: Organization | null) {
38
38
  // Load cached balances
39
- const cachedOutstandingBalances = await CachedOutstandingBalance.getForObjects(objectIds, organization?.id)
39
+ const cachedOutstandingBalances = await CachedOutstandingBalance.getForObjects(objectIds, organization?.id);
40
40
 
41
- const organizationIds = Formatter.uniqueArray(cachedOutstandingBalances.map(b => b.organizationId))
41
+ const organizationIds = Formatter.uniqueArray(cachedOutstandingBalances.map(b => b.organizationId));
42
42
 
43
- let addOrganization = false
44
- const i = organization ? organizationIds.indexOf(organization.id) : -1
43
+ let addOrganization = false;
44
+ const i = organization ? organizationIds.indexOf(organization.id) : -1;
45
45
  if (i !== -1) {
46
- organizationIds.splice(i, 1)
47
- addOrganization = true
46
+ organizationIds.splice(i, 1);
47
+ addOrganization = true;
48
48
  }
49
49
 
50
- const organizations = await Organization.getByIDs(...organizationIds)
50
+ const organizations = await Organization.getByIDs(...organizationIds);
51
51
 
52
52
  if (addOrganization && organization) {
53
- organizations.push(organization)
53
+ organizations.push(organization);
54
54
  }
55
55
 
56
- const authenticatedOrganizations = await AuthenticatedStructures.organizations(organizations)
56
+ const authenticatedOrganizations = await AuthenticatedStructures.organizations(organizations);
57
57
 
58
- const billingStatus = OrganizationBillingStatus.create({})
58
+ const billingStatus = OrganizationBillingStatus.create({});
59
59
 
60
60
  for (const organization of authenticatedOrganizations) {
61
- const items = cachedOutstandingBalances.filter(b => b.organizationId === organization.id)
61
+ const items = cachedOutstandingBalances.filter(b => b.organizationId === organization.id);
62
62
 
63
63
  let amount = 0;
64
64
  let amountPending = 0;
65
65
 
66
66
  for (const item of items) {
67
- amount += item.amount
68
- amountPending += item.amountPending
67
+ amount += item.amount;
68
+ amountPending += item.amountPending;
69
69
  }
70
70
 
71
71
  billingStatus.organizations.push(OrganizationBillingStatusItem.create({
72
72
  organization,
73
73
  amount,
74
- amountPending
75
- }))
74
+ amountPending,
75
+ }));
76
76
  }
77
77
 
78
- return billingStatus
78
+ return billingStatus;
79
79
  }
80
80
  }
@@ -1,23 +1,23 @@
1
- import { DecodedRequest, Endpoint, Request, Response } from "@simonbackx/simple-endpoints";
2
- import { BalanceItem, Member, Organization, Payment } from "@stamhoofd/models";
3
- import { OrganizationDetailedBillingStatus, OrganizationDetailedBillingStatusItem } from "@stamhoofd/structures";
1
+ import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
2
+ import { BalanceItem, Member, Organization, Payment } from '@stamhoofd/models';
3
+ import { OrganizationDetailedBillingStatus, OrganizationDetailedBillingStatusItem } from '@stamhoofd/structures';
4
4
 
5
- import { Formatter } from "@stamhoofd/utility";
6
- import { AuthenticatedStructures } from "../../../helpers/AuthenticatedStructures";
7
- import { Context } from "../../../helpers/Context";
5
+ import { Formatter } from '@stamhoofd/utility';
6
+ import { AuthenticatedStructures } from '../../../helpers/AuthenticatedStructures';
7
+ import { Context } from '../../../helpers/Context';
8
8
 
9
9
  type Params = Record<string, never>;
10
- type Query = undefined
11
- type Body = undefined
12
- type ResponseBody = OrganizationDetailedBillingStatus
10
+ type Query = undefined;
11
+ type Body = undefined;
12
+ type ResponseBody = OrganizationDetailedBillingStatus;
13
13
 
14
14
  export class GetUserDetailedBilingStatusEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
15
15
  protected doesMatch(request: Request): [true, Params] | [false] {
16
- if (request.method != "GET") {
16
+ if (request.method !== 'GET') {
17
17
  return [false];
18
18
  }
19
19
 
20
- const params = Endpoint.parseParameters(request.url, "/user/billing/status/detailed", {});
20
+ const params = Endpoint.parseParameters(request.url, '/user/billing/status/detailed', {});
21
21
 
22
22
  if (params) {
23
23
  return [true, params as Params];
@@ -27,14 +27,14 @@ export class GetUserDetailedBilingStatusEndpoint extends Endpoint<Params, Query,
27
27
 
28
28
  async handle(_: DecodedRequest<Params, Query, Body>) {
29
29
  const organization = await Context.setUserOrganizationScope();
30
- const {user} = await Context.authenticate()
30
+ const { user } = await Context.authenticate();
31
31
 
32
- const memberIds = await Member.getMemberIdsWithRegistrationForUser(user)
32
+ const memberIds = await Member.getMemberIdsWithRegistrationForUser(user);
33
33
 
34
34
  const balanceItemModels = await BalanceItem.balanceItemsForUsersAndMembers(organization?.id ?? null, [user.id], memberIds);
35
-
35
+
36
36
  // todo: this is a duplicate query
37
- const {payments, balanceItemPayments} = await BalanceItem.loadPayments(balanceItemModels)
37
+ const { payments, balanceItemPayments } = await BalanceItem.loadPayments(balanceItemModels);
38
38
 
39
39
  return new Response(await GetUserDetailedBilingStatusEndpoint.getDetailedBillingStatus(balanceItemModels, payments));
40
40
  }
@@ -42,42 +42,42 @@ export class GetUserDetailedBilingStatusEndpoint extends Endpoint<Params, Query,
42
42
  static async getDetailedBillingStatus(balanceItemModels: BalanceItem[], paymentModels: Payment[]) {
43
43
  const organizationIds = Formatter.uniqueArray([
44
44
  ...balanceItemModels.map(b => b.organizationId),
45
- ...paymentModels.map(p => p.organizationId).filter(p => p !== null)
46
- ])
47
-
45
+ ...paymentModels.map(p => p.organizationId).filter(p => p !== null),
46
+ ]);
47
+
48
48
  // Group by organization you'll have to pay to
49
49
  if (organizationIds.length === 0) {
50
- return OrganizationDetailedBillingStatus.create({})
50
+ return OrganizationDetailedBillingStatus.create({});
51
51
  }
52
52
 
53
53
  // Optimization: prevent fetching the organization we already have
54
- const organization = Context.organization
54
+ const organization = Context.organization;
55
55
 
56
- let addOrganization = false
57
- const i = organization ? organizationIds.indexOf(organization.id) : -1
56
+ let addOrganization = false;
57
+ const i = organization ? organizationIds.indexOf(organization.id) : -1;
58
58
  if (i !== -1) {
59
- organizationIds.splice(i, 1)
60
- addOrganization = true
59
+ organizationIds.splice(i, 1);
60
+ addOrganization = true;
61
61
  }
62
62
 
63
- const organizationModels = await Organization.getByIDs(...organizationIds)
63
+ const organizationModels = await Organization.getByIDs(...organizationIds);
64
64
 
65
65
  if (addOrganization && organization) {
66
- organizationModels.push(organization)
66
+ organizationModels.push(organization);
67
67
  }
68
68
 
69
- const balanceItems = await BalanceItem.getStructureWithPayments(balanceItemModels)
70
- const organizations = await AuthenticatedStructures.organizations(organizationModels)
71
- const payments = await AuthenticatedStructures.paymentsGeneral(paymentModels, false)
69
+ const balanceItems = await BalanceItem.getStructureWithPayments(balanceItemModels);
70
+ const organizations = await AuthenticatedStructures.organizations(organizationModels);
71
+ const payments = await AuthenticatedStructures.paymentsGeneral(paymentModels, false);
72
72
 
73
73
  return OrganizationDetailedBillingStatus.create({
74
- organizations: organizations.map(o => {
74
+ organizations: organizations.map((o) => {
75
75
  return OrganizationDetailedBillingStatusItem.create({
76
76
  organization: o,
77
77
  balanceItems: balanceItems.filter(b => b.organizationId == o.id),
78
- payments: payments.filter(p => p.organizationId === o.id)
79
- })
80
- })
81
- })
78
+ payments: payments.filter(p => p.organizationId === o.id),
79
+ });
80
+ }),
81
+ });
82
82
  }
83
83
  }