@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
@@ -3,13 +3,14 @@ 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 { BalanceItem, Organization, Platform, STPackage } from '@stamhoofd/models';
6
- import { BalanceItemStatus, BalanceItemType, CheckoutResponse, OrganizationPackagesStatus, OrganizationCheckout, STPackageStruct } from '@stamhoofd/structures';
6
+ import { BalanceItemStatus, BalanceItemType, CheckoutResponse, OrganizationCheckout, OrganizationPackagesStatus, STPackageStruct } from '@stamhoofd/structures';
7
+ import { CreateMandateSettings } from '@stamhoofd/structures/checkout/CreateMandateSettings.js';
7
8
  import { AuthenticatedStructures } from '../../../../helpers/AuthenticatedStructures.js';
8
9
  import { Context } from '../../../../helpers/Context.js';
10
+ import { BalanceItemService } from '../../../../services/BalanceItemService.js';
9
11
  import { PaymentService } from '../../../../services/PaymentService.js';
10
12
  import { STPackageService } from '../../../../services/STPackageService.js';
11
- import { CreateMandateSettings } from '@stamhoofd/structures/checkout/CreateMandateSettings.js';
12
- import { BalanceItemService } from '../../../../services/BalanceItemService.js';
13
+ import { VATService } from '../../../../services/VATService.js';
13
14
 
14
15
  type Params = { sellingOrganizationId: string };
15
16
  type Query = undefined;
@@ -27,7 +28,7 @@ export class OrganizationCheckoutEndpoint extends Endpoint<Params, Query, Body,
27
28
  return [false];
28
29
  }
29
30
 
30
- const params = Endpoint.parseParameters(request.url, '/billing/@sellingOrganizationId/checkout', {sellingOrganizationId: String});
31
+ const params = Endpoint.parseParameters(request.url, '/billing/@sellingOrganizationId/checkout', { sellingOrganizationId: String });
31
32
 
32
33
  if (params) {
33
34
  return [true, params as Params];
@@ -45,30 +46,15 @@ export class OrganizationCheckoutEndpoint extends Endpoint<Params, Query, Body,
45
46
  }
46
47
  const checkout = request.body;
47
48
 
48
- // Validate company
49
- if (checkout.customer && checkout.customer.company) {
50
- // Search company id
51
- // this avoids needing to check the VAT number every time
52
- const id = checkout.customer.company.id;
53
- const foundCompany = organization.meta.companies.find(c => c.id === id);
54
-
55
- if (!foundCompany) {
56
- throw new SimpleError({
57
- code: 'invalid_data',
58
- message: $t(`%w1`),
59
- });
60
- }
61
- }
62
-
63
49
  const id = request.params.sellingOrganizationId;
64
50
  if (!id) {
65
51
  throw new SimpleError({
66
52
  code: 'unavailable',
67
53
  message: 'This is temporarily unavailable',
68
- human: $t('%1Rz')
69
- })
54
+ human: $t('%1Rz'),
55
+ });
70
56
  }
71
-
57
+
72
58
  const sellingOrganization = await Organization.getByID(id);
73
59
  if (!sellingOrganization || !sellingOrganization.active) {
74
60
  throw new SimpleError({
@@ -76,8 +62,8 @@ export class OrganizationCheckoutEndpoint extends Endpoint<Params, Query, Body,
76
62
  code: 'not_found',
77
63
  message: 'Selling organization not found',
78
64
  human: $t('%1R5'),
79
- field: 'sellingOrganization'
80
- })
65
+ field: 'sellingOrganization',
66
+ });
81
67
  }
82
68
 
83
69
  if (sellingOrganization.id === organization.id) {
@@ -88,8 +74,8 @@ export class OrganizationCheckoutEndpoint extends Endpoint<Params, Query, Body,
88
74
  }
89
75
 
90
76
  const packages: STPackageStruct[] = [];
91
- const balanceItems: Map<BalanceItem, number> = new Map();
92
77
  const models: STPackage[] = [];
78
+ const balanceItems: Map<BalanceItem, number> = new Map();
93
79
 
94
80
  const membershipOrganizationId = (await Platform.getShared()).membershipOrganizationId;
95
81
 
@@ -120,11 +106,12 @@ export class OrganizationCheckoutEndpoint extends Endpoint<Params, Query, Body,
120
106
  model.disableSave();
121
107
  }
122
108
 
123
- const balanceItem = await STPackageService.chargePackage(model, undefined, checkout.customer ?? undefined);
109
+ const balanceItem = await STPackageService.chargePackage(model, sellingOrganization, checkout.customer?.company);
124
110
  if (balanceItem) {
125
- balanceItem.VATExcempt = PaymentService.getVATExcempt({
126
- customer: checkout.customer,
127
- sellingOrganization
111
+ balanceItem.VATExcempt = VATService.getVATExcempt({
112
+ company: checkout.customer?.company,
113
+ sellingOrganization,
114
+ type: 'services',
128
115
  });
129
116
  balanceItems.set(balanceItem, balanceItem.priceWithVAT);
130
117
  }
@@ -135,9 +122,9 @@ export class OrganizationCheckoutEndpoint extends Endpoint<Params, Query, Body,
135
122
  } else {
136
123
  // Security addition
137
124
  if (balanceItem && balanceItem.id) {
138
- throw new Error('Unexpected balance item save')
125
+ throw new Error('Unexpected balance item save');
139
126
  }
140
- balanceItem?.disableSave()
127
+ balanceItem?.disableSave();
141
128
  }
142
129
 
143
130
  models.push(model);
@@ -145,7 +132,7 @@ export class OrganizationCheckoutEndpoint extends Endpoint<Params, Query, Body,
145
132
  if (model.meta.requiresMandate) {
146
133
  if (checkout.proForma) {
147
134
  if (!checkout.createMandate) {
148
- checkout.createMandate = CreateMandateSettings.create({saveAsDefault: true})
135
+ checkout.createMandate = CreateMandateSettings.create({ saveAsDefault: true });
149
136
  }
150
137
  } else {
151
138
  // setting checkout.mandate is not enough - we also need to set it as default.
@@ -153,15 +140,15 @@ export class OrganizationCheckoutEndpoint extends Endpoint<Params, Query, Body,
153
140
  if (!checkout.createMandate) {
154
141
  throw new SimpleError({
155
142
  code: '',
156
- message: $t('%1Rh')
157
- })
143
+ message: $t('%1Rh'),
144
+ });
158
145
  }
159
146
 
160
147
  if (!checkout.createMandate.saveAsDefault) {
161
148
  throw new SimpleError({
162
149
  code: '',
163
- message: $t('%1Qp')
164
- })
150
+ message: $t('%1Qp'),
151
+ });
165
152
  }
166
153
  }
167
154
  }
@@ -172,10 +159,10 @@ export class OrganizationCheckoutEndpoint extends Endpoint<Params, Query, Body,
172
159
  await BalanceItemService.flushCaches(organization.id);
173
160
 
174
161
  // Validate balance items (can only happen serverside)
175
- const balanceItemIds = [...request.body.balances.keys()]
176
- let balanceItemsModels: BalanceItem[] = [];
162
+ const balanceItemIds = [...request.body.balances.keys()];
163
+
177
164
  if (balanceItemIds.length > 0) {
178
- balanceItemsModels = await BalanceItem.select().where('id', balanceItemIds).andWhere('organizationId', sellingOrganization.id).limit(balanceItemIds.length).fetch();
165
+ const balanceItemsModels = await BalanceItem.select().where('id', balanceItemIds).andWhere('organizationId', sellingOrganization.id).limit(balanceItemIds.length).fetch();
179
166
 
180
167
  if (balanceItemsModels.length !== balanceItemIds.length) {
181
168
  throw new SimpleError({
@@ -217,38 +204,54 @@ export class OrganizationCheckoutEndpoint extends Endpoint<Params, Query, Body,
217
204
  message: $t(`%vg`),
218
205
  });
219
206
  }
220
- balanceItems.set(item, amount)
207
+ balanceItems.set(item, amount);
221
208
  }
222
209
  }
223
210
 
224
211
  // If still zero payment
225
- const { price: totalPrice, roundingAmount } = PaymentService.calculateTotalPrice({
226
- balanceItems,
227
- organization: sellingOrganization
228
- })
229
- const minimumAmount = 2_00;
230
-
231
- if (totalPrice < minimumAmount && checkout.createMandate && !checkout.mandate) {
212
+ let { price: totalPrice, roundingAmount } = PaymentService.calculateTotalPrice({
213
+ balanceItems,
214
+ organization: sellingOrganization,
215
+ });
216
+ const minimumAmount = checkout.createMandate && !checkout.mandate ? 2_00 : 0;
217
+
218
+ // Automatically add discounts
219
+ await BalanceItemService.applyDiscountsToCheckout({
220
+ totalPrice: totalPrice - roundingAmount,
221
+ minimumAmount,
222
+ balanceItems,
223
+ sellingOrganizationId: sellingOrganization.id,
224
+ payingOrganizationId: organization.id,
225
+ });
226
+
227
+ // Update price and rounding
228
+ ({ price: totalPrice, roundingAmount } = PaymentService.calculateTotalPrice({
229
+ balanceItems,
230
+ organization: sellingOrganization,
231
+ }));
232
+
233
+ if (totalPrice < minimumAmount) {
232
234
  const item = new BalanceItem();
233
235
  item.type = BalanceItemType.AdministrationFee;
234
- item.description = $t('%1Q4')
236
+ item.description = $t('%1Q4');
235
237
  item.payingOrganizationId = organization.id;
236
238
  item.organizationId = sellingOrganization.id;
237
239
  item.VATPercentage = 21;
238
- item.VATExcempt = PaymentService.getVATExcempt({
239
- customer: checkout.customer,
240
- sellingOrganization
240
+ item.VATExcempt = VATService.getVATExcempt({
241
+ company: checkout.customer?.company,
242
+ sellingOrganization,
243
+ type: 'services',
241
244
  });
242
245
  item.VATIncluded = !item.VATExcempt; // Makes sure price with VAT always matches unitPrice
243
246
  item.quantity = 1;
244
- item.unitPrice = minimumAmount - (totalPrice - roundingAmount);
247
+ item.unitPrice = minimumAmount - (totalPrice - roundingAmount);
245
248
  item.createdAt = new Date();
246
249
  item.status = BalanceItemStatus.Hidden;
247
250
 
248
251
  if (!request.body.proForma) {
249
252
  await item.save();
250
253
  } else {
251
- item.disableSave()
254
+ item.disableSave();
252
255
  }
253
256
 
254
257
  balanceItems.set(item, item.priceWithVAT);
@@ -265,9 +268,9 @@ export class OrganizationCheckoutEndpoint extends Endpoint<Params, Query, Body,
265
268
 
266
269
  return new Response(CheckoutResponse.create({
267
270
  payment: result.payment,
268
- invoice: result.invoice
271
+ invoice: result.invoice,
269
272
  }));
270
- }
273
+ }
271
274
 
272
275
  const result = await PaymentService.createPayment({
273
276
  balanceItems,
@@ -279,7 +282,7 @@ export class OrganizationCheckoutEndpoint extends Endpoint<Params, Query, Body,
279
282
  createMandate: checkout.createMandate,
280
283
  useMandate: checkout.mandate,
281
284
  paymentConfiguration: sellingOrganization.meta.registrationPaymentConfiguration,
282
- privatePaymentConfiguration: sellingOrganization.privateMeta.registrationPaymentConfiguration
285
+ privatePaymentConfiguration: sellingOrganization.privateMeta.registrationPaymentConfiguration,
283
286
  });
284
287
 
285
288
  if (!result) {
@@ -304,5 +307,5 @@ export class OrganizationCheckoutEndpoint extends Endpoint<Params, Query, Body,
304
307
  }));
305
308
  }
306
309
 
307
- setPayment
310
+ setPayment;
308
311
  }
@@ -11,13 +11,13 @@ import { PaymentMandateService } from '../../../../services/PaymentMandateServic
11
11
  type Params = { sellingOrganizationId: string };
12
12
  type Query = undefined;
13
13
  type Body = PatchableArrayAutoEncoder<PaymentMandate>;
14
- type ResponseBody = PaymentMandate[]
14
+ type ResponseBody = PaymentMandate[];
15
15
 
16
16
  export class DeleteOrganizationMandateEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
17
17
  bodyDecoder = new PatchableArrayDecoder(
18
- PaymentMandate as Decoder<PaymentMandate>,
19
- PaymentMandate.patchType() as Decoder<AutoEncoderPatchType<PaymentMandate>>,
20
- StringDecoder
18
+ PaymentMandate as Decoder<PaymentMandate>,
19
+ PaymentMandate.patchType() as Decoder<AutoEncoderPatchType<PaymentMandate>>,
20
+ StringDecoder,
21
21
  ) as Decoder<PatchableArrayAutoEncoder<PaymentMandate>>;
22
22
 
23
23
  protected doesMatch(request: Request): [true, Params] | [false] {
@@ -25,7 +25,7 @@ export class DeleteOrganizationMandateEndpoint extends Endpoint<Params, Query, B
25
25
  return [false];
26
26
  }
27
27
 
28
- const params = Endpoint.parseParameters(request.url, '/billing/@sellingOrganizationId/mandates', {sellingOrganizationId: String});
28
+ const params = Endpoint.parseParameters(request.url, '/billing/@sellingOrganizationId/mandates', { sellingOrganizationId: String });
29
29
 
30
30
  if (params) {
31
31
  return [true, params as Params];
@@ -37,15 +37,15 @@ export class DeleteOrganizationMandateEndpoint extends Endpoint<Params, Query, B
37
37
  const payingOrganization = await Context.setOrganizationScope();
38
38
  const { user } = await Context.authenticate();
39
39
 
40
- const id = request.params.sellingOrganizationId;
40
+ const id = request.params.sellingOrganizationId;
41
41
  if (!id) {
42
42
  throw new SimpleError({
43
43
  code: 'unavailable',
44
44
  message: 'This is temporarily unavailable',
45
- human: $t('%1Rz')
46
- })
45
+ human: $t('%1Rz'),
46
+ });
47
47
  }
48
-
48
+
49
49
  const sellingOrganization = await Organization.getByID(id);
50
50
  if (!sellingOrganization || !sellingOrganization.active) {
51
51
  throw new SimpleError({
@@ -53,14 +53,14 @@ export class DeleteOrganizationMandateEndpoint extends Endpoint<Params, Query, B
53
53
  code: 'not_found',
54
54
  message: 'Selling organization not found',
55
55
  human: $t('%1R5'),
56
- field: 'sellingOrganization'
57
- })
56
+ field: 'sellingOrganization',
57
+ });
58
58
  }
59
59
 
60
60
  const mandates = await PaymentMandateService.getMandates({
61
61
  sellingOrganization,
62
62
  user,
63
- payingOrganization
63
+ payingOrganization,
64
64
  });
65
65
 
66
66
  for (const patch of request.body.getPatches()) {
@@ -69,26 +69,26 @@ export class DeleteOrganizationMandateEndpoint extends Endpoint<Params, Query, B
69
69
  throw new SimpleError({
70
70
  code: 'not_found',
71
71
  message: 'This payment mandate is not found',
72
- human: $t('%1R8')
73
- })
72
+ human: $t('%1R8'),
73
+ });
74
74
  }
75
75
 
76
76
  if (patch.isDefault === true) {
77
77
  await PaymentMandateService.setDefaultMandate({
78
78
  mandateId: mandate.id,
79
- sellingOrganization,
79
+ sellingOrganizationId: sellingOrganization.id,
80
80
  payingOrganizationId: payingOrganization,
81
- payingUserId: null
82
- })
81
+ payingUserId: null,
82
+ });
83
83
  }
84
84
  }
85
85
 
86
86
  const updatedMandates = await PaymentMandateService.getMandates({
87
87
  sellingOrganization,
88
88
  user,
89
- payingOrganization
90
- })
89
+ payingOrganization,
90
+ });
91
91
 
92
- return new Response(PaymentMandateService.groupByMandate(updatedMandates).mandates);
92
+ return new Response(PaymentMandateService.groupByMandate(updatedMandates).mandates);
93
93
  }
94
94
  }
@@ -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 { DocumentTemplate } from '@stamhoofd/models';
@@ -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,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 { DocumentTemplate } from '@stamhoofd/models';
4
4
  import type { CountFilteredRequest, DocumentTemplatePrivate, StamhoofdFilter } 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,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 { Document } from '@stamhoofd/models';
4
4
  import type { CountFilteredRequest, Document as DocumentStruct, StamhoofdFilter } from '@stamhoofd/structures';
@@ -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 { Document, DocumentTemplate, Member, Registration } from '@stamhoofd/models';
@@ -45,6 +45,14 @@ export class PatchDocumentEndpoint extends Endpoint<Params, Query, Body, Respons
45
45
  throw Context.auth.notFoundOrNoAccess($t(`%EK`));
46
46
  }
47
47
 
48
+ if (document.isLocked) {
49
+ throw new SimpleError({
50
+ code: 'locked',
51
+ message: 'Document is locked',
52
+ human: $t(`%1Uc`),
53
+ });
54
+ }
55
+
48
56
  if (patch.data) {
49
57
  document.data.patchOrPut(patch.data);
50
58
  }
@@ -1,7 +1,7 @@
1
1
  import { PatchableArray } from '@simonbackx/simple-encoding';
2
- import type { Endpoint} from '@simonbackx/simple-endpoints';
2
+ import type { Endpoint } from '@simonbackx/simple-endpoints';
3
3
  import { Request } from '@simonbackx/simple-endpoints';
4
- import type { Organization, RegistrationPeriod, User} from '@stamhoofd/models';
4
+ import type { Organization, RegistrationPeriod, User } from '@stamhoofd/models';
5
5
  import { DocumentTemplate, DocumentTemplateFactory, OrganizationFactory, RegistrationPeriodFactory, Token, UserFactory } from '@stamhoofd/models';
6
6
  import { SQL } from '@stamhoofd/sql';
7
7
  import { DocumentPrivateSettings, DocumentStatus, DocumentTemplateDefinition, DocumentTemplatePrivate, PermissionLevel, Permissions } from '@stamhoofd/structures';
@@ -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 { DocumentTemplate } from '@stamhoofd/models';
@@ -1,5 +1,5 @@
1
1
  import { ArrayDecoder, StringDecoder } 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 { EmailAddress } from '@stamhoofd/email';
@@ -1,5 +1,5 @@
1
1
  import { Request } from '@simonbackx/simple-endpoints';
2
- import type { Organization, RegistrationPeriod} from '@stamhoofd/models';
2
+ import type { Organization, RegistrationPeriod } from '@stamhoofd/models';
3
3
  import { EmailTemplate, GroupFactory, OrganizationFactory, Platform, RegistrationPeriodFactory, Token, UserFactory } from '@stamhoofd/models';
4
4
  import { EmailTemplateType, PermissionLevel, PermissionRoleDetailed, Permissions, PermissionsResourceType, ResourcePermissions, Version } from '@stamhoofd/structures';
5
5
  import { TestUtils } from '@stamhoofd/test-utils';
@@ -1,8 +1,8 @@
1
- import type { Decoder} from '@simonbackx/simple-encoding';
1
+ import type { Decoder } from '@simonbackx/simple-encoding';
2
2
  import { AutoEncoder, EnumDecoder, field, StringDecoder } from '@simonbackx/simple-encoding';
3
- import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
3
+ import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
4
4
  import { Endpoint, Response } from '@simonbackx/simple-endpoints';
5
- import { EmailTemplate } from '@stamhoofd/models';
5
+ import { EmailTemplate, Platform } from '@stamhoofd/models';
6
6
  import { EmailTemplate as EmailTemplateStruct, EmailTemplateType } from '@stamhoofd/structures';
7
7
  import { Formatter } from '@stamhoofd/utility';
8
8
 
@@ -60,11 +60,13 @@ export class GetEmailTemplatesEndpoint extends Endpoint<Params, Query, Body, Res
60
60
  });
61
61
  }
62
62
 
63
+ const platform = await Platform.getShared();
64
+
63
65
  const types = (request.query.types ?? [...Object.values(EmailTemplateType)]).filter((type) => {
64
66
  if (!organization) {
65
67
  return EmailTemplateStruct.allowPlatformLevel(type);
66
68
  }
67
- return EmailTemplateStruct.allowOrganizationLevel(type);
69
+ return EmailTemplateStruct.allowOrganizationLevel(type, organization, platform);
68
70
  });
69
71
 
70
72
  if (types.length === 0) {
@@ -86,10 +88,10 @@ export class GetEmailTemplatesEndpoint extends Endpoint<Params, Query, Body, Res
86
88
  // Required for event emails when logged in as the platform admin
87
89
  (request.query.webshopId || request.query.groupIds)
88
90
  ? await EmailTemplate.where({
89
- webshopId: request.query.webshopId ?? null,
90
- groupId: request.query.groupIds ? { sign: 'IN', value: request.query.groupIds } : null,
91
- type: { sign: 'IN', value: types },
92
- })
91
+ webshopId: request.query.webshopId ?? null,
92
+ groupId: request.query.groupIds ? { sign: 'IN', value: request.query.groupIds } : null,
93
+ type: { sign: 'IN', value: types },
94
+ })
93
95
  : []
94
96
  );
95
97
 
@@ -1,7 +1,7 @@
1
1
  import type { PatchableArrayAutoEncoder } from '@simonbackx/simple-encoding';
2
2
  import { PatchableArray } from '@simonbackx/simple-encoding';
3
3
  import { Request } from '@simonbackx/simple-endpoints';
4
- import type { Organization, RegistrationPeriod} from '@stamhoofd/models';
4
+ import type { Organization, RegistrationPeriod } from '@stamhoofd/models';
5
5
  import { EmailTemplate, GroupFactory, OrganizationFactory, Platform, RegistrationPeriodFactory, Token, UserFactory } from '@stamhoofd/models';
6
6
  import { EmailTemplate as EmailTemplateStruct, EmailTemplateType, PermissionLevel, PermissionRoleDetailed, Permissions, PermissionsResourceType, ResourcePermissions, Version } from '@stamhoofd/structures';
7
7
  import { TestUtils } from '@stamhoofd/test-utils';
@@ -1,8 +1,8 @@
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
- import { EmailTemplate, Group, Webshop } from '@stamhoofd/models';
5
+ import { EmailTemplate, Group, Platform, Webshop } from '@stamhoofd/models';
6
6
  import { EmailTemplate as EmailTemplateStruct, PermissionLevel } from '@stamhoofd/structures';
7
7
 
8
8
  import { Context } from '../../../../helpers/Context.js';
@@ -38,7 +38,6 @@ export class PatchEmailTemplatesEndpoint extends Endpoint<Params, Query, Body, R
38
38
  throw Context.auth.error();
39
39
  }
40
40
  }
41
-
42
41
  const templates: EmailTemplate[] = [];
43
42
 
44
43
  // Get all patches
@@ -61,11 +60,11 @@ export class PatchEmailTemplatesEndpoint extends Endpoint<Params, Query, Body, R
61
60
  for (const put of request.body.getPuts()) {
62
61
  const struct = put.put;
63
62
 
64
- if (!EmailTemplateStruct.allowOrganizationLevel(struct.type) && organization) {
63
+ if (organization && !EmailTemplateStruct.allowOrganizationLevel(struct.type, organization, await Platform.getShared())) {
65
64
  throw Context.auth.error();
66
65
  }
67
66
 
68
- if (!EmailTemplateStruct.allowPlatformLevel(struct.type) && !organization) {
67
+ if (!organization && !EmailTemplateStruct.allowPlatformLevel(struct.type)) {
69
68
  throw Context.auth.error();
70
69
  }
71
70
 
@@ -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,17 +1,18 @@
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 { Invoice } from '@stamhoofd/models';
6
6
  import { applySQLSorter, compileToSQLFilter } from '@stamhoofd/sql';
7
- import type { CountFilteredRequest, InvoiceStruct, StamhoofdFilter} from '@stamhoofd/structures';
7
+ import type { CountFilteredRequest, InvoiceStruct, StamhoofdFilter } from '@stamhoofd/structures';
8
8
  import { LimitedFilteredRequest, PaginatedResponse, assertSort, getSortFilter } from '@stamhoofd/structures';
9
9
 
10
10
  import { AuthenticatedStructures } from '../../../../helpers/AuthenticatedStructures.js';
11
11
  import { Context } from '../../../../helpers/Context.js';
12
+ import { InvoicePdfService } from '../../../../services/InvoicePdfService.js';
13
+ import { InvoiceXMlService } from '../../../../services/InvoiceXMLService.js';
12
14
  import { invoiceFilterCompilers } from '../../../../sql-filters/invoices.js';
13
15
  import { invoiceSorters } from '../../../../sql-sorters/invoices.js';
14
- import { InvoiceService } from '../../../../services/InvoiceService.js';
15
16
 
16
17
  type Params = Record<string, never>;
17
18
  type Query = LimitedFilteredRequest;
@@ -155,8 +156,7 @@ export class GetInvoicesEndpoint extends Endpoint<Params, Query, Body, ResponseB
155
156
 
156
157
  try {
157
158
  invoices = await query.fetch();
158
- }
159
- catch (error) {
159
+ } catch (error) {
160
160
  if (error.message.includes('ER_QUERY_TIMEOUT')) {
161
161
  throw new SimpleError({
162
162
  code: 'timeout',
@@ -188,8 +188,12 @@ export class GetInvoicesEndpoint extends Endpoint<Params, Query, Body, ResponseB
188
188
  }
189
189
 
190
190
  for (const invoice of invoices) {
191
+ if (invoice.number && !invoice.pdf && STAMHOOFD.environment === 'development') {
192
+ await InvoicePdfService.generatePdf(invoice);
193
+ }
194
+
191
195
  if (invoice.number && STAMHOOFD.environment === 'development') {
192
- await InvoiceService.generatePdf(invoice)
196
+ await InvoiceXMlService.generateXml(invoice);
193
197
  }
194
198
  }
195
199
 
@@ -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 { Invoice as InvoiceStruct } from '@stamhoofd/structures';
6
6
 
@@ -44,6 +44,15 @@ export class PatchInvoicesEndpoint extends Endpoint<Params, Query, Body, Respons
44
44
  const invoices: Invoice[] = [];
45
45
 
46
46
  for (const { put } of request.body.getPuts()) {
47
+ if (put.payingOrganizationId) {
48
+ if (!await Context.auth.hasFullAccess(put.payingOrganizationId)) {
49
+ Context.auth.error($t('%1Xw'));
50
+ }
51
+ }
52
+
53
+ put.stripeAccountId = null;
54
+ put.reference = null;
55
+
47
56
  const model = await InvoiceService.createFrom(organization, put);
48
57
  invoices.push(model);
49
58
  }
@@ -1,7 +1,7 @@
1
- import type { DecodedRequest, Request} from '@simonbackx/simple-endpoints';
1
+ import type { DecodedRequest, Request } from '@simonbackx/simple-endpoints';
2
2
  import { Endpoint, Response } from '@simonbackx/simple-endpoints';
3
3
  import { MollieToken } from '@stamhoofd/models';
4
- import type { Organization as OrganizationStruct} from '@stamhoofd/structures';
4
+ import type { Organization as OrganizationStruct } from '@stamhoofd/structures';
5
5
  import { CheckMollieResponse, PermissionLevel } from '@stamhoofd/structures';
6
6
 
7
7
  import { AuthenticatedStructures } from '../../../../helpers/AuthenticatedStructures.js';
@@ -37,7 +37,7 @@ export class CheckMollieEndpoint extends Endpoint<Params, Query, Body, ResponseB
37
37
  throw Context.auth.error();
38
38
  }
39
39
 
40
- const service = await MollieService.create({sellingOrganization: organization })
40
+ const service = await MollieService.create({ sellingOrganization: organization });
41
41
 
42
42
  if (!service) {
43
43
  organization.privateMeta.mollieOnboarding = null;
@@ -64,8 +64,7 @@ export class CheckMollieEndpoint extends Endpoint<Params, Query, Body, ResponseB
64
64
  const profile = profiles.find(p => p.id === s);
65
65
  if (!profile) {
66
66
  organization.privateMeta.mollieProfile = null;
67
- }
68
- else {
67
+ } else {
69
68
  organization.privateMeta.mollieProfile = profile;
70
69
  }
71
70
  }