@stamhoofd/models 2.1.1

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 (481) hide show
  1. package/dist/src/assets/Metropolis-Black.woff2 +0 -0
  2. package/dist/src/assets/Metropolis-BlackItalic.woff2 +0 -0
  3. package/dist/src/assets/Metropolis-Bold.woff2 +0 -0
  4. package/dist/src/assets/Metropolis-BoldItalic.woff2 +0 -0
  5. package/dist/src/assets/Metropolis-ExtraBold.woff2 +0 -0
  6. package/dist/src/assets/Metropolis-ExtraBoldItalic.woff2 +0 -0
  7. package/dist/src/assets/Metropolis-ExtraLight.woff2 +0 -0
  8. package/dist/src/assets/Metropolis-ExtraLightItalic.woff2 +0 -0
  9. package/dist/src/assets/Metropolis-Light.woff2 +0 -0
  10. package/dist/src/assets/Metropolis-LightItalic.woff2 +0 -0
  11. package/dist/src/assets/Metropolis-Medium.woff2 +0 -0
  12. package/dist/src/assets/Metropolis-MediumItalic.woff2 +0 -0
  13. package/dist/src/assets/Metropolis-Regular.woff2 +0 -0
  14. package/dist/src/assets/Metropolis-RegularItalic.woff2 +0 -0
  15. package/dist/src/assets/Metropolis-SemiBold.woff2 +0 -0
  16. package/dist/src/assets/Metropolis-SemiBoldItalic.woff2 +0 -0
  17. package/dist/src/assets/Metropolis-Thin.woff2 +0 -0
  18. package/dist/src/assets/Metropolis-ThinItalic.woff2 +0 -0
  19. package/dist/src/assets/assets/Metropolis-Black.woff2 +0 -0
  20. package/dist/src/assets/assets/Metropolis-BlackItalic.woff2 +0 -0
  21. package/dist/src/assets/assets/Metropolis-Bold.woff2 +0 -0
  22. package/dist/src/assets/assets/Metropolis-BoldItalic.woff2 +0 -0
  23. package/dist/src/assets/assets/Metropolis-ExtraBold.woff2 +0 -0
  24. package/dist/src/assets/assets/Metropolis-ExtraBoldItalic.woff2 +0 -0
  25. package/dist/src/assets/assets/Metropolis-ExtraLight.woff2 +0 -0
  26. package/dist/src/assets/assets/Metropolis-ExtraLightItalic.woff2 +0 -0
  27. package/dist/src/assets/assets/Metropolis-Light.woff2 +0 -0
  28. package/dist/src/assets/assets/Metropolis-LightItalic.woff2 +0 -0
  29. package/dist/src/assets/assets/Metropolis-Medium.woff2 +0 -0
  30. package/dist/src/assets/assets/Metropolis-MediumItalic.woff2 +0 -0
  31. package/dist/src/assets/assets/Metropolis-Regular.woff2 +0 -0
  32. package/dist/src/assets/assets/Metropolis-RegularItalic.woff2 +0 -0
  33. package/dist/src/assets/assets/Metropolis-SemiBold.woff2 +0 -0
  34. package/dist/src/assets/assets/Metropolis-SemiBoldItalic.woff2 +0 -0
  35. package/dist/src/assets/assets/Metropolis-Thin.woff2 +0 -0
  36. package/dist/src/assets/assets/Metropolis-ThinItalic.woff2 +0 -0
  37. package/dist/src/assets/assets/logo.png +0 -0
  38. package/dist/src/assets/logo.png +0 -0
  39. package/dist/src/factories/AddressFactory.d.ts +10 -0
  40. package/dist/src/factories/AddressFactory.d.ts.map +1 -0
  41. package/dist/src/factories/AddressFactory.js +42 -0
  42. package/dist/src/factories/AddressFactory.js.map +1 -0
  43. package/dist/src/factories/EmergencyContactFactory.d.ts +9 -0
  44. package/dist/src/factories/EmergencyContactFactory.d.ts.map +1 -0
  45. package/dist/src/factories/EmergencyContactFactory.js +42 -0
  46. package/dist/src/factories/EmergencyContactFactory.js.map +1 -0
  47. package/dist/src/factories/GroupFactory.d.ts +19 -0
  48. package/dist/src/factories/GroupFactory.d.ts.map +1 -0
  49. package/dist/src/factories/GroupFactory.js +52 -0
  50. package/dist/src/factories/GroupFactory.js.map +1 -0
  51. package/dist/src/factories/MemberFactory.d.ts +16 -0
  52. package/dist/src/factories/MemberFactory.d.ts.map +1 -0
  53. package/dist/src/factories/MemberFactory.js +98 -0
  54. package/dist/src/factories/MemberFactory.js.map +1 -0
  55. package/dist/src/factories/OrganizationFactory.d.ts +16 -0
  56. package/dist/src/factories/OrganizationFactory.d.ts.map +1 -0
  57. package/dist/src/factories/OrganizationFactory.js +40 -0
  58. package/dist/src/factories/OrganizationFactory.js.map +1 -0
  59. package/dist/src/factories/ParentFactory.d.ts +10 -0
  60. package/dist/src/factories/ParentFactory.d.ts.map +1 -0
  61. package/dist/src/factories/ParentFactory.js +44 -0
  62. package/dist/src/factories/ParentFactory.js.map +1 -0
  63. package/dist/src/factories/RecordFactory.d.ts +10 -0
  64. package/dist/src/factories/RecordFactory.d.ts.map +1 -0
  65. package/dist/src/factories/RecordFactory.js +14 -0
  66. package/dist/src/factories/RecordFactory.js.map +1 -0
  67. package/dist/src/factories/RegisterCodeFactory.d.ts +18 -0
  68. package/dist/src/factories/RegisterCodeFactory.d.ts.map +1 -0
  69. package/dist/src/factories/RegisterCodeFactory.js +19 -0
  70. package/dist/src/factories/RegisterCodeFactory.js.map +1 -0
  71. package/dist/src/factories/RegistrationFactory.d.ts +14 -0
  72. package/dist/src/factories/RegistrationFactory.d.ts.map +1 -0
  73. package/dist/src/factories/RegistrationFactory.js +26 -0
  74. package/dist/src/factories/RegistrationFactory.js.map +1 -0
  75. package/dist/src/factories/UserFactory.d.ts +21 -0
  76. package/dist/src/factories/UserFactory.d.ts.map +1 -0
  77. package/dist/src/factories/UserFactory.js +41 -0
  78. package/dist/src/factories/UserFactory.js.map +1 -0
  79. package/dist/src/factories/WebshopFactory.d.ts +16 -0
  80. package/dist/src/factories/WebshopFactory.d.ts.map +1 -0
  81. package/dist/src/factories/WebshopFactory.js +35 -0
  82. package/dist/src/factories/WebshopFactory.js.map +1 -0
  83. package/dist/src/helpers/DNSValidator.d.ts +6 -0
  84. package/dist/src/helpers/DNSValidator.d.ts.map +1 -0
  85. package/dist/src/helpers/DNSValidator.js +144 -0
  86. package/dist/src/helpers/DNSValidator.js.map +1 -0
  87. package/dist/src/helpers/EmailBuilder.d.ts +22 -0
  88. package/dist/src/helpers/EmailBuilder.d.ts.map +1 -0
  89. package/dist/src/helpers/EmailBuilder.js +100 -0
  90. package/dist/src/helpers/EmailBuilder.js.map +1 -0
  91. package/dist/src/helpers/GroupBuilder.d.ts +9 -0
  92. package/dist/src/helpers/GroupBuilder.d.ts.map +1 -0
  93. package/dist/src/helpers/GroupBuilder.js +382 -0
  94. package/dist/src/helpers/GroupBuilder.js.map +1 -0
  95. package/dist/src/helpers/Handlebars.d.ts +2 -0
  96. package/dist/src/helpers/Handlebars.d.ts.map +1 -0
  97. package/dist/src/helpers/Handlebars.js +192 -0
  98. package/dist/src/helpers/Handlebars.js.map +1 -0
  99. package/dist/src/helpers/InvoiceBuilder.d.ts +29 -0
  100. package/dist/src/helpers/InvoiceBuilder.d.ts.map +1 -0
  101. package/dist/src/helpers/InvoiceBuilder.js +406 -0
  102. package/dist/src/helpers/InvoiceBuilder.js.map +1 -0
  103. package/dist/src/helpers/InvoiceBuilder.test.d.ts +2 -0
  104. package/dist/src/helpers/InvoiceBuilder.test.d.ts.map +1 -0
  105. package/dist/src/helpers/InvoiceBuilder.test.js +52 -0
  106. package/dist/src/helpers/InvoiceBuilder.test.js.map +1 -0
  107. package/dist/src/helpers/RateLimiter.d.ts +27 -0
  108. package/dist/src/helpers/RateLimiter.d.ts.map +1 -0
  109. package/dist/src/helpers/RateLimiter.js +57 -0
  110. package/dist/src/helpers/RateLimiter.js.map +1 -0
  111. package/dist/src/helpers/WebshopCounter.d.ts +6 -0
  112. package/dist/src/helpers/WebshopCounter.d.ts.map +1 -0
  113. package/dist/src/helpers/WebshopCounter.js +36 -0
  114. package/dist/src/helpers/WebshopCounter.js.map +1 -0
  115. package/dist/src/helpers/WebshopCounter.test.d.ts +2 -0
  116. package/dist/src/helpers/WebshopCounter.test.d.ts.map +1 -0
  117. package/dist/src/helpers/WebshopCounter.test.js +17 -0
  118. package/dist/src/helpers/WebshopCounter.test.js.map +1 -0
  119. package/dist/src/index.d.ts +18 -0
  120. package/dist/src/index.d.ts.map +1 -0
  121. package/dist/src/index.js +23 -0
  122. package/dist/src/index.js.map +1 -0
  123. package/dist/src/migrations/1593773929-create-initial-tables.sql +634 -0
  124. package/dist/src/migrations/1605261999-gemeenten-tmp.sql +2820 -0
  125. package/dist/src/migrations/1605262045-import-postcodes.d.ts +16 -0
  126. package/dist/src/migrations/1605262045-import-postcodes.d.ts.map +1 -0
  127. package/dist/src/migrations/1605262045-import-postcodes.js +116 -0
  128. package/dist/src/migrations/1605262045-import-postcodes.js.map +1 -0
  129. package/dist/src/migrations/1605262046-import-postcodes-nl.d.ts +4 -0
  130. package/dist/src/migrations/1605262046-import-postcodes-nl.d.ts.map +1 -0
  131. package/dist/src/migrations/1605262046-import-postcodes-nl.js +83 -0
  132. package/dist/src/migrations/1605262046-import-postcodes-nl.js.map +1 -0
  133. package/dist/src/migrations/1605279038-drop-gemeenten-tmp.sql +1 -0
  134. package/dist/src/migrations/1648392491-default-templates.sql +9 -0
  135. package/dist/src/migrations/1651245707-default-templates-reminders.sql +6 -0
  136. package/dist/src/migrations/1708607340-tickets-deleted-at.sql +1 -0
  137. package/dist/src/migrations/1710459176-register-code-invoices.sql +3 -0
  138. package/dist/src/migrations/1712158247-discount-codes.sql +17 -0
  139. package/dist/src/migrations/1713178665-drop-invites.sql +1 -0
  140. package/dist/src/migrations/1713178666-drop-keychain.sql +1 -0
  141. package/dist/src/migrations/1713178667-drop-challenges.sql +1 -0
  142. package/dist/src/migrations/1713178668-drop-user-keys.sql +7 -0
  143. package/dist/src/migrations/1713178669-drop-organization-key.sql +2 -0
  144. package/dist/src/migrations/data/postcodes/nl/Drenthe +291 -0
  145. package/dist/src/migrations/data/postcodes/nl/Flevoland +107 -0
  146. package/dist/src/migrations/data/postcodes/nl/Friesland +518 -0
  147. package/dist/src/migrations/data/postcodes/nl/Gelderland +601 -0
  148. package/dist/src/migrations/data/postcodes/nl/Groningen +279 -0
  149. package/dist/src/migrations/data/postcodes/nl/Limburg +324 -0
  150. package/dist/src/migrations/data/postcodes/nl/Noord-Brabant +620 -0
  151. package/dist/src/migrations/data/postcodes/nl/Noord-Holland +566 -0
  152. package/dist/src/migrations/data/postcodes/nl/Overrijsel +344 -0
  153. package/dist/src/migrations/data/postcodes/nl/Utrecht +278 -0
  154. package/dist/src/migrations/data/postcodes/nl/Zeeland +179 -0
  155. package/dist/src/migrations/data/postcodes/nl/Zuid-Holland +662 -0
  156. package/dist/src/models/BalanceItem.d.ts +57 -0
  157. package/dist/src/models/BalanceItem.d.ts.map +1 -0
  158. package/dist/src/models/BalanceItem.js +346 -0
  159. package/dist/src/models/BalanceItem.js.map +1 -0
  160. package/dist/src/models/BalanceItemPayment.d.ts +31 -0
  161. package/dist/src/models/BalanceItemPayment.d.ts.map +1 -0
  162. package/dist/src/models/BalanceItemPayment.js +101 -0
  163. package/dist/src/models/BalanceItemPayment.js.map +1 -0
  164. package/dist/src/models/BuckarooPayment.d.ts +8 -0
  165. package/dist/src/models/BuckarooPayment.d.ts.map +1 -0
  166. package/dist/src/models/BuckarooPayment.js +24 -0
  167. package/dist/src/models/BuckarooPayment.js.map +1 -0
  168. package/dist/src/models/Document.d.ts +44 -0
  169. package/dist/src/models/Document.d.ts.map +1 -0
  170. package/dist/src/models/Document.js +194 -0
  171. package/dist/src/models/Document.js.map +1 -0
  172. package/dist/src/models/DocumentTemplate.d.ts +45 -0
  173. package/dist/src/models/DocumentTemplate.d.ts.map +1 -0
  174. package/dist/src/models/DocumentTemplate.js +533 -0
  175. package/dist/src/models/DocumentTemplate.js.map +1 -0
  176. package/dist/src/models/EmailTemplate.d.ts +22 -0
  177. package/dist/src/models/EmailTemplate.d.ts.map +1 -0
  178. package/dist/src/models/EmailTemplate.js +70 -0
  179. package/dist/src/models/EmailTemplate.js.map +1 -0
  180. package/dist/src/models/EmailVerificationCode.d.ts +60 -0
  181. package/dist/src/models/EmailVerificationCode.d.ts.map +1 -0
  182. package/dist/src/models/EmailVerificationCode.js +307 -0
  183. package/dist/src/models/EmailVerificationCode.js.map +1 -0
  184. package/dist/src/models/Group.d.ts +36 -0
  185. package/dist/src/models/Group.d.ts.map +1 -0
  186. package/dist/src/models/Group.js +231 -0
  187. package/dist/src/models/Group.js.map +1 -0
  188. package/dist/src/models/Image.d.ts +12 -0
  189. package/dist/src/models/Image.d.ts.map +1 -0
  190. package/dist/src/models/Image.js +137 -0
  191. package/dist/src/models/Image.js.map +1 -0
  192. package/dist/src/models/Member.d.ts +66 -0
  193. package/dist/src/models/Member.d.ts.map +1 -0
  194. package/dist/src/models/Member.js +309 -0
  195. package/dist/src/models/Member.js.map +1 -0
  196. package/dist/src/models/MemberResponsibilityRecord.d.ts +11 -0
  197. package/dist/src/models/MemberResponsibilityRecord.d.ts.map +1 -0
  198. package/dist/src/models/MemberResponsibilityRecord.js +47 -0
  199. package/dist/src/models/MemberResponsibilityRecord.js.map +1 -0
  200. package/dist/src/models/MolliePayment.d.ts +8 -0
  201. package/dist/src/models/MolliePayment.d.ts.map +1 -0
  202. package/dist/src/models/MolliePayment.js +24 -0
  203. package/dist/src/models/MolliePayment.js.map +1 -0
  204. package/dist/src/models/MollieToken.d.ts +45 -0
  205. package/dist/src/models/MollieToken.d.ts.map +1 -0
  206. package/dist/src/models/MollieToken.js +333 -0
  207. package/dist/src/models/MollieToken.js.map +1 -0
  208. package/dist/src/models/OneTimeToken.d.ts +38 -0
  209. package/dist/src/models/OneTimeToken.d.ts.map +1 -0
  210. package/dist/src/models/OneTimeToken.js +126 -0
  211. package/dist/src/models/OneTimeToken.js.map +1 -0
  212. package/dist/src/models/Order.d.ts +99 -0
  213. package/dist/src/models/Order.d.ts.map +1 -0
  214. package/dist/src/models/Order.js +912 -0
  215. package/dist/src/models/Order.js.map +1 -0
  216. package/dist/src/models/Organization.d.ts +119 -0
  217. package/dist/src/models/Organization.d.ts.map +1 -0
  218. package/dist/src/models/Organization.js +900 -0
  219. package/dist/src/models/Organization.js.map +1 -0
  220. package/dist/src/models/OrganizationRegistrationPeriod.d.ts +14 -0
  221. package/dist/src/models/OrganizationRegistrationPeriod.d.ts.map +1 -0
  222. package/dist/src/models/OrganizationRegistrationPeriod.js +62 -0
  223. package/dist/src/models/OrganizationRegistrationPeriod.js.map +1 -0
  224. package/dist/src/models/PasswordToken.d.ts +29 -0
  225. package/dist/src/models/PasswordToken.d.ts.map +1 -0
  226. package/dist/src/models/PasswordToken.js +118 -0
  227. package/dist/src/models/PasswordToken.js.map +1 -0
  228. package/dist/src/models/PayconiqPayment.d.ts +18 -0
  229. package/dist/src/models/PayconiqPayment.d.ts.map +1 -0
  230. package/dist/src/models/PayconiqPayment.js +216 -0
  231. package/dist/src/models/PayconiqPayment.js.map +1 -0
  232. package/dist/src/models/Payment.d.ts +62 -0
  233. package/dist/src/models/Payment.d.ts.map +1 -0
  234. package/dist/src/models/Payment.js +199 -0
  235. package/dist/src/models/Payment.js.map +1 -0
  236. package/dist/src/models/Platform.d.ts +15 -0
  237. package/dist/src/models/Platform.d.ts.map +1 -0
  238. package/dist/src/models/Platform.js +77 -0
  239. package/dist/src/models/Platform.js.map +1 -0
  240. package/dist/src/models/RegisterCode.d.ts +27 -0
  241. package/dist/src/models/RegisterCode.d.ts.map +1 -0
  242. package/dist/src/models/RegisterCode.js +162 -0
  243. package/dist/src/models/RegisterCode.js.map +1 -0
  244. package/dist/src/models/Registration.d.ts +47 -0
  245. package/dist/src/models/Registration.d.ts.map +1 -0
  246. package/dist/src/models/Registration.js +369 -0
  247. package/dist/src/models/Registration.js.map +1 -0
  248. package/dist/src/models/RegistrationPeriod.d.ts +15 -0
  249. package/dist/src/models/RegistrationPeriod.d.ts.map +1 -0
  250. package/dist/src/models/RegistrationPeriod.js +64 -0
  251. package/dist/src/models/RegistrationPeriod.js.map +1 -0
  252. package/dist/src/models/STCredit.d.ts +20 -0
  253. package/dist/src/models/STCredit.d.ts.map +1 -0
  254. package/dist/src/models/STCredit.js +129 -0
  255. package/dist/src/models/STCredit.js.map +1 -0
  256. package/dist/src/models/STInvoice.d.ts +51 -0
  257. package/dist/src/models/STInvoice.d.ts.map +1 -0
  258. package/dist/src/models/STInvoice.js +453 -0
  259. package/dist/src/models/STInvoice.js.map +1 -0
  260. package/dist/src/models/STPackage.d.ts +36 -0
  261. package/dist/src/models/STPackage.d.ts.map +1 -0
  262. package/dist/src/models/STPackage.js +300 -0
  263. package/dist/src/models/STPackage.js.map +1 -0
  264. package/dist/src/models/STPendingInvoice.d.ts +45 -0
  265. package/dist/src/models/STPendingInvoice.d.ts.map +1 -0
  266. package/dist/src/models/STPendingInvoice.js +284 -0
  267. package/dist/src/models/STPendingInvoice.js.map +1 -0
  268. package/dist/src/models/StripeAccount.d.ts +17 -0
  269. package/dist/src/models/StripeAccount.d.ts.map +1 -0
  270. package/dist/src/models/StripeAccount.js +81 -0
  271. package/dist/src/models/StripeAccount.js.map +1 -0
  272. package/dist/src/models/StripeCheckoutSession.d.ts +9 -0
  273. package/dist/src/models/StripeCheckoutSession.d.ts.map +1 -0
  274. package/dist/src/models/StripeCheckoutSession.js +31 -0
  275. package/dist/src/models/StripeCheckoutSession.js.map +1 -0
  276. package/dist/src/models/StripePaymentIntent.d.ts +9 -0
  277. package/dist/src/models/StripePaymentIntent.d.ts.map +1 -0
  278. package/dist/src/models/StripePaymentIntent.js +31 -0
  279. package/dist/src/models/StripePaymentIntent.js.map +1 -0
  280. package/dist/src/models/Ticket.d.ts +61 -0
  281. package/dist/src/models/Ticket.d.ts.map +1 -0
  282. package/dist/src/models/Ticket.js +143 -0
  283. package/dist/src/models/Ticket.js.map +1 -0
  284. package/dist/src/models/Token.d.ts +49 -0
  285. package/dist/src/models/Token.d.ts.map +1 -0
  286. package/dist/src/models/Token.js +218 -0
  287. package/dist/src/models/Token.js.map +1 -0
  288. package/dist/src/models/Token.test.d.ts +2 -0
  289. package/dist/src/models/Token.test.d.ts.map +1 -0
  290. package/dist/src/models/Token.test.js +60 -0
  291. package/dist/src/models/Token.test.js.map +1 -0
  292. package/dist/src/models/UsedRegisterCode.d.ts +22 -0
  293. package/dist/src/models/UsedRegisterCode.d.ts.map +1 -0
  294. package/dist/src/models/UsedRegisterCode.js +158 -0
  295. package/dist/src/models/UsedRegisterCode.js.map +1 -0
  296. package/dist/src/models/User.d.ts +55 -0
  297. package/dist/src/models/User.d.ts.map +1 -0
  298. package/dist/src/models/User.js +314 -0
  299. package/dist/src/models/User.js.map +1 -0
  300. package/dist/src/models/UserPermissions.d.ts +15 -0
  301. package/dist/src/models/UserPermissions.d.ts.map +1 -0
  302. package/dist/src/models/UserPermissions.js +57 -0
  303. package/dist/src/models/UserPermissions.js.map +1 -0
  304. package/dist/src/models/Webshop.d.ts +44 -0
  305. package/dist/src/models/Webshop.d.ts.map +1 -0
  306. package/dist/src/models/Webshop.js +184 -0
  307. package/dist/src/models/Webshop.js.map +1 -0
  308. package/dist/src/models/WebshopDiscountCode.d.ts +18 -0
  309. package/dist/src/models/WebshopDiscountCode.d.ts.map +1 -0
  310. package/dist/src/models/WebshopDiscountCode.js +88 -0
  311. package/dist/src/models/WebshopDiscountCode.js.map +1 -0
  312. package/dist/src/models/addresses/City.d.ts +14 -0
  313. package/dist/src/models/addresses/City.d.ts.map +1 -0
  314. package/dist/src/models/addresses/City.js +37 -0
  315. package/dist/src/models/addresses/City.js.map +1 -0
  316. package/dist/src/models/addresses/PostalCode.d.ts +20 -0
  317. package/dist/src/models/addresses/PostalCode.d.ts.map +1 -0
  318. package/dist/src/models/addresses/PostalCode.js +138 -0
  319. package/dist/src/models/addresses/PostalCode.js.map +1 -0
  320. package/dist/src/models/addresses/PostalCode.test.d.ts +2 -0
  321. package/dist/src/models/addresses/PostalCode.test.d.ts.map +1 -0
  322. package/dist/src/models/addresses/PostalCode.test.js +98 -0
  323. package/dist/src/models/addresses/PostalCode.test.js.map +1 -0
  324. package/dist/src/models/addresses/Province.d.ts +9 -0
  325. package/dist/src/models/addresses/Province.d.ts.map +1 -0
  326. package/dist/src/models/addresses/Province.js +24 -0
  327. package/dist/src/models/addresses/Province.js.map +1 -0
  328. package/dist/src/models/addresses/Street.d.ts +10 -0
  329. package/dist/src/models/addresses/Street.d.ts.map +1 -0
  330. package/dist/src/models/addresses/Street.js +26 -0
  331. package/dist/src/models/addresses/Street.js.map +1 -0
  332. package/dist/src/models/index.d.ts +37 -0
  333. package/dist/src/models/index.d.ts.map +1 -0
  334. package/dist/src/models/index.js +53 -0
  335. package/dist/src/models/index.js.map +1 -0
  336. package/dist/src/structures/OrganizationServerMetaData.d.ts +43 -0
  337. package/dist/src/structures/OrganizationServerMetaData.d.ts.map +1 -0
  338. package/dist/src/structures/OrganizationServerMetaData.js +128 -0
  339. package/dist/src/structures/OrganizationServerMetaData.js.map +1 -0
  340. package/dist/tests/jest.global.setup.d.ts +3 -0
  341. package/dist/tests/jest.global.setup.d.ts.map +1 -0
  342. package/dist/tests/jest.global.setup.js +20 -0
  343. package/dist/tests/jest.global.setup.js.map +1 -0
  344. package/dist/tests/jest.setup.d.ts +2 -0
  345. package/dist/tests/jest.setup.d.ts.map +1 -0
  346. package/dist/tests/jest.setup.js +15 -0
  347. package/dist/tests/jest.setup.js.map +1 -0
  348. package/package.json +30 -0
  349. package/src/assets/Metropolis-Black.woff2 +0 -0
  350. package/src/assets/Metropolis-BlackItalic.woff2 +0 -0
  351. package/src/assets/Metropolis-Bold.woff2 +0 -0
  352. package/src/assets/Metropolis-BoldItalic.woff2 +0 -0
  353. package/src/assets/Metropolis-ExtraBold.woff2 +0 -0
  354. package/src/assets/Metropolis-ExtraBoldItalic.woff2 +0 -0
  355. package/src/assets/Metropolis-ExtraLight.woff2 +0 -0
  356. package/src/assets/Metropolis-ExtraLightItalic.woff2 +0 -0
  357. package/src/assets/Metropolis-Light.woff2 +0 -0
  358. package/src/assets/Metropolis-LightItalic.woff2 +0 -0
  359. package/src/assets/Metropolis-Medium.woff2 +0 -0
  360. package/src/assets/Metropolis-MediumItalic.woff2 +0 -0
  361. package/src/assets/Metropolis-Regular.woff2 +0 -0
  362. package/src/assets/Metropolis-RegularItalic.woff2 +0 -0
  363. package/src/assets/Metropolis-SemiBold.woff2 +0 -0
  364. package/src/assets/Metropolis-SemiBoldItalic.woff2 +0 -0
  365. package/src/assets/Metropolis-Thin.woff2 +0 -0
  366. package/src/assets/Metropolis-ThinItalic.woff2 +0 -0
  367. package/src/assets/logo.png +0 -0
  368. package/src/factories/AddressFactory.ts +42 -0
  369. package/src/factories/EmergencyContactFactory.ts +43 -0
  370. package/src/factories/GroupFactory.ts +66 -0
  371. package/src/factories/MemberFactory.ts +122 -0
  372. package/src/factories/OrganizationFactory.ts +45 -0
  373. package/src/factories/ParentFactory.ts +49 -0
  374. package/src/factories/RecordFactory.ts +12 -0
  375. package/src/factories/RegisterCodeFactory.ts +25 -0
  376. package/src/factories/RegistrationFactory.ts +32 -0
  377. package/src/factories/UserFactory.ts +66 -0
  378. package/src/factories/WebshopFactory.ts +43 -0
  379. package/src/helpers/DNSValidator.ts +153 -0
  380. package/src/helpers/EmailBuilder.ts +127 -0
  381. package/src/helpers/GroupBuilder.ts +438 -0
  382. package/src/helpers/Handlebars.ts +203 -0
  383. package/src/helpers/InvoiceBuilder.test.ts +57 -0
  384. package/src/helpers/InvoiceBuilder.ts +501 -0
  385. package/src/helpers/RateLimiter.ts +75 -0
  386. package/src/helpers/WebshopCounter.test.ts +16 -0
  387. package/src/helpers/WebshopCounter.ts +36 -0
  388. package/src/index.ts +21 -0
  389. package/src/migrations/1593773929-create-initial-tables.sql +634 -0
  390. package/src/migrations/1605261999-gemeenten-tmp.sql +2820 -0
  391. package/src/migrations/1605262045-import-postcodes.ts +132 -0
  392. package/src/migrations/1605262046-import-postcodes-nl.ts +97 -0
  393. package/src/migrations/1605279038-drop-gemeenten-tmp.sql +1 -0
  394. package/src/migrations/1648392491-default-templates.sql +9 -0
  395. package/src/migrations/1651245707-default-templates-reminders.sql +6 -0
  396. package/src/migrations/1708607340-tickets-deleted-at.sql +1 -0
  397. package/src/migrations/1710459176-register-code-invoices.sql +3 -0
  398. package/src/migrations/1712158247-discount-codes.sql +17 -0
  399. package/src/migrations/1713178665-drop-invites.sql +1 -0
  400. package/src/migrations/1713178666-drop-keychain.sql +1 -0
  401. package/src/migrations/1713178667-drop-challenges.sql +1 -0
  402. package/src/migrations/1713178668-drop-user-keys.sql +7 -0
  403. package/src/migrations/1713178669-drop-organization-key.sql +2 -0
  404. package/src/migrations/1714985451-user-nullable-organization-id.sql +2 -0
  405. package/src/migrations/1714985452-email-verification-code-nullable-organization-id.sql +2 -0
  406. package/src/migrations/1714985453-user-organization-permissions.sql +2 -0
  407. package/src/migrations/1714985454-user-organization-permissions.sql +2 -0
  408. package/src/migrations/1715079362-platform.sql +6 -0
  409. package/src/migrations/1715181649-registrations-organization-id.sql +2 -0
  410. package/src/migrations/1715181650-registrations-organization-id-fill.sql +1 -0
  411. package/src/migrations/1715181651-registrations-organization-id-drop-null.sql +2 -0
  412. package/src/migrations/1716117067-members-nullable-organization-id.sql +2 -0
  413. package/src/migrations/1719567581-registration-periods.sql +13 -0
  414. package/src/migrations/1719567582-organization-registration-periods.sql +13 -0
  415. package/src/migrations/1719567881-organization-periodId.sql +2 -0
  416. package/src/migrations/1719567882-groups-periodId.sql +2 -0
  417. package/src/migrations/1719567883-platform-periodId.sql +2 -0
  418. package/src/migrations/1719568079-default-period.sql +2 -0
  419. package/src/migrations/1719568080-set-default-period-platform.sql +1 -0
  420. package/src/migrations/1719568081-set-default-period-organizations.sql +1 -0
  421. package/src/migrations/1719568082-set-default-period-groups.sql +1 -0
  422. package/src/migrations/1719580828-registrations-periodId.sql +2 -0
  423. package/src/migrations/1719580829-set-default-period-registrations.sql +1 -0
  424. package/src/migrations/data/postcodes/nl/Drenthe +291 -0
  425. package/src/migrations/data/postcodes/nl/Flevoland +107 -0
  426. package/src/migrations/data/postcodes/nl/Friesland +518 -0
  427. package/src/migrations/data/postcodes/nl/Gelderland +601 -0
  428. package/src/migrations/data/postcodes/nl/Groningen +279 -0
  429. package/src/migrations/data/postcodes/nl/Limburg +324 -0
  430. package/src/migrations/data/postcodes/nl/Noord-Brabant +620 -0
  431. package/src/migrations/data/postcodes/nl/Noord-Holland +566 -0
  432. package/src/migrations/data/postcodes/nl/Overrijsel +344 -0
  433. package/src/migrations/data/postcodes/nl/Utrecht +278 -0
  434. package/src/migrations/data/postcodes/nl/Zeeland +179 -0
  435. package/src/migrations/data/postcodes/nl/Zuid-Holland +662 -0
  436. package/src/models/BalanceItem.ts +392 -0
  437. package/src/models/BalanceItemPayment.ts +106 -0
  438. package/src/models/BuckarooPayment.ts +19 -0
  439. package/src/models/Document.ts +203 -0
  440. package/src/models/DocumentTemplate.ts +583 -0
  441. package/src/models/EmailTemplate.ts +64 -0
  442. package/src/models/EmailVerificationCode.ts +352 -0
  443. package/src/models/Group.ts +293 -0
  444. package/src/models/Image.ts +147 -0
  445. package/src/models/Member.ts +386 -0
  446. package/src/models/MemberResponsibilityRecord.ts +39 -0
  447. package/src/models/MolliePayment.ts +19 -0
  448. package/src/models/MollieToken.ts +369 -0
  449. package/src/models/OneTimeToken.ts +131 -0
  450. package/src/models/Order.ts +1030 -0
  451. package/src/models/Organization.ts +1085 -0
  452. package/src/models/OrganizationRegistrationPeriod.ts +54 -0
  453. package/src/models/PasswordToken.ts +139 -0
  454. package/src/models/PayconiqPayment.ts +241 -0
  455. package/src/models/Payment.ts +216 -0
  456. package/src/models/Platform.ts +76 -0
  457. package/src/models/RegisterCode.ts +164 -0
  458. package/src/models/Registration.ts +405 -0
  459. package/src/models/RegistrationPeriod.ts +55 -0
  460. package/src/models/STCredit.ts +134 -0
  461. package/src/models/STInvoice.ts +507 -0
  462. package/src/models/STPackage.ts +324 -0
  463. package/src/models/STPendingInvoice.ts +308 -0
  464. package/src/models/StripeAccount.ts +71 -0
  465. package/src/models/StripeCheckoutSession.ts +22 -0
  466. package/src/models/StripePaymentIntent.ts +22 -0
  467. package/src/models/Ticket.ts +145 -0
  468. package/src/models/Token.test.ts +69 -0
  469. package/src/models/Token.ts +269 -0
  470. package/src/models/UsedRegisterCode.ts +166 -0
  471. package/src/models/User.ts +445 -0
  472. package/src/models/UserPermissions.ts +54 -0
  473. package/src/models/Webshop.ts +206 -0
  474. package/src/models/WebshopDiscountCode.ts +81 -0
  475. package/src/models/addresses/City.ts +31 -0
  476. package/src/models/addresses/PostalCode.test.ts +117 -0
  477. package/src/models/addresses/PostalCode.ts +164 -0
  478. package/src/models/addresses/Province.ts +20 -0
  479. package/src/models/addresses/Street.ts +25 -0
  480. package/src/models/index.ts +49 -0
  481. package/src/structures/OrganizationServerMetaData.ts +117 -0
@@ -0,0 +1,76 @@
1
+ import { column, Model } from "@simonbackx/simple-database";
2
+ import { QueueHandler } from "@stamhoofd/queues";
3
+ import { Platform as PlatformStruct,PlatformConfig, PlatformPrivateConfig } from "@stamhoofd/structures";
4
+ import { v4 as uuidv4 } from "uuid";
5
+ import { RegistrationPeriod } from "./RegistrationPeriod";
6
+
7
+
8
+ export class Platform extends Model {
9
+ static table = "platform";
10
+
11
+ @column({
12
+ primary: true, type: "string", beforeSave(value) {
13
+ return value ?? uuidv4();
14
+ }
15
+ })
16
+ id!: string;
17
+
18
+ @column({ type: "json", decoder: PlatformConfig })
19
+ config: PlatformConfig = PlatformConfig.create({})
20
+
21
+ @column({ type: "string" })
22
+ periodId: string
23
+
24
+ @column({ type: "json", decoder: PlatformPrivateConfig })
25
+ privateConfig: PlatformPrivateConfig = PlatformPrivateConfig.create({})
26
+
27
+ static sharedStruct: PlatformStruct | null = null;
28
+
29
+ static async getSharedStruct(): Promise<PlatformStruct> {
30
+ const struct = await this.getSharedPrivateStruct();
31
+ const clone = struct.clone();
32
+ clone.privateConfig = null;
33
+ clone.setShared();
34
+
35
+ return clone;
36
+ }
37
+
38
+ static async getSharedPrivateStruct(): Promise<PlatformStruct> {
39
+ if (this.sharedStruct && this.sharedStruct.privateConfig) {
40
+ return this.sharedStruct;
41
+ }
42
+
43
+ return await QueueHandler.schedule('Platform.getSharedStruct', async () => {
44
+ const model = await this.getShared();
45
+ const period = await RegistrationPeriod.getByID(model.periodId);
46
+ const struct = PlatformStruct.create({
47
+ ...model,
48
+ period: period?.getStructure() ?? undefined
49
+ });
50
+ this.sharedStruct = struct;
51
+
52
+ return struct;
53
+ });
54
+ }
55
+
56
+ static async getShared(): Promise<Platform> {
57
+ return QueueHandler.schedule('Platform.getShared', async () => {
58
+ // Build a new one
59
+ let model = await this.getByID('1');
60
+ if (!model) {
61
+ // Create a new platform
62
+ model = new Platform();
63
+ model.id = '1';
64
+ model.periodId = (await RegistrationPeriod.all())[0].id;
65
+ await model.save();
66
+ }
67
+
68
+ return model;
69
+ });
70
+ }
71
+
72
+ async save() {
73
+ Platform.sharedStruct = null
74
+ return await super.save()
75
+ }
76
+ }
@@ -0,0 +1,164 @@
1
+ import { column, Model } from "@simonbackx/simple-database";
2
+ import { SimpleError } from "@simonbackx/simple-errors";
3
+ import { EmailInterfaceBase } from "@stamhoofd/email";
4
+ import basex from "base-x";
5
+ import crypto from "crypto";
6
+
7
+ import { Organization } from "./Organization";
8
+ import { STCredit } from "./STCredit";
9
+ import { UsedRegisterCode } from "./UsedRegisterCode";
10
+ const ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
11
+ const bs58 = basex(ALPHABET)
12
+
13
+ async function randomBytes(size: number): Promise<Buffer> {
14
+ return new Promise((resolve, reject) => {
15
+ crypto.randomBytes(size, (err: Error | null, buf: Buffer) => {
16
+ if (err) {
17
+ reject(err);
18
+ return;
19
+ }
20
+ resolve(buf);
21
+ });
22
+ });
23
+ }
24
+
25
+ export class RegisterCode extends Model {
26
+ static table = "register_codes";
27
+
28
+ @column({ type: "string", primary: true })
29
+ code: string;
30
+
31
+ @column({ type: "string" })
32
+ description: string;
33
+
34
+ @column({ type: "string", nullable: true })
35
+ customMessage: string|null = null;
36
+
37
+ @column({ type: "string", nullable: true })
38
+ organizationId: string | null;
39
+
40
+ @column({ type: "integer" })
41
+ value: number;
42
+
43
+ /**
44
+ * Invoice usages to the owning organization
45
+ */
46
+ @column({ type: "integer", nullable: true })
47
+ invoiceValue: number|null = null
48
+
49
+ @column({
50
+ type: "datetime", beforeSave(old?: any) {
51
+ if (old !== undefined) {
52
+ return old;
53
+ }
54
+ const date = new Date()
55
+ date.setMilliseconds(0)
56
+ return date
57
+ }
58
+ })
59
+ createdAt: Date
60
+
61
+ @column({
62
+ type: "datetime", beforeSave() {
63
+ const date = new Date()
64
+ date.setMilliseconds(0)
65
+ return date
66
+ },
67
+ skipUpdate: true
68
+ })
69
+ updatedAt: Date
70
+
71
+ async generateCode() {
72
+ this.code = bs58.encode(await randomBytes(8)).toUpperCase();
73
+ }
74
+
75
+ /**
76
+ * Prepares a register code for usage.
77
+ * Returns the models to save and the emails to send when succesful
78
+ */
79
+ static async applyRegisterCode(organization: Organization, codeString: string): Promise<{models: Model[], emails: EmailInterfaceBase[]}> {
80
+ const alreadyUsed = await UsedRegisterCode.getFor(organization.id)
81
+ if (alreadyUsed) {
82
+ throw new SimpleError({
83
+ code: "invalid_field",
84
+ message: "Invalid register code",
85
+ human: "Je hebt al een doorverwijzingscode gebruikt",
86
+ field: "registerCode",
87
+ });
88
+ }
89
+
90
+ const code = await RegisterCode.getByID(codeString)
91
+ if (!code) {
92
+ throw new SimpleError({
93
+ code: "invalid_field",
94
+ message: "Invalid register code",
95
+ human: "De doorverwijzingscode die je hebt opgegeven is niet langer geldig",
96
+ field: "registerCode",
97
+ });
98
+ }
99
+
100
+ const otherOrganization = code.organizationId ? await Organization.getByID(code.organizationId) : undefined
101
+
102
+ const delayEmails: EmailInterfaceBase[] = []
103
+ let credit: STCredit | undefined = undefined
104
+ let usedCode: UsedRegisterCode | undefined = undefined
105
+
106
+ if (code.value > 0) {
107
+ // Create initial credit
108
+ credit = new STCredit()
109
+ credit.organizationId = organization.id
110
+ credit.change = code.value
111
+ credit.description = otherOrganization ? ("Tegoed gekregen van "+otherOrganization.name) : code.description
112
+
113
+ // Expire in one year (will get extended for every purchase or activation)
114
+ credit.expireAt = new Date()
115
+ credit.expireAt.setFullYear(credit.expireAt.getFullYear() + 1)
116
+ credit.expireAt.setMilliseconds(0)
117
+
118
+ // Save later
119
+ }
120
+
121
+ if (otherOrganization) {
122
+ const admins = await otherOrganization.getAdminToEmails()
123
+ if (admins) {
124
+ if (code.invoiceValue) {
125
+ // Delay email until everything is validated and saved
126
+ delayEmails.push({
127
+ to: admins,
128
+ bcc: "simon@stamhoofd.be",
129
+ subject: organization.name+" heeft jullie doorverwijzingslink gebruikt 🥳",
130
+ type: "transactional",
131
+ text: "Dag "+otherOrganization.name+",\n\nGoed nieuws! "+organization.name+" heeft jullie doorverwijzingslink gebruikt om zich op Stamhoofd te registreren.\n\n— Stamhoofd"
132
+ })
133
+ } else {
134
+ // Delay email until everything is validated and saved
135
+ delayEmails.push({
136
+ to: admins,
137
+ bcc: "simon@stamhoofd.be",
138
+ subject: organization.name+" heeft jullie doorverwijzingslink gebruikt 🥳",
139
+ type: "transactional",
140
+ text: "Dag "+otherOrganization.name+",\n\nGoed nieuws! "+organization.name+" heeft jullie doorverwijzingslink gebruikt om zich op Stamhoofd te registreren. Als zij minstens 1 euro op Stamhoofd uitgeven ontvangen jullie een tegoed dat kan oplopen tot 100 euro per vereniging (zie daarvoor Stamhoofd > Instellingen). Lees zeker onze tips na om nog een groter bedrag te verzamelen 😉\n\n— Stamhoofd"
141
+ })
142
+ }
143
+ }
144
+ } else {
145
+ delayEmails.push({
146
+ to: 'hallo@stamhoofd.be',
147
+ subject: organization.name+" heeft jullie doorverwijzingslink gebruikt 🥳",
148
+ type: "transactional",
149
+ text: "Dag Stamhoofd,\n\nGoed nieuws! "+organization.name+" heeft jullie doorverwijzingslink "+code.code+" gebruikt om zich op Stamhoofd te registreren. \n\n— Stamhoofd"
150
+ })
151
+ }
152
+
153
+ // Save that we used this code (so we can reward the other organization)
154
+ usedCode = new UsedRegisterCode()
155
+ usedCode.organizationId = organization.id
156
+ usedCode.code = code.code
157
+
158
+ // Save later
159
+ return {
160
+ models: credit ? [credit, usedCode] : [usedCode],
161
+ emails: delayEmails
162
+ }
163
+ }
164
+ }
@@ -0,0 +1,405 @@
1
+ import { column, Database, ManyToOneRelation, Model } from '@simonbackx/simple-database';
2
+ import { Email } from '@stamhoofd/email';
3
+ import { EmailTemplateType, PaymentMethod, PaymentMethodHelper, Recipient, Registration as RegistrationStructure, Replacement } from '@stamhoofd/structures';
4
+ import { Formatter } from '@stamhoofd/utility';
5
+ import { v4 as uuidv4 } from "uuid";
6
+
7
+ import { getEmailBuilder } from '../helpers/EmailBuilder';
8
+ import { Document, EmailTemplate, Organization, User } from './';
9
+
10
+ export class Registration extends Model {
11
+ static table = "registrations"
12
+
13
+ @column({
14
+ primary: true, type: "string", beforeSave(value) {
15
+ return value ?? uuidv4();
16
+ }
17
+ })
18
+ id!: string;
19
+
20
+ @column({ type: "string" })
21
+ memberId: string;
22
+
23
+ @column({ type: "string" })
24
+ organizationId: string
25
+
26
+ @column({ type: "string" })
27
+ periodId: string;
28
+
29
+ @column({ type: "string", foreignKey: Registration.group})
30
+ groupId: string;
31
+
32
+ /**
33
+ * @deprecated
34
+ */
35
+ @column({ type: "string", nullable: true })
36
+ paymentId: string | null = null
37
+
38
+ @column({ type: "integer" })
39
+ cycle: number;
40
+
41
+ @column({ type: "integer", nullable: true })
42
+ price: number | null = null;
43
+
44
+ @column({
45
+ type: "datetime", beforeSave(old?: any) {
46
+ if (old !== undefined) {
47
+ return old;
48
+ }
49
+ const date = new Date()
50
+ date.setMilliseconds(0)
51
+ return date
52
+ }
53
+ })
54
+ createdAt: Date
55
+
56
+ @column({
57
+ type: "datetime", beforeSave() {
58
+ const date = new Date()
59
+ date.setMilliseconds(0)
60
+ return date
61
+ },
62
+ skipUpdate: true
63
+ })
64
+ updatedAt: Date
65
+
66
+ @column({ type: "datetime", nullable: true })
67
+ registeredAt: Date | null = null
68
+
69
+ @column({ type: "datetime", nullable: true })
70
+ reservedUntil: Date | null = null
71
+
72
+ @column({ type: "boolean" })
73
+ waitingList = false
74
+
75
+ /**
76
+ * When a registration is on the waiting list or is invite only, set this to true to allow the user to
77
+ * register normally.
78
+ */
79
+ @column({ type: "boolean" })
80
+ canRegister = false
81
+
82
+ @column({ type: "datetime", nullable: true})
83
+ deactivatedAt: Date | null = null
84
+
85
+ /**
86
+ * Part of price that is paid
87
+ */
88
+ @column({ type: "integer" })
89
+ pricePaid = 0
90
+
91
+ static group: ManyToOneRelation<"group", import('./Group').Group>
92
+
93
+ getStructure(this: Registration & {group: import('./Group').Group}) {
94
+ return RegistrationStructure.create({
95
+ ...this,
96
+ group: this.group.getStructure(),
97
+ price: this.price ?? 0
98
+ })
99
+ }
100
+
101
+ /**
102
+ * Update the outstanding balance of multiple members in one go (or all members)
103
+ */
104
+ static async updateOutstandingBalance(registrationIds: string[] | 'all', organizationId: string) {
105
+ if (registrationIds !== 'all' && registrationIds.length == 0) {
106
+ return
107
+ }
108
+
109
+ const params: any[] = []
110
+ let firstWhere = ''
111
+ let secondWhere = ''
112
+
113
+ if (registrationIds !== 'all') {
114
+ firstWhere = ` AND registrationId IN (?)`
115
+ params.push(registrationIds)
116
+
117
+ secondWhere = `WHERE registrations.id IN (?)`
118
+ params.push(registrationIds)
119
+ }
120
+
121
+ const query = `UPDATE
122
+ registrations
123
+ LEFT JOIN (
124
+ SELECT
125
+ registrationId,
126
+ sum(price) AS price,
127
+ sum(pricePaid) AS pricePaid
128
+ FROM
129
+ balance_items
130
+ WHERE status != 'Hidden'${firstWhere}
131
+ GROUP BY
132
+ registrationId
133
+ ) i ON i.registrationId = registrations.id
134
+ SET registrations.price = coalesce(i.price, 0), registrations.pricePaid = coalesce(i.pricePaid, 0)
135
+ ${secondWhere}`
136
+
137
+ await Database.update(query, params)
138
+
139
+ if (registrationIds !== 'all') {
140
+ await Document.updateForRegistrations(registrationIds, organizationId)
141
+ }
142
+ }
143
+
144
+ /**
145
+ * Get the number of active members that are currently registered
146
+ * This is used for billing
147
+ */
148
+ static async getActiveMembers(organizationId: string): Promise<number> {
149
+ const query = `
150
+ SELECT COUNT(DISTINCT \`${Registration.table}\`.memberId) as c FROM \`${Registration.table}\`
151
+ JOIN \`groups\` ON \`groups\`.id = \`${Registration.table}\`.groupId
152
+ WHERE \`groups\`.organizationId = ? AND \`${Registration.table}\`.cycle = \`groups\`.cycle AND \`groups\`.deletedAt is null AND \`groups\`.status != 'Archived' AND \`${Registration.table}\`.registeredAt is not null AND \`${Registration.table}\`.waitingList = 0`
153
+
154
+ const [results] = await Database.select(query, [organizationId])
155
+ const count = results[0]['']['c'];
156
+
157
+ if (Number.isInteger(count)) {
158
+ return count as number
159
+ } else {
160
+ console.error("Unexpected result for occupancy", results)
161
+ throw new Error("Query failed")
162
+ }
163
+ }
164
+
165
+ async markValid(this: Registration) {
166
+ if (this.registeredAt !== null) {
167
+ await this.save();
168
+ return false;
169
+ }
170
+ this.reservedUntil = null
171
+ this.registeredAt = new Date()
172
+ await this.save();
173
+
174
+ await this.sendEmailTemplate({
175
+ type: EmailTemplateType.RegistrationConfirmation
176
+ });
177
+
178
+ const {Member} = await import('./Member');
179
+ const member = await Member.getByID(this.memberId);
180
+ if (member) {
181
+ const registrationMemberRelation = new ManyToOneRelation(Member, "member")
182
+ registrationMemberRelation.foreignKey = Member.registrations.foreignKey
183
+ await Document.updateForRegistration(this.setRelation(registrationMemberRelation, member))
184
+ }
185
+
186
+ return true;
187
+ }
188
+
189
+ async getRecipients(organization: Organization, group: import('./').Group) {
190
+ const {Member} = await import('./Member');
191
+
192
+ const member = await Member.getWithRegistrations(this.memberId);
193
+
194
+ if (!member) {
195
+ return [];
196
+ }
197
+
198
+ return member.users.map(user => Recipient.create({
199
+ firstName: user.firstName,
200
+ lastName: user.lastName,
201
+ email: user.email,
202
+ userId: user.id,
203
+ replacements: [
204
+ Replacement.create({
205
+ token: "firstName",
206
+ value: member.details.firstName,
207
+ }),
208
+ Replacement.create({
209
+ token: "lastName",
210
+ value: member.details.lastName,
211
+ }),
212
+ Replacement.create({
213
+ token: "email",
214
+ value: user.email
215
+ }),
216
+ Replacement.create({
217
+ token: "registerUrl",
218
+ value: "https://" + organization.getHost()
219
+ }),
220
+ Replacement.create({
221
+ token: "organizationName",
222
+ value: organization.name
223
+ }),
224
+ Replacement.create({
225
+ token: "groupName",
226
+ value: group.settings.name
227
+ }),
228
+ Replacement.create({
229
+ token: "loginDetails",
230
+ value: "",
231
+ html: user.hasAccount() ? `<p class="description"><em>Je kan op het ledenportaal inloggen met <strong>${Formatter.escapeHtml(user.email)}</strong></em></p>` : `<p class="description"><em>Je kan op het ledenportaal een nieuw account aanmaken met het e-mailadres <strong>${Formatter.escapeHtml(user.email)}</strong>, dan krijg je automatisch toegang tot alle bestaande gegevens.</em></p>`
232
+ }),
233
+ ]
234
+ }));
235
+ }
236
+
237
+ async sendEmailTemplate(data: {
238
+ type: EmailTemplateType
239
+ }) {
240
+ const Group = (await import('./')).Group
241
+ const group = await Group.getByID(this.groupId);
242
+
243
+ if (!group) {
244
+ return
245
+ }
246
+
247
+ // Most specific template: for specific group
248
+ let templates = (await EmailTemplate.where({ type: data.type, groupId: this.groupId, organizationId: group.organizationId }))
249
+
250
+ // Then for organization
251
+ if (templates.length == 0) {
252
+ templates = (await EmailTemplate.where({ type: data.type, organizationId: group.organizationId, groupId: null }))
253
+ }
254
+
255
+ // Then default
256
+ if (templates.length == 0) {
257
+ templates = (await EmailTemplate.where({ type: data.type, organizationId: null, groupId: null }))
258
+ }
259
+
260
+ if (templates.length == 0) {
261
+ console.error("Could not find email template for type "+data.type)
262
+ return
263
+ }
264
+
265
+ const template = templates[0]
266
+
267
+ const organization = await Organization.getByID(group.organizationId);
268
+ if (!organization) {
269
+ return
270
+ }
271
+
272
+ const recipients = await this.getRecipients(organization, group)
273
+
274
+ const {from, replyTo} = organization.getGroupEmail(group)
275
+
276
+ // Create e-mail builder
277
+ const builder = await getEmailBuilder(organization, {
278
+ recipients,
279
+ subject: template.subject,
280
+ html: template.html,
281
+ from,
282
+ type: "transactional",
283
+ replyTo
284
+ })
285
+
286
+ Email.schedule(builder)
287
+ }
288
+
289
+ static async sendTransferEmail(user: User, organization: Organization, payment: import('./').Payment) {
290
+ const data = {
291
+ type: EmailTemplateType.RegistrationTransferDetails
292
+ };
293
+
294
+ // First fetch template
295
+ let templates = (await EmailTemplate.where({ type: data.type, organizationId: organization.id, groupId: null }))
296
+
297
+ if (templates.length == 0) {
298
+ templates = (await EmailTemplate.where({ type: data.type, organizationId: null, groupId: null }))
299
+ }
300
+
301
+ if (templates.length == 0) {
302
+ console.error("Could not find email template for type "+data.type)
303
+ return
304
+ }
305
+
306
+ const template = templates[0]
307
+
308
+ const paymentGeneral = await payment.getGeneralStructure();
309
+ const registrations = paymentGeneral.registrations
310
+ let groupIds = registrations.map(r => r.groupId);
311
+
312
+ // Remove duplicate groupIds
313
+ groupIds = groupIds.filter((v, i, a) => a.indexOf(v) === i);
314
+
315
+ const recipients = [
316
+ Recipient.create({
317
+ firstName: user.firstName,
318
+ lastName: user.lastName,
319
+ email: user.email,
320
+ userId: user.id,
321
+ replacements: [
322
+ Replacement.create({
323
+ token: "priceToPay",
324
+ value: Formatter.price(payment.price)
325
+ }),
326
+ Replacement.create({
327
+ token: "paymentMethod",
328
+ value: PaymentMethodHelper.getName(payment.method ?? PaymentMethod.Unknown)
329
+ }),
330
+ Replacement.create({
331
+ token: "transferDescription",
332
+ value: (payment.transferDescription ?? "")
333
+ }),
334
+ Replacement.create({
335
+ token: "transferBankAccount",
336
+ value: payment.transferSettings?.iban ?? ""
337
+ }),
338
+ Replacement.create({
339
+ token: "transferBankCreditor",
340
+ value: payment.transferSettings?.creditor ?? organization.name
341
+ }),
342
+ Replacement.create({
343
+ token: "overviewTable",
344
+ value: "",
345
+ html: paymentGeneral.getDetailsHTMLTable()
346
+ }),
347
+ Replacement.create({
348
+ token: "overviewContext",
349
+ value: "Inschrijving van " + paymentGeneral.memberFirstNames
350
+ }),
351
+ Replacement.create({
352
+ token: "memberNames",
353
+ value: paymentGeneral.memberNames
354
+ }),
355
+ Replacement.create({
356
+ token: "overviewTable",
357
+ value: "",
358
+ html: paymentGeneral.getDetailsHTMLTable()
359
+ }),
360
+ Replacement.create({
361
+ token: "paymentTable",
362
+ value: "",
363
+ html: paymentGeneral.getHTMLTable()
364
+ }),
365
+ Replacement.create({
366
+ token: "registerUrl",
367
+ value: "https://" + organization.getHost()
368
+ }),
369
+ Replacement.create({
370
+ token: "organizationName",
371
+ value: organization.name
372
+ }),
373
+ Replacement.create({
374
+ token: "loginDetails",
375
+ value: "",
376
+ html: user.hasAccount() ? `<p class="description"><em>Je kan op het ledenportaal inloggen met <strong>${Formatter.escapeHtml(user.email)}</strong></em></p>` : `<p class="description"><em>Je kan op het ledenportaal een nieuw account aanmaken met het e-mailadres <strong>${Formatter.escapeHtml(user.email)}</strong>, dan krijg je automatisch toegang tot alle bestaande gegevens.</em></p>`
377
+ })
378
+ ]
379
+ })
380
+ ];
381
+
382
+ let {from, replyTo} = organization.getDefaultEmail()
383
+
384
+ if (groupIds.length == 1) {
385
+ const Group = (await import('./')).Group
386
+ const group = await Group.getByID(groupIds[0]);
387
+ if (group) {
388
+ const groupEmail = organization.getGroupEmail(group)
389
+ from = groupEmail.from
390
+ replyTo = groupEmail.replyTo
391
+ }
392
+ }
393
+
394
+ // Create e-mail builder
395
+ const builder = await getEmailBuilder(organization, {
396
+ recipients,
397
+ subject: template.subject,
398
+ html: template.html,
399
+ from,
400
+ replyTo
401
+ })
402
+
403
+ Email.schedule(builder)
404
+ }
405
+ }
@@ -0,0 +1,55 @@
1
+ import { column, Model } from '@simonbackx/simple-database';
2
+ import { RegistrationPeriodSettings, RegistrationPeriod as RegistrationPeriodStruct } from '@stamhoofd/structures';
3
+ import { v4 as uuidv4 } from "uuid";
4
+
5
+ export class RegistrationPeriod extends Model {
6
+ static table = "registration_periods";
7
+
8
+ @column({
9
+ primary: true, type: "string", beforeSave(value) {
10
+ return value ?? uuidv4();
11
+ }
12
+ })
13
+ id!: string;
14
+
15
+ @column({ type: "string", nullable: true })
16
+ organizationId: string | null = null;
17
+
18
+ @column({ type: "datetime" })
19
+ startDate: Date
20
+
21
+ @column({ type: "datetime" })
22
+ endDate: Date
23
+
24
+ @column({ type: "json", decoder: RegistrationPeriodSettings })
25
+ settings: RegistrationPeriodSettings;
26
+
27
+ @column({ type: "boolean" })
28
+ locked = false
29
+
30
+ @column({
31
+ type: "datetime", beforeSave(old?: any) {
32
+ if (old !== undefined) {
33
+ return old;
34
+ }
35
+ const date = new Date()
36
+ date.setMilliseconds(0)
37
+ return date
38
+ }
39
+ })
40
+ createdAt: Date
41
+
42
+ @column({
43
+ type: "datetime", beforeSave() {
44
+ const date = new Date()
45
+ date.setMilliseconds(0)
46
+ return date
47
+ },
48
+ skipUpdate: true
49
+ })
50
+ updatedAt: Date
51
+
52
+ getStructure() {
53
+ return RegistrationPeriodStruct.create(this)
54
+ }
55
+ }