@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
@@ -0,0 +1,176 @@
1
+ import { registerCron } from '@stamhoofd/crons';
2
+ import { BalanceItem, Organization, Payment, Platform } from '@stamhoofd/models';
3
+ import { SQL } from '@stamhoofd/sql';
4
+ import type { PaymentProvider } from '@stamhoofd/structures';
5
+ import { BalanceItemRelation, BalanceItemRelationType, BalanceItemStatus, BalanceItemType, getPaymentProviderName, PaymentMethod, PaymentStatus, TranslatedString } from '@stamhoofd/structures';
6
+ import { Formatter } from '@stamhoofd/utility';
7
+ import { BalanceItemService } from '../services/BalanceItemService.js';
8
+ import { PaymentService } from '../services/PaymentService.js';
9
+ import { VATService } from '../services/VATService.js';
10
+
11
+ // Charge manual service fees every night
12
+ registerCron('transfer-fees', chargeTransferFees);
13
+
14
+ async function chargeTransferFees() {
15
+ if (STAMHOOFD.environment !== 'development' && (new Date().getHours() > 5 || new Date().getHours() < 2)) {
16
+ return;
17
+ }
18
+ const membershipOrganizationId = (await Platform.getShared()).membershipOrganizationId;
19
+ if (!membershipOrganizationId) {
20
+ return;
21
+ }
22
+
23
+ const membershipOrganization = await Organization.getByID(membershipOrganizationId, true);
24
+
25
+ // Succeeded payments
26
+ const payments = await Payment.select()
27
+ .where('status', PaymentStatus.Succeeded)
28
+ .where('transferFeeManual', '>', 0)
29
+ .where('transferFeeManualCharged', 0)
30
+ .where('createdAt', '<', STAMHOOFD.environment !== 'development' ? new Date() : Formatter.dateIso(new Date(Date.now() + 1000 * 60 * 60 * 24)))
31
+ .limit(200)
32
+ .orderBy('createdAt', 'ASC')
33
+ .fetch();
34
+
35
+ // Pending payments older than 14 days with method = Transfer or PointOfSale
36
+ const pendingPayments = await Payment.select()
37
+ .where('status', [PaymentStatus.Pending, PaymentStatus.Created])
38
+ .where('method', [PaymentMethod.Transfer, PaymentMethod.PointOfSale, PaymentMethod.Unknown])
39
+ .where('transferFeeManual', '>', 0)
40
+ .where('transferFeeManualCharged', 0)
41
+ .where('createdAt', '<', Formatter.dateIso(new Date(Date.now() - 1000 * 60 * 60 * 24 * 14)))
42
+ .limit(200)
43
+ .orderBy('createdAt', 'ASC')
44
+ .fetch();
45
+
46
+ const allPayments = [...payments, ...pendingPayments];
47
+
48
+ console.log('Found ' + allPayments.length + ' payments to charge service fees for');
49
+
50
+ const mappedToOrganizationId = new Map<string, Payment[]>();
51
+ for (const payment of allPayments) {
52
+ if (!payment.organizationId) {
53
+ console.warn('Payment without organizationId, skipping', payment.id);
54
+ continue;
55
+ }
56
+ if (!mappedToOrganizationId.has(payment.organizationId)) {
57
+ mappedToOrganizationId.set(payment.organizationId, []);
58
+ }
59
+ mappedToOrganizationId.get(payment.organizationId)!.push(payment);
60
+ }
61
+
62
+ for (const [organizationId, payments] of mappedToOrganizationId.entries()) {
63
+ const organization = await Organization.getByID(organizationId);
64
+ if (!organization) {
65
+ console.warn('Organization not found for ID', organizationId);
66
+ continue;
67
+ }
68
+
69
+ // Group payments by Formatter.dateNumber(p.createdAt)
70
+ const groupedPayments: Map<string, Payment[]> = new Map();
71
+ for (const payment of payments) {
72
+ const date = Formatter.dateNumber(payment.createdAt);
73
+ if (!groupedPayments.has(date)) {
74
+ groupedPayments.set(date, []);
75
+ }
76
+ groupedPayments.get(date)!.push(payment);
77
+ }
78
+
79
+ for (const [_, payments] of groupedPayments) {
80
+ const totalFees = payments.reduce((sum, payment) => sum + payment.transferFeeManual - payment.transferFeeManualCharged, 0);
81
+ const groupedByDate = new Map<string, Payment[]>();
82
+
83
+ for (const p of payments) {
84
+ const date = Formatter.dateNumber(p.createdAt);
85
+ const existing = groupedByDate.get(date);
86
+ if (existing) {
87
+ existing.push(p);
88
+ } else {
89
+ groupedByDate.set(date, [p]);
90
+ }
91
+ }
92
+
93
+ for (const [day, payments] of groupedByDate) {
94
+ const groupedByProvider = new Map<PaymentProvider | null, Payment[]>();
95
+
96
+ for (const p of payments) {
97
+ const provider = p.provider;
98
+ const existing = groupedByProvider.get(provider);
99
+ if (existing) {
100
+ existing.push(p);
101
+ } else {
102
+ groupedByProvider.set(provider, [p]);
103
+ }
104
+ }
105
+
106
+ for (const [provider, payments] of groupedByProvider) {
107
+ const date = new Date(Math.min(...payments.map(p => p.createdAt.getTime())));
108
+ const startOfDay = Formatter.luxon(date).startOf('day').toJSDate();
109
+ const endOfDay = Formatter.luxon(date).endOf('day').toJSDate();
110
+
111
+ // Ms don't work when querying MySQL, they get lost
112
+ startOfDay.setMilliseconds(0);
113
+ endOfDay.setMilliseconds(0);
114
+
115
+ const item = new BalanceItem();
116
+ item.type = BalanceItemType.TransferFee;
117
+ item.description = $t('%1Yq', { date: day });
118
+
119
+ if (provider) {
120
+ item.relations.set(BalanceItemRelationType.PaymentProvider, BalanceItemRelation.create({
121
+ id: provider,
122
+ name: TranslatedString.create(getPaymentProviderName(provider)),
123
+ }));
124
+ }
125
+
126
+ item.payingOrganizationId = organization.id;
127
+ item.organizationId = membershipOrganizationId;
128
+ item.VATPercentage = 21;
129
+ item.VATExcempt = VATService.getVATExcempt({
130
+ company: organization.defaultCompanies[0] ?? null,
131
+ sellingOrganization: membershipOrganization,
132
+ type: 'services',
133
+ });
134
+ item.VATIncluded = false;
135
+ item.quantity = 1;
136
+ item.unitPrice = totalFees;
137
+ item.createdAt = new Date();
138
+ item.status = BalanceItemStatus.Due;
139
+ item.startDate = startOfDay;
140
+ item.endDate = endOfDay;
141
+
142
+ // Check if we find an existing one
143
+ const existingAll = await BalanceItem.select()
144
+ .where('type', BalanceItemType.TransferFee)
145
+ .where('organizationId', membershipOrganizationId)
146
+ .where('VATPercentage', item.VATPercentage)
147
+ .where('VATIncluded', item.VATIncluded)
148
+ .where('VATExcempt', item.VATExcempt)
149
+ .where('payingOrganizationId', organization.id)
150
+ .where('status', BalanceItemStatus.Due)
151
+ .where('startDate', startOfDay)
152
+ .where('endDate', endOfDay)
153
+ .fetch();
154
+ const existing = provider ? existingAll.find(e => e.relations.get(BalanceItemRelationType.PaymentProvider)?.id === provider) : existingAll.find(e => !e.relations.has(BalanceItemRelationType.PaymentProvider));
155
+
156
+ if (existing) {
157
+ existing.unitPrice += totalFees;
158
+ await existing.save();
159
+ BalanceItemService.scheduleUpdate(existing);
160
+ } else {
161
+ await item.save();
162
+ BalanceItemService.scheduleUpdate(item);
163
+ }
164
+
165
+ const { changedRows } = await Payment.update()
166
+ .where('id', payments.map(p => p.id))
167
+ .set('transferFeeManualCharged', SQL.column('transferFeeManual'))
168
+ .update();
169
+ if (changedRows !== payments.length) {
170
+ console.error('Unexpected change in transferFeeManualCharged. Expected ' + payments.length + ', updated only ' + changedRows);
171
+ }
172
+ }
173
+ }
174
+ }
175
+ }
176
+ }
@@ -17,10 +17,10 @@ async function updateCachedBalances() {
17
17
  * Cached balances of member should be updated before the cached balances of the user
18
18
  * because the cached balances of the user are dependent on the cached balances of the member.
19
19
  */
20
- .orderBy('objectType', 'ASC')
20
+ .orderBy('objectType', 'ASC')
21
21
  // minimize the number of queries when updating
22
- .orderBy('organizationId', 'ASC')
23
- .limit(100).fetch();
22
+ .orderBy('organizationId', 'ASC')
23
+ .limit(100).fetch();
24
24
 
25
25
  // Group by object type, next by organization id
26
26
  const grouped = new Map<ReceivableBalanceType, Map<string, CachedBalance[]>>();
@@ -51,7 +51,7 @@ async function updateCachedBalances() {
51
51
  const bIsMember = b[0] === ReceivableBalanceType.member;
52
52
  if (aIsMember && !bIsMember) return -1;
53
53
  if (!aIsMember && bIsMember) return 1;
54
- return 0;
54
+ return 0;
55
55
  });
56
56
 
57
57
  for (const [objectType, organizationMap] of objectTypeMemberFirst) {
package/src/crons.ts CHANGED
@@ -1,9 +1,8 @@
1
1
  import { Database } from '@simonbackx/simple-database';
2
+ import { registerCron } from '@stamhoofd/crons';
2
3
  import { Group, Organization, Payment, Registration, STPackage, Webshop } from '@stamhoofd/models';
3
- import { PaymentMethod, PaymentProvider, PaymentStatus } from '@stamhoofd/structures';
4
- import { Formatter } from '@stamhoofd/utility';
5
4
  import { SQL } from '@stamhoofd/sql';
6
- import { registerCron } from '@stamhoofd/crons';
5
+ import { PaymentMethod, PaymentProvider, PaymentStatus } from '@stamhoofd/structures';
7
6
  import { checkSettlements } from './helpers/CheckSettlements.js';
8
7
  import { PaymentService } from './services/PaymentService.js';
9
8
  import { RegistrationService } from './services/RegistrationService.js';
@@ -41,8 +40,7 @@ async function checkDNS() {
41
40
  }
42
41
  try {
43
42
  await organization.updateDNSRecords();
44
- }
45
- catch (e) {
43
+ } catch (e) {
46
44
  console.error(e);
47
45
  }
48
46
  }
@@ -229,8 +227,7 @@ async function doCheckPayments(payments: Payment[]) {
229
227
  await PaymentService.pollStatus(payment.id, organization);
230
228
  continue;
231
229
  }
232
- }
233
- else {
230
+ } else {
234
231
  // deprecated
235
232
  }
236
233
 
@@ -240,8 +237,7 @@ async function doCheckPayments(payments: Payment[]) {
240
237
  payment.status = PaymentStatus.Failed;
241
238
  await payment.save();
242
239
  }
243
- }
244
- catch (e) {
240
+ } catch (e) {
245
241
  console.error(e);
246
242
  }
247
243
  }
@@ -303,8 +299,7 @@ async function checkFailedBuckarooPayments() {
303
299
  continue;
304
300
  }
305
301
  }
306
- }
307
- catch (e) {
302
+ } catch (e) {
308
303
  console.error(e);
309
304
  }
310
305
  }
@@ -312,8 +307,7 @@ async function checkFailedBuckarooPayments() {
312
307
  if (payments.length === 0) {
313
308
  didCheckBuckaroo = true;
314
309
  lastBuckarooId = '';
315
- }
316
- else {
310
+ } else {
317
311
  lastBuckarooId = payments[payments.length - 1].id;
318
312
  }
319
313
  }
@@ -361,56 +355,6 @@ async function checkReservedUntil() {
361
355
  }
362
356
  }
363
357
 
364
- let lastDripCheck: Date | null = null;
365
- let lastDripId = '';
366
- async function checkDrips() {
367
- if (STAMHOOFD.environment === 'development') {
368
- return;
369
- }
370
-
371
- if (STAMHOOFD.userMode === 'platform') {
372
- return;
373
- }
374
-
375
- if (lastDripCheck && lastDripCheck > new Date(new Date().getTime() - 6 * 60 * 60 * 1000)) {
376
- console.log('Skip Drip check');
377
- return;
378
- }
379
-
380
- // Only send emails between 8:00 - 18:00 CET
381
- const CETTime = Formatter.timeIso(new Date());
382
- if ((CETTime < '08:00' || CETTime > '18:00') && STAMHOOFD.environment === 'production') {
383
- console.log('Skip Drip check: outside hours');
384
- return;
385
- }
386
-
387
- const organizations = await Organization.where({ id: { sign: '>', value: lastDripId } }, {
388
- limit: STAMHOOFD.environment === 'production' ? 30 : 100,
389
- sort: ['id'],
390
- });
391
-
392
- if (organizations.length == 0) {
393
- // Wait before starting again
394
- lastDripId = '';
395
- lastDripCheck = new Date();
396
- return;
397
- }
398
-
399
- console.log('Checking drips...');
400
-
401
- for (const organization of organizations) {
402
- console.log(organization.name);
403
- try {
404
- await organization.checkDrips();
405
- }
406
- catch (e) {
407
- console.error(e);
408
- }
409
- }
410
-
411
- lastDripId = organizations[organizations.length - 1].id;
412
- }
413
-
414
358
  registerCron('checkSettlements', checkSettlements);
415
359
  registerCron('checkExpirationEmails', checkExpirationEmails);
416
360
  registerCron('checkReservedUntil', checkReservedUntil);
@@ -419,7 +363,6 @@ registerCron('checkWebshopDNS', checkWebshopDNS);
419
363
  registerCron('checkPayments', checkPayments);
420
364
  registerCron('checkOldPayments', checkOldPayments);
421
365
  registerCron('checkOldDirectDebitPayments', checkOldDirectDebitPayments);
422
- registerCron('checkDrips', checkDrips);
423
366
 
424
367
  // Register other crons
425
368
  import './crons/index.js';
package/src/debug.ts CHANGED
@@ -10,8 +10,10 @@ import { SQLLogger } from '@stamhoofd/sql';
10
10
  import { ContextInstance } from './helpers/Context.js';
11
11
 
12
12
  export function loadDebugFunctions({ routerServer }: { routerServer: RouterServer }) {
13
- SQLLogger.slowQueryThresholdMs = 75;
14
- SQLLogger.explainAllAndLogInefficient = true;
13
+ if (process.env.LOG_SLOW_QUERIES) {
14
+ SQLLogger.slowQueryThresholdMs = 75;
15
+ SQLLogger.explainAllAndLogInefficient = true;
16
+ }
15
17
 
16
18
  if (process.env.LOG_REQUEST_QUERIES) {
17
19
  loadRequestQueries({ routerServer });
@@ -1,6 +1,6 @@
1
1
  import { Email, Member } from '@stamhoofd/models';
2
2
  import { SQL } from '@stamhoofd/sql';
3
- import type { LimitedFilteredRequest} from '@stamhoofd/structures';
3
+ import type { LimitedFilteredRequest } from '@stamhoofd/structures';
4
4
  import { EmailRecipient, EmailRecipientFilterType, PaginatedResponse, Replacement } from '@stamhoofd/structures';
5
5
  import { GetDocumentsEndpoint } from '../endpoints/organization/dashboard/documents/GetDocumentsEndpoint.js';
6
6
 
@@ -1,6 +1,6 @@
1
1
  import { Email } from '@stamhoofd/models';
2
2
  import { SQL } from '@stamhoofd/sql';
3
- import type { EmailRecipient, LimitedFilteredRequest, MembersBlob} from '@stamhoofd/structures';
3
+ import type { EmailRecipient, LimitedFilteredRequest, MembersBlob } from '@stamhoofd/structures';
4
4
  import { EmailRecipientFilterType, PaginatedResponse, mergeFilters } from '@stamhoofd/structures';
5
5
  import { GetMembersEndpoint } from '../endpoints/global/members/GetMembersEndpoint.js';
6
6
 
@@ -1,4 +1,4 @@
1
- import type { RecipientLoader} from '@stamhoofd/models';
1
+ import type { RecipientLoader } from '@stamhoofd/models';
2
2
  import { BalanceItem, BalanceItemPayment, Email, Member, MemberResponsibilityRecord, Order, Organization, Payment, User, Webshop } from '@stamhoofd/models';
3
3
  import { compileToSQLFilter, SQL } from '@stamhoofd/sql';
4
4
  import type { LimitedFilteredRequest, PaymentGeneral, StamhoofdFilter } from '@stamhoofd/structures';
@@ -206,8 +206,7 @@ async function getRecipients(result: PaginatedResponse<PaymentGeneral[], Limited
206
206
  recipients.push(...await getUserRecipients(userIds, replacementOptions));
207
207
  recipients.push(...await getMemberRecipients(memberIds, replacementOptions));
208
208
  recipients.push(...await getOrderRecipients(orderIds, replacementOptions));
209
- }
210
- else {
209
+ } else {
211
210
  recipients.push(...await getOrganizationRecipients(organizationIds, replacementOptions, subFilter));
212
211
  }
213
212
 
@@ -273,8 +272,7 @@ async function getMembersForOrganizations(organizationIds: string[], filter: Sta
273
272
  const membersForOrganization = result.get(organizationId);
274
273
  if (membersForOrganization) {
275
274
  membersForOrganization.push(member);
276
- }
277
- else {
275
+ } else {
278
276
  result.set(organizationId, [member]);
279
277
  }
280
278
  }
@@ -301,7 +299,7 @@ async function getOrganizationRecipients(ids: { organizationId: string; payment:
301
299
 
302
300
  if (subFilter === null) {
303
301
  // Use full admins instead
304
- const admins = await User.getAdmins(allOrganizationIds, {verified: true});
302
+ const admins = await User.getAdmins(allOrganizationIds, { verified: true });
305
303
  for (const { organizationId, payment } of ids) {
306
304
  const organization = organizationMap.get(organizationId);
307
305
  if (!organization) {
@@ -1,6 +1,6 @@
1
1
  import { Email, Member } from '@stamhoofd/models';
2
2
  import { SQL } from '@stamhoofd/sql';
3
- import type { EmailRecipient, LimitedFilteredRequest, RegistrationsBlob} from '@stamhoofd/structures';
3
+ import type { EmailRecipient, LimitedFilteredRequest, RegistrationsBlob } from '@stamhoofd/structures';
4
4
  import { EmailRecipientFilterType, PaginatedResponse, mergeFilters } from '@stamhoofd/structures';
5
5
  import { GetRegistrationsEndpoint } from '../endpoints/global/registration/GetRegistrationsEndpoint.js';
6
6
  import { memberJoin } from '../sql-filters/registrations.js';
@@ -1,5 +1,5 @@
1
1
  import { Order, Organization, Webshop } from '@stamhoofd/models';
2
- import type { BalanceItemPaymentsHtmlTableItem, PaymentGeneral} from '@stamhoofd/structures';
2
+ import type { BalanceItemPaymentsHtmlTableItem, PaymentGeneral } from '@stamhoofd/structures';
3
3
  import { BalanceItemRelationType, BalanceItemType, getBalanceItemPaymentsHtmlTable, PaymentMethod, PaymentMethodHelper, Replacement, Webshop as WebshopStruct } from '@stamhoofd/structures';
4
4
  import { Formatter } from '@stamhoofd/utility';
5
5
  import { createOrderDataHTMLTable } from '../helpers/email-html-helpers.js';
@@ -106,8 +106,7 @@ export function getEmailReplacementsForPayment(payment: PaymentGeneral, options:
106
106
  });
107
107
  paymentUrl = 'https://' + webshopStruct.getUrl(organization) + '/order/' + (singleOrder.id);
108
108
  }
109
- }
110
- else {
109
+ } else {
111
110
  // Fallback (should not happen, but better than leaving {{orderUrl}} in place)
112
111
  orderUrlReplacement = Replacement.create({
113
112
  token: 'orderUrl',
@@ -221,12 +220,10 @@ function getPaymentContext(payment: PaymentGeneral, { orderMap, webshopMap }: Re
221
220
  webshop: webshop.meta.name,
222
221
  orderNumber: order.number ?? '',
223
222
  }));
224
- }
225
- else {
223
+ } else {
226
224
  overviewContext.add(webshop.meta.name);
227
225
  }
228
- }
229
- else {
226
+ } else {
230
227
  overviewContext.add($t('%1L0', {
231
228
  orderNumber: order.number ?? '',
232
229
  }));
@@ -239,8 +236,7 @@ function getPaymentContext(payment: PaymentGeneral, { orderMap, webshopMap }: Re
239
236
  const memberName = balanceItem.relations.get(BalanceItemRelationType.Member)?.name.toString();
240
237
  if (memberName) {
241
238
  registrationMemberNames.add(memberName);
242
- }
243
- else {
239
+ } else {
244
240
  overviewContext.add(balanceItem.itemTitle);
245
241
  }
246
242
 
@@ -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 { SimpleError } from '@simonbackx/simple-errors';
5
5
  import { ChargeRequest, LimitedFilteredRequest, PermissionLevel } 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 { SimpleError } from '@simonbackx/simple-errors';
4
4
  import { QueueHandler } from '@stamhoofd/queues';
@@ -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 { QueueHandler } from '@stamhoofd/queues';
@@ -107,8 +107,7 @@ export class GetChargeMembershipsSummaryEndpoint extends Endpoint<Params, Query,
107
107
 
108
108
  if (!trial) {
109
109
  query.where(noTrial);
110
- }
111
- else {
110
+ } else {
112
111
  query.whereNot(noTrial);
113
112
  }
114
113
 
@@ -174,8 +173,7 @@ export class GetChargeMembershipsSummaryEndpoint extends Endpoint<Params, Query,
174
173
 
175
174
  if (!trial) {
176
175
  query.where(trialQ);
177
- }
178
- else {
176
+ } else {
179
177
  query.whereNot(trialQ);
180
178
  }
181
179
 
@@ -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 { SimpleError } from '@simonbackx/simple-errors';
5
5
  import { ChargeRequest, LimitedFilteredRequest } from '@stamhoofd/structures';
@@ -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,10 +1,10 @@
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 { Organization } from '@stamhoofd/models';
6
6
  import { SQL, applySQLSorter, compileToSQLFilter } from '@stamhoofd/sql';
7
- import type { CountFilteredRequest, Organization as OrganizationStruct, StamhoofdFilter} from '@stamhoofd/structures';
7
+ import type { CountFilteredRequest, Organization as OrganizationStruct, StamhoofdFilter } from '@stamhoofd/structures';
8
8
  import { LimitedFilteredRequest, PaginatedResponse, PermissionLevel, assertSort, getSortFilter } from '@stamhoofd/structures';
9
9
 
10
10
  import type { SQLResultNamespacedRow } from '@simonbackx/simple-database';
@@ -76,9 +76,16 @@ export class GetOrganizationsEndpoint extends Endpoint<Params, Query, Body, Resp
76
76
 
77
77
  // todo: auto detect e-mailaddresses and search on admins
78
78
  searchFilter = {
79
- name: {
80
- $contains: q.search,
81
- },
79
+ $or: [
80
+ {
81
+ name: {
82
+ $contains: q.search,
83
+ },
84
+ },
85
+ {
86
+ uri: q.search,
87
+ },
88
+ ],
82
89
  };
83
90
 
84
91
  if (searchFilter) {
@@ -125,8 +132,7 @@ export class GetOrganizationsEndpoint extends Endpoint<Params, Query, Body, Resp
125
132
 
126
133
  try {
127
134
  data = await query.fetch();
128
- }
129
- catch (error) {
135
+ } catch (error) {
130
136
  if (error.message.includes('ER_QUERY_TIMEOUT')) {
131
137
  throw new SimpleError({
132
138
  code: 'timeout',
@@ -1,6 +1,6 @@
1
- import type { AutoEncoderPatchType, Decoder, PatchableArrayAutoEncoder} from '@simonbackx/simple-encoding';
1
+ import type { AutoEncoderPatchType, Decoder, PatchableArrayAutoEncoder } from '@simonbackx/simple-encoding';
2
2
  import { 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 { Organization, OrganizationRegistrationPeriod, Platform, RegistrationPeriod } from '@stamhoofd/models';
@@ -133,8 +133,7 @@ export class PatchOrganizationsEndpoint extends Endpoint<Params, Query, Body, Re
133
133
  if (STAMHOOFD.userMode === 'platform') {
134
134
  const periodId = (await Platform.getShared()).periodIdIfPlatform;
135
135
  organization.periodId = periodId;
136
- }
137
- else {
136
+ } else {
138
137
  period = new RegistrationPeriod();
139
138
  period.configureForNewOrganization();
140
139
  await period.save();
@@ -147,8 +146,7 @@ export class PatchOrganizationsEndpoint extends Endpoint<Params, Query, Body, Re
147
146
 
148
147
  try {
149
148
  await organization.save();
150
- }
151
- catch (e) {
149
+ } catch (e) {
152
150
  console.error(e);
153
151
  throw new SimpleError({
154
152
  code: 'creating_organization',
@@ -4,8 +4,8 @@ import { AccessRight, OrganizationPackagesStatus, STPackage, STPackageBundle, ST
4
4
  import { STExpect, TestUtils } from '@stamhoofd/test-utils';
5
5
  import { testServer } from '../../../../tests/helpers/TestServer.js';
6
6
  import { initAdmin, initPlatformAdmin } from '../../../../tests/init/index.js';
7
+ import { initMembershipOrganization } from '../../../../tests/init/initMembershipOrganization.js';
7
8
  import { PatchPackagesEndpoint } from './PatchPackagesEndpoint.js';
8
- import { PatchableArray } from '@simonbackx/simple-encoding';
9
9
 
10
10
  const baseUrl = `/organization/packages`;
11
11
  const endpoint = new PatchPackagesEndpoint();
@@ -15,6 +15,10 @@ describe('Endpoint.PatchPackagesEndpoint', () => {
15
15
  TestUtils.setEnvironment('userMode', 'organization');
16
16
  });
17
17
 
18
+ beforeAll(async () => {
19
+ await initMembershipOrganization();
20
+ });
21
+
18
22
  describe('Permission checking', () => {
19
23
  test('Cannot patch organization packages as finance director', async () => {
20
24
  const organization = await new OrganizationFactory({}).create();
@@ -39,7 +43,7 @@ describe('Endpoint.PatchPackagesEndpoint', () => {
39
43
  path: baseUrl,
40
44
  host: organization.getApiHost(),
41
45
  body: OrganizationPackagesStatus.patch({
42
-
46
+
43
47
  }),
44
48
  headers: {
45
49
  authorization: 'Bearer ' + adminToken.accessToken,
@@ -56,8 +60,8 @@ describe('Endpoint.PatchPackagesEndpoint', () => {
56
60
  const { adminToken } = await initPlatformAdmin();
57
61
 
58
62
  const patch = OrganizationPackagesStatus.patch({});
59
-
60
- const pack = STPackageBundleHelper.getCurrentPackage(STPackageBundle.Webshops, new Date())
63
+
64
+ const pack = STPackageBundleHelper.getCurrentPackage(STPackageBundle.Webshops, new Date());
61
65
  pack.validAt = new Date(); // ignored by backend for now
62
66
  patch.packages.addPut(pack);
63
67
 
@@ -96,10 +100,10 @@ describe('Endpoint.PatchPackagesEndpoint', () => {
96
100
 
97
101
  const patch = OrganizationPackagesStatus.patch({});
98
102
  const removeAt = new Date();
99
- removeAt.setMilliseconds(0)
103
+ removeAt.setMilliseconds(0);
100
104
  patch.packages.addPatch(STPackage.patch({
101
105
  id: package1.id,
102
- removeAt
106
+ removeAt,
103
107
  }));
104
108
 
105
109
  // Try to request all members at organization