@stamhoofd/backend 2.120.6 → 2.122.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 (434) hide show
  1. package/output-2.txt +1 -0
  2. package/output.txt +1 -0
  3. package/package.json +70 -53
  4. package/src/audit-logs/EventNotificationLogger.ts +40 -0
  5. package/src/audit-logs/ModelLogger.ts +19 -15
  6. package/src/audit-logs/OrganizationLogger.ts +1 -1
  7. package/src/audit-logs/RegistrationInvitationLogger.ts +46 -0
  8. package/src/audit-logs/init.ts +9 -1
  9. package/src/boot.ts +19 -18
  10. package/src/crons/amazon-ses.ts +13 -26
  11. package/src/crons/balance-emails.ts +3 -5
  12. package/src/crons/clearExcelCache.test.ts +1 -1
  13. package/src/crons/clearExcelCache.ts +1 -2
  14. package/src/crons/drip-emails.ts +42 -0
  15. package/src/crons/endFunctionsOfUsersWithoutRegistration.ts +4 -0
  16. package/src/crons/helpers/isOutside.ts +11 -0
  17. package/src/crons/helpers/useSavedIterator.ts +32 -0
  18. package/src/crons/index.ts +7 -0
  19. package/src/crons/invoices.ts +160 -0
  20. package/src/crons/members-fees.ts +50 -0
  21. package/src/crons/mollie-chargebacks.ts +86 -0
  22. package/src/crons/service-fees.ts +152 -0
  23. package/src/crons/stripe-invoices.ts +48 -0
  24. package/src/crons/transfer-fees.ts +176 -0
  25. package/src/crons/update-cached-balances.ts +4 -4
  26. package/src/crons.ts +54 -74
  27. package/src/debug.ts +4 -2
  28. package/src/email-recipient-loaders/documents.ts +1 -1
  29. package/src/email-recipient-loaders/members.ts +1 -1
  30. package/src/email-recipient-loaders/payments.ts +87 -46
  31. package/src/email-recipient-loaders/registrations.ts +1 -1
  32. package/src/email-replacements/getEmailReplacementsForPayment.ts +5 -9
  33. package/src/endpoints/admin/members/ChargeMembersEndpoint.ts +1 -1
  34. package/src/endpoints/admin/memberships/ChargeMembershipsEndpoint.ts +1 -1
  35. package/src/endpoints/admin/memberships/GetChargeMembershipsSummaryEndpoint.ts +3 -5
  36. package/src/endpoints/admin/organizations/ChargeOrganizationsEndpoint.ts +1 -1
  37. package/src/endpoints/admin/organizations/GetOrganizationsCountEndpoint.ts +1 -1
  38. package/src/endpoints/admin/organizations/GetOrganizationsEndpoint.ts +13 -7
  39. package/src/endpoints/admin/organizations/PatchOrganizationsEndpoint.ts +4 -6
  40. package/src/endpoints/admin/organizations/PatchPackagesEndpoint.test.ts +10 -6
  41. package/src/endpoints/admin/organizations/PatchPackagesEndpoint.ts +39 -21
  42. package/src/endpoints/admin/registrations/ChargeRegistrationsEndpoint.ts +1 -1
  43. package/src/endpoints/auth/CreateAdminEndpoint.ts +23 -5
  44. package/src/endpoints/auth/CreateTokenEndpoint.ts +2 -2
  45. package/src/endpoints/auth/DeleteTokenEndpoint.ts +1 -1
  46. package/src/endpoints/auth/DeleteUserEndpoint.ts +3 -3
  47. package/src/endpoints/auth/ForgotPasswordEndpoint.ts +1 -1
  48. package/src/endpoints/auth/GetOtherUserEndpoint.ts +1 -1
  49. package/src/endpoints/auth/GetUserEndpoint.ts +1 -1
  50. package/src/endpoints/auth/OpenIDConnectAuthTokenEndpoint.ts +1 -1
  51. package/src/endpoints/auth/OpenIDConnectStartEndpoint.ts +1 -1
  52. package/src/endpoints/auth/PatchUserEndpoint.ts +5 -8
  53. package/src/endpoints/auth/PollEmailVerificationEndpoint.ts +1 -1
  54. package/src/endpoints/auth/RetryEmailVerificationEndpoint.ts +1 -1
  55. package/src/endpoints/auth/SignupEndpoint.ts +2 -3
  56. package/src/endpoints/auth/VerifyEmailEndpoint.ts +20 -3
  57. package/src/endpoints/frontend/FrontendEnvironmentEndpoint.ts +2 -1
  58. package/src/endpoints/global/addresses/SearchRegionsEndpoint.ts +2 -4
  59. package/src/endpoints/global/addresses/ValidateAddressEndpoint.ts +1 -1
  60. package/src/endpoints/global/audit-logs/GetAuditLogsEndpoint.ts +5 -7
  61. package/src/endpoints/global/caddy/CheckDomainCertEndpoint.ts +2 -2
  62. package/src/endpoints/global/email/CreateEmailEndpoint.ts +3 -4
  63. package/src/endpoints/global/email/GetAdminEmailsEndpoint.test.ts +1 -1
  64. package/src/endpoints/global/email/GetAdminEmailsEndpoint.ts +1 -2
  65. package/src/endpoints/global/email/GetEmailAddressEndpoint.ts +4 -6
  66. package/src/endpoints/global/email/GetEmailEndpoint.ts +1 -1
  67. package/src/endpoints/global/email/GetUserEmailsEndpoint.test.ts +1 -1
  68. package/src/endpoints/global/email/GetUserEmailsEndpoint.ts +1 -1
  69. package/src/endpoints/global/email/ManageEmailAddressEndpoint.ts +6 -10
  70. package/src/endpoints/global/email/PatchEmailEndpoint.test.ts +4 -7
  71. package/src/endpoints/global/email/PatchEmailEndpoint.ts +6 -9
  72. package/src/endpoints/global/email-recipients/GetEmailRecipientsCountEndpoint.ts +1 -1
  73. package/src/endpoints/global/email-recipients/GetEmailRecipientsEndpoint.test.ts +1 -1
  74. package/src/endpoints/global/email-recipients/GetEmailRecipientsEndpoint.ts +1 -1
  75. package/src/endpoints/global/email-recipients/RetryEmailRecipientEndpoint.ts +2 -2
  76. package/src/endpoints/global/events/GetEventNotificationsCountEndpoint.ts +1 -1
  77. package/src/endpoints/global/events/GetEventNotificationsEndpoint.ts +3 -3
  78. package/src/endpoints/global/events/GetEventsEndpoint.ts +3 -3
  79. package/src/endpoints/global/events/PatchEventNotificationsEndpoint.test.ts +49 -4
  80. package/src/endpoints/global/events/PatchEventNotificationsEndpoint.ts +5 -8
  81. package/src/endpoints/global/events/PatchEventsEndpoint.test.ts +12 -44
  82. package/src/endpoints/global/events/PatchEventsEndpoint.ts +128 -127
  83. package/src/endpoints/global/files/ExportToExcelEndpoint.ts +9 -9
  84. package/src/endpoints/global/files/GetFileCache.ts +3 -4
  85. package/src/endpoints/global/files/UploadFile.ts +3 -4
  86. package/src/endpoints/global/files/UploadImage.ts +3 -4
  87. package/src/endpoints/global/groups/GetGroupsCountEndpoint.ts +51 -0
  88. package/src/endpoints/global/groups/GetGroupsEndpoint.test.ts +1 -1
  89. package/src/endpoints/global/groups/GetGroupsEndpoint.ts +4 -2
  90. package/src/endpoints/global/members/GetMemberFamilyEndpoint.ts +2 -3
  91. package/src/endpoints/global/members/GetMembersCountEndpoint.ts +1 -1
  92. package/src/endpoints/global/members/GetMembersEndpoint.test.ts +2 -2
  93. package/src/endpoints/global/members/GetMembersEndpoint.ts +10 -12
  94. package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.test.ts +195 -12
  95. package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.ts +16 -22
  96. package/src/endpoints/global/members/helpers/validateGroupFilter.ts +6 -30
  97. package/src/endpoints/global/members/shouldCheckIfMemberIsDuplicate.ts +1 -1
  98. package/src/endpoints/global/organizations/CheckRegisterCodeEndpoint.ts +1 -1
  99. package/src/endpoints/global/organizations/CreateOrganizationEndpoint.ts +40 -8
  100. package/src/endpoints/global/organizations/GetOrganizationFromDomainEndpoint.ts +2 -2
  101. package/src/endpoints/global/organizations/GetOrganizationFromUriEndpoint.ts +2 -2
  102. package/src/endpoints/global/organizations/SearchOrganizationEndpoint.test.ts +4 -1
  103. package/src/endpoints/global/organizations/SearchOrganizationEndpoint.ts +4 -5
  104. package/src/endpoints/global/payments/StripeWebhookEndpoint.ts +9 -16
  105. package/src/endpoints/global/platform/GetPlatformAdminsEndpoint.ts +1 -1
  106. package/src/endpoints/global/platform/GetPlatformEndpoint.ts +1 -1
  107. package/src/endpoints/global/platform/PatchPlatformEnpoint.test.ts +1 -1
  108. package/src/endpoints/global/platform/PatchPlatformEnpoint.ts +32 -13
  109. package/src/endpoints/global/platform-memberships/GetPlatformMembershipsCountEndpoint.ts +31 -31
  110. package/src/endpoints/global/platform-memberships/GetPlatformMembershipsEndpoint.ts +18 -20
  111. package/src/endpoints/global/registration/GetRegistrationsCountEndpoint.ts +1 -1
  112. package/src/endpoints/global/registration/GetRegistrationsEndpoint.test.ts +1 -1
  113. package/src/endpoints/global/registration/GetRegistrationsEndpoint.ts +6 -10
  114. package/src/endpoints/global/registration/GetUserDetailedPayableBalanceEndpoint.ts +35 -6
  115. package/src/endpoints/global/registration/GetUserDocumentsEndpoint.ts +2 -2
  116. package/src/endpoints/global/registration/GetUserMembersEndpoint.ts +1 -1
  117. package/src/endpoints/global/registration/GetUserPayableBalanceEndpoint.ts +1 -1
  118. package/src/endpoints/global/registration/PatchUserMembersEndpoint.test.ts +2 -2
  119. package/src/endpoints/global/registration/PatchUserMembersEndpoint.ts +3 -3
  120. package/src/endpoints/global/registration/RegisterMembersEndpoint.test.ts +90 -6
  121. package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +38 -33
  122. package/src/endpoints/global/registration-invitations/GetRegistrationInvitationsCountEndpoint.ts +45 -0
  123. package/src/endpoints/global/registration-invitations/GetRegistrationInvitationsEndpoint.test.ts +494 -0
  124. package/src/endpoints/global/registration-invitations/GetRegistrationInvitationsEndpoint.ts +213 -0
  125. package/src/endpoints/global/registration-invitations/PatchRegistrationInvitationsEndpoint.test.ts +404 -0
  126. package/src/endpoints/global/registration-invitations/PatchRegistrationInvitationsEndpoint.ts +167 -0
  127. package/src/endpoints/global/registration-periods/GetRegistrationPeriodsCountEndpoint.ts +43 -0
  128. package/src/endpoints/global/registration-periods/GetRegistrationPeriodsEndpoint.ts +1 -1
  129. package/src/endpoints/global/registration-periods/PatchRegistrationPeriodsEndpoint.ts +13 -5
  130. package/src/endpoints/global/sso/GetSSOEndpoint.ts +2 -3
  131. package/src/endpoints/global/sso/SetSSOEndpoint.ts +1 -1
  132. package/src/endpoints/global/webshops/GetWebshopFromDomainEndpoint.ts +2 -2
  133. package/src/endpoints/global/webshops/GetWebshopsEndpoint.test.ts +1 -2
  134. package/src/endpoints/global/webshops/GetWebshopsEndpoint.ts +2 -4
  135. package/src/endpoints/organization/dashboard/balance-items/GetBalanceItemEndpoint.ts +2 -2
  136. package/src/endpoints/organization/dashboard/balance-items/GetBalanceItemsCountEndpoint.ts +1 -1
  137. package/src/endpoints/organization/dashboard/balance-items/GetBalanceItemsEndpoint.ts +3 -4
  138. package/src/endpoints/organization/dashboard/balance-items/PatchBalanceItemsEndpoint.ts +19 -6
  139. package/src/endpoints/organization/dashboard/billing/ApplyRegisterCodeEndpoint.test.ts +73 -0
  140. package/src/endpoints/organization/dashboard/billing/ApplyRegisterCodeEndpoint.ts +89 -0
  141. package/src/endpoints/{global → organization/dashboard}/billing/DeactivatePackageEndpoint.ts +4 -9
  142. package/src/endpoints/organization/dashboard/billing/DeleteOrganizationMandateEndpoint.ts +62 -0
  143. package/src/endpoints/organization/dashboard/billing/GetOrganizationDetailedPayableBalanceCollectionEndpoint.ts +56 -0
  144. package/src/endpoints/organization/dashboard/billing/GetOrganizationDetailedPayableBalanceEndpoint.ts +41 -18
  145. package/src/endpoints/organization/dashboard/billing/GetOrganizationMandatesEndpoint.ts +64 -0
  146. package/src/endpoints/organization/dashboard/billing/GetOrganizationPayableBalanceEndpoint.ts +2 -2
  147. package/src/endpoints/organization/dashboard/billing/GetOrganizationPayableInvoicesEndpoint.ts +68 -0
  148. package/src/endpoints/organization/dashboard/billing/GetPackagesEndpoint.ts +12 -4
  149. package/src/endpoints/organization/dashboard/billing/GetRegisterCodeEndpoint.ts +66 -0
  150. package/src/endpoints/organization/dashboard/billing/OrganizationCheckoutEndpoint.test.ts +949 -0
  151. package/src/endpoints/organization/dashboard/billing/OrganizationCheckoutEndpoint.ts +311 -0
  152. package/src/endpoints/organization/dashboard/billing/PatchOrganizationMandatesEndpoint.ts +94 -0
  153. package/src/endpoints/organization/dashboard/documents/GetDocumentTemplateXML.ts +1 -1
  154. package/src/endpoints/organization/dashboard/documents/GetDocumentTemplatesCountEndpoint.ts +1 -1
  155. package/src/endpoints/organization/dashboard/documents/GetDocumentTemplatesEndpoint.ts +1 -1
  156. package/src/endpoints/organization/dashboard/documents/GetDocumentsCountEndpoint.ts +1 -1
  157. package/src/endpoints/organization/dashboard/documents/GetDocumentsEndpoint.ts +1 -1
  158. package/src/endpoints/organization/dashboard/documents/PatchDocumentEndpoint.ts +10 -2
  159. package/src/endpoints/organization/dashboard/documents/PatchDocumentTemplatesEndpoint.test.ts +2 -2
  160. package/src/endpoints/organization/dashboard/documents/PatchDocumentTemplatesEndpoint.ts +2 -2
  161. package/src/endpoints/organization/dashboard/email/CheckEmailBouncesEndpoint.ts +1 -1
  162. package/src/endpoints/organization/dashboard/email-templates/GetEmailTemplatesEndpoint.test.ts +1 -1
  163. package/src/endpoints/organization/dashboard/email-templates/GetEmailTemplatesEndpoint.ts +10 -8
  164. package/src/endpoints/organization/dashboard/email-templates/PatchEmailTemplatesEndpoint.test.ts +1 -1
  165. package/src/endpoints/organization/dashboard/email-templates/PatchEmailTemplatesEndpoint.ts +5 -6
  166. package/src/endpoints/organization/dashboard/invoices/GetInvoicesCountEndpoint.ts +1 -1
  167. package/src/endpoints/organization/dashboard/invoices/GetInvoicesEndpoint.ts +15 -4
  168. package/src/endpoints/organization/dashboard/invoices/PatchInvoicesEndpoint.ts +11 -2
  169. package/src/endpoints/organization/dashboard/mollie/CheckMollieEndpoint.ts +8 -8
  170. package/src/endpoints/organization/dashboard/mollie/ConnectMollieEndpoint.ts +10 -5
  171. package/src/endpoints/organization/dashboard/mollie/DisconnectMollieEndpoint.ts +2 -2
  172. package/src/endpoints/organization/dashboard/mollie/GetMollieDashboardEndpoint.ts +7 -7
  173. package/src/endpoints/organization/dashboard/nolt/CreateNoltTokenEndpoint.ts +1 -1
  174. package/src/endpoints/organization/dashboard/organization/GetOrganizationArchivedGroups.ts +2 -2
  175. package/src/endpoints/organization/dashboard/organization/GetOrganizationDeletedGroups.ts +1 -1
  176. package/src/endpoints/organization/dashboard/organization/GetUitpasClientIdEndpoint.ts +1 -1
  177. package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.test.ts +2 -2
  178. package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.ts +67 -20
  179. package/src/endpoints/organization/dashboard/organization/SearchUitpasOrganizersEndpoint.ts +2 -2
  180. package/src/endpoints/organization/dashboard/organization/SetOrganizationDomainEndpoint.ts +5 -10
  181. package/src/endpoints/organization/dashboard/organization/SetUitpasClientCredentialsEndpoint.ts +1 -1
  182. package/src/endpoints/organization/dashboard/payments/GetPaymentsCountEndpoint.ts +1 -1
  183. package/src/endpoints/organization/dashboard/payments/GetPaymentsEndpoint.ts +3 -4
  184. package/src/endpoints/organization/dashboard/payments/PatchPaymentsEndpoint.ts +24 -17
  185. package/src/endpoints/organization/dashboard/receivable-balances/ChargeReceivableBalancesEndpoint.ts +134 -0
  186. package/src/endpoints/organization/dashboard/receivable-balances/GetReceivableBalanceEndpoint.ts +2 -3
  187. package/src/endpoints/organization/dashboard/receivable-balances/GetReceivableBalancesCountEndpoint.ts +1 -1
  188. package/src/endpoints/organization/dashboard/receivable-balances/GetReceivableBalancesEndpoint.ts +1 -1
  189. package/src/endpoints/organization/dashboard/registration-periods/GetOrganizationRegistrationPeriodsEndpoint.test.ts +1 -1
  190. package/src/endpoints/organization/dashboard/registration-periods/GetOrganizationRegistrationPeriodsEndpoint.ts +2 -3
  191. package/src/endpoints/organization/dashboard/registration-periods/MoveRegistrationPeriods.test.ts +1 -1
  192. package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.test.ts +1 -1
  193. package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.ts +32 -22
  194. package/src/endpoints/organization/dashboard/registration-periods/SetupStepReviewEndpoint.ts +4 -5
  195. package/src/endpoints/organization/dashboard/stripe/ConnectStripeEndpoint.ts +1 -1
  196. package/src/endpoints/organization/dashboard/stripe/DeleteStripeAccountEndpoint.ts +2 -3
  197. package/src/endpoints/organization/dashboard/stripe/GetStripeAccountLinkEndpoint.ts +2 -2
  198. package/src/endpoints/organization/dashboard/stripe/GetStripeAccountsEndpoint.ts +1 -1
  199. package/src/endpoints/organization/dashboard/stripe/GetStripeLoginLinkEndpoint.ts +2 -2
  200. package/src/endpoints/organization/dashboard/stripe/UpdateStripeAccountEndpoint.ts +1 -1
  201. package/src/endpoints/organization/dashboard/users/CreateApiUserEndpoint.ts +1 -1
  202. package/src/endpoints/organization/dashboard/users/DeleteUserEndpoint.ts +1 -1
  203. package/src/endpoints/organization/dashboard/users/GetApiUsersEndpoint.ts +1 -1
  204. package/src/endpoints/organization/dashboard/users/GetOrganizationAdminsEndpoint.ts +1 -1
  205. package/src/endpoints/organization/dashboard/users/PatchApiUserEndpoint.ts +4 -6
  206. package/src/endpoints/organization/dashboard/webshops/CreateWebshopEndpoint.ts +10 -15
  207. package/src/endpoints/organization/dashboard/webshops/DeleteWebshopEndpoint.ts +1 -1
  208. package/src/endpoints/organization/dashboard/webshops/GetDiscountCodesEndpoint.ts +2 -2
  209. package/src/endpoints/organization/dashboard/webshops/GetWebshopOrdersCountEndpoint.ts +1 -1
  210. package/src/endpoints/organization/dashboard/webshops/GetWebshopOrdersEndpoint.ts +1 -1
  211. package/src/endpoints/organization/dashboard/webshops/GetWebshopTicketsEndpoint.ts +1 -1
  212. package/src/endpoints/organization/dashboard/webshops/GetWebshopUriAvailabilityEndpoint.ts +11 -2
  213. package/src/endpoints/organization/dashboard/webshops/PatchDiscountCodesEndpoint.ts +4 -6
  214. package/src/endpoints/organization/dashboard/webshops/PatchWebshopEndpoint.ts +29 -8
  215. package/src/endpoints/organization/dashboard/webshops/PatchWebshopOrdersEndpoint.ts +21 -28
  216. package/src/endpoints/organization/dashboard/webshops/PatchWebshopTicketsEndpoint.ts +1 -1
  217. package/src/endpoints/organization/dashboard/webshops/SearchUitpasEventsEndpoint.ts +2 -2
  218. package/src/endpoints/organization/dashboard/webshops/VerifyWebshopDomainEndpoint.ts +2 -3
  219. package/src/endpoints/organization/dashboard/webshops/WebshopReservedPathSegments.test.ts +95 -0
  220. package/src/endpoints/organization/shared/ExchangePaymentEndpoint.ts +15 -13
  221. package/src/endpoints/organization/shared/GetDocumentHtml.ts +1 -1
  222. package/src/endpoints/organization/shared/GetPaymentEndpoint.ts +1 -1
  223. package/src/endpoints/organization/shared/GetUitpasNumberDetailsEndpoint.ts +3 -5
  224. package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.ts +1 -1
  225. package/src/endpoints/organization/webshops/CheckWebshopDiscountCodesEndpoint.ts +4 -1
  226. package/src/endpoints/organization/webshops/GetOrderByPaymentEndpoint.ts +14 -3
  227. package/src/endpoints/organization/webshops/GetOrderEndpoint.ts +14 -2
  228. package/src/endpoints/organization/webshops/GetTicketsEndpoint.ts +37 -16
  229. package/src/endpoints/organization/webshops/GetWebshopEndpoint.test.ts +34 -2
  230. package/src/endpoints/organization/webshops/GetWebshopEndpoint.ts +4 -2
  231. package/src/endpoints/organization/webshops/PlaceOrderEndpoint.test.ts +74 -3
  232. package/src/endpoints/organization/webshops/PlaceOrderEndpoint.ts +28 -50
  233. package/src/endpoints/organization/webshops/RetrieveUitpasSocialTariffPriceEndpoint.ts +3 -5
  234. package/src/endpoints/organization/webshops/WebshopAuthHelper.ts +36 -0
  235. package/src/endpoints/system/HealthEndpoint.ts +1 -1
  236. package/src/excel-loaders/balance-items.ts +1 -1
  237. package/src/excel-loaders/event-notifications.ts +1 -1
  238. package/src/excel-loaders/members.ts +1 -1
  239. package/src/excel-loaders/organizations.ts +3 -3
  240. package/src/excel-loaders/payments.ts +31 -1
  241. package/src/excel-loaders/platform-memberships.ts +13 -14
  242. package/src/excel-loaders/receivable-balances.ts +2 -2
  243. package/src/excel-loaders/registrations.ts +2 -3
  244. package/src/helpers/AddressValidator.ts +7 -14
  245. package/src/helpers/AdminPermissionChecker.ts +60 -65
  246. package/src/helpers/AuthenticatedStructures.ts +153 -51
  247. package/src/helpers/BalanceItemRelationsBackfiller.test.ts +174 -0
  248. package/src/helpers/BalanceItemRelationsBackfiller.ts +163 -0
  249. package/src/helpers/BuckarooHelper.ts +2 -4
  250. package/src/helpers/CheckSettlements.ts +12 -24
  251. package/src/helpers/Context.ts +15 -10
  252. package/src/helpers/CookieHelper.ts +1 -2
  253. package/src/helpers/EmailResumer.ts +1 -2
  254. package/src/helpers/FileCache.ts +2 -3
  255. package/src/helpers/FinancialSupportHelper.ts +21 -0
  256. package/src/helpers/FlagMomentCleanup.ts +1 -2
  257. package/src/helpers/ForwardHandler.ts +5 -10
  258. package/src/helpers/GlobalHelper.ts +3 -3
  259. package/src/helpers/LegacyBillingConverter.ts +787 -0
  260. package/src/helpers/MemberMerger.test.ts +782 -0
  261. package/src/helpers/MemberMerger.ts +600 -0
  262. package/src/helpers/MemberUserSyncer.ts +6 -12
  263. package/src/helpers/MembershipCharger.ts +2 -4
  264. package/src/helpers/PaymentCustomerResolver.test.ts +203 -0
  265. package/src/helpers/PaymentCustomerResolver.ts +144 -0
  266. package/src/helpers/PeriodHelper.ts +2 -3
  267. package/src/helpers/RecordAnswerHelper.test.ts +741 -0
  268. package/src/helpers/RecordAnswerHelper.ts +116 -0
  269. package/src/helpers/SeedTools.ts +106 -0
  270. package/src/helpers/ServiceFeeHelper.ts +125 -15
  271. package/src/helpers/SetupStepUpdater.ts +38 -32
  272. package/src/helpers/StamhoofdFilterAccessHelper.ts +52 -0
  273. package/src/helpers/StripeHelper.ts +15 -38
  274. package/src/helpers/StripeInvoicer.ts +419 -0
  275. package/src/helpers/StripePayoutChecker.ts +5 -10
  276. package/src/helpers/TagHelper.ts +7 -8
  277. package/src/helpers/TemporaryMemberAccess.ts +1 -2
  278. package/src/helpers/ThrottledQueue.ts +1 -2
  279. package/src/helpers/UitpasTokenRepository.ts +1 -2
  280. package/src/helpers/ViesHelper.ts +11 -11
  281. package/src/helpers/XlsxTransformerColumnHelper.ts +1 -1
  282. package/src/helpers/outstandingBalanceJoin.ts +2 -2
  283. package/src/helpers/updateMemberDetailsUitpasNumber.ts +3 -5
  284. package/src/migrate.ts +12 -5
  285. package/src/{seeds → migrations}/0000000004-single-organization.ts +10 -1
  286. package/src/migrations/0000000006-default-organization.ts +139 -0
  287. package/src/{seeds → migrations}/1715028563-user-permissions.ts +17 -27
  288. package/src/{seeds/1765896674-document-update-year.test.ts → migrations/1750090029-document-update-year.test.ts} +27 -26
  289. package/src/migrations/1750090029-document-update-year.ts +103 -0
  290. package/src/migrations/1750090030-records-configuration.ts +92 -0
  291. package/src/migrations/1750090031-records-configuration-webshops.ts +36 -0
  292. package/src/migrations/1752848540-national-numbers.ts +585 -0
  293. package/src/migrations/1752848550-records-configuration-group-filter.ts +1064 -0
  294. package/src/{seeds → migrations}/1752848561-groups-registration-periods.ts +95 -27
  295. package/src/{seeds → migrations}/1754560914-groups-prices.test.ts +1 -1
  296. package/src/{seeds → migrations}/1754560914-groups-prices.ts +9 -15
  297. package/src/{seeds → migrations}/1756293699-fill-previous-next-period-id.ts +1 -2
  298. package/src/migrations/1761665607-sync-member-users.ts +40 -0
  299. package/src/migrations/1779121239-default-invoice-email-template.sql +3 -0
  300. package/src/migrations/1779121240-invoice-email-template.sql +6 -0
  301. package/src/migrations/1779986893-default-payment-failed-email-templates.sql +4 -0
  302. package/src/migrations/1780578166-convert-legacy-billing.ts +13 -0
  303. package/src/{seeds/1755876819-remove-duplicate-members.ts → migrations/1780665426-remove-duplicate-members.ts} +23 -4
  304. package/src/migrations/1780933598-document-groups.ts +88 -0
  305. package/src/migrations/1781692342-balance-item-relations.ts +13 -0
  306. package/src/migrations/1781857866-platform-admins.ts +103 -0
  307. package/src/migrations/1781857867-rm-old-platform-admins.ts +25 -0
  308. package/src/seeds/0000000001-throw.ts +5 -0
  309. package/src/seeds/1760702452-update-balance-price-paid.ts +19 -0
  310. package/src/seeds/1760702453-update-balance-invoiced.ts +19 -0
  311. package/src/seeds/1760702454-update-cached-outstanding-balance-from-items.ts +51 -14
  312. package/src/seeds/1773754928-force-save-members.ts +41 -8
  313. package/src/seeds/1780665427-schedule-stock-updates.ts +45 -0
  314. package/src/seeds/1780665428-group-update-occupancy.ts +31 -0
  315. package/src/seeds/1780915001-fill-payment-customer.ts +70 -0
  316. package/src/seeds/1780915002-update-orders.ts +39 -0
  317. package/src/seeds/1782047708-organization-company-address.ts +44 -0
  318. package/src/seeds-temporary/1769088653-uitpas-status.ts +1 -2
  319. package/src/seeds-temporary/1780416000-migrate-audit-log-legacy-enums.test.ts +69 -0
  320. package/src/seeds-temporary/1780416000-migrate-audit-log-legacy-enums.ts +85 -0
  321. package/src/services/AuditLogService.test.ts +51 -0
  322. package/src/services/AuditLogService.ts +45 -0
  323. package/src/services/BalanceItemService.ts +148 -55
  324. package/src/services/CpuService.ts +3 -6
  325. package/src/services/DatabaseCollationService.test.ts +1 -2
  326. package/src/services/DocumentService.ts +1 -2
  327. package/src/services/EventNotificationService.ts +1 -1
  328. package/src/services/FileSignService.ts +2 -4
  329. package/src/services/InvoicePdfService.ts +286 -0
  330. package/src/services/InvoiceService.ts +330 -77
  331. package/src/services/InvoiceXMLService.ts +424 -0
  332. package/src/services/MemberNumberService.ts +6 -11
  333. package/src/services/MemberRecordStore.ts +8 -10
  334. package/src/services/MollieService.ts +530 -0
  335. package/src/services/PaymentMandateService.ts +214 -0
  336. package/src/services/PaymentReallocationService.test.ts +1 -1
  337. package/src/services/PaymentReallocationService.ts +7 -9
  338. package/src/services/PaymentService.ts +820 -328
  339. package/src/services/PlatformMembershipService.ts +5 -9
  340. package/src/services/ReferralService.ts +223 -0
  341. package/src/services/RegistrationService.ts +125 -54
  342. package/src/services/SSOService.test.ts +119 -0
  343. package/src/services/SSOService.ts +56 -49
  344. package/src/services/STPackageService.ts +97 -68
  345. package/src/services/UniqueMemberNumberService.ts +69 -0
  346. package/src/services/UniqueUserService.ts +3 -6
  347. package/src/services/VATService.ts +85 -0
  348. package/src/services/data/invoice.hbs.html +686 -0
  349. package/src/services/uitpas/PassholderEndpoints.ts +3 -6
  350. package/src/services/uitpas/UitpasService.ts +6 -10
  351. package/src/services/uitpas/checkUitpasNumbers.ts +2 -4
  352. package/src/services/uitpas/getSocialTariffForUitpasNumbers.ts +3 -6
  353. package/src/services/uitpas/searchUitpasEvents.ts +1 -2
  354. package/src/sql-filters/audit-logs.ts +1 -1
  355. package/src/sql-filters/balance-item-payments.ts +1 -1
  356. package/src/sql-filters/balance-items.ts +1 -1
  357. package/src/sql-filters/base-registration-filter-compilers.ts +5 -33
  358. package/src/sql-filters/document-templates.ts +1 -1
  359. package/src/sql-filters/documents.ts +1 -1
  360. package/src/sql-filters/email-recipients.ts +1 -1
  361. package/src/sql-filters/emails.ts +1 -1
  362. package/src/sql-filters/event-notifications.ts +1 -1
  363. package/src/sql-filters/events.ts +6 -1
  364. package/src/sql-filters/groups.ts +16 -1
  365. package/src/sql-filters/invoiced-balance-items.ts +1 -1
  366. package/src/sql-filters/invoices.ts +1 -1
  367. package/src/sql-filters/member-responsibility-records.ts +1 -1
  368. package/src/sql-filters/members.ts +1 -1
  369. package/src/sql-filters/orders.ts +4 -4
  370. package/src/sql-filters/organization-registration-periods.ts +1 -1
  371. package/src/sql-filters/organizations.ts +1 -1
  372. package/src/sql-filters/payments.ts +5 -0
  373. package/src/sql-filters/platform-memberships.ts +3 -3
  374. package/src/sql-filters/receivable-balances.ts +1 -1
  375. package/src/sql-filters/registration-invitations.ts +90 -0
  376. package/src/sql-filters/registration-periods.ts +1 -1
  377. package/src/sql-filters/registrations.ts +1 -1
  378. package/src/sql-filters/tickets.ts +1 -1
  379. package/src/sql-filters/users.ts +1 -1
  380. package/src/sql-sorters/groups.ts +23 -0
  381. package/src/sql-sorters/platform-memberships.ts +16 -16
  382. package/src/sql-sorters/registration-invitations.ts +36 -0
  383. package/tests/actions/patchOrganizationMember.ts +1 -1
  384. package/tests/actions/patchUserMember.ts +1 -1
  385. package/tests/assertions/assertBalances.ts +6 -12
  386. package/tests/e2e/api-rate-limits.test.ts +12 -24
  387. package/tests/e2e/bundle-discounts.test.ts +4 -1
  388. package/tests/e2e/charge-members.test.ts +13 -11
  389. package/tests/e2e/documents.test.ts +4 -1
  390. package/tests/e2e/register.test.ts +7 -9
  391. package/tests/e2e/stock.test.ts +4 -3
  392. package/tests/e2e/tickets.test.ts +1 -1
  393. package/tests/helpers/MollieMocker.ts +462 -0
  394. package/tests/helpers/PayconiqMocker.ts +138 -45
  395. package/tests/helpers/StripeMocker.ts +9 -6
  396. package/tests/helpers/index.ts +4 -0
  397. package/tests/init/initAdmin.ts +2 -2
  398. package/tests/init/initBundleDiscount.ts +1 -1
  399. package/tests/init/initMembershipOrganization.ts +13 -0
  400. package/tests/init/initPermissionRole.ts +3 -4
  401. package/tests/vitest.global.setup.ts +1 -1
  402. package/vitest.config.js +7 -0
  403. package/.nvmrc +0 -1
  404. package/src/endpoints/global/billing/ActivatePackagesEndpoint.ts +0 -216
  405. package/src/helpers/GroupBuilder.ts +0 -418
  406. package/src/seeds/0000000000-example.ts +0 -11
  407. package/src/seeds/1722256498-group-update-occupancy.ts +0 -52
  408. package/src/seeds/1726572303-schedule-stock-updates.ts +0 -52
  409. package/src/seeds/1726847064-setup-steps.ts +0 -16
  410. package/src/seeds/1728928974-update-cached-outstanding-balance-from-items.ts +0 -31
  411. package/src/seeds/1729253172-update-orders.ts +0 -21
  412. package/src/seeds/1733319079-fill-paying-organization-ids.ts +0 -68
  413. package/src/seeds/1733748412-update-deleted-order-numbers.ts +0 -109
  414. package/src/seeds/1733994455-balance-item-status-open.ts +0 -30
  415. package/src/seeds/1740046783-update-membership.ts +0 -17
  416. package/src/seeds/1741008870-fix-auditlog-description.ts +0 -50
  417. package/src/seeds/1741011468-fix-auditlog-description-uft16.ts +0 -88
  418. package/src/seeds/1741268179-fix-group-dates-of-events.ts +0 -32
  419. package/src/seeds/1750090030-records-configuration.ts +0 -26
  420. package/src/seeds/1751445358-upload-email-attachments.ts +0 -106
  421. package/src/seeds/1755532883-update-email-sender-ids.ts +0 -47
  422. package/src/seeds/1755790070-fill-email-recipient-errors.ts +0 -96
  423. package/src/seeds/1756115432-remove-old-drafts.ts +0 -16
  424. package/src/seeds/1756115433-fill-email-recipient-organization-id.ts +0 -30
  425. package/src/seeds/1756303697-update-email-counts.ts +0 -76
  426. package/src/seeds/1761665607-sync-member-users.ts +0 -59
  427. package/src/seeds/1765896674-document-update-year.ts +0 -66
  428. /package/src/{seeds → migrations}/0000000001-development-user.ts +0 -0
  429. /package/src/{seeds → migrations}/0000000002-clear-stamhoofd-email-templates.ts +0 -0
  430. /package/src/{seeds → migrations}/0000000003-default-email-templates.ts +0 -0
  431. /package/src/{seeds → migrations}/1752848561-groups-registration-periods.test.ts +0 -0
  432. /package/src/{seeds → migrations}/1766150402-document-published-at.test.ts +0 -0
  433. /package/src/{seeds → migrations}/1766150402-document-published-at.ts +0 -0
  434. /package/src/{seeds → migrations}/data/default-email-templates.sql +0 -0
@@ -1,6 +1,6 @@
1
- import type { Decoder} from '@simonbackx/simple-encoding';
1
+ import type { Decoder } from '@simonbackx/simple-encoding';
2
2
  import { AutoEncoder, field, StringDecoder } from '@simonbackx/simple-encoding';
3
- import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
3
+ import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
4
4
  import { Endpoint, Response } from '@simonbackx/simple-endpoints';
5
5
  import { SimpleError } from '@simonbackx/simple-errors';
6
6
  import { Organization } from '@stamhoofd/models';
@@ -1,6 +1,6 @@
1
- import type { Decoder} from '@simonbackx/simple-encoding';
1
+ import type { Decoder } from '@simonbackx/simple-encoding';
2
2
  import { AutoEncoder, field, StringDecoder } from '@simonbackx/simple-encoding';
3
- import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
3
+ import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
4
4
  import { Endpoint, Response } from '@simonbackx/simple-endpoints';
5
5
  import { SimpleError } from '@simonbackx/simple-errors';
6
6
  import { Organization } from '@stamhoofd/models';
@@ -1,5 +1,5 @@
1
1
  import { Request } from '@simonbackx/simple-endpoints';
2
- import { OrganizationFactory } from '@stamhoofd/models';
2
+ import { OrganizationFactory, Platform } from '@stamhoofd/models';
3
3
  import { v4 as uuidv4 } from 'uuid';
4
4
 
5
5
  import { Database } from '@simonbackx/simple-database';
@@ -14,6 +14,9 @@ describe('Endpoint.SearchOrganization', () => {
14
14
  await Database.update('UPDATE registration_periods set organizationId = null, customName = ? where organizationId is not null', ['delete']);
15
15
  await Database.delete('DELETE FROM `organizations`');
16
16
  await Database.delete('DELETE FROM `registration_periods` where customName = ?', ['delete']);
17
+
18
+ // Force reload Platform (membership organization id might be cleared)
19
+ await Platform.clearCache();
17
20
  });
18
21
 
19
22
  test('Search for a given organization using exact search', async () => {
@@ -1,9 +1,9 @@
1
- import type { Decoder} from '@simonbackx/simple-encoding';
1
+ import type { Decoder } from '@simonbackx/simple-encoding';
2
2
  import { AutoEncoder, field, StringDecoder } from '@simonbackx/simple-encoding';
3
- import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
3
+ import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
4
4
  import { Endpoint, Response } from '@simonbackx/simple-endpoints';
5
5
  import { Organization } from '@stamhoofd/models';
6
- import type { SQLWhere} from '@stamhoofd/sql';
6
+ import type { SQLWhere } from '@stamhoofd/sql';
7
7
  import { scalarToSQLExpression, SQL, SQLMatch, SQLWhereLike } from '@stamhoofd/sql';
8
8
  import type { Organization as OrganizationStruct } from '@stamhoofd/structures';
9
9
  import { AuthenticatedStructures } from '../../../helpers/AuthenticatedStructures.js';
@@ -48,8 +48,7 @@ export class SearchOrganizationEndpoint extends Endpoint<Params, Query, Body, Re
48
48
  // give higher relevance if the searchindex includes the exact sentence
49
49
  // give lower relevance if the last word is not a complete match
50
50
  matchValue = `>("${query}") (${query}) <(${query}*)`;
51
- }
52
- else {
51
+ } else {
53
52
  // give higher relevance if the searchindex includes the exact word
54
53
  matchValue = `>${query} ${query}*`;
55
54
  }
@@ -1,6 +1,6 @@
1
- import type { Decoder} from '@simonbackx/simple-encoding';
1
+ import type { Decoder } from '@simonbackx/simple-encoding';
2
2
  import { AnyDecoder, AutoEncoder, field, StringDecoder } from '@simonbackx/simple-encoding';
3
- import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
3
+ import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
4
4
  import { Endpoint, Response } from '@simonbackx/simple-endpoints';
5
5
  import { SimpleError } from '@simonbackx/simple-errors';
6
6
  import { Organization, StripeAccount, StripeCheckoutSession, StripePaymentIntent } from '@stamhoofd/models';
@@ -74,8 +74,7 @@ export class StripeWebookEndpoint extends Endpoint<Params, Query, Body, Response
74
74
  });
75
75
  }
76
76
  event = await stripe.webhooks.constructEventAsync(await request.request.bodyPromise!, sig, secret);
77
- }
78
- catch (err) {
77
+ } catch (err) {
79
78
  throw new SimpleError({
80
79
  code: 'invalid_signature',
81
80
  message: 'Invalid signature',
@@ -96,8 +95,7 @@ export class StripeWebookEndpoint extends Endpoint<Params, Query, Body, Response
96
95
  model.setMetaFromStripeAccount(account);
97
96
  await model.save();
98
97
  });
99
- }
100
- else {
98
+ } else {
101
99
  console.warn('Could not find stripe account with id', id);
102
100
  }
103
101
  }
@@ -126,8 +124,7 @@ export class StripeWebookEndpoint extends Endpoint<Params, Query, Body, Response
126
124
  const [model] = await StripeCheckoutSession.where({ stripeSessionId: checkoutId }, { limit: 1 });
127
125
  if (model && model.organizationId) {
128
126
  await this.checkDebounced(model.paymentId, model.organizationId);
129
- }
130
- else {
127
+ } else {
131
128
  console.warn('Could not find stripe checkout session with id', checkoutId);
132
129
  }
133
130
  break;
@@ -148,8 +145,7 @@ export class StripeWebookEndpoint extends Endpoint<Params, Query, Body, Response
148
145
  const intentId = request.body.data.object.payment_intent;
149
146
  if (intentId && typeof intentId === 'string') {
150
147
  await this.updateIntent(intentId);
151
- }
152
- else {
148
+ } else {
153
149
  console.log('Received charge event without payment intent', request.body);
154
150
  }
155
151
  break;
@@ -170,13 +166,11 @@ export class StripeWebookEndpoint extends Endpoint<Params, Query, Body, Response
170
166
  const organization = await Organization.getByID(organizationId);
171
167
  if (organization) {
172
168
  await PaymentService.pollStatus(paymentId, organization);
173
- }
174
- else {
169
+ } else {
175
170
  console.warn('Could not find organization with id', organizationId);
176
171
  }
177
172
  }, 1000);
178
- }
179
- catch (e) {
173
+ } catch (e) {
180
174
  if (isDebouncedError(e)) {
181
175
  // Okay, we are debounced (new request came in)
182
176
  console.log('Debounced', paymentId);
@@ -191,8 +185,7 @@ export class StripeWebookEndpoint extends Endpoint<Params, Query, Body, Response
191
185
  const [model] = await StripePaymentIntent.where({ stripeIntentId: intentId }, { limit: 1 });
192
186
  if (model && model.organizationId) {
193
187
  await this.checkDebounced(model.paymentId, model.organizationId);
194
- }
195
- else {
188
+ } else {
196
189
  console.warn('Could not find stripe payment intent with id', intentId);
197
190
  }
198
191
  }
@@ -1,4 +1,4 @@
1
- import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
1
+ import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
2
2
  import { Endpoint, Response } from '@simonbackx/simple-endpoints';
3
3
  import { User } from '@stamhoofd/models';
4
4
  import { OrganizationAdmins } from '@stamhoofd/structures';
@@ -1,4 +1,4 @@
1
- import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
1
+ import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
2
2
  import { Endpoint, Response } from '@simonbackx/simple-endpoints';
3
3
  import { Platform } from '@stamhoofd/models';
4
4
  import type { Platform as PlatformStruct } from '@stamhoofd/structures';
@@ -1,5 +1,5 @@
1
1
  import { Request } from '@simonbackx/simple-endpoints';
2
- import type { Organization} from '@stamhoofd/models';
2
+ import type { Organization } from '@stamhoofd/models';
3
3
  import { OrganizationFactory, Platform, RegistrationPeriod, RegistrationPeriodFactory, Token, UserFactory } from '@stamhoofd/models';
4
4
  import { PermissionLevel, Permissions, PlatformConfig, Platform as PlatformStruct, Version } from '@stamhoofd/structures';
5
5
 
@@ -1,17 +1,18 @@
1
- import type { AutoEncoderPatchType, Decoder} from '@simonbackx/simple-encoding';
1
+ import type { AutoEncoderPatchType, Decoder } from '@simonbackx/simple-encoding';
2
2
  import { isPatchableArray, patchObject } from '@simonbackx/simple-encoding';
3
- import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
3
+ import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
4
4
  import { Endpoint, Response } from '@simonbackx/simple-endpoints';
5
5
  import { Organization, Platform, RegistrationPeriod } from '@stamhoofd/models';
6
- import type { MemberResponsibility, PlatformConfig, PlatformPremiseType} from '@stamhoofd/structures';
6
+ import type { EventNotificationType, MemberResponsibility, PlatformConfig, PlatformPremiseType } from '@stamhoofd/structures';
7
7
  import { Platform as PlatformStruct } from '@stamhoofd/structures';
8
8
 
9
9
  import { SimpleError } from '@simonbackx/simple-errors';
10
- import { QueueHandler } from '@stamhoofd/queues';
10
+ import { isAbortedError, isCanceledError, QueueHandler } from '@stamhoofd/queues';
11
11
  import { Context } from '../../../helpers/Context.js';
12
12
  import { MembershipCharger } from '../../../helpers/MembershipCharger.js';
13
13
  import { MemberUserSyncer } from '../../../helpers/MemberUserSyncer.js';
14
14
  import { PeriodHelper } from '../../../helpers/PeriodHelper.js';
15
+ import { RecordAnswerHelper } from '../../../helpers/RecordAnswerHelper.js';
15
16
  import { SetupStepUpdater } from '../../../helpers/SetupStepUpdater.js';
16
17
  import { TagHelper } from '../../../helpers/TagHelper.js';
17
18
  import { PlatformMembershipService } from '../../../services/PlatformMembershipService.js';
@@ -95,6 +96,24 @@ export class PatchPlatformEndpoint extends Endpoint<
95
96
 
96
97
  if (request.body.config.organizationLevelRecordsConfiguration) {
97
98
  shouldUpdateSetupSteps = true;
99
+
100
+ RecordAnswerHelper.throwIfPatchOrPutIsInvalid(
101
+ platform.config.organizationLevelRecordsConfiguration.recordCategories,
102
+ request.body.config.organizationLevelRecordsConfiguration.recordCategories);
103
+ }
104
+
105
+ if (request.body.config.recordsConfiguration) {
106
+ RecordAnswerHelper.throwIfPatchOrPutIsInvalid(
107
+ platform.config.recordsConfiguration.recordCategories,
108
+ request.body.config.recordsConfiguration.recordCategories);
109
+ }
110
+
111
+ if (request.body.config.eventNotificationTypes) {
112
+ RecordAnswerHelper.throwIfPatchOrPutsAreInvalid<'recordCategories', string, EventNotificationType, AutoEncoderPatchType<EventNotificationType>>(
113
+ platform.config.eventNotificationTypes,
114
+ request.body.config.eventNotificationTypes,
115
+ 'recordCategories',
116
+ );
98
117
  }
99
118
 
100
119
  const newConfig = request.body.config;
@@ -112,8 +131,7 @@ export class PatchPlatformEndpoint extends Endpoint<
112
131
  newConfig,
113
132
  oldConfig,
114
133
  );
115
- }
116
- else {
134
+ } else {
117
135
  platform.config = patchObject(platform.config, newConfig);
118
136
  }
119
137
  }
@@ -190,8 +208,7 @@ export class PatchPlatformEndpoint extends Endpoint<
190
208
  });
191
209
  }
192
210
  platform.membershipOrganizationId = organization.id;
193
- }
194
- else {
211
+ } else {
195
212
  platform.membershipOrganizationId = null;
196
213
  }
197
214
  }
@@ -210,8 +227,7 @@ export class PatchPlatformEndpoint extends Endpoint<
210
227
  });
211
228
  }
212
229
  platform.membershipOrganizationId = organization.id;
213
- }
214
- else {
230
+ } else {
215
231
  platform.membershipOrganizationId = null;
216
232
  }
217
233
  }
@@ -231,13 +247,16 @@ export class PatchPlatformEndpoint extends Endpoint<
231
247
  }
232
248
 
233
249
  if (shouldUpdateTags) {
234
- await TagHelper.updateOrganizations();
250
+ try {
251
+ await TagHelper.updateOrganizations();
252
+ } catch (e) {
253
+ if (!isAbortedError(e) && !isCanceledError(e)) throw e;
254
+ }
235
255
  }
236
256
 
237
257
  if (shouldMoveToPeriod) {
238
258
  PeriodHelper.moveAllOrganizationsToPeriod(shouldMoveToPeriod).catch(console.error);
239
- }
240
- else if (shouldUpdateSetupSteps) {
259
+ } else if (shouldUpdateSetupSteps) {
241
260
  // Do not call this right away when moving to a period, because this needs to happen AFTER moving to the period
242
261
  SetupStepUpdater.updateSetupStepsForAllOrganizationsInCurrentPeriod().catch(console.error);
243
262
  }
@@ -8,40 +8,40 @@ import { GetPlatformMembershipsEndpoint } from './GetPlatformMembershipsEndpoint
8
8
  type Params = Record<string, never>;
9
9
  type Query = CountFilteredRequest;
10
10
  type Body = undefined;
11
- type ResponseBody = CountResponse
11
+ type ResponseBody = CountResponse;
12
12
 
13
13
  export class GetPlatformMembershipsCountEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
14
14
  queryDecoder = CountFilteredRequest as Decoder<CountFilteredRequest>;
15
15
 
16
16
  protected doesMatch(request: Request): [true, Params] | [false] {
17
- if (request.method !== 'GET') {
18
- return [false];
19
- }
20
-
21
- const params = Endpoint.parseParameters(request.url, '/platform-memberships/count', {});
22
-
23
- if (params) {
24
- return [true, params as Params];
25
- }
26
- return [false];
27
- }
28
-
29
- async handle(request: DecodedRequest<Params, Query, Body>) {
30
- await Context.authenticate();
31
-
32
- if (!Context.auth.hasPlatformFullAccess()) {
33
- throw Context.auth.error();
34
- }
35
-
36
- const query = await GetPlatformMembershipsEndpoint.buildQuery(request.query);
37
-
38
- const count = await query
39
- .count();
40
-
41
- return new Response(
42
- CountResponse.create({
43
- count,
44
- }),
45
- );
46
- }
17
+ if (request.method !== 'GET') {
18
+ return [false];
19
+ }
20
+
21
+ const params = Endpoint.parseParameters(request.url, '/platform-memberships/count', {});
22
+
23
+ if (params) {
24
+ return [true, params as Params];
25
+ }
26
+ return [false];
27
+ }
28
+
29
+ async handle(request: DecodedRequest<Params, Query, Body>) {
30
+ await Context.authenticate();
31
+
32
+ if (!Context.auth.hasPlatformFullAccess()) {
33
+ throw Context.auth.error();
34
+ }
35
+
36
+ const query = await GetPlatformMembershipsEndpoint.buildQuery(request.query);
37
+
38
+ const count = await query
39
+ .count();
40
+
41
+ return new Response(
42
+ CountResponse.create({
43
+ count,
44
+ }),
45
+ );
46
+ }
47
47
  }
@@ -16,7 +16,6 @@ type Query = LimitedFilteredRequest;
16
16
  type Body = undefined;
17
17
  type ResponseBody = PaginatedResponse<PlatformMembership[], LimitedFilteredRequest>;
18
18
 
19
-
20
19
  const sorters = platformMembershipSorters;
21
20
  const filterCompilers = platformMembershipFilterCompilers;
22
21
 
@@ -37,9 +36,9 @@ export class GetPlatformMembershipsEndpoint extends Endpoint<Params, Query, Body
37
36
  }
38
37
 
39
38
  static async buildQuery(q: CountFilteredRequest | LimitedFilteredRequest) {
40
- if (!Context.auth.hasPlatformFullAccess()) {
41
- throw Context.auth.error();
42
- }
39
+ if (!Context.auth.hasPlatformFullAccess()) {
40
+ throw Context.auth.error();
41
+ }
43
42
 
44
43
  const query = MemberPlatformMembership.select()
45
44
  .setMaxExecutionTime(15 * 1000)
@@ -77,21 +76,21 @@ export class GetPlatformMembershipsEndpoint extends Endpoint<Params, Query, Body
77
76
  if (search.match(/^\d{4}-\d{6}-\d{1,2}$/) || search.match(/^\d{9,10}$/)) {
78
77
  return {
79
78
  member: {
80
- memberNumber: {
79
+ memberNumber: {
81
80
  $eq: search,
82
81
  },
83
-
84
- }
82
+
83
+ },
85
84
  };
86
85
  }
87
86
 
88
87
  return {
89
- member: {
90
- name: {
91
- $contains: search,
92
- }
93
- }
94
- };
88
+ member: {
89
+ name: {
90
+ $contains: search,
91
+ },
92
+ },
93
+ };
95
94
  }
96
95
 
97
96
  static async buildData(requestQuery: LimitedFilteredRequest) {
@@ -101,8 +100,7 @@ export class GetPlatformMembershipsEndpoint extends Endpoint<Params, Query, Body
101
100
 
102
101
  try {
103
102
  data = await query.fetch();
104
- }
105
- catch (error) {
103
+ } catch (error) {
106
104
  if (error.message.includes('ER_QUERY_TIMEOUT')) {
107
105
  throw new SimpleError({
108
106
  code: 'timeout',
@@ -118,7 +116,7 @@ export class GetPlatformMembershipsEndpoint extends Endpoint<Params, Query, Body
118
116
  const balanceItemIds = Formatter.uniqueArray(data.map(d => d.balanceItemId));
119
117
  const members = await Member.getByIDs(...memberIds);
120
118
  const organizations = await Organization.getByIDs(...organizationIds);
121
- const balanceItems = await BalanceItem.getByIDs(...balanceItemIds)
119
+ const balanceItems = await BalanceItem.getByIDs(...balanceItemIds);
122
120
  const balanceItemStructures = await BalanceItem.getStructureWithPayments(balanceItems);
123
121
 
124
122
  const results: PlatformMembership[] = [];
@@ -149,7 +147,7 @@ export class GetPlatformMembershipsEndpoint extends Endpoint<Params, Query, Body
149
147
  ...model,
150
148
  balanceItem: balanceItem,
151
149
  member: PlatformMembershipMemberDetails.create(member),
152
- organization: PlatformMembershipOrganizationDetails.create(organization)
150
+ organization: PlatformMembershipOrganizationDetails.create(organization),
153
151
  }));
154
152
  }
155
153
 
@@ -182,9 +180,9 @@ export class GetPlatformMembershipsEndpoint extends Endpoint<Params, Query, Body
182
180
  async handle(request: DecodedRequest<Params, Query, Body>) {
183
181
  await Context.authenticate();
184
182
 
185
- if (!Context.auth.hasPlatformFullAccess()) {
186
- throw Context.auth.error();
187
- }
183
+ if (!Context.auth.hasPlatformFullAccess()) {
184
+ throw Context.auth.error();
185
+ }
188
186
 
189
187
  const maxLimit = 1000;
190
188
 
@@ -1,5 +1,5 @@
1
1
  import type { Decoder } from '@simonbackx/simple-encoding';
2
- import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
2
+ import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
3
3
  import { Endpoint, Response } from '@simonbackx/simple-endpoints';
4
4
  import { CountFilteredRequest, CountResponse } from '@stamhoofd/structures';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import { Request } from '@simonbackx/simple-endpoints';
2
- import type { RegistrationPeriod} from '@stamhoofd/models';
2
+ import type { RegistrationPeriod } from '@stamhoofd/models';
3
3
  import { EventFactory, GroupFactory, MemberFactory, OrganizationFactory, RegistrationFactory, RegistrationPeriodFactory, Token, UserFactory } from '@stamhoofd/models';
4
4
  import { AccessRight, EventMeta, GroupType, LimitedFilteredRequest, NamedObject, PermissionLevel, PermissionRoleDetailed, Permissions, PermissionsResourceType, ResourcePermissions } from '@stamhoofd/structures';
5
5
  import { STExpect, TestUtils } from '@stamhoofd/test-utils';
@@ -1,9 +1,9 @@
1
1
  import type { Decoder } from '@simonbackx/simple-encoding';
2
- import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
2
+ import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
3
3
  import { Endpoint, Response } from '@simonbackx/simple-endpoints';
4
4
  import { SimpleError } from '@simonbackx/simple-errors';
5
5
  import { Group, Member, Platform, Registration } from '@stamhoofd/models';
6
- import type { SQLExpression, SQLSortDefinitions} from '@stamhoofd/sql';
6
+ import type { SQLExpression, SQLSortDefinitions } from '@stamhoofd/sql';
7
7
  import { SQL, SQLSelect, applySQLSorter, compileToSQLFilter } from '@stamhoofd/sql';
8
8
  import type { CountFilteredRequest, RegistrationWithMemberBlob, StamhoofdFilter, RegistrationsBlob } from '@stamhoofd/structures';
9
9
  import { GroupType, LimitedFilteredRequest, PaginatedResponse, PermissionLevel, assertSort } from '@stamhoofd/structures';
@@ -108,8 +108,7 @@ export class GetRegistrationsEndpoint extends Endpoint<Params, Query, Body, Resp
108
108
  },
109
109
  },
110
110
  };
111
- }
112
- else {
111
+ } else {
113
112
  // Can only access current period
114
113
  scopeFilter = {
115
114
  member: {
@@ -122,8 +121,7 @@ export class GetRegistrationsEndpoint extends Endpoint<Params, Query, Body, Resp
122
121
  },
123
122
  };
124
123
  }
125
- }
126
- else {
124
+ } else {
127
125
  // Check which normal membership groups we have access to and filter on those
128
126
  const groups = await Group.getAll(organization.id, organization.periodId, true, [GroupType.Membership, GroupType.WaitingList]);
129
127
  Context.auth.cacheGroups(groups);
@@ -202,8 +200,7 @@ export class GetRegistrationsEndpoint extends Endpoint<Params, Query, Body, Resp
202
200
 
203
201
  try {
204
202
  data = await query.fetch();
205
- }
206
- catch (error) {
203
+ } catch (error) {
207
204
  if (error.message.includes('ER_QUERY_TIMEOUT')) {
208
205
  throw new SimpleError({
209
206
  code: 'timeout',
@@ -217,8 +214,7 @@ export class GetRegistrationsEndpoint extends Endpoint<Params, Query, Body, Resp
217
214
  for (const registration of data) {
218
215
  if (registration.group.settings.implicitlyAllowViewRegistrations) {
219
216
  // okay, only need to check if we can access the members (next step)
220
- }
221
- else {
217
+ } else {
222
218
  if (!await Context.auth.canAccessRegistration(registration, permissionLevel)) {
223
219
  throw Context.auth.error();
224
220
  }
@@ -1,12 +1,13 @@
1
- import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
1
+ import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
2
2
  import { Endpoint, Response } from '@simonbackx/simple-endpoints';
3
- import type { Payment } from '@stamhoofd/models';
3
+ import { BalanceItemPayment, Payment } from '@stamhoofd/models';
4
4
  import { BalanceItem, Member, Organization } from '@stamhoofd/models';
5
- import { DetailedPayableBalanceCollection, DetailedPayableBalance } from '@stamhoofd/structures';
5
+ import { DetailedPayableBalanceCollection, DetailedPayableBalance, PaymentStatus } from '@stamhoofd/structures';
6
6
 
7
7
  import { Formatter } from '@stamhoofd/utility';
8
8
  import { AuthenticatedStructures } from '../../../helpers/AuthenticatedStructures.js';
9
9
  import { Context } from '../../../helpers/Context.js';
10
+ import { SQL, SQLWhereExists } from '@stamhoofd/sql';
10
11
 
11
12
  type Params = Record<string, never>;
12
13
  type Query = undefined;
@@ -38,7 +39,35 @@ export class GetUserDetailedPayableBalanceEndpoint extends Endpoint<Params, Quer
38
39
  const balanceItemModels = await BalanceItem.balanceItemsForUsersAndMembers(organization?.id ?? null, [user.id], memberIds);
39
40
 
40
41
  // todo: this is a duplicate query
41
- const { payments, balanceItemPayments } = await BalanceItem.loadPayments(balanceItemModels);
42
+ const q = Payment.select()
43
+ .where(
44
+ SQL.where('payingUserId', user.id)
45
+ .or(
46
+ new SQLWhereExists(SQL.subQuery(
47
+ SQL.select().from('balance_items')
48
+ .join(SQL.innerJoin(
49
+ SQL.table(BalanceItemPayment.table))
50
+ .where(
51
+ SQL.column(BalanceItemPayment.table, 'balanceItemId'),
52
+ SQL.column(BalanceItem.table, 'id'),
53
+ ),
54
+ )
55
+ .where(SQL.where('memberId', memberIds).or('userId', user.id))
56
+ .where(SQL.column(BalanceItemPayment.table, 'paymentId'), SQL.column(Payment.table, 'id')),
57
+ ),
58
+ ),
59
+ ),
60
+ )
61
+ .whereNot('status', PaymentStatus.Failed);
62
+
63
+ if (organization) {
64
+ q.where('organizationId', organization.id);
65
+ }
66
+
67
+ q.orderBy('createdAt', 'DESC');
68
+ q.limit(100);
69
+
70
+ const payments = await q.fetch();
42
71
 
43
72
  return new Response(await GetUserDetailedPayableBalanceEndpoint.getDetailedBillingStatus(balanceItemModels, payments));
44
73
  }
@@ -71,8 +100,8 @@ export class GetUserDetailedPayableBalanceEndpoint extends Endpoint<Params, Quer
71
100
  }
72
101
 
73
102
  const balanceItems = await BalanceItem.getStructureWithPayments(balanceItemModels);
74
- const organizations = await AuthenticatedStructures.organizations(organizationModels);
75
- const payments = await AuthenticatedStructures.paymentsGeneral(paymentModels, false);
103
+ const organizations = await AuthenticatedStructures.baseOrganizations(organizationModels);
104
+ const payments = await AuthenticatedStructures.payments(paymentModels);
76
105
 
77
106
  return DetailedPayableBalanceCollection.create({
78
107
  organizations: organizations.map((o) => {
@@ -1,7 +1,7 @@
1
- import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
1
+ import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
2
2
  import { Endpoint, Response } from '@simonbackx/simple-endpoints';
3
3
  import { Document, DocumentTemplate, Member } from '@stamhoofd/models';
4
- import type { Document as DocumentStruct} from '@stamhoofd/structures';
4
+ import type { Document as DocumentStruct } from '@stamhoofd/structures';
5
5
  import { DocumentStatus } from '@stamhoofd/structures';
6
6
  import { Sorter } from '@stamhoofd/utility';
7
7
 
@@ -1,4 +1,4 @@
1
- import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
1
+ import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
2
2
  import { Endpoint, Response } from '@simonbackx/simple-endpoints';
3
3
  import { Member } from '@stamhoofd/models';
4
4
  import type { MembersBlob } from '@stamhoofd/structures';
@@ -1,4 +1,4 @@
1
- import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
1
+ import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
2
2
  import { Endpoint, Response } from '@simonbackx/simple-endpoints';
3
3
  import { CachedBalance, Organization } from '@stamhoofd/models';
4
4
  import { PayableBalance, PayableBalanceCollection, ReceivableBalanceType } from '@stamhoofd/structures';
@@ -1,9 +1,9 @@
1
1
  import { Database } from '@simonbackx/simple-database';
2
2
  import { PatchableArray, PatchMap } from '@simonbackx/simple-encoding';
3
- import type { Endpoint} from '@simonbackx/simple-endpoints';
3
+ import type { Endpoint } from '@simonbackx/simple-endpoints';
4
4
  import { Request } from '@simonbackx/simple-endpoints';
5
5
  import { GroupFactory, Member, MemberFactory, OrganizationFactory, Platform, RegistrationFactory, Token, UserFactory } from '@stamhoofd/models';
6
- import type { PatchAnswers} from '@stamhoofd/structures';
6
+ import type { PatchAnswers } from '@stamhoofd/structures';
7
7
  import { MemberDetails, MemberWithRegistrationsBlob, OrganizationMetaData, OrganizationRecordsConfiguration, Parent, PermissionLevel, RecordCategory, RecordSettings, RecordTextAnswer, TranslatedString, UitpasNumberDetails, UitpasSocialTariff, UitpasSocialTariffStatus } from '@stamhoofd/structures';
8
8
  import { STExpect, TestUtils } from '@stamhoofd/test-utils';
9
9
  import { testServer } from '../../../../tests/helpers/TestServer.js';
@@ -1,11 +1,11 @@
1
- import type { AutoEncoderPatchType, Decoder, PatchableArrayAutoEncoder} from '@simonbackx/simple-encoding';
1
+ import type { AutoEncoderPatchType, Decoder, PatchableArrayAutoEncoder } from '@simonbackx/simple-encoding';
2
2
  import { isEmptyPatch, PatchableArrayDecoder, StringDecoder } from '@simonbackx/simple-encoding';
3
- import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
3
+ import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
4
4
  import { Endpoint, Response } from '@simonbackx/simple-endpoints';
5
5
  import { SimpleError } from '@simonbackx/simple-errors';
6
6
  import type { Group, Registration } from '@stamhoofd/models';
7
7
  import { Document, Member, RateLimiter } from '@stamhoofd/models';
8
- import type { MemberDetails, MembersBlob} from '@stamhoofd/structures';
8
+ import type { MemberDetails, MembersBlob } from '@stamhoofd/structures';
9
9
  import { MemberWithRegistrationsBlob } from '@stamhoofd/structures';
10
10
 
11
11
  import type { OneToManyRelation } from '@simonbackx/simple-database';