@stamhoofd/backend 2.120.6 → 2.122.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (434) hide show
  1. package/output-2.txt +1 -0
  2. package/output.txt +1 -0
  3. package/package.json +70 -53
  4. package/src/audit-logs/EventNotificationLogger.ts +40 -0
  5. package/src/audit-logs/ModelLogger.ts +19 -15
  6. package/src/audit-logs/OrganizationLogger.ts +1 -1
  7. package/src/audit-logs/RegistrationInvitationLogger.ts +46 -0
  8. package/src/audit-logs/init.ts +9 -1
  9. package/src/boot.ts +19 -18
  10. package/src/crons/amazon-ses.ts +13 -26
  11. package/src/crons/balance-emails.ts +3 -5
  12. package/src/crons/clearExcelCache.test.ts +1 -1
  13. package/src/crons/clearExcelCache.ts +1 -2
  14. package/src/crons/drip-emails.ts +42 -0
  15. package/src/crons/endFunctionsOfUsersWithoutRegistration.ts +4 -0
  16. package/src/crons/helpers/isOutside.ts +11 -0
  17. package/src/crons/helpers/useSavedIterator.ts +32 -0
  18. package/src/crons/index.ts +7 -0
  19. package/src/crons/invoices.ts +160 -0
  20. package/src/crons/members-fees.ts +50 -0
  21. package/src/crons/mollie-chargebacks.ts +86 -0
  22. package/src/crons/service-fees.ts +152 -0
  23. package/src/crons/stripe-invoices.ts +48 -0
  24. package/src/crons/transfer-fees.ts +176 -0
  25. package/src/crons/update-cached-balances.ts +4 -4
  26. package/src/crons.ts +54 -74
  27. package/src/debug.ts +4 -2
  28. package/src/email-recipient-loaders/documents.ts +1 -1
  29. package/src/email-recipient-loaders/members.ts +1 -1
  30. package/src/email-recipient-loaders/payments.ts +87 -46
  31. package/src/email-recipient-loaders/registrations.ts +1 -1
  32. package/src/email-replacements/getEmailReplacementsForPayment.ts +5 -9
  33. package/src/endpoints/admin/members/ChargeMembersEndpoint.ts +1 -1
  34. package/src/endpoints/admin/memberships/ChargeMembershipsEndpoint.ts +1 -1
  35. package/src/endpoints/admin/memberships/GetChargeMembershipsSummaryEndpoint.ts +3 -5
  36. package/src/endpoints/admin/organizations/ChargeOrganizationsEndpoint.ts +1 -1
  37. package/src/endpoints/admin/organizations/GetOrganizationsCountEndpoint.ts +1 -1
  38. package/src/endpoints/admin/organizations/GetOrganizationsEndpoint.ts +13 -7
  39. package/src/endpoints/admin/organizations/PatchOrganizationsEndpoint.ts +4 -6
  40. package/src/endpoints/admin/organizations/PatchPackagesEndpoint.test.ts +10 -6
  41. package/src/endpoints/admin/organizations/PatchPackagesEndpoint.ts +39 -21
  42. package/src/endpoints/admin/registrations/ChargeRegistrationsEndpoint.ts +1 -1
  43. package/src/endpoints/auth/CreateAdminEndpoint.ts +23 -5
  44. package/src/endpoints/auth/CreateTokenEndpoint.ts +2 -2
  45. package/src/endpoints/auth/DeleteTokenEndpoint.ts +1 -1
  46. package/src/endpoints/auth/DeleteUserEndpoint.ts +3 -3
  47. package/src/endpoints/auth/ForgotPasswordEndpoint.ts +1 -1
  48. package/src/endpoints/auth/GetOtherUserEndpoint.ts +1 -1
  49. package/src/endpoints/auth/GetUserEndpoint.ts +1 -1
  50. package/src/endpoints/auth/OpenIDConnectAuthTokenEndpoint.ts +1 -1
  51. package/src/endpoints/auth/OpenIDConnectStartEndpoint.ts +1 -1
  52. package/src/endpoints/auth/PatchUserEndpoint.ts +5 -8
  53. package/src/endpoints/auth/PollEmailVerificationEndpoint.ts +1 -1
  54. package/src/endpoints/auth/RetryEmailVerificationEndpoint.ts +1 -1
  55. package/src/endpoints/auth/SignupEndpoint.ts +2 -3
  56. package/src/endpoints/auth/VerifyEmailEndpoint.ts +20 -3
  57. package/src/endpoints/frontend/FrontendEnvironmentEndpoint.ts +2 -1
  58. package/src/endpoints/global/addresses/SearchRegionsEndpoint.ts +2 -4
  59. package/src/endpoints/global/addresses/ValidateAddressEndpoint.ts +1 -1
  60. package/src/endpoints/global/audit-logs/GetAuditLogsEndpoint.ts +5 -7
  61. package/src/endpoints/global/caddy/CheckDomainCertEndpoint.ts +2 -2
  62. package/src/endpoints/global/email/CreateEmailEndpoint.ts +3 -4
  63. package/src/endpoints/global/email/GetAdminEmailsEndpoint.test.ts +1 -1
  64. package/src/endpoints/global/email/GetAdminEmailsEndpoint.ts +1 -2
  65. package/src/endpoints/global/email/GetEmailAddressEndpoint.ts +4 -6
  66. package/src/endpoints/global/email/GetEmailEndpoint.ts +1 -1
  67. package/src/endpoints/global/email/GetUserEmailsEndpoint.test.ts +1 -1
  68. package/src/endpoints/global/email/GetUserEmailsEndpoint.ts +1 -1
  69. package/src/endpoints/global/email/ManageEmailAddressEndpoint.ts +6 -10
  70. package/src/endpoints/global/email/PatchEmailEndpoint.test.ts +4 -7
  71. package/src/endpoints/global/email/PatchEmailEndpoint.ts +6 -9
  72. package/src/endpoints/global/email-recipients/GetEmailRecipientsCountEndpoint.ts +1 -1
  73. package/src/endpoints/global/email-recipients/GetEmailRecipientsEndpoint.test.ts +1 -1
  74. package/src/endpoints/global/email-recipients/GetEmailRecipientsEndpoint.ts +1 -1
  75. package/src/endpoints/global/email-recipients/RetryEmailRecipientEndpoint.ts +2 -2
  76. package/src/endpoints/global/events/GetEventNotificationsCountEndpoint.ts +1 -1
  77. package/src/endpoints/global/events/GetEventNotificationsEndpoint.ts +3 -3
  78. package/src/endpoints/global/events/GetEventsEndpoint.ts +3 -3
  79. package/src/endpoints/global/events/PatchEventNotificationsEndpoint.test.ts +49 -4
  80. package/src/endpoints/global/events/PatchEventNotificationsEndpoint.ts +5 -8
  81. package/src/endpoints/global/events/PatchEventsEndpoint.test.ts +12 -44
  82. package/src/endpoints/global/events/PatchEventsEndpoint.ts +128 -127
  83. package/src/endpoints/global/files/ExportToExcelEndpoint.ts +9 -9
  84. package/src/endpoints/global/files/GetFileCache.ts +3 -4
  85. package/src/endpoints/global/files/UploadFile.ts +3 -4
  86. package/src/endpoints/global/files/UploadImage.ts +3 -4
  87. package/src/endpoints/global/groups/GetGroupsCountEndpoint.ts +51 -0
  88. package/src/endpoints/global/groups/GetGroupsEndpoint.test.ts +1 -1
  89. package/src/endpoints/global/groups/GetGroupsEndpoint.ts +4 -2
  90. package/src/endpoints/global/members/GetMemberFamilyEndpoint.ts +2 -3
  91. package/src/endpoints/global/members/GetMembersCountEndpoint.ts +1 -1
  92. package/src/endpoints/global/members/GetMembersEndpoint.test.ts +2 -2
  93. package/src/endpoints/global/members/GetMembersEndpoint.ts +10 -12
  94. package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.test.ts +195 -12
  95. package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.ts +16 -22
  96. package/src/endpoints/global/members/helpers/validateGroupFilter.ts +6 -30
  97. package/src/endpoints/global/members/shouldCheckIfMemberIsDuplicate.ts +1 -1
  98. package/src/endpoints/global/organizations/CheckRegisterCodeEndpoint.ts +1 -1
  99. package/src/endpoints/global/organizations/CreateOrganizationEndpoint.ts +40 -8
  100. package/src/endpoints/global/organizations/GetOrganizationFromDomainEndpoint.ts +2 -2
  101. package/src/endpoints/global/organizations/GetOrganizationFromUriEndpoint.ts +2 -2
  102. package/src/endpoints/global/organizations/SearchOrganizationEndpoint.test.ts +4 -1
  103. package/src/endpoints/global/organizations/SearchOrganizationEndpoint.ts +4 -5
  104. package/src/endpoints/global/payments/StripeWebhookEndpoint.ts +9 -16
  105. package/src/endpoints/global/platform/GetPlatformAdminsEndpoint.ts +1 -1
  106. package/src/endpoints/global/platform/GetPlatformEndpoint.ts +1 -1
  107. package/src/endpoints/global/platform/PatchPlatformEnpoint.test.ts +1 -1
  108. package/src/endpoints/global/platform/PatchPlatformEnpoint.ts +32 -13
  109. package/src/endpoints/global/platform-memberships/GetPlatformMembershipsCountEndpoint.ts +31 -31
  110. package/src/endpoints/global/platform-memberships/GetPlatformMembershipsEndpoint.ts +18 -20
  111. package/src/endpoints/global/registration/GetRegistrationsCountEndpoint.ts +1 -1
  112. package/src/endpoints/global/registration/GetRegistrationsEndpoint.test.ts +1 -1
  113. package/src/endpoints/global/registration/GetRegistrationsEndpoint.ts +6 -10
  114. package/src/endpoints/global/registration/GetUserDetailedPayableBalanceEndpoint.ts +35 -6
  115. package/src/endpoints/global/registration/GetUserDocumentsEndpoint.ts +2 -2
  116. package/src/endpoints/global/registration/GetUserMembersEndpoint.ts +1 -1
  117. package/src/endpoints/global/registration/GetUserPayableBalanceEndpoint.ts +1 -1
  118. package/src/endpoints/global/registration/PatchUserMembersEndpoint.test.ts +2 -2
  119. package/src/endpoints/global/registration/PatchUserMembersEndpoint.ts +3 -3
  120. package/src/endpoints/global/registration/RegisterMembersEndpoint.test.ts +90 -6
  121. package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +38 -33
  122. package/src/endpoints/global/registration-invitations/GetRegistrationInvitationsCountEndpoint.ts +45 -0
  123. package/src/endpoints/global/registration-invitations/GetRegistrationInvitationsEndpoint.test.ts +494 -0
  124. package/src/endpoints/global/registration-invitations/GetRegistrationInvitationsEndpoint.ts +213 -0
  125. package/src/endpoints/global/registration-invitations/PatchRegistrationInvitationsEndpoint.test.ts +404 -0
  126. package/src/endpoints/global/registration-invitations/PatchRegistrationInvitationsEndpoint.ts +167 -0
  127. package/src/endpoints/global/registration-periods/GetRegistrationPeriodsCountEndpoint.ts +43 -0
  128. package/src/endpoints/global/registration-periods/GetRegistrationPeriodsEndpoint.ts +1 -1
  129. package/src/endpoints/global/registration-periods/PatchRegistrationPeriodsEndpoint.ts +13 -5
  130. package/src/endpoints/global/sso/GetSSOEndpoint.ts +2 -3
  131. package/src/endpoints/global/sso/SetSSOEndpoint.ts +1 -1
  132. package/src/endpoints/global/webshops/GetWebshopFromDomainEndpoint.ts +2 -2
  133. package/src/endpoints/global/webshops/GetWebshopsEndpoint.test.ts +1 -2
  134. package/src/endpoints/global/webshops/GetWebshopsEndpoint.ts +2 -4
  135. package/src/endpoints/organization/dashboard/balance-items/GetBalanceItemEndpoint.ts +2 -2
  136. package/src/endpoints/organization/dashboard/balance-items/GetBalanceItemsCountEndpoint.ts +1 -1
  137. package/src/endpoints/organization/dashboard/balance-items/GetBalanceItemsEndpoint.ts +3 -4
  138. package/src/endpoints/organization/dashboard/balance-items/PatchBalanceItemsEndpoint.ts +19 -6
  139. package/src/endpoints/organization/dashboard/billing/ApplyRegisterCodeEndpoint.test.ts +73 -0
  140. package/src/endpoints/organization/dashboard/billing/ApplyRegisterCodeEndpoint.ts +89 -0
  141. package/src/endpoints/{global → organization/dashboard}/billing/DeactivatePackageEndpoint.ts +4 -9
  142. package/src/endpoints/organization/dashboard/billing/DeleteOrganizationMandateEndpoint.ts +62 -0
  143. package/src/endpoints/organization/dashboard/billing/GetOrganizationDetailedPayableBalanceCollectionEndpoint.ts +56 -0
  144. package/src/endpoints/organization/dashboard/billing/GetOrganizationDetailedPayableBalanceEndpoint.ts +41 -18
  145. package/src/endpoints/organization/dashboard/billing/GetOrganizationMandatesEndpoint.ts +64 -0
  146. package/src/endpoints/organization/dashboard/billing/GetOrganizationPayableBalanceEndpoint.ts +2 -2
  147. package/src/endpoints/organization/dashboard/billing/GetOrganizationPayableInvoicesEndpoint.ts +68 -0
  148. package/src/endpoints/organization/dashboard/billing/GetPackagesEndpoint.ts +12 -4
  149. package/src/endpoints/organization/dashboard/billing/GetRegisterCodeEndpoint.ts +66 -0
  150. package/src/endpoints/organization/dashboard/billing/OrganizationCheckoutEndpoint.test.ts +949 -0
  151. package/src/endpoints/organization/dashboard/billing/OrganizationCheckoutEndpoint.ts +311 -0
  152. package/src/endpoints/organization/dashboard/billing/PatchOrganizationMandatesEndpoint.ts +94 -0
  153. package/src/endpoints/organization/dashboard/documents/GetDocumentTemplateXML.ts +1 -1
  154. package/src/endpoints/organization/dashboard/documents/GetDocumentTemplatesCountEndpoint.ts +1 -1
  155. package/src/endpoints/organization/dashboard/documents/GetDocumentTemplatesEndpoint.ts +1 -1
  156. package/src/endpoints/organization/dashboard/documents/GetDocumentsCountEndpoint.ts +1 -1
  157. package/src/endpoints/organization/dashboard/documents/GetDocumentsEndpoint.ts +1 -1
  158. package/src/endpoints/organization/dashboard/documents/PatchDocumentEndpoint.ts +10 -2
  159. package/src/endpoints/organization/dashboard/documents/PatchDocumentTemplatesEndpoint.test.ts +2 -2
  160. package/src/endpoints/organization/dashboard/documents/PatchDocumentTemplatesEndpoint.ts +2 -2
  161. package/src/endpoints/organization/dashboard/email/CheckEmailBouncesEndpoint.ts +1 -1
  162. package/src/endpoints/organization/dashboard/email-templates/GetEmailTemplatesEndpoint.test.ts +1 -1
  163. package/src/endpoints/organization/dashboard/email-templates/GetEmailTemplatesEndpoint.ts +10 -8
  164. package/src/endpoints/organization/dashboard/email-templates/PatchEmailTemplatesEndpoint.test.ts +1 -1
  165. package/src/endpoints/organization/dashboard/email-templates/PatchEmailTemplatesEndpoint.ts +5 -6
  166. package/src/endpoints/organization/dashboard/invoices/GetInvoicesCountEndpoint.ts +1 -1
  167. package/src/endpoints/organization/dashboard/invoices/GetInvoicesEndpoint.ts +15 -4
  168. package/src/endpoints/organization/dashboard/invoices/PatchInvoicesEndpoint.ts +11 -2
  169. package/src/endpoints/organization/dashboard/mollie/CheckMollieEndpoint.ts +8 -8
  170. package/src/endpoints/organization/dashboard/mollie/ConnectMollieEndpoint.ts +10 -5
  171. package/src/endpoints/organization/dashboard/mollie/DisconnectMollieEndpoint.ts +2 -2
  172. package/src/endpoints/organization/dashboard/mollie/GetMollieDashboardEndpoint.ts +7 -7
  173. package/src/endpoints/organization/dashboard/nolt/CreateNoltTokenEndpoint.ts +1 -1
  174. package/src/endpoints/organization/dashboard/organization/GetOrganizationArchivedGroups.ts +2 -2
  175. package/src/endpoints/organization/dashboard/organization/GetOrganizationDeletedGroups.ts +1 -1
  176. package/src/endpoints/organization/dashboard/organization/GetUitpasClientIdEndpoint.ts +1 -1
  177. package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.test.ts +2 -2
  178. package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.ts +67 -20
  179. package/src/endpoints/organization/dashboard/organization/SearchUitpasOrganizersEndpoint.ts +2 -2
  180. package/src/endpoints/organization/dashboard/organization/SetOrganizationDomainEndpoint.ts +5 -10
  181. package/src/endpoints/organization/dashboard/organization/SetUitpasClientCredentialsEndpoint.ts +1 -1
  182. package/src/endpoints/organization/dashboard/payments/GetPaymentsCountEndpoint.ts +1 -1
  183. package/src/endpoints/organization/dashboard/payments/GetPaymentsEndpoint.ts +3 -4
  184. package/src/endpoints/organization/dashboard/payments/PatchPaymentsEndpoint.ts +24 -17
  185. package/src/endpoints/organization/dashboard/receivable-balances/ChargeReceivableBalancesEndpoint.ts +134 -0
  186. package/src/endpoints/organization/dashboard/receivable-balances/GetReceivableBalanceEndpoint.ts +2 -3
  187. package/src/endpoints/organization/dashboard/receivable-balances/GetReceivableBalancesCountEndpoint.ts +1 -1
  188. package/src/endpoints/organization/dashboard/receivable-balances/GetReceivableBalancesEndpoint.ts +1 -1
  189. package/src/endpoints/organization/dashboard/registration-periods/GetOrganizationRegistrationPeriodsEndpoint.test.ts +1 -1
  190. package/src/endpoints/organization/dashboard/registration-periods/GetOrganizationRegistrationPeriodsEndpoint.ts +2 -3
  191. package/src/endpoints/organization/dashboard/registration-periods/MoveRegistrationPeriods.test.ts +1 -1
  192. package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.test.ts +1 -1
  193. package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.ts +32 -22
  194. package/src/endpoints/organization/dashboard/registration-periods/SetupStepReviewEndpoint.ts +4 -5
  195. package/src/endpoints/organization/dashboard/stripe/ConnectStripeEndpoint.ts +1 -1
  196. package/src/endpoints/organization/dashboard/stripe/DeleteStripeAccountEndpoint.ts +2 -3
  197. package/src/endpoints/organization/dashboard/stripe/GetStripeAccountLinkEndpoint.ts +2 -2
  198. package/src/endpoints/organization/dashboard/stripe/GetStripeAccountsEndpoint.ts +1 -1
  199. package/src/endpoints/organization/dashboard/stripe/GetStripeLoginLinkEndpoint.ts +2 -2
  200. package/src/endpoints/organization/dashboard/stripe/UpdateStripeAccountEndpoint.ts +1 -1
  201. package/src/endpoints/organization/dashboard/users/CreateApiUserEndpoint.ts +1 -1
  202. package/src/endpoints/organization/dashboard/users/DeleteUserEndpoint.ts +1 -1
  203. package/src/endpoints/organization/dashboard/users/GetApiUsersEndpoint.ts +1 -1
  204. package/src/endpoints/organization/dashboard/users/GetOrganizationAdminsEndpoint.ts +1 -1
  205. package/src/endpoints/organization/dashboard/users/PatchApiUserEndpoint.ts +4 -6
  206. package/src/endpoints/organization/dashboard/webshops/CreateWebshopEndpoint.ts +10 -15
  207. package/src/endpoints/organization/dashboard/webshops/DeleteWebshopEndpoint.ts +1 -1
  208. package/src/endpoints/organization/dashboard/webshops/GetDiscountCodesEndpoint.ts +2 -2
  209. package/src/endpoints/organization/dashboard/webshops/GetWebshopOrdersCountEndpoint.ts +1 -1
  210. package/src/endpoints/organization/dashboard/webshops/GetWebshopOrdersEndpoint.ts +1 -1
  211. package/src/endpoints/organization/dashboard/webshops/GetWebshopTicketsEndpoint.ts +1 -1
  212. package/src/endpoints/organization/dashboard/webshops/GetWebshopUriAvailabilityEndpoint.ts +11 -2
  213. package/src/endpoints/organization/dashboard/webshops/PatchDiscountCodesEndpoint.ts +4 -6
  214. package/src/endpoints/organization/dashboard/webshops/PatchWebshopEndpoint.ts +29 -8
  215. package/src/endpoints/organization/dashboard/webshops/PatchWebshopOrdersEndpoint.ts +21 -28
  216. package/src/endpoints/organization/dashboard/webshops/PatchWebshopTicketsEndpoint.ts +1 -1
  217. package/src/endpoints/organization/dashboard/webshops/SearchUitpasEventsEndpoint.ts +2 -2
  218. package/src/endpoints/organization/dashboard/webshops/VerifyWebshopDomainEndpoint.ts +2 -3
  219. package/src/endpoints/organization/dashboard/webshops/WebshopReservedPathSegments.test.ts +95 -0
  220. package/src/endpoints/organization/shared/ExchangePaymentEndpoint.ts +15 -13
  221. package/src/endpoints/organization/shared/GetDocumentHtml.ts +1 -1
  222. package/src/endpoints/organization/shared/GetPaymentEndpoint.ts +1 -1
  223. package/src/endpoints/organization/shared/GetUitpasNumberDetailsEndpoint.ts +3 -5
  224. package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.ts +1 -1
  225. package/src/endpoints/organization/webshops/CheckWebshopDiscountCodesEndpoint.ts +4 -1
  226. package/src/endpoints/organization/webshops/GetOrderByPaymentEndpoint.ts +14 -3
  227. package/src/endpoints/organization/webshops/GetOrderEndpoint.ts +14 -2
  228. package/src/endpoints/organization/webshops/GetTicketsEndpoint.ts +37 -16
  229. package/src/endpoints/organization/webshops/GetWebshopEndpoint.test.ts +34 -2
  230. package/src/endpoints/organization/webshops/GetWebshopEndpoint.ts +4 -2
  231. package/src/endpoints/organization/webshops/PlaceOrderEndpoint.test.ts +74 -3
  232. package/src/endpoints/organization/webshops/PlaceOrderEndpoint.ts +28 -50
  233. package/src/endpoints/organization/webshops/RetrieveUitpasSocialTariffPriceEndpoint.ts +3 -5
  234. package/src/endpoints/organization/webshops/WebshopAuthHelper.ts +36 -0
  235. package/src/endpoints/system/HealthEndpoint.ts +1 -1
  236. package/src/excel-loaders/balance-items.ts +1 -1
  237. package/src/excel-loaders/event-notifications.ts +1 -1
  238. package/src/excel-loaders/members.ts +1 -1
  239. package/src/excel-loaders/organizations.ts +3 -3
  240. package/src/excel-loaders/payments.ts +31 -1
  241. package/src/excel-loaders/platform-memberships.ts +13 -14
  242. package/src/excel-loaders/receivable-balances.ts +2 -2
  243. package/src/excel-loaders/registrations.ts +2 -3
  244. package/src/helpers/AddressValidator.ts +7 -14
  245. package/src/helpers/AdminPermissionChecker.ts +60 -65
  246. package/src/helpers/AuthenticatedStructures.ts +153 -51
  247. package/src/helpers/BalanceItemRelationsBackfiller.test.ts +174 -0
  248. package/src/helpers/BalanceItemRelationsBackfiller.ts +163 -0
  249. package/src/helpers/BuckarooHelper.ts +2 -4
  250. package/src/helpers/CheckSettlements.ts +12 -24
  251. package/src/helpers/Context.ts +15 -10
  252. package/src/helpers/CookieHelper.ts +1 -2
  253. package/src/helpers/EmailResumer.ts +1 -2
  254. package/src/helpers/FileCache.ts +2 -3
  255. package/src/helpers/FinancialSupportHelper.ts +21 -0
  256. package/src/helpers/FlagMomentCleanup.ts +1 -2
  257. package/src/helpers/ForwardHandler.ts +5 -10
  258. package/src/helpers/GlobalHelper.ts +3 -3
  259. package/src/helpers/LegacyBillingConverter.ts +787 -0
  260. package/src/helpers/MemberMerger.test.ts +782 -0
  261. package/src/helpers/MemberMerger.ts +600 -0
  262. package/src/helpers/MemberUserSyncer.ts +6 -12
  263. package/src/helpers/MembershipCharger.ts +2 -4
  264. package/src/helpers/PaymentCustomerResolver.test.ts +203 -0
  265. package/src/helpers/PaymentCustomerResolver.ts +144 -0
  266. package/src/helpers/PeriodHelper.ts +2 -3
  267. package/src/helpers/RecordAnswerHelper.test.ts +741 -0
  268. package/src/helpers/RecordAnswerHelper.ts +116 -0
  269. package/src/helpers/SeedTools.ts +106 -0
  270. package/src/helpers/ServiceFeeHelper.ts +125 -15
  271. package/src/helpers/SetupStepUpdater.ts +38 -32
  272. package/src/helpers/StamhoofdFilterAccessHelper.ts +52 -0
  273. package/src/helpers/StripeHelper.ts +15 -38
  274. package/src/helpers/StripeInvoicer.ts +419 -0
  275. package/src/helpers/StripePayoutChecker.ts +5 -10
  276. package/src/helpers/TagHelper.ts +7 -8
  277. package/src/helpers/TemporaryMemberAccess.ts +1 -2
  278. package/src/helpers/ThrottledQueue.ts +1 -2
  279. package/src/helpers/UitpasTokenRepository.ts +1 -2
  280. package/src/helpers/ViesHelper.ts +11 -11
  281. package/src/helpers/XlsxTransformerColumnHelper.ts +1 -1
  282. package/src/helpers/outstandingBalanceJoin.ts +2 -2
  283. package/src/helpers/updateMemberDetailsUitpasNumber.ts +3 -5
  284. package/src/migrate.ts +12 -5
  285. package/src/{seeds → migrations}/0000000004-single-organization.ts +10 -1
  286. package/src/migrations/0000000006-default-organization.ts +139 -0
  287. package/src/{seeds → migrations}/1715028563-user-permissions.ts +17 -27
  288. package/src/{seeds/1765896674-document-update-year.test.ts → migrations/1750090029-document-update-year.test.ts} +27 -26
  289. package/src/migrations/1750090029-document-update-year.ts +103 -0
  290. package/src/migrations/1750090030-records-configuration.ts +92 -0
  291. package/src/migrations/1750090031-records-configuration-webshops.ts +36 -0
  292. package/src/migrations/1752848540-national-numbers.ts +585 -0
  293. package/src/migrations/1752848550-records-configuration-group-filter.ts +1064 -0
  294. package/src/{seeds → migrations}/1752848561-groups-registration-periods.ts +95 -27
  295. package/src/{seeds → migrations}/1754560914-groups-prices.test.ts +1 -1
  296. package/src/{seeds → migrations}/1754560914-groups-prices.ts +9 -15
  297. package/src/{seeds → migrations}/1756293699-fill-previous-next-period-id.ts +1 -2
  298. package/src/migrations/1761665607-sync-member-users.ts +40 -0
  299. package/src/migrations/1779121239-default-invoice-email-template.sql +3 -0
  300. package/src/migrations/1779121240-invoice-email-template.sql +6 -0
  301. package/src/migrations/1779986893-default-payment-failed-email-templates.sql +4 -0
  302. package/src/migrations/1780578166-convert-legacy-billing.ts +13 -0
  303. package/src/{seeds/1755876819-remove-duplicate-members.ts → migrations/1780665426-remove-duplicate-members.ts} +23 -4
  304. package/src/migrations/1780933598-document-groups.ts +88 -0
  305. package/src/migrations/1781692342-balance-item-relations.ts +13 -0
  306. package/src/migrations/1781857866-platform-admins.ts +103 -0
  307. package/src/migrations/1781857867-rm-old-platform-admins.ts +25 -0
  308. package/src/seeds/0000000001-throw.ts +5 -0
  309. package/src/seeds/1760702452-update-balance-price-paid.ts +19 -0
  310. package/src/seeds/1760702453-update-balance-invoiced.ts +19 -0
  311. package/src/seeds/1760702454-update-cached-outstanding-balance-from-items.ts +51 -14
  312. package/src/seeds/1773754928-force-save-members.ts +41 -8
  313. package/src/seeds/1780665427-schedule-stock-updates.ts +45 -0
  314. package/src/seeds/1780665428-group-update-occupancy.ts +31 -0
  315. package/src/seeds/1780915001-fill-payment-customer.ts +70 -0
  316. package/src/seeds/1780915002-update-orders.ts +39 -0
  317. package/src/seeds/1782047708-organization-company-address.ts +44 -0
  318. package/src/seeds-temporary/1769088653-uitpas-status.ts +1 -2
  319. package/src/seeds-temporary/1780416000-migrate-audit-log-legacy-enums.test.ts +69 -0
  320. package/src/seeds-temporary/1780416000-migrate-audit-log-legacy-enums.ts +85 -0
  321. package/src/services/AuditLogService.test.ts +51 -0
  322. package/src/services/AuditLogService.ts +45 -0
  323. package/src/services/BalanceItemService.ts +148 -55
  324. package/src/services/CpuService.ts +3 -6
  325. package/src/services/DatabaseCollationService.test.ts +1 -2
  326. package/src/services/DocumentService.ts +1 -2
  327. package/src/services/EventNotificationService.ts +1 -1
  328. package/src/services/FileSignService.ts +2 -4
  329. package/src/services/InvoicePdfService.ts +286 -0
  330. package/src/services/InvoiceService.ts +330 -77
  331. package/src/services/InvoiceXMLService.ts +424 -0
  332. package/src/services/MemberNumberService.ts +6 -11
  333. package/src/services/MemberRecordStore.ts +8 -10
  334. package/src/services/MollieService.ts +530 -0
  335. package/src/services/PaymentMandateService.ts +214 -0
  336. package/src/services/PaymentReallocationService.test.ts +1 -1
  337. package/src/services/PaymentReallocationService.ts +7 -9
  338. package/src/services/PaymentService.ts +820 -328
  339. package/src/services/PlatformMembershipService.ts +5 -9
  340. package/src/services/ReferralService.ts +223 -0
  341. package/src/services/RegistrationService.ts +125 -54
  342. package/src/services/SSOService.test.ts +119 -0
  343. package/src/services/SSOService.ts +56 -49
  344. package/src/services/STPackageService.ts +97 -68
  345. package/src/services/UniqueMemberNumberService.ts +69 -0
  346. package/src/services/UniqueUserService.ts +3 -6
  347. package/src/services/VATService.ts +85 -0
  348. package/src/services/data/invoice.hbs.html +686 -0
  349. package/src/services/uitpas/PassholderEndpoints.ts +3 -6
  350. package/src/services/uitpas/UitpasService.ts +6 -10
  351. package/src/services/uitpas/checkUitpasNumbers.ts +2 -4
  352. package/src/services/uitpas/getSocialTariffForUitpasNumbers.ts +3 -6
  353. package/src/services/uitpas/searchUitpasEvents.ts +1 -2
  354. package/src/sql-filters/audit-logs.ts +1 -1
  355. package/src/sql-filters/balance-item-payments.ts +1 -1
  356. package/src/sql-filters/balance-items.ts +1 -1
  357. package/src/sql-filters/base-registration-filter-compilers.ts +5 -33
  358. package/src/sql-filters/document-templates.ts +1 -1
  359. package/src/sql-filters/documents.ts +1 -1
  360. package/src/sql-filters/email-recipients.ts +1 -1
  361. package/src/sql-filters/emails.ts +1 -1
  362. package/src/sql-filters/event-notifications.ts +1 -1
  363. package/src/sql-filters/events.ts +6 -1
  364. package/src/sql-filters/groups.ts +16 -1
  365. package/src/sql-filters/invoiced-balance-items.ts +1 -1
  366. package/src/sql-filters/invoices.ts +1 -1
  367. package/src/sql-filters/member-responsibility-records.ts +1 -1
  368. package/src/sql-filters/members.ts +1 -1
  369. package/src/sql-filters/orders.ts +4 -4
  370. package/src/sql-filters/organization-registration-periods.ts +1 -1
  371. package/src/sql-filters/organizations.ts +1 -1
  372. package/src/sql-filters/payments.ts +5 -0
  373. package/src/sql-filters/platform-memberships.ts +3 -3
  374. package/src/sql-filters/receivable-balances.ts +1 -1
  375. package/src/sql-filters/registration-invitations.ts +90 -0
  376. package/src/sql-filters/registration-periods.ts +1 -1
  377. package/src/sql-filters/registrations.ts +1 -1
  378. package/src/sql-filters/tickets.ts +1 -1
  379. package/src/sql-filters/users.ts +1 -1
  380. package/src/sql-sorters/groups.ts +23 -0
  381. package/src/sql-sorters/platform-memberships.ts +16 -16
  382. package/src/sql-sorters/registration-invitations.ts +36 -0
  383. package/tests/actions/patchOrganizationMember.ts +1 -1
  384. package/tests/actions/patchUserMember.ts +1 -1
  385. package/tests/assertions/assertBalances.ts +6 -12
  386. package/tests/e2e/api-rate-limits.test.ts +12 -24
  387. package/tests/e2e/bundle-discounts.test.ts +4 -1
  388. package/tests/e2e/charge-members.test.ts +13 -11
  389. package/tests/e2e/documents.test.ts +4 -1
  390. package/tests/e2e/register.test.ts +7 -9
  391. package/tests/e2e/stock.test.ts +4 -3
  392. package/tests/e2e/tickets.test.ts +1 -1
  393. package/tests/helpers/MollieMocker.ts +462 -0
  394. package/tests/helpers/PayconiqMocker.ts +138 -45
  395. package/tests/helpers/StripeMocker.ts +9 -6
  396. package/tests/helpers/index.ts +4 -0
  397. package/tests/init/initAdmin.ts +2 -2
  398. package/tests/init/initBundleDiscount.ts +1 -1
  399. package/tests/init/initMembershipOrganization.ts +13 -0
  400. package/tests/init/initPermissionRole.ts +3 -4
  401. package/tests/vitest.global.setup.ts +1 -1
  402. package/vitest.config.js +7 -0
  403. package/.nvmrc +0 -1
  404. package/src/endpoints/global/billing/ActivatePackagesEndpoint.ts +0 -216
  405. package/src/helpers/GroupBuilder.ts +0 -418
  406. package/src/seeds/0000000000-example.ts +0 -11
  407. package/src/seeds/1722256498-group-update-occupancy.ts +0 -52
  408. package/src/seeds/1726572303-schedule-stock-updates.ts +0 -52
  409. package/src/seeds/1726847064-setup-steps.ts +0 -16
  410. package/src/seeds/1728928974-update-cached-outstanding-balance-from-items.ts +0 -31
  411. package/src/seeds/1729253172-update-orders.ts +0 -21
  412. package/src/seeds/1733319079-fill-paying-organization-ids.ts +0 -68
  413. package/src/seeds/1733748412-update-deleted-order-numbers.ts +0 -109
  414. package/src/seeds/1733994455-balance-item-status-open.ts +0 -30
  415. package/src/seeds/1740046783-update-membership.ts +0 -17
  416. package/src/seeds/1741008870-fix-auditlog-description.ts +0 -50
  417. package/src/seeds/1741011468-fix-auditlog-description-uft16.ts +0 -88
  418. package/src/seeds/1741268179-fix-group-dates-of-events.ts +0 -32
  419. package/src/seeds/1750090030-records-configuration.ts +0 -26
  420. package/src/seeds/1751445358-upload-email-attachments.ts +0 -106
  421. package/src/seeds/1755532883-update-email-sender-ids.ts +0 -47
  422. package/src/seeds/1755790070-fill-email-recipient-errors.ts +0 -96
  423. package/src/seeds/1756115432-remove-old-drafts.ts +0 -16
  424. package/src/seeds/1756115433-fill-email-recipient-organization-id.ts +0 -30
  425. package/src/seeds/1756303697-update-email-counts.ts +0 -76
  426. package/src/seeds/1761665607-sync-member-users.ts +0 -59
  427. package/src/seeds/1765896674-document-update-year.ts +0 -66
  428. /package/src/{seeds → migrations}/0000000001-development-user.ts +0 -0
  429. /package/src/{seeds → migrations}/0000000002-clear-stamhoofd-email-templates.ts +0 -0
  430. /package/src/{seeds → migrations}/0000000003-default-email-templates.ts +0 -0
  431. /package/src/{seeds → migrations}/1752848561-groups-registration-periods.test.ts +0 -0
  432. /package/src/{seeds → migrations}/1766150402-document-published-at.test.ts +0 -0
  433. /package/src/{seeds → migrations}/1766150402-document-published-at.ts +0 -0
  434. /package/src/{seeds → migrations}/data/default-email-templates.sql +0 -0
@@ -0,0 +1,782 @@
1
+ import {
2
+ Address,
3
+ BooleanStatus,
4
+ EmergencyContact,
5
+ Gender,
6
+ MemberDetails,
7
+ Parent,
8
+ RecordAnswer,
9
+ RecordSettings,
10
+ ReviewTime,
11
+ ReviewTimes,
12
+ TranslatedString,
13
+ UitpasNumberDetails,
14
+ UitpasSocialTariff,
15
+ UitpasSocialTariffStatus,
16
+ } from '@stamhoofd/structures';
17
+ import { Country } from '@stamhoofd/types/Country';
18
+ import { v4 as uuidv4 } from 'uuid';
19
+ import { Member } from '@stamhoofd/models';
20
+ import { mergeMemberDetails, selectBaseMember } from './MemberMerger.js';
21
+
22
+ describe('member merge', () => {
23
+ describe('mergeMemberDetails', () => {
24
+ describe('empty base details', () => {
25
+ // #region arrange
26
+ const m1 = new Member();
27
+ const m2 = new Member();
28
+ const d1Old = MemberDetails.create({
29
+ firstName: ' ',
30
+ lastName: '',
31
+ birthDay: undefined,
32
+ memberNumber: undefined,
33
+ uitpasNumberDetails: undefined,
34
+ email: ' ',
35
+ phone: undefined,
36
+ gender: Gender.Other,
37
+ requiresFinancialSupport: undefined,
38
+ dataPermissions: undefined,
39
+ address: undefined,
40
+ parents: [],
41
+ emergencyContacts: [],
42
+ reviewTimes: undefined,
43
+ recordAnswers: undefined,
44
+ unverifiedEmails: [],
45
+ unverifiedPhones: [],
46
+ unverifiedAddresses: [],
47
+ notes: undefined,
48
+ });
49
+
50
+ const recordAnswer = RecordAnswer.create({
51
+ settings: RecordSettings.create({
52
+ name: TranslatedString.create('answer1'),
53
+ required: true,
54
+ choices: [],
55
+ }),
56
+ });
57
+
58
+ const d2Old = MemberDetails.create({
59
+ firstName: 'John',
60
+ lastName: 'Doe',
61
+ birthDay: new Date(1990, 1, 1),
62
+ memberNumber: '123',
63
+ uitpasNumberDetails: UitpasNumberDetails.create({
64
+ uitpasNumber: '56',
65
+ }),
66
+ email: 'b7v2x@example.com',
67
+ phone: '04863544',
68
+ gender: Gender.Male,
69
+ requiresFinancialSupport: BooleanStatus.create({ value: true }),
70
+ dataPermissions: BooleanStatus.create({ value: true }),
71
+ address: Address.create({
72
+ city: 'Amsterdam',
73
+ street: 'Mozartstraat',
74
+ number: '1',
75
+ postalCode: '1011AB',
76
+ country: Country.Netherlands,
77
+ }),
78
+ parents: [Parent.create({ firstName: 'John', lastName: 'Doe' })],
79
+ emergencyContacts: [
80
+ EmergencyContact.create({
81
+ name: 'blabla',
82
+ title: 'title',
83
+ phone: '04863544654',
84
+ }),
85
+ ],
86
+ reviewTimes: ReviewTimes.create({
87
+ times: [
88
+ ReviewTime.create({
89
+ name: 'parents',
90
+ reviewedAt: new Date(2020, 1, 1),
91
+ }),
92
+ ReviewTime.create({
93
+ name: 'details',
94
+ reviewedAt: new Date(2021, 1, 1),
95
+ }),
96
+ ],
97
+ }),
98
+ recordAnswers: new Map([[recordAnswer.id, recordAnswer]]),
99
+ unverifiedEmails: ['email1@test.be', 'email2@test.be'],
100
+ unverifiedPhones: ['04863545', '04863546'],
101
+ unverifiedAddresses: [
102
+ Address.create({
103
+ city: 'Amsterdam',
104
+ street: 'Mozartstraat',
105
+ number: '2',
106
+ postalCode: '1011AB',
107
+ country: Country.Netherlands,
108
+ }),
109
+ ],
110
+ notes: 'note1',
111
+ });
112
+
113
+ m1.details = d1Old.clone();
114
+ m2.details = d2Old.clone();
115
+ // #endregion
116
+
117
+ // act
118
+ let d1: MemberDetails;
119
+
120
+ beforeAll(() => {
121
+ mergeMemberDetails(m1, m2);
122
+ d1 = m1.details;
123
+ });
124
+
125
+ // assert
126
+ test('firstName', () => {
127
+ expect(d1.firstName).toBe(d2Old.firstName);
128
+ });
129
+
130
+ test('lastName', () => {
131
+ expect(d1.lastName).toBe(d2Old.lastName);
132
+ });
133
+
134
+ test('memberNumber', () => {
135
+ expect(d1.memberNumber).toBe(d2Old.memberNumber);
136
+ });
137
+
138
+ test('uitpasNumber', () => {
139
+ expect(d1.uitpasNumberDetails?.uitpasNumber).toBe(d2Old.uitpasNumberDetails?.uitpasNumber);
140
+ });
141
+
142
+ test('email', () => {
143
+ expect(d1.email).toBe(d2Old.email);
144
+ expect(d1.unverifiedEmails).not.toContain(d2Old.email);
145
+ });
146
+
147
+ test('phone', () => {
148
+ expect(d1.phone).toBe(d2Old.phone);
149
+ expect(d1.unverifiedPhones).not.toContain(d2Old.phone);
150
+ });
151
+
152
+ test('gender', () => {
153
+ expect(d1.gender).toBe(d2Old.gender);
154
+ });
155
+
156
+ test('birthDay', () => {
157
+ expect(d1.birthDay?.getTime() ?? -1).toBe(
158
+ d2Old.birthDay?.getTime() ?? -1,
159
+ );
160
+ });
161
+
162
+ test('requires financial support', () => {
163
+ expect(d1.requiresFinancialSupport?.date.getTime() ?? -1).toBe(
164
+ d2Old.requiresFinancialSupport?.date.getTime() ?? -1,
165
+ );
166
+ });
167
+
168
+ test('data permissions', () => {
169
+ expect(d1.dataPermissions?.date.getTime() ?? -1).toBe(
170
+ d2Old.dataPermissions?.date.getTime() ?? -1,
171
+ );
172
+ });
173
+
174
+ test('address', () => {
175
+ expect(d1.address?.id).toBe(d2Old.address?.id);
176
+ });
177
+
178
+ test('parents', () => {
179
+ expect(d1.parents.length).toBe(d2Old.parents.length);
180
+ });
181
+
182
+ test('emergency contacts', () => {
183
+ expect(d1.emergencyContacts.length).toBe(
184
+ d2Old.emergencyContacts.length,
185
+ );
186
+ });
187
+
188
+ test('review times', () => {
189
+ expect(d1.reviewTimes.times.length).toBe(
190
+ d2Old.reviewTimes.times.length,
191
+ );
192
+ });
193
+
194
+ test('answers', () => {
195
+ expect(d1.recordAnswers.size).toBe(d2Old.recordAnswers.size);
196
+ });
197
+
198
+ test('unverifiedEmails', () => {
199
+ expect(d1.unverifiedEmails.length).toBe(d2Old.unverifiedEmails.length);
200
+ });
201
+
202
+ test('unverifiedPhones', () => {
203
+ expect(d1.unverifiedPhones.length).toBe(d2Old.unverifiedPhones.length);
204
+ });
205
+
206
+ test('unverifiedAddresses', () => {
207
+ expect(d1.unverifiedAddresses.length).toBe(
208
+ d2Old.unverifiedAddresses.length,
209
+ );
210
+ });
211
+
212
+ test('notes', () => {
213
+ expect(d1.notes).toEqual('note1');
214
+ });
215
+ });
216
+
217
+ describe('empty other details', () => {
218
+ // #region arrange
219
+ const m1 = new Member();
220
+ const m2 = new Member();
221
+
222
+ const recordAnswer = RecordAnswer.create({
223
+ settings: RecordSettings.create({
224
+ name: TranslatedString.create('answer1'),
225
+ required: true,
226
+ choices: [],
227
+ }),
228
+ });
229
+
230
+ const d1Old = MemberDetails.create({
231
+ firstName: 'John',
232
+ lastName: 'Doe',
233
+ birthDay: new Date(1990, 1, 1),
234
+ memberNumber: '123',
235
+ uitpasNumberDetails: UitpasNumberDetails.create({
236
+ uitpasNumber: '56',
237
+ }),
238
+ email: 'b7v2x@example.com',
239
+ phone: '04863544',
240
+ gender: Gender.Male,
241
+ requiresFinancialSupport: BooleanStatus.create({ value: true }),
242
+ dataPermissions: BooleanStatus.create({ value: true }),
243
+ address: Address.create({
244
+ city: 'Amsterdam',
245
+ street: 'Mozartstraat',
246
+ number: '1',
247
+ postalCode: '1011AB',
248
+ country: Country.Netherlands,
249
+ }),
250
+ parents: [Parent.create({ firstName: 'John', lastName: 'Doe' })],
251
+ emergencyContacts: [
252
+ EmergencyContact.create({
253
+ name: 'blabla',
254
+ title: 'title',
255
+ phone: '04863544654',
256
+ }),
257
+ ],
258
+ reviewTimes: ReviewTimes.create({
259
+ times: [
260
+ ReviewTime.create({
261
+ name: 'parents',
262
+ reviewedAt: new Date(2020, 1, 1),
263
+ }),
264
+ ReviewTime.create({
265
+ name: 'details',
266
+ reviewedAt: new Date(2021, 1, 1),
267
+ }),
268
+ ],
269
+ }),
270
+ recordAnswers: new Map([[recordAnswer.id, recordAnswer]]),
271
+ unverifiedEmails: ['email1@test.be', 'email2@test.be'],
272
+ unverifiedPhones: ['04863545', '04863546'],
273
+ unverifiedAddresses: [
274
+ Address.create({
275
+ city: 'Amsterdam',
276
+ street: 'Mozartstraat',
277
+ number: '2',
278
+ postalCode: '1011AB',
279
+ country: Country.Netherlands,
280
+ }),
281
+ ],
282
+ notes: 'note1',
283
+ });
284
+
285
+ const d2Old = MemberDetails.create({
286
+ firstName: ' ',
287
+ lastName: '',
288
+ birthDay: undefined,
289
+ memberNumber: undefined,
290
+ uitpasNumberDetails: undefined,
291
+ email: ' ',
292
+ phone: undefined,
293
+ gender: Gender.Other,
294
+ requiresFinancialSupport: undefined,
295
+ dataPermissions: undefined,
296
+ address: undefined,
297
+ parents: [],
298
+ emergencyContacts: [],
299
+ reviewTimes: undefined,
300
+ recordAnswers: undefined,
301
+ unverifiedEmails: [],
302
+ unverifiedPhones: [],
303
+ unverifiedAddresses: [],
304
+ notes: undefined,
305
+ });
306
+
307
+ m1.details = d1Old.clone();
308
+ m2.details = d2Old.clone();
309
+ // #endregion
310
+
311
+ // act
312
+ let d1: MemberDetails;
313
+
314
+ beforeAll(() => {
315
+ mergeMemberDetails(m1, m2);
316
+ d1 = m1.details;
317
+ });
318
+
319
+ // assert
320
+ test('firstName', () => {
321
+ expect(d1.firstName).toBe(d1Old.firstName);
322
+ });
323
+
324
+ test('lastName', () => {
325
+ expect(d1.lastName).toBe(d1Old.lastName);
326
+ });
327
+
328
+ test('memberNumber', () => {
329
+ expect(d1.memberNumber).toBe(d1Old.memberNumber);
330
+ });
331
+
332
+ test('uitpasNumber', () => {
333
+ expect(d1.uitpasNumberDetails?.uitpasNumber).toBe(d1Old.uitpasNumberDetails?.uitpasNumber);
334
+ });
335
+
336
+ test('email', () => {
337
+ expect(d1.email).toBe(d1Old.email);
338
+ expect(d1.unverifiedEmails).not.toContain(d2Old.email);
339
+ });
340
+
341
+ test('phone', () => {
342
+ expect(d1.phone).toBe(d1Old.phone);
343
+ expect(d1.unverifiedPhones).not.toContain(d2Old.phone);
344
+ });
345
+
346
+ test('gender', () => {
347
+ expect(d1.gender).toBe(d1Old.gender);
348
+ });
349
+
350
+ test('birthDay', () => {
351
+ expect(d1.birthDay?.getTime() ?? -1).toBe(
352
+ d1Old.birthDay?.getTime() ?? -1,
353
+ );
354
+ });
355
+
356
+ test('requires financial support', () => {
357
+ expect(d1.requiresFinancialSupport?.date.getTime() ?? -1).toBe(
358
+ d1Old.requiresFinancialSupport?.date.getTime() ?? -1,
359
+ );
360
+ });
361
+
362
+ test('data permissions', () => {
363
+ expect(d1.dataPermissions?.date.getTime() ?? -1).toBe(
364
+ d1Old.dataPermissions?.date.getTime() ?? -1,
365
+ );
366
+ });
367
+
368
+ test('address', () => {
369
+ expect(d1.address?.id).toBe(d1Old.address?.id);
370
+ });
371
+
372
+ test('parents', () => {
373
+ expect(d1.parents.length).toBe(d1Old.parents.length);
374
+ });
375
+
376
+ test('emergency contacts', () => {
377
+ expect(d1.emergencyContacts.length).toBe(
378
+ d1Old.emergencyContacts.length,
379
+ );
380
+ });
381
+
382
+ test('review times', () => {
383
+ expect(d1.reviewTimes.times.length).toBe(
384
+ d1Old.reviewTimes.times.length,
385
+ );
386
+ });
387
+
388
+ test('answers', () => {
389
+ expect(d1.recordAnswers.size).toBe(d1Old.recordAnswers.size);
390
+ });
391
+
392
+ test('unverifiedEmails', () => {
393
+ expect(d1.unverifiedEmails.length).toBe(d1Old.unverifiedEmails.length);
394
+ });
395
+
396
+ test('unverifiedPhones', () => {
397
+ expect(d1.unverifiedPhones.length).toBe(d1Old.unverifiedPhones.length);
398
+ });
399
+
400
+ test('unverifiedAddresses', () => {
401
+ expect(d1.unverifiedAddresses.length).toBe(
402
+ d1Old.unverifiedAddresses.length,
403
+ );
404
+ });
405
+
406
+ test('notes', () => {
407
+ expect(d1.notes).toEqual('note1');
408
+ });
409
+ });
410
+
411
+ describe('complete base and other details', () => {
412
+ // #region arrange
413
+ const m1 = new Member();
414
+ const m2 = new Member();
415
+
416
+ const recordAnswer1 = RecordAnswer.create({
417
+ settings: RecordSettings.create({
418
+ name: TranslatedString.create('answer1'),
419
+ required: true,
420
+ choices: [],
421
+ }),
422
+ });
423
+
424
+ const recordAnswer1b = recordAnswer1.clone();
425
+ recordAnswer1b.date = new Date(1990, 1, 1);
426
+
427
+ const recordAnswer2 = RecordAnswer.create({
428
+ settings: RecordSettings.create({
429
+ name: TranslatedString.create('answer2'),
430
+ required: true,
431
+ choices: [],
432
+ }),
433
+ });
434
+
435
+ // will not changed because cloned
436
+ const oldParent1 = Parent.create({
437
+ firstName: 'John',
438
+ lastName: 'Doe',
439
+ email: 'john@test.be',
440
+ phone: '04111111',
441
+ });
442
+
443
+ const parent1Alt = Parent.create({
444
+ firstName: 'John',
445
+ lastName: 'Doe',
446
+ email: 'oldJohn@test.be',
447
+ phone: '0499999',
448
+ address: Address.create({
449
+ street: 'John street',
450
+ number: '5',
451
+ city: 'Amsterdam',
452
+ postalCode: '1011AB',
453
+ country: Country.Belgium,
454
+ }),
455
+ });
456
+
457
+ const d1Old = MemberDetails.create({
458
+ firstName: 'Jöhn',
459
+ lastName: 'Dôe',
460
+ birthDay: new Date(1990, 1, 1),
461
+ memberNumber: '123',
462
+ uitpasNumberDetails: UitpasNumberDetails.create({
463
+ uitpasNumber: '56',
464
+ socialTariff: UitpasSocialTariff.create({
465
+ status: UitpasSocialTariffStatus.Unknown,
466
+ updatedAt: new Date(2000, 0, 1),
467
+ }),
468
+ }),
469
+ email: 'b7v2x@example.com',
470
+ phone: '04863544',
471
+ gender: Gender.Male,
472
+ requiresFinancialSupport: BooleanStatus.create({
473
+ value: true,
474
+ date: new Date(2021, 1, 1),
475
+ }),
476
+ dataPermissions: BooleanStatus.create({
477
+ value: true,
478
+ date: new Date(2020, 1, 1),
479
+ }),
480
+ address: Address.create({
481
+ city: 'Amsterdam',
482
+ street: 'Mozartstraat',
483
+ number: '1',
484
+ postalCode: '1011AB',
485
+ country: Country.Netherlands,
486
+ }),
487
+ parents: [oldParent1],
488
+ emergencyContacts: [
489
+ EmergencyContact.create({
490
+ name: 'blabla',
491
+ title: 'title',
492
+ phone: '04863544654',
493
+ }),
494
+ EmergencyContact.create({
495
+ name: 'blabla2',
496
+ title: 'title2',
497
+ phone: '04863544654',
498
+ }),
499
+ ],
500
+ reviewTimes: ReviewTimes.create({
501
+ times: [
502
+ ReviewTime.create({
503
+ name: 'parents',
504
+ reviewedAt: new Date(2020, 1, 1),
505
+ }),
506
+ ReviewTime.create({
507
+ name: 'details',
508
+ reviewedAt: new Date(2021, 1, 1),
509
+ }),
510
+ ],
511
+ }),
512
+ recordAnswers: new Map([[recordAnswer1.id, recordAnswer1]]),
513
+ unverifiedEmails: ['email1@test.be', 'email2@test.be'],
514
+ unverifiedPhones: ['04863545', '04863546'],
515
+ unverifiedAddresses: [
516
+ Address.create({
517
+ city: 'Amsterdam',
518
+ street: 'Mozartstraat',
519
+ number: '2',
520
+ postalCode: '1011AB',
521
+ country: Country.Netherlands,
522
+ }),
523
+ ],
524
+ notes: 'note1',
525
+ });
526
+
527
+ const d2Old = MemberDetails.create({
528
+ firstName: 'John',
529
+ lastName: 'Doe',
530
+ birthDay: new Date(2000, 1, 1),
531
+ memberNumber: '123456',
532
+ uitpasNumberDetails: UitpasNumberDetails.create({
533
+ uitpasNumber: '567',
534
+ socialTariff: UitpasSocialTariff.create({
535
+ status: UitpasSocialTariffStatus.Active,
536
+ updatedAt: new Date(2000, 0, 2),
537
+ }),
538
+ }),
539
+ email: 'other@example.com',
540
+ phone: '048635449',
541
+ gender: Gender.Female,
542
+ // earlier date
543
+ requiresFinancialSupport: BooleanStatus.create({
544
+ value: false,
545
+ date: new Date(2020, 1, 1),
546
+ }),
547
+ // older date
548
+ dataPermissions: BooleanStatus.create({
549
+ value: false,
550
+ date: new Date(2021, 1, 1),
551
+ }),
552
+ address: Address.create({
553
+ city: 'Amsterdam',
554
+ street: 'Mozartstraat',
555
+ number: '5',
556
+ postalCode: '1011AB',
557
+ country: Country.Netherlands,
558
+ }),
559
+ parents: [
560
+ parent1Alt,
561
+ Parent.create({ firstName: 'John', lastName: 'Other' }),
562
+ ],
563
+ emergencyContacts: [
564
+ EmergencyContact.create({
565
+ name: 'other emergency contact',
566
+ title: 'title',
567
+ phone: '04863544654',
568
+ }),
569
+ EmergencyContact.create({
570
+ name: 'blabla',
571
+ title: 'title',
572
+ phone: '04863544654',
573
+ }),
574
+ ],
575
+ reviewTimes: ReviewTimes.create({
576
+ times: [
577
+ ReviewTime.create({
578
+ name: 'parents',
579
+ reviewedAt: new Date(2019, 1, 1),
580
+ }),
581
+ ReviewTime.create({
582
+ name: 'details',
583
+ reviewedAt: new Date(2023, 1, 1),
584
+ }),
585
+ ],
586
+ }),
587
+ recordAnswers: new Map([
588
+ [recordAnswer2.id, recordAnswer2],
589
+ [recordAnswer1.id, recordAnswer1],
590
+ [recordAnswer1b.id, recordAnswer1b],
591
+ ]),
592
+ unverifiedEmails: ['otherUnverivied@test.be'],
593
+ unverifiedPhones: ['0486354599', '0486354699'],
594
+ unverifiedAddresses: [
595
+ Address.create({
596
+ city: 'Amsterdam',
597
+ street: 'AndereStraat',
598
+ number: '100',
599
+ postalCode: '1011AB',
600
+ country: Country.Netherlands,
601
+ }),
602
+ ],
603
+ notes: 'note2',
604
+ });
605
+
606
+ m1.details = d1Old.clone();
607
+ m2.details = d2Old.clone();
608
+ // #endregion
609
+
610
+ // act
611
+ let d1: MemberDetails;
612
+ let parent1: Parent;
613
+
614
+ beforeAll(() => {
615
+ mergeMemberDetails(m1, m2);
616
+ d1 = m1.details;
617
+ parent1 = d1.parents.find(p => p.id === oldParent1.id)!;
618
+ });
619
+
620
+ // assert
621
+ test('firstName', () => {
622
+ expect(d1.firstName).toBe(d1Old.firstName);
623
+ });
624
+
625
+ test('lastName', () => {
626
+ expect(d1.lastName).toBe(d1Old.lastName);
627
+ });
628
+
629
+ test('memberNumber', () => {
630
+ expect(d1.memberNumber).toBe(d1Old.memberNumber);
631
+ });
632
+
633
+ test('uitpasNumber', () => {
634
+ expect(d1.uitpasNumberDetails?.uitpasNumber).toBe(d2Old.uitpasNumberDetails?.uitpasNumber);
635
+ });
636
+
637
+ test('email', () => {
638
+ expect(d1.email).toBe(d2Old.email);
639
+ expect(d1.alternativeEmails).toContain(d1Old.email);
640
+ expect(d1.unverifiedEmails).not.toContain(d1Old.email);
641
+ });
642
+
643
+ test('phone', () => {
644
+ expect(d1.phone).toBe(d2Old.phone);
645
+ expect(d1.unverifiedPhones).toContain(d1Old.phone);
646
+ });
647
+
648
+ test('gender', () => {
649
+ expect(d1.gender).toBe(d2Old.gender);
650
+ });
651
+
652
+ test('birthDay', () => {
653
+ expect(d1.birthDay?.getTime() ?? -1).toBe(
654
+ d2Old.birthDay?.getTime() ?? -1,
655
+ );
656
+ });
657
+
658
+ test('requires financial support', () => {
659
+ expect(d1.requiresFinancialSupport?.date.getTime() ?? -1).toBe(
660
+ d1Old.requiresFinancialSupport?.date.getTime() ?? -1,
661
+ );
662
+ });
663
+
664
+ test('data permissions', () => {
665
+ expect(d1.dataPermissions?.date.getTime() ?? -1).toBe(
666
+ d2Old.dataPermissions?.date.getTime() ?? -1,
667
+ );
668
+ });
669
+
670
+ test('address', () => {
671
+ expect(d1.address?.id).toBe(d2Old.address?.id);
672
+ expect(d1.unverifiedAddresses.map(a => a.id)).toContain(
673
+ d1Old.address?.id,
674
+ );
675
+ });
676
+
677
+ test('parents', () => {
678
+ expect(d1.parents.length).toBe(2);
679
+ expect(parent1.firstName).toBe(parent1Alt.firstName);
680
+ expect(parent1.lastName).toBe(parent1Alt.lastName);
681
+ expect(parent1.email).toBe(parent1Alt.email?.toLowerCase());
682
+ expect(parent1.phone).toBe(parent1Alt.phone);
683
+ expect(parent1.address?.id).toBe(parent1Alt.address?.id);
684
+ expect(d1.unverifiedPhones).toContain(oldParent1.phone);
685
+ expect(parent1.alternativeEmails).toContain(oldParent1.email!.toLocaleLowerCase());
686
+ });
687
+
688
+ test('emergency contacts', () => {
689
+ expect(d1.emergencyContacts.length).toBe(3);
690
+ });
691
+
692
+ test('review times', () => {
693
+ expect(d1.reviewTimes.times.length).toBe(2);
694
+ });
695
+
696
+ test('answers', () => {
697
+ expect(d1.recordAnswers.size).toBe(3);
698
+ });
699
+
700
+ test('unverifiedEmails', () => {
701
+ expect(d1.unverifiedEmails.sort()).toEqual([
702
+ 'email1@test.be',
703
+ 'email2@test.be',
704
+ 'otherunverivied@test.be',
705
+ ].sort());
706
+ });
707
+
708
+ test('unverifiedPhones', () => {
709
+ expect(d1.unverifiedPhones.length).toBe(6);
710
+ });
711
+
712
+ test('unverifiedAddresses', () => {
713
+ // expect(d1.unverifiedAddresses.length).toBe(3);
714
+
715
+ // Should be combination of unverified addresses + address of the second member (which coulnd't be merged)
716
+ const addressIds = d1.unverifiedAddresses.map(a => a.id);
717
+ expect(addressIds.sort()).toEqual([
718
+ d1Old.address!.id,
719
+ d1Old.unverifiedAddresses[0].id,
720
+ d2Old.unverifiedAddresses[0].id,
721
+ ].sort());
722
+ });
723
+
724
+ test('notes', () => {
725
+ expect(d1.notes).toEqual('note1\nnote2');
726
+ });
727
+ });
728
+ });
729
+
730
+ test('select base member should return last created member', () => {
731
+ const m1 = new Member();
732
+ m1.createdAt = new Date(2020, 0, 1);
733
+ m1.id = uuidv4();
734
+ const m2 = new Member();
735
+ m2.createdAt = new Date(2021, 0, 1);
736
+ m2.id = uuidv4();
737
+ const m3 = new Member();
738
+ m3.createdAt = new Date(2022, 0, 1);
739
+ m3.id = uuidv4();
740
+
741
+ const members = [m1, m3, m2];
742
+
743
+ const { base, others } = selectBaseMember(members);
744
+
745
+ expect(base.id).toBe(m3.id);
746
+
747
+ expect(others).toHaveLength(2);
748
+ const otherIds = others.map(m => m.id);
749
+ expect(otherIds).toContain(m1.id);
750
+ expect(otherIds).toContain(m2.id);
751
+ });
752
+
753
+ describe('Regressions', () => {
754
+ /**
755
+ * tests STA-460
756
+ */
757
+ test('Members with same email addreses do not get the email added as alternative email', () => {
758
+ const m1 = new Member();
759
+ const m2 = new Member();
760
+
761
+ const base = MemberDetails.create({
762
+ email: 'example@example.com',
763
+ firstName: 'John',
764
+ lastName: 'Doe',
765
+ });
766
+
767
+ const other = MemberDetails.create({
768
+ email: 'example@example.com',
769
+ firstName: 'John',
770
+ lastName: 'Doe',
771
+ });
772
+
773
+ m1.details = base.clone();
774
+ m2.details = other.clone();
775
+
776
+ mergeMemberDetails(m1, m2);
777
+
778
+ expect(m1.details.email).toBe('example@example.com');
779
+ expect(m1.details.alternativeEmails).toEqual([]);
780
+ });
781
+ });
782
+ });