@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
@@ -101,12 +101,10 @@ export class AdminPermissionChecker {
101
101
  const resolved = await cache;
102
102
  if (resolved) {
103
103
  cached.push(resolved);
104
- }
105
- else {
104
+ } else {
106
105
  // Not found, no need to readd
107
106
  }
108
- }
109
- else {
107
+ } else {
110
108
  remainingIds.push(groupId);
111
109
  }
112
110
  }
@@ -225,15 +223,13 @@ export class AdminPermissionChecker {
225
223
  if (this.user.organizationId && organizationId !== this.user.organizationId) {
226
224
  return false;
227
225
  }
228
- }
229
- else {
226
+ } else {
230
227
  if (STAMHOOFD.userMode === 'organization') {
231
228
  // User is limited to a scope: can't access platform resources
232
229
  if (this.user.organizationId) {
233
230
  return false;
234
231
  }
235
- }
236
- else {
232
+ } else {
237
233
  // User can access platform resources (e.g. API keys)
238
234
  }
239
235
  }
@@ -323,8 +319,7 @@ export class AdminPermissionChecker {
323
319
  if (group.settings.allowRegistrationsByOrganization && !group.getStructure().closed) {
324
320
  if (group.organizationId !== asOrganizationId) {
325
321
  return await this.hasFullAccess(asOrganizationId);
326
- }
327
- else {
322
+ } else {
328
323
  return await this.hasSomeAccess(asOrganizationId);
329
324
  }
330
325
  }
@@ -350,8 +345,7 @@ export class AdminPermissionChecker {
350
345
  try {
351
346
  await this.checkEventAccess(event);
352
347
  return true;
353
- }
354
- catch (e) {
348
+ } catch (e) {
355
349
  if (isSimpleError(e) || isSimpleErrors(e)) {
356
350
  return false;
357
351
  }
@@ -630,7 +624,7 @@ export class AdminPermissionChecker {
630
624
  ): Promise<boolean> {
631
625
  // These balance items are out of scope - but we do have access to them
632
626
  for (const balanceItem of balanceItems) {
633
- if (balanceItem.payingOrganizationId && this.checkScope(balanceItem.payingOrganizationId)) {
627
+ if (balanceItem.payingOrganizationId && (this.checkScope(balanceItem.payingOrganizationId) || this.checkScope(balanceItem.organizationId))) {
634
628
  if (await this.canManagePayments(balanceItem.payingOrganizationId)) {
635
629
  return true;
636
630
  }
@@ -802,7 +796,12 @@ export class AdminPermissionChecker {
802
796
  return false;
803
797
  }
804
798
 
805
- return EmailTemplateStruct.allowOrganizationLevel(template.type);
799
+ if (!this.organization) {
800
+ const org = await this.getOrganization(template.organizationId);
801
+ return EmailTemplateStruct.allowOrganizationLevel(template.type, org, this.platform);
802
+ }
803
+
804
+ return EmailTemplateStruct.allowOrganizationLevel(template.type, this.organization, this.platform);
806
805
  }
807
806
 
808
807
  // Note: if the template has an organizationId of null, everyone can access it, but only for reading
@@ -870,8 +869,7 @@ export class AdminPermissionChecker {
870
869
  if (await this.canManagePayments(member.organizationId)) {
871
870
  return true;
872
871
  }
873
- }
874
- else {
872
+ } else {
875
873
  const organizationIds = Formatter.uniqueArray(member.registrations.map(r => r.organizationId));
876
874
  for (const organizationId of organizationIds) {
877
875
  if (await this.canManagePayments(organizationId)) {
@@ -1159,14 +1157,12 @@ export class AdminPermissionChecker {
1159
1157
  if (this.checkScope(member.organizationId)) {
1160
1158
  organizations.push(await this.getOrganization(member.organizationId));
1161
1159
  }
1162
- }
1163
- else {
1160
+ } else {
1164
1161
  if (organizationId) {
1165
1162
  if (this.checkScope(organizationId)) {
1166
1163
  organizations.push(await this.getOrganization(organizationId));
1167
1164
  }
1168
- }
1169
- else {
1165
+ } else {
1170
1166
  for (const registration of member.registrations) {
1171
1167
  if (this.checkScope(registration.organizationId)) {
1172
1168
  if (!organizations.find(o => o.id === registration.organizationId)) {
@@ -1207,8 +1203,7 @@ export class AdminPermissionChecker {
1207
1203
  if (platformPermissions.hasAccessRight(AccessRight.OrganizationManagePayments)) {
1208
1204
  return true;
1209
1205
  }
1210
- }
1211
- else {
1206
+ } else {
1212
1207
  if (platformPermissions.hasAccessRight(level === PermissionLevel.Read ? AccessRight.MemberReadFinancialData : AccessRight.MemberWriteFinancialData)) {
1213
1208
  return true;
1214
1209
  }
@@ -1286,8 +1281,8 @@ export class AdminPermissionChecker {
1286
1281
  return {
1287
1282
  record,
1288
1283
  rootCategoryId: recordCategory.id,
1289
- organizationId: this.organization.id
1290
- }
1284
+ organizationId: this.organization.id,
1285
+ };
1291
1286
  }
1292
1287
  }
1293
1288
  }
@@ -1332,8 +1327,7 @@ export class AdminPermissionChecker {
1332
1327
  record: record.record,
1333
1328
  };
1334
1329
  }
1335
- }
1336
- else {
1330
+ } else {
1337
1331
  // ONLY check current scoped organization
1338
1332
  if (this.organization) {
1339
1333
  const organizationPermissions = await this.getOrganizationPermissions(this.organization.id);
@@ -1368,14 +1362,13 @@ export class AdminPermissionChecker {
1368
1362
  };
1369
1363
  }
1370
1364
 
1371
- private async loopRecordAnswerSettingsAccess<T extends RecordAnswer | AutoEncoderPatchType<RecordAnswer>>({member, level, recordAnswers, callback }:
1365
+ private async loopRecordAnswerSettingsAccess<T extends RecordAnswer | AutoEncoderPatchType<RecordAnswer>>({ member, level, recordAnswers, callback }:
1372
1366
  {
1373
- member: MemberWithUsersRegistrationsAndGroups,
1374
- level: PermissionLevel,
1375
- recordAnswers: PatchMap<string, T | null | undefined> | Map<string, T>
1376
- callback: (result: { canAccess: false; record: RecordSettings | null } | { canAccess: true; record: RecordSettings }, entry: [keys: string, value: T | null | undefined]) => void
1377
- }): Promise<void>
1378
- {
1367
+ member: MemberWithUsersRegistrationsAndGroups;
1368
+ level: PermissionLevel;
1369
+ recordAnswers: PatchMap<string, T | null | undefined> | Map<string, T>;
1370
+ callback: (result: { canAccess: false; record: RecordSettings | null } | { canAccess: true; record: RecordSettings }, entry: [keys: string, value: T | null | undefined]) => void;
1371
+ }): Promise<void> {
1379
1372
  if (STAMHOOFD.userMode !== 'platform') {
1380
1373
  let organization = this.organization;
1381
1374
 
@@ -1388,11 +1381,11 @@ export class AdminPermissionChecker {
1388
1381
  if (member.registrations.length === 0) {
1389
1382
  // no access to any records (theoretically a global admin should have access, but normally this case should not happen)
1390
1383
  for (const entry of recordAnswers.entries()) {
1391
- callback({canAccess: false, record: null}, entry);
1384
+ callback({ canAccess: false, record: null }, entry);
1392
1385
  }
1393
1386
  return;
1394
1387
  }
1395
-
1388
+
1396
1389
  // in userMode organization a member can only be linked to 1 organization
1397
1390
  organizationId = member.registrations[0].organizationId;
1398
1391
  }
@@ -1401,7 +1394,7 @@ export class AdminPermissionChecker {
1401
1394
  }
1402
1395
 
1403
1396
  const organizationId = organization.id;
1404
- const map = new Map<string, RecordCacheEntry>()
1397
+ const map = new Map<string, RecordCacheEntry>();
1405
1398
 
1406
1399
  // create map
1407
1400
  for (const category of organization.meta.recordsConfiguration.recordCategories) {
@@ -1415,7 +1408,7 @@ export class AdminPermissionChecker {
1415
1408
  });
1416
1409
  }
1417
1410
  }
1418
-
1411
+
1419
1412
  for (const entry of recordAnswers.entries()) {
1420
1413
  const key = entry[0];
1421
1414
  const cachedRecordEntry = map.get(key);
@@ -1425,11 +1418,11 @@ export class AdminPermissionChecker {
1425
1418
  record: cachedRecordEntry.record,
1426
1419
  organizationId: cachedRecordEntry.organizationId,
1427
1420
  rootCategoryId: cachedRecordEntry.rootCategoryId,
1428
- level
1421
+ level,
1429
1422
  });
1430
- callback({canAccess, record: cachedRecordEntry.record}, entry);
1423
+ callback({ canAccess, record: cachedRecordEntry.record }, entry);
1431
1424
  } else {
1432
- callback({canAccess: false, record: null}, entry);
1425
+ callback({ canAccess: false, record: null }, entry);
1433
1426
  }
1434
1427
  }
1435
1428
 
@@ -1437,7 +1430,7 @@ export class AdminPermissionChecker {
1437
1430
  }
1438
1431
 
1439
1432
  // userMode platform
1440
- for (const entry of recordAnswers.entries()) {
1433
+ for (const entry of recordAnswers.entries()) {
1441
1434
  const key = entry[0];
1442
1435
  const cachedRecordEntry = await MemberRecordStore.getRecord(key);
1443
1436
  if (cachedRecordEntry) {
@@ -1446,18 +1439,18 @@ export class AdminPermissionChecker {
1446
1439
  record: cachedRecordEntry.record,
1447
1440
  organizationId: cachedRecordEntry.organizationId,
1448
1441
  rootCategoryId: cachedRecordEntry.rootCategoryId,
1449
- level
1442
+ level,
1450
1443
  });
1451
- callback({canAccess, record: cachedRecordEntry.record}, entry);
1444
+ callback({ canAccess, record: cachedRecordEntry.record }, entry);
1452
1445
  } else {
1453
- callback({canAccess: false, record: null}, entry);
1446
+ callback({ canAccess: false, record: null }, entry);
1454
1447
  }
1455
1448
  }
1456
1449
  }
1457
1450
 
1458
- private async checkRecordAccess({member, level, record, organizationId, rootCategoryId}: {member: MemberWithUsersRegistrationsAndGroups, record: RecordSettings, organizationId: string | null, rootCategoryId: string, level: PermissionLevel}): Promise<boolean> {
1451
+ private async checkRecordAccess({ member, level, record, organizationId, rootCategoryId }: { member: MemberWithUsersRegistrationsAndGroups; record: RecordSettings; organizationId: string | null; rootCategoryId: string; level: PermissionLevel }): Promise<boolean> {
1459
1452
  if (!this.checkScope(organizationId)) {
1460
- return false
1453
+ return false;
1461
1454
  }
1462
1455
 
1463
1456
  const isUserManager = this.isUserManager(member);
@@ -1476,8 +1469,7 @@ export class AdminPermissionChecker {
1476
1469
  if (organizationPermissions && organizationPermissions.hasResourceAccess(PermissionsResourceType.RecordCategories, rootCategoryId, level)) {
1477
1470
  return true;
1478
1471
  }
1479
- }
1480
- else {
1472
+ } else {
1481
1473
  // Also check current scoped organization
1482
1474
  if (this.organization) {
1483
1475
  const organizationPermissions = await this.getOrganizationPermissions(this.organization.id);
@@ -1522,8 +1514,7 @@ export class AdminPermissionChecker {
1522
1514
  if (await this.canAccessRegistration(registration, level)) {
1523
1515
  return true;
1524
1516
  }
1525
- }
1526
- else {
1517
+ } else {
1527
1518
  checkedOrganizations.set(registration.organizationId, false);
1528
1519
  }
1529
1520
  }
@@ -1557,14 +1548,13 @@ export class AdminPermissionChecker {
1557
1548
  callback: ({ canAccess, record }, [key, value]) => {
1558
1549
  if (!canAccess) {
1559
1550
  cloned.details.recordAnswers.delete(key);
1560
- }
1561
- else {
1551
+ } else {
1562
1552
  if (value && RecordAnswerHelper.haveTypesSameClass(value.settings.type, record.type)) {
1563
1553
  // Force update
1564
1554
  value.settings = record;
1565
1555
  }
1566
1556
  }
1567
- }
1557
+ },
1568
1558
  });
1569
1559
 
1570
1560
  const isUserManager = this.isUserManager(member);
@@ -1671,14 +1661,12 @@ export class AdminPermissionChecker {
1671
1661
  if (data.details.uitpasNumberDetails && data.details.uitpasNumberDetails.socialTariff !== undefined) {
1672
1662
  if (data.details.uitpasNumberDetails.uitpasNumber === undefined) {
1673
1663
  data.details.uitpasNumberDetails = undefined;
1674
- }
1675
- else if (data.details.uitpasNumberDetails.uitpasNumber !== member.details.uitpasNumberDetails?.uitpasNumber) {
1664
+ } else if (data.details.uitpasNumberDetails.uitpasNumber !== member.details.uitpasNumberDetails?.uitpasNumber) {
1676
1665
  // if uitpas number did change -> status should be reset
1677
1666
  data.details.uitpasNumberDetails = UitpasNumberDetails.create({
1678
1667
  uitpasNumber: data.details.uitpasNumberDetails.uitpasNumber,
1679
1668
  });
1680
- }
1681
- else {
1669
+ } else {
1682
1670
  // if uitpas number did not change
1683
1671
  data.details.uitpasNumberDetails.socialTariff = member.details.uitpasNumberDetails?.socialTariff;
1684
1672
  }
@@ -1697,7 +1685,7 @@ export class AdminPermissionChecker {
1697
1685
  member,
1698
1686
  level: PermissionLevel.Write,
1699
1687
  recordAnswers: data.details.recordAnswers,
1700
- callback: ({canAccess, record}, [_key, value]) => {
1688
+ callback: ({ canAccess, record }, [_key, value]) => {
1701
1689
  if (!canAccess) {
1702
1690
  throw new SimpleError({
1703
1691
  code: 'permission_denied',
@@ -1710,8 +1698,8 @@ export class AdminPermissionChecker {
1710
1698
  if (value) {
1711
1699
  value.settings = record;
1712
1700
  }
1713
- }
1714
- })
1701
+ },
1702
+ });
1715
1703
  }
1716
1704
 
1717
1705
  const isUserManager = this.isUserManager(member);
@@ -1739,7 +1727,7 @@ export class AdminPermissionChecker {
1739
1727
  }
1740
1728
  return null;
1741
1729
  });
1742
-
1730
+
1743
1731
  const preventSelfAssignment = financialSupportSettings?.preventSelfAssignment === true;
1744
1732
 
1745
1733
  if (preventSelfAssignment) {
@@ -1755,8 +1743,7 @@ export class AdminPermissionChecker {
1755
1743
  if (data.details.requiresFinancialSupport) {
1756
1744
  if (isUserManager) {
1757
1745
  // Already handled
1758
- }
1759
- else {
1746
+ } else {
1760
1747
  throw new SimpleError({
1761
1748
  code: 'permission_denied',
1762
1749
  message: 'Je hebt geen toegangsrechten om de financiële status van dit lid aan te passen',
@@ -2,7 +2,8 @@ import { SimpleError } from '@simonbackx/simple-errors';
2
2
  import type { AuditLog, Document, EventNotification, MemberWithUsersRegistrationsAndGroups, Order, Ticket } from '@stamhoofd/models';
3
3
  import { BalanceItem, CachedBalance, Event, Group, Invoice, Member, MemberPlatformMembership, MemberResponsibilityRecord, Organization, OrganizationRegistrationPeriod, Payment, Registration, RegistrationInvitation, RegistrationPeriod, User, Webshop } from '@stamhoofd/models';
4
4
  import type { PaymentGeneral } from '@stamhoofd/structures';
5
- import { AuditLogReplacement, AuditLogReplacementType, AuditLog as AuditLogStruct, BalanceItem as BalanceItemStruct, DetailedReceivableBalance, Document as DocumentStruct, EventNotification as EventNotificationStruct, Event as EventStruct, GenericBalance, Group as GroupStruct, GroupType, InvitationGroupData, InvitationMemberData, InvoicedBalanceItem, InvoiceStruct, MemberPlatformMembership as MemberPlatformMembershipStruct, MemberRegistrationInvitation, MembersBlob, MemberWithRegistrationsBlob, NamedObject, OrganizationRegistrationPeriod as OrganizationRegistrationPeriodStruct, Organization as OrganizationStruct, PaymentCustomer, PermissionLevel, Platform, PrivateOrder, PrivateWebshop, ReceivableBalanceObject, ReceivableBalanceObjectContact, ReceivableBalance as ReceivableBalanceStruct, ReceivableBalanceType, RegistrationInvitation as RegistrationInvitationStruct, RegistrationsBlob, RegistrationWithMemberBlob, TicketPrivate, UserWithMembers, WebshopPreview, Webshop as WebshopStruct } from '@stamhoofd/structures';
5
+ import { BaseOrganization, getAppHost } from '@stamhoofd/structures';
6
+ import { Payment as PaymentStruct, AuditLogReplacement, AuditLogReplacementType, AuditLog as AuditLogStruct, BalanceItem as BalanceItemStruct, DetailedReceivableBalance, Document as DocumentStruct, EventNotification as EventNotificationStruct, Event as EventStruct, GenericBalance, Group as GroupStruct, GroupType, InvitationGroupData, InvitationMemberData, InvoicedBalanceItem, InvoiceStruct, MemberPlatformMembership as MemberPlatformMembershipStruct, MemberRegistrationInvitation, MembersBlob, MemberWithRegistrationsBlob, NamedObject, OrganizationRegistrationPeriod as OrganizationRegistrationPeriodStruct, Organization as OrganizationStruct, PaymentCustomer, PermissionLevel, Platform, PrivateOrder, PrivateWebshop, ReceivableBalanceObject, ReceivableBalanceObjectContact, ReceivableBalance as ReceivableBalanceStruct, ReceivableBalanceType, RegistrationInvitation as RegistrationInvitationStruct, RegistrationsBlob, RegistrationWithMemberBlob, TicketPrivate, UserWithMembers, WebshopPreview, Webshop as WebshopStruct } from '@stamhoofd/structures';
6
7
  import { Sorter } from '@stamhoofd/utility';
7
8
 
8
9
  import { SQL } from '@stamhoofd/sql';
@@ -55,6 +56,22 @@ export class AuthenticatedStructures {
55
56
  }, includeSettlements);
56
57
  }
57
58
 
59
+ /**
60
+ *
61
+ * @param payments
62
+ * @param checkPermissions Only set to undefined when not returned in the API + not for public use
63
+ * @returns
64
+ */
65
+ static async payments(payments: Payment[]): Promise<PaymentStruct[]> {
66
+ if (payments.length === 0) {
67
+ return [];
68
+ }
69
+
70
+ return payments.map((p) => {
71
+ return PaymentStruct.create(p);
72
+ });
73
+ }
74
+
58
75
  static async invoices(invoices: Invoice[]): Promise<InvoiceStruct[]> {
59
76
  if (invoices.length === 0) {
60
77
  return [];
@@ -92,8 +109,7 @@ export class AuthenticatedStructures {
92
109
 
93
110
  if (existingGroup) {
94
111
  waitingLists.push(existingGroup);
95
- }
96
- else {
112
+ } else {
97
113
  waitingListsToFetch.push(waitingListId);
98
114
  }
99
115
  }
@@ -159,13 +175,11 @@ export class AuthenticatedStructures {
159
175
  .where(whereGroupIds)
160
176
  .orWhere(whereWaitingList)
161
177
  .fetch();
162
- }
163
- else {
178
+ } else {
164
179
  groups = await Group.select()
165
180
  .where(whereGroupIds).fetch();
166
181
  }
167
- }
168
- else if (organizationIds.length && periodIds.length) {
182
+ } else if (organizationIds.length && periodIds.length) {
169
183
  groups = await Group.select()
170
184
  .where(whereWaitingList)
171
185
  .fetch();
@@ -222,6 +236,16 @@ export class AuthenticatedStructures {
222
236
  return WebshopPreview.create(webshop);
223
237
  }
224
238
 
239
+ static async baseOrganizations(organizations: Organization[]): Promise<BaseOrganization[]> {
240
+ if (organizations.length === 0) {
241
+ return [];
242
+ }
243
+
244
+ return organizations.map((o) => {
245
+ return BaseOrganization.create(o);
246
+ });
247
+ }
248
+
225
249
  static async organizations(organizations: Organization[]): Promise<OrganizationStruct[]> {
226
250
  if (organizations.length === 0) {
227
251
  return [];
@@ -235,8 +259,7 @@ export class AuthenticatedStructures {
235
259
  const array = periodIdOrganizationsMap.get(periodId);
236
260
  if (array !== undefined) {
237
261
  array.push(organization);
238
- }
239
- else {
262
+ } else {
240
263
  periodIdOrganizationsMap.set(periodId, [organization]);
241
264
  }
242
265
  }
@@ -287,8 +310,7 @@ export class AuthenticatedStructures {
287
310
  organizationIdsToGetWebshopsFor.push(organization.id);
288
311
  }
289
312
  organizationData.set(organizationId, { organizationRegistrationPeriod, canAccessPrivateData });
290
- }
291
- else {
313
+ } else {
292
314
  // Should never happen
293
315
  throw new Error('Organization registration period model not found for organization id ' + organizationId + ' and period id ' + periodId);
294
316
  }
@@ -298,14 +320,14 @@ export class AuthenticatedStructures {
298
320
  // Get webshop previews
299
321
  const webshops = organizationIdsToGetWebshopsFor.length > 0
300
322
  ? await Webshop.where(
301
- {
302
- organizationId: {
303
- sign: 'IN',
304
- value: organizationIdsToGetWebshopsFor,
323
+ {
324
+ organizationId: {
325
+ sign: 'IN',
326
+ value: organizationIdsToGetWebshopsFor,
327
+ },
305
328
  },
306
- },
307
- { select: Webshop.selectColumnsWithout(undefined, 'products', 'categories') },
308
- )
329
+ { select: Webshop.selectColumnsWithout(undefined, 'products', 'categories') },
330
+ )
309
331
  : [];
310
332
 
311
333
  const webshopPreviews = new Map<string, WebshopPreview[]>();
@@ -321,8 +343,7 @@ export class AuthenticatedStructures {
321
343
 
322
344
  if (array) {
323
345
  array.push(preview);
324
- }
325
- else {
346
+ } else {
326
347
  webshopPreviews.set(organizationId, [preview]);
327
348
  }
328
349
  }
@@ -356,8 +377,7 @@ export class AuthenticatedStructures {
356
377
  privateMeta: organization.privateMeta.removedPrivateKeys,
357
378
  webshops: webshopPreviews.get(organization.id)?.sort((a, b) => Sorter.byDateValue(b.createdAt, a.createdAt)),
358
379
  });
359
- }
360
- else {
380
+ } else {
361
381
  result = OrganizationStruct.create({
362
382
  ...baseStruct,
363
383
  period,
@@ -447,21 +467,22 @@ export class AuthenticatedStructures {
447
467
  // Load responsibilities
448
468
  const responsibilities = members.length > 0
449
469
  ? await MemberResponsibilityRecord.select()
450
- .where('memberId', members.map(m => m.id))
451
- .where(SQL.where('endDate', null).or('endDate', '>', new Date()))
452
- .fetch()
470
+ .where('memberId', members.map(m => m.id))
471
+ .where(SQL.where('endDate', null).or('endDate', '>', new Date()))
472
+ .fetch()
453
473
  : [];
454
474
  const platformMemberships = members.length > 0
455
475
  ? await MemberPlatformMembership.select()
456
- .where('memberId', members.map(m => m.id))
457
- .where('deletedAt', null)
458
- .where('periodId', relevantPeriodIds)
459
- .fetch()
476
+ .where('memberId', members.map(m => m.id))
477
+ .where('deletedAt', null)
478
+ .where('periodId', relevantPeriodIds)
479
+ .fetch()
460
480
  : [];
461
481
  const registrationInvitations = members.length > 0
462
482
  ? await RegistrationInvitation.select()
463
- .where('memberId', members.map(m => m.id))
464
- .fetch() : [];
483
+ .where('memberId', members.map(m => m.id))
484
+ .fetch()
485
+ : [];
465
486
 
466
487
  const memberRegistrationInvitations: Map<string, MemberRegistrationInvitation[]> = registrationInvitations.length > 0 ? await this.memberRegistrationInvitations(registrationInvitations) : new Map();
467
488
 
@@ -646,8 +667,7 @@ export class AuthenticatedStructures {
646
667
  const g = allGroups.get(r.groupId);
647
668
  if (g) {
648
669
  base.group = g;
649
- }
650
- else {
670
+ } else {
651
671
  console.error('Group not preloaded for registration', r.id, r.groupId);
652
672
  }
653
673
 
@@ -782,8 +802,7 @@ export class AuthenticatedStructures {
782
802
  const array = eventIdsMapping.get(notificationId);
783
803
  if (array) {
784
804
  array.push(eventId);
785
- }
786
- else {
805
+ } else {
787
806
  eventIdsMapping.set(notificationId, [eventId]);
788
807
  }
789
808
 
@@ -942,7 +961,7 @@ export class AuthenticatedStructures {
942
961
  return (await this.receivableBalancesHelper(balances)).map(({ balance, object }) => ReceivableBalanceStruct.create({ ...balance, object }));
943
962
  }
944
963
 
945
- private static async receivableBalancesHelper(balances: CachedBalance[]): Promise< { balance: CachedBalance; object: ReceivableBalanceObject }[]> {
964
+ private static async receivableBalancesHelper(balances: CachedBalance[]): Promise<{ balance: CachedBalance; object: ReceivableBalanceObject }[]> {
946
965
  if (balances.length === 0) {
947
966
  return [];
948
967
  }
@@ -979,7 +998,7 @@ export class AuthenticatedStructures {
979
998
  const result: { balance: CachedBalance; object: ReceivableBalanceObject }[] = [];
980
999
 
981
1000
  function getMemberContacts(member: Member, balance: CachedBalance) {
982
- const url = Context.organization && Context.organization.id === balance.organizationId ? 'https://' + Context.organization.getHost() : '';
1001
+ const url = Context.organization && Context.organization.id === balance.organizationId ? 'https://' + getAppHost('registration', Context.organization, false) : '';
983
1002
  return [
984
1003
  ...(member.details.getMemberEmails().length
985
1004
  ? [
@@ -1072,8 +1091,7 @@ export class AuthenticatedStructures {
1072
1091
  })),
1073
1092
  });
1074
1093
  }
1075
- }
1076
- else if (balance.objectType === ReceivableBalanceType.member) {
1094
+ } else if (balance.objectType === ReceivableBalanceType.member) {
1077
1095
  const member = members.find(m => m.id === balance.objectId) ?? null;
1078
1096
  if (member) {
1079
1097
  object = ReceivableBalanceObject.create({
@@ -1083,8 +1101,7 @@ export class AuthenticatedStructures {
1083
1101
  contacts: getMemberContacts(member, balance),
1084
1102
  });
1085
1103
  }
1086
- }
1087
- else if (balance.objectType === ReceivableBalanceType.registration) {
1104
+ } else if (balance.objectType === ReceivableBalanceType.registration) {
1088
1105
  const registration = registrations.find(r => r.id === balance.objectId) ?? null;
1089
1106
  if (!registration) {
1090
1107
  continue;
@@ -1098,11 +1115,10 @@ export class AuthenticatedStructures {
1098
1115
  contacts: getMemberContacts(member, balance),
1099
1116
  });
1100
1117
  }
1101
- }
1102
- else if (balance.objectType === ReceivableBalanceType.user || balance.objectType === ReceivableBalanceType.userWithoutMembers) {
1118
+ } else if (balance.objectType === ReceivableBalanceType.user || balance.objectType === ReceivableBalanceType.userWithoutMembers) {
1103
1119
  const user = users.find(m => m.id === balance.objectId) ?? null;
1104
1120
  if (user) {
1105
- const url = Context.organization && Context.organization.id === balance.organizationId ? 'https://' + Context.organization.getHost() : '';
1121
+ const url = Context.organization && Context.organization.id === balance.organizationId ? 'https://' + getAppHost('registration', Context.organization, user.permissions?.forOrganization(Context.organization)?.isEmpty === false) : '';
1106
1122
  object = ReceivableBalanceObject.create({
1107
1123
  id: balance.objectId,
1108
1124
  name: user.name || user.email,
@@ -1176,15 +1192,13 @@ export class AuthenticatedStructures {
1176
1192
  id: '',
1177
1193
  name: $t(`%wi`) + ' ' + Platform.shared.config.name,
1178
1194
  });
1179
- }
1180
- else {
1195
+ } else {
1181
1196
  userStruct = NamedObject.create({
1182
1197
  id: '',
1183
1198
  name: $t(`%Gr`),
1184
1199
  });
1185
1200
  }
1186
- }
1187
- else {
1201
+ } else {
1188
1202
  userStruct = NamedObject.create({
1189
1203
  id: user.id,
1190
1204
  name: (user.firstName || user.lastName) ? (user.firstName + ' ' + user.lastName) : user.email,
@@ -1239,7 +1253,7 @@ export class AuthenticatedStructures {
1239
1253
  code: 'group_not_found',
1240
1254
  message: 'Group not found',
1241
1255
  human: $t(`%1SM`),
1242
- })
1256
+ });
1243
1257
  }
1244
1258
 
1245
1259
  const result = MemberRegistrationInvitation.create({
@@ -1251,8 +1265,8 @@ export class AuthenticatedStructures {
1251
1265
  periodId: group.periodId,
1252
1266
  }),
1253
1267
  organizationId: invitation.organizationId,
1254
- createdAt: invitation.createdAt
1255
- })
1268
+ createdAt: invitation.createdAt,
1269
+ });
1256
1270
 
1257
1271
  let array = results.get(invitation.memberId);
1258
1272
  if (!array) {
@@ -1277,7 +1291,7 @@ export class AuthenticatedStructures {
1277
1291
  code: 'member_not_found',
1278
1292
  message: 'Member not found',
1279
1293
  human: $t(`%EO`),
1280
- })
1294
+ });
1281
1295
  }
1282
1296
 
1283
1297
  const group = groups.find(g => g.id === invitation.groupId);
@@ -1286,7 +1300,7 @@ export class AuthenticatedStructures {
1286
1300
  code: 'group_not_found',
1287
1301
  message: 'Group not found',
1288
1302
  human: $t(`%1SM`),
1289
- })
1303
+ });
1290
1304
  }
1291
1305
 
1292
1306
  return RegistrationInvitationStruct.create({
@@ -1295,7 +1309,7 @@ export class AuthenticatedStructures {
1295
1309
  id: group.id,
1296
1310
  name: group.settings.name,
1297
1311
  type: group.type,
1298
- periodId: group.periodId
1312
+ periodId: group.periodId,
1299
1313
  }),
1300
1314
  organizationId: invitation.organizationId,
1301
1315
  member: InvitationMemberData.create({
@@ -1304,7 +1318,7 @@ export class AuthenticatedStructures {
1304
1318
  lastName: member.lastName,
1305
1319
  birthDay: member.details.birthDay,
1306
1320
  }),
1307
- createdAt: invitation.createdAt
1321
+ createdAt: invitation.createdAt,
1308
1322
  });
1309
1323
  });
1310
1324
  }