@stamhoofd/backend 2.121.0 → 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 (429) hide show
  1. package/output-2.txt +1 -0
  2. package/output.txt +1 -0
  3. package/package.json +69 -52
  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 +24 -24
  8. package/src/audit-logs/init.ts +8 -2
  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 +5 -0
  19. package/src/crons/invoices.ts +32 -38
  20. package/src/crons/members-fees.ts +50 -0
  21. package/src/crons/mollie-chargebacks.ts +14 -15
  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 +7 -64
  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 +4 -6
  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 +1 -1
  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 +11 -11
  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 +35 -34
  122. package/src/endpoints/global/registration-invitations/GetRegistrationInvitationsCountEndpoint.ts +1 -1
  123. package/src/endpoints/global/registration-invitations/GetRegistrationInvitationsEndpoint.test.ts +62 -63
  124. package/src/endpoints/global/registration-invitations/GetRegistrationInvitationsEndpoint.ts +6 -9
  125. package/src/endpoints/global/registration-invitations/PatchRegistrationInvitationsEndpoint.test.ts +51 -52
  126. package/src/endpoints/global/registration-invitations/PatchRegistrationInvitationsEndpoint.ts +6 -7
  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 +7 -9
  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/organization/dashboard/billing/DeactivatePackageEndpoint.ts +1 -5
  142. package/src/endpoints/organization/dashboard/billing/DeleteOrganizationMandateEndpoint.ts +11 -11
  143. package/src/endpoints/organization/dashboard/billing/GetOrganizationDetailedPayableBalanceCollectionEndpoint.ts +2 -2
  144. package/src/endpoints/organization/dashboard/billing/GetOrganizationDetailedPayableBalanceEndpoint.ts +8 -8
  145. package/src/endpoints/organization/dashboard/billing/GetOrganizationMandatesEndpoint.ts +9 -9
  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 +4 -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 +60 -57
  152. package/src/endpoints/organization/dashboard/billing/PatchOrganizationMandatesEndpoint.ts +20 -20
  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 +10 -6
  168. package/src/endpoints/organization/dashboard/invoices/PatchInvoicesEndpoint.ts +11 -2
  169. package/src/endpoints/organization/dashboard/mollie/CheckMollieEndpoint.ts +4 -5
  170. package/src/endpoints/organization/dashboard/mollie/ConnectMollieEndpoint.ts +5 -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 +50 -12
  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 +21 -14
  185. package/src/endpoints/organization/dashboard/receivable-balances/ChargeReceivableBalancesEndpoint.ts +35 -28
  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 +19 -18
  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 +22 -7
  215. package/src/endpoints/organization/dashboard/webshops/PatchWebshopOrdersEndpoint.ts +20 -27
  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 +2 -2
  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 +16 -33
  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 +50 -63
  246. package/src/helpers/AuthenticatedStructures.ts +69 -55
  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 +2 -2
  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 +105 -110
  268. package/src/helpers/RecordAnswerHelper.ts +7 -7
  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 +14 -36
  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 +7 -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/{seeds → migrations}/1750090030-records-configuration.ts +33 -32
  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 +70 -26
  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/1779121240-invoice-email-template.sql +6 -0
  300. package/src/migrations/1779986893-default-payment-failed-email-templates.sql +4 -0
  301. package/src/migrations/1780578166-convert-legacy-billing.ts +13 -0
  302. package/src/{seeds/1755876819-remove-duplicate-members.ts → migrations/1780665426-remove-duplicate-members.ts} +23 -4
  303. package/src/migrations/1780933598-document-groups.ts +88 -0
  304. package/src/migrations/1781692342-balance-item-relations.ts +13 -0
  305. package/src/migrations/1781857866-platform-admins.ts +103 -0
  306. package/src/migrations/1781857867-rm-old-platform-admins.ts +25 -0
  307. package/src/seeds/0000000001-throw.ts +5 -0
  308. package/src/seeds/1760702452-update-balance-price-paid.ts +19 -0
  309. package/src/seeds/1760702453-update-balance-invoiced.ts +19 -0
  310. package/src/seeds/1760702454-update-cached-outstanding-balance-from-items.ts +51 -14
  311. package/src/seeds/1773754928-force-save-members.ts +41 -8
  312. package/src/seeds/1780665427-schedule-stock-updates.ts +45 -0
  313. package/src/seeds/1780665428-group-update-occupancy.ts +31 -0
  314. package/src/seeds/1780915001-fill-payment-customer.ts +70 -0
  315. package/src/seeds/1780915002-update-orders.ts +39 -0
  316. package/src/seeds/1782047708-organization-company-address.ts +44 -0
  317. package/src/seeds-temporary/1769088653-uitpas-status.ts +1 -2
  318. package/src/seeds-temporary/1780416000-migrate-audit-log-legacy-enums.test.ts +69 -0
  319. package/src/seeds-temporary/1780416000-migrate-audit-log-legacy-enums.ts +85 -0
  320. package/src/services/AuditLogService.test.ts +51 -0
  321. package/src/services/AuditLogService.ts +45 -0
  322. package/src/services/BalanceItemService.ts +141 -44
  323. package/src/services/CpuService.ts +3 -6
  324. package/src/services/DatabaseCollationService.test.ts +1 -2
  325. package/src/services/DocumentService.ts +1 -2
  326. package/src/services/EventNotificationService.ts +1 -1
  327. package/src/services/FileSignService.ts +2 -4
  328. package/src/services/InvoicePdfService.ts +286 -0
  329. package/src/services/InvoiceService.ts +204 -251
  330. package/src/services/InvoiceXMLService.ts +424 -0
  331. package/src/services/MemberNumberService.ts +6 -11
  332. package/src/services/MemberRecordStore.ts +8 -10
  333. package/src/services/MollieService.ts +114 -121
  334. package/src/services/PaymentMandateService.ts +45 -45
  335. package/src/services/PaymentReallocationService.test.ts +1 -1
  336. package/src/services/PaymentReallocationService.ts +7 -9
  337. package/src/services/PaymentService.ts +444 -308
  338. package/src/services/PlatformMembershipService.ts +4 -8
  339. package/src/services/ReferralService.ts +223 -0
  340. package/src/services/RegistrationService.ts +63 -53
  341. package/src/services/SSOService.test.ts +119 -0
  342. package/src/services/SSOService.ts +56 -49
  343. package/src/services/STPackageService.ts +97 -61
  344. package/src/services/UniqueMemberNumberService.ts +69 -0
  345. package/src/services/UniqueUserService.ts +3 -6
  346. package/src/services/VATService.ts +85 -0
  347. package/src/services/uitpas/PassholderEndpoints.ts +3 -6
  348. package/src/services/uitpas/UitpasService.ts +6 -10
  349. package/src/services/uitpas/checkUitpasNumbers.ts +2 -4
  350. package/src/services/uitpas/getSocialTariffForUitpasNumbers.ts +3 -6
  351. package/src/services/uitpas/searchUitpasEvents.ts +1 -2
  352. package/src/sql-filters/audit-logs.ts +1 -1
  353. package/src/sql-filters/balance-item-payments.ts +1 -1
  354. package/src/sql-filters/balance-items.ts +1 -1
  355. package/src/sql-filters/base-registration-filter-compilers.ts +5 -33
  356. package/src/sql-filters/document-templates.ts +1 -1
  357. package/src/sql-filters/documents.ts +1 -1
  358. package/src/sql-filters/email-recipients.ts +1 -1
  359. package/src/sql-filters/emails.ts +1 -1
  360. package/src/sql-filters/event-notifications.ts +1 -1
  361. package/src/sql-filters/events.ts +6 -1
  362. package/src/sql-filters/groups.ts +5 -0
  363. package/src/sql-filters/invoiced-balance-items.ts +1 -1
  364. package/src/sql-filters/invoices.ts +1 -1
  365. package/src/sql-filters/member-responsibility-records.ts +1 -1
  366. package/src/sql-filters/members.ts +1 -1
  367. package/src/sql-filters/orders.ts +4 -4
  368. package/src/sql-filters/organization-registration-periods.ts +1 -1
  369. package/src/sql-filters/organizations.ts +1 -1
  370. package/src/sql-filters/platform-memberships.ts +3 -3
  371. package/src/sql-filters/receivable-balances.ts +1 -1
  372. package/src/sql-filters/registration-periods.ts +1 -1
  373. package/src/sql-filters/registrations.ts +1 -1
  374. package/src/sql-filters/tickets.ts +1 -1
  375. package/src/sql-filters/users.ts +1 -1
  376. package/src/sql-sorters/groups.ts +23 -0
  377. package/src/sql-sorters/platform-memberships.ts +16 -16
  378. package/src/sql-sorters/registration-invitations.ts +2 -2
  379. package/tests/actions/patchOrganizationMember.ts +1 -1
  380. package/tests/actions/patchUserMember.ts +1 -1
  381. package/tests/assertions/assertBalances.ts +6 -12
  382. package/tests/e2e/api-rate-limits.test.ts +12 -24
  383. package/tests/e2e/bundle-discounts.test.ts +4 -1
  384. package/tests/e2e/charge-members.test.ts +13 -11
  385. package/tests/e2e/documents.test.ts +4 -1
  386. package/tests/e2e/register.test.ts +7 -9
  387. package/tests/e2e/stock.test.ts +4 -3
  388. package/tests/e2e/tickets.test.ts +1 -1
  389. package/tests/helpers/MollieMocker.ts +462 -0
  390. package/tests/helpers/PayconiqMocker.ts +138 -45
  391. package/tests/helpers/StripeMocker.ts +9 -6
  392. package/tests/helpers/index.ts +4 -0
  393. package/tests/init/initAdmin.ts +2 -2
  394. package/tests/init/initBundleDiscount.ts +1 -1
  395. package/tests/init/initMembershipOrganization.ts +13 -0
  396. package/tests/init/initPermissionRole.ts +3 -4
  397. package/tests/vitest.global.setup.ts +1 -1
  398. package/vitest.config.js +6 -0
  399. package/.nvmrc +0 -1
  400. package/src/helpers/GroupBuilder.ts +0 -418
  401. package/src/seeds/0000000000-example.ts +0 -11
  402. package/src/seeds/1722256498-group-update-occupancy.ts +0 -52
  403. package/src/seeds/1726572303-schedule-stock-updates.ts +0 -52
  404. package/src/seeds/1726847064-setup-steps.ts +0 -16
  405. package/src/seeds/1728928974-update-cached-outstanding-balance-from-items.ts +0 -31
  406. package/src/seeds/1729253172-update-orders.ts +0 -21
  407. package/src/seeds/1733319079-fill-paying-organization-ids.ts +0 -68
  408. package/src/seeds/1733748412-update-deleted-order-numbers.ts +0 -109
  409. package/src/seeds/1733994455-balance-item-status-open.ts +0 -30
  410. package/src/seeds/1740046783-update-membership.ts +0 -17
  411. package/src/seeds/1741008870-fix-auditlog-description.ts +0 -50
  412. package/src/seeds/1741011468-fix-auditlog-description-uft16.ts +0 -88
  413. package/src/seeds/1741268179-fix-group-dates-of-events.ts +0 -32
  414. package/src/seeds/1751445358-upload-email-attachments.ts +0 -106
  415. package/src/seeds/1755532883-update-email-sender-ids.ts +0 -47
  416. package/src/seeds/1755790070-fill-email-recipient-errors.ts +0 -96
  417. package/src/seeds/1756115432-remove-old-drafts.ts +0 -16
  418. package/src/seeds/1756115433-fill-email-recipient-organization-id.ts +0 -30
  419. package/src/seeds/1756303697-update-email-counts.ts +0 -76
  420. package/src/seeds/1761665607-sync-member-users.ts +0 -59
  421. package/src/seeds/1765896674-document-update-year.ts +0 -66
  422. /package/src/{seeds → migrations}/0000000001-development-user.ts +0 -0
  423. /package/src/{seeds → migrations}/0000000002-clear-stamhoofd-email-templates.ts +0 -0
  424. /package/src/{seeds → migrations}/0000000003-default-email-templates.ts +0 -0
  425. /package/src/{seeds → migrations}/1752848561-groups-registration-periods.test.ts +0 -0
  426. /package/src/{seeds → migrations}/1766150402-document-published-at.test.ts +0 -0
  427. /package/src/{seeds → migrations}/1766150402-document-published-at.ts +0 -0
  428. /package/src/{seeds → migrations}/1779121239-default-invoice-email-template.sql +0 -0
  429. /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 { 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
 
@@ -7,7 +7,7 @@ import type { EventNotificationType, MemberResponsibility, PlatformConfig, Platf
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';
@@ -113,7 +113,7 @@ export class PatchPlatformEndpoint extends Endpoint<
113
113
  platform.config.eventNotificationTypes,
114
114
  request.body.config.eventNotificationTypes,
115
115
  'recordCategories',
116
- )
116
+ );
117
117
  }
118
118
 
119
119
  const newConfig = request.body.config;
@@ -131,8 +131,7 @@ export class PatchPlatformEndpoint extends Endpoint<
131
131
  newConfig,
132
132
  oldConfig,
133
133
  );
134
- }
135
- else {
134
+ } else {
136
135
  platform.config = patchObject(platform.config, newConfig);
137
136
  }
138
137
  }
@@ -209,8 +208,7 @@ export class PatchPlatformEndpoint extends Endpoint<
209
208
  });
210
209
  }
211
210
  platform.membershipOrganizationId = organization.id;
212
- }
213
- else {
211
+ } else {
214
212
  platform.membershipOrganizationId = null;
215
213
  }
216
214
  }
@@ -229,8 +227,7 @@ export class PatchPlatformEndpoint extends Endpoint<
229
227
  });
230
228
  }
231
229
  platform.membershipOrganizationId = organization.id;
232
- }
233
- else {
230
+ } else {
234
231
  platform.membershipOrganizationId = null;
235
232
  }
236
233
  }
@@ -250,13 +247,16 @@ export class PatchPlatformEndpoint extends Endpoint<
250
247
  }
251
248
 
252
249
  if (shouldUpdateTags) {
253
- await TagHelper.updateOrganizations();
250
+ try {
251
+ await TagHelper.updateOrganizations();
252
+ } catch (e) {
253
+ if (!isAbortedError(e) && !isCanceledError(e)) throw e;
254
+ }
254
255
  }
255
256
 
256
257
  if (shouldMoveToPeriod) {
257
258
  PeriodHelper.moveAllOrganizationsToPeriod(shouldMoveToPeriod).catch(console.error);
258
- }
259
- else if (shouldUpdateSetupSteps) {
259
+ } else if (shouldUpdateSetupSteps) {
260
260
  // Do not call this right away when moving to a period, because this needs to happen AFTER moving to the period
261
261
  SetupStepUpdater.updateSetupStepsForAllOrganizationsInCurrentPeriod().catch(console.error);
262
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';
@@ -1,7 +1,7 @@
1
1
  import { PatchMap } from '@simonbackx/simple-encoding';
2
2
  import { Request } from '@simonbackx/simple-endpoints';
3
3
  import { EmailMocker } from '@stamhoofd/email';
4
- import type { MemberWithUsersRegistrationsAndGroups, Organization, RegistrationPeriod} from '@stamhoofd/models';
4
+ import type { MemberWithUsersRegistrationsAndGroups, Organization, RegistrationPeriod } from '@stamhoofd/models';
5
5
  import { BalanceItemFactory, Group, GroupFactory, Member, MemberFactory, OrganizationFactory, OrganizationRegistrationPeriodFactory, Registration, RegistrationFactory, RegistrationPeriodFactory, Token, UserFactory } from '@stamhoofd/models';
6
6
  import { AccessRight, BalanceItemCartItem, BalanceItemStatus, BalanceItemType, BooleanStatus, Company, GroupOption, GroupOptionMenu, IDRegisterCart, IDRegisterCheckout, IDRegisterItem, OrganizationPackages, PaymentCustomer, PaymentMethod, PermissionLevel, Permissions, PermissionsResourceType, ReduceablePrice, RegisterItemOption, ResourcePermissions, STPackageStatus, STPackageType, UitpasNumberDetails, UitpasSocialTariff, UitpasSocialTariffStatus, UserPermissions, Version } from '@stamhoofd/structures';
7
7
  import { STExpect, TestUtils } from '@stamhoofd/test-utils';
@@ -865,7 +865,7 @@ describe('Endpoint.RegisterMembers', () => {
865
865
 
866
866
  expect(response.body).toBeDefined();
867
867
  expect(response.body.registrations.length).toBe(1);
868
- expect(response.body.paymentUrl).toMatch(/payconiq\.com/);
868
+ expect(response.body.paymentUrl).toMatch(/payconiq-checkout\.test/);
869
869
 
870
870
  expect(response.body.registrations[0]).toMatchObject({
871
871
  registeredAt: null,
@@ -925,8 +925,7 @@ describe('Endpoint.RegisterMembers', () => {
925
925
  expect(trialUntil!.getFullYear()).toBe(2023);
926
926
  expect(trialUntil!.getMonth()).toBe(4);
927
927
  expect(trialUntil!.getDate()).toBe(19);
928
- }
929
- finally {
928
+ } finally {
930
929
  vitest.useRealTimers();
931
930
  }
932
931
  }, 20_00000);
@@ -2316,6 +2315,91 @@ describe('Endpoint.RegisterMembers', () => {
2316
2315
  test('Should fail if company does not exist on organization', async () => {
2317
2316
  const { organization, group, groupPrice, member, token, organization2 } = await initDualData();
2318
2317
 
2318
+ const c = Company.create({
2319
+ name: 'test company A',
2320
+ });
2321
+ organization2.meta.companies = [c];
2322
+ await organization2.save();
2323
+
2324
+ const body = IDRegisterCheckout.create({
2325
+ cart: IDRegisterCart.create({
2326
+ items: [
2327
+ IDRegisterItem.create({
2328
+ id: uuidv4(),
2329
+ replaceRegistrationIds: [],
2330
+ options: [],
2331
+ groupPrice,
2332
+ organizationId: organization.id,
2333
+ groupId: group.id,
2334
+ memberId: member.id,
2335
+ }),
2336
+ ],
2337
+ balanceItems: [
2338
+ ],
2339
+ deleteRegistrationIds: [],
2340
+ }),
2341
+ administrationFee: 0,
2342
+ freeContribution: 0,
2343
+ paymentMethod: PaymentMethod.PointOfSale,
2344
+ totalPrice: 25_0000,
2345
+ customer: PaymentCustomer.create({
2346
+ company: Company.create({ // different id (important for the test)
2347
+ name: 'test company',
2348
+ }),
2349
+ }),
2350
+ asOrganizationId: organization2.id,
2351
+ });
2352
+
2353
+ await expect(post(body, organization, token))
2354
+ .rejects
2355
+ .toThrow(/Cannot set company data/);
2356
+ });
2357
+
2358
+ test('Should not fail if using default company on organization', async () => {
2359
+ const { organization, group, groupPrice, member, token, organization2 } = await initDualData();
2360
+ organization2.meta.companies = [];
2361
+ await organization2.save();
2362
+
2363
+ const body = IDRegisterCheckout.create({
2364
+ cart: IDRegisterCart.create({
2365
+ items: [
2366
+ IDRegisterItem.create({
2367
+ id: uuidv4(),
2368
+ replaceRegistrationIds: [],
2369
+ options: [],
2370
+ groupPrice,
2371
+ organizationId: organization.id,
2372
+ groupId: group.id,
2373
+ memberId: member.id,
2374
+ }),
2375
+ ],
2376
+ balanceItems: [
2377
+ ],
2378
+ deleteRegistrationIds: [],
2379
+ }),
2380
+ administrationFee: 0,
2381
+ freeContribution: 0,
2382
+ paymentMethod: PaymentMethod.PointOfSale,
2383
+ totalPrice: 25_0000,
2384
+ customer: PaymentCustomer.create({
2385
+ company: organization2.defaultCompanies[0],
2386
+ }),
2387
+ asOrganizationId: organization2.id,
2388
+ });
2389
+
2390
+ const result = await post(body, organization, token);
2391
+ expect(result.body.registrations.length).toEqual(1);
2392
+ });
2393
+
2394
+ test('Should fail if company exists but is patched on organization', async () => {
2395
+ const { organization, group, groupPrice, member, token, organization2 } = await initDualData();
2396
+
2397
+ const c = Company.create({
2398
+ name: 'test company A',
2399
+ });
2400
+ organization2.meta.companies = [c];
2401
+ await organization2.save();
2402
+
2319
2403
  const body = IDRegisterCheckout.create({
2320
2404
  cart: IDRegisterCart.create({
2321
2405
  items: [
@@ -2338,7 +2422,7 @@ describe('Endpoint.RegisterMembers', () => {
2338
2422
  paymentMethod: PaymentMethod.PointOfSale,
2339
2423
  totalPrice: 25_0000,
2340
2424
  customer: PaymentCustomer.create({
2341
- company: Company.create({
2425
+ company: c.patch({
2342
2426
  name: 'test company',
2343
2427
  }),
2344
2428
  }),
@@ -2347,7 +2431,7 @@ describe('Endpoint.RegisterMembers', () => {
2347
2431
 
2348
2432
  await expect(post(body, organization, token))
2349
2433
  .rejects
2350
- .toThrow('Oeps, de facturatiegegevens die je probeerde te selecteren lijken niet meer te bestaan.');
2434
+ .toThrow(/Cannot change company data/);
2351
2435
  });
2352
2436
  });
2353
2437