@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,324 @@
1
+ import { column, Model } from "@simonbackx/simple-database";
2
+ import { SimpleError } from "@simonbackx/simple-errors";
3
+ import { Email } from "@stamhoofd/email";
4
+ import { EmailTemplateType, Recipient, Replacement, STPackageMeta, STPackageStatus, STPackageType } from '@stamhoofd/structures';
5
+ import { Formatter } from "@stamhoofd/utility";
6
+ import { v4 as uuidv4 } from "uuid";
7
+
8
+ import { getEmailBuilder } from "../helpers/EmailBuilder";
9
+ import { GroupBuilder } from "../helpers/GroupBuilder";
10
+ import { EmailTemplate } from "./";
11
+ import { Organization } from "./";
12
+
13
+ export class STPackage extends Model {
14
+ static table = "stamhoofd_packages";
15
+
16
+ // Columns
17
+ @column({
18
+ primary: true, type: "string", beforeSave(value) {
19
+ return value ?? uuidv4();
20
+ }
21
+ })
22
+ id!: string;
23
+
24
+ /**
25
+ * We keep packages of deleted organizations for statistics, so this doesn't have a foreign key
26
+ */
27
+ @column({ type: "string"})
28
+ organizationId: string
29
+
30
+ @column({ type: "json", decoder: STPackageMeta })
31
+ meta: STPackageMeta
32
+
33
+ @column({
34
+ type: "datetime", beforeSave(old?: any) {
35
+ if (old !== undefined) {
36
+ return old;
37
+ }
38
+ const date = new Date()
39
+ date.setMilliseconds(0)
40
+ return date
41
+ }
42
+ })
43
+ createdAt: Date
44
+
45
+ @column({
46
+ type: "datetime", beforeSave() {
47
+ const date = new Date()
48
+ date.setMilliseconds(0)
49
+ return date
50
+ },
51
+ skipUpdate: true
52
+ })
53
+ updatedAt: Date
54
+
55
+ @column({ type: "datetime", nullable: true })
56
+ validAt: Date | null = null
57
+
58
+ @column({ type: "datetime", nullable: true })
59
+ validUntil: Date | null = null
60
+
61
+ @column({ type: "datetime", nullable: true })
62
+ removeAt: Date | null = null
63
+
64
+ @column({ type: "integer" })
65
+ emailCount = 0
66
+
67
+ @column({ type: "datetime", nullable: true })
68
+ lastEmailAt: Date | null = null
69
+
70
+ static async getForOrganization(organizationId: string) {
71
+ const pack1 = await STPackage.where({ organizationId, validAt: { sign: "!=", value: null }, removeAt: { sign: ">", value: new Date() }})
72
+ const pack2 = await STPackage.where({ organizationId, validAt: { sign: "!=", value: null }, removeAt: null })
73
+
74
+ return [...pack1, ...pack2]
75
+ }
76
+
77
+ static async getForOrganizationIncludingExpired(organizationId: string) {
78
+ return await STPackage.where({ organizationId, validAt: { sign: "!=", value: null }}, {sort: [{column: 'validAt', direction: 'DESC'}]})
79
+ }
80
+
81
+ static async getOrganizationPackagesMap(organizationId: string): Promise<Map<STPackageType, STPackageStatus>> {
82
+ const packages = await this.getForOrganizationIncludingExpired(organizationId)
83
+
84
+ const map = new Map<STPackageType, STPackageStatus>()
85
+ for (const pack of packages) {
86
+ const exist = map.get(pack.meta.type)
87
+ if (exist) {
88
+ exist.merge(pack.createStatus())
89
+ } else {
90
+ map.set(pack.meta.type, pack.createStatus())
91
+ }
92
+ }
93
+
94
+ return map;
95
+ }
96
+
97
+ static async updateOrganizationPackages(organizationId: string) {
98
+ console.log("Updating packages for organization "+organizationId)
99
+ const map = await this.getOrganizationPackagesMap(organizationId)
100
+
101
+ const organization = await Organization.getByID(organizationId)
102
+ if (organization) {
103
+ const didUseMembers = organization.meta.packages.useMembers && organization.meta.packages.useActivities
104
+ organization.meta.packages.packages = map
105
+ await organization.save()
106
+
107
+ if (!didUseMembers && organization.meta.packages.useMembers && organization.meta.packages.useActivities) {
108
+ console.log("Building groups and categories for "+organization.id)
109
+ const builder = new GroupBuilder(organization)
110
+ await builder.build()
111
+ }
112
+ } else {
113
+ console.error("Couldn't find organization when updating packages "+organizationId)
114
+ }
115
+ }
116
+
117
+ async activate() {
118
+ if (this.validAt !== null) {
119
+ return
120
+ }
121
+ this.validAt = new Date()
122
+ await this.save()
123
+
124
+ if (this.meta.didRenewId) {
125
+ const pack = await STPackage.getByID(this.meta.didRenewId)
126
+ if (pack && pack.organizationId === this.organizationId) {
127
+ await pack.didRenew(this)
128
+ }
129
+ }
130
+ }
131
+
132
+ async didRenew(renewed: STPackage) {
133
+ this.removeAt = renewed.meta.startDate ?? renewed.validAt ?? new Date()
134
+ this.meta.allowRenew = false
135
+ await this.save()
136
+ }
137
+
138
+ async deactivate() {
139
+ if (this.removeAt !== null && this.removeAt <= new Date()) {
140
+ return
141
+ }
142
+ this.removeAt = new Date()
143
+ await this.save()
144
+ }
145
+
146
+ /**
147
+ * Create a renewed package, but not yet saved!
148
+ */
149
+ createRenewed(): STPackage {
150
+ if (!this.meta.allowRenew) {
151
+ throw new SimpleError({
152
+ code: "not_allowed",
153
+ message: "Not allowed",
154
+ human: "Je kan dit pakket niet verlengen"
155
+ })
156
+ }
157
+
158
+ const pack = new STPackage()
159
+ pack.id = uuidv4()
160
+ pack.meta = this.meta
161
+
162
+ // Not yet valid / active (ignored until valid)
163
+ pack.validAt = null
164
+ pack.organizationId = this.organizationId
165
+
166
+ pack.meta.startDate = new Date(Math.max(new Date().getTime(), this.validUntil?.getTime() ?? 0))
167
+ pack.meta.paidAmount = 0
168
+ pack.meta.paidPrice = 0
169
+ pack.meta.firstFailedPayment = null
170
+ pack.meta.didRenewId = this.id
171
+
172
+ // Duration for renewals is always a year ATM
173
+ pack.validUntil = new Date(pack.meta.startDate)
174
+ pack.validUntil.setFullYear(pack.validUntil.getFullYear() + 1)
175
+
176
+ // Remove (= not renewable) if not renewed after 3 months
177
+ pack.removeAt = new Date(pack.validUntil)
178
+ pack.removeAt.setMonth(pack.removeAt.getMonth() + 3)
179
+
180
+ // Custom renewals for single webshop:
181
+ if (this.meta.type === STPackageType.SingleWebshop) {
182
+ // Disable functions after two months
183
+ pack.validUntil = new Date(pack.meta.startDate)
184
+ pack.validUntil.setMonth(pack.validUntil.getMonth() + 2)
185
+ pack.removeAt = new Date(pack.validUntil)
186
+ }
187
+
188
+ return pack
189
+ }
190
+
191
+ createStatus(): STPackageStatus {
192
+ // TODO: if payment failed: temporary set valid until to 2 weeks after last/first failed payment
193
+
194
+ return STPackageStatus.create({
195
+ startDate: this.meta.startDate,
196
+ validUntil: this.validUntil,
197
+ removeAt: this.removeAt,
198
+ firstFailedPayment: this.meta.firstFailedPayment
199
+ })
200
+ }
201
+
202
+ async sendExpiryEmail() {
203
+ if (this.validAt === null) {
204
+ // never activated
205
+ return
206
+ }
207
+
208
+ if (this.removeAt && this.removeAt <= new Date()) {
209
+ this.emailCount += 1
210
+ await this.save()
211
+ return;
212
+ }
213
+
214
+ let allowDays = 0;
215
+ let type: EmailTemplateType | null = null;
216
+
217
+ if (this.meta.type === STPackageType.Members) {
218
+ type = EmailTemplateType.MembersExpirationReminder;
219
+ allowDays = 32;
220
+ } else if (this.meta.type === STPackageType.Webshops) {
221
+ type = EmailTemplateType.WebshopsExpirationReminder;
222
+ allowDays = 32;
223
+ } else if (this.meta.type === STPackageType.SingleWebshop) {
224
+ type = EmailTemplateType.SingleWebshopExpirationReminder;
225
+ allowDays = 7;
226
+ } else if (this.meta.type === STPackageType.TrialMembers) {
227
+ type = EmailTemplateType.TrialMembersExpirationReminder;
228
+ allowDays = 3;
229
+ } else if (this.meta.type === STPackageType.TrialWebshops) {
230
+ type = EmailTemplateType.TrialWebshopsExpirationReminder;
231
+ allowDays = 3;
232
+ }
233
+
234
+ const allowFrom = new Date(Date.now() + 1000 * 60 * 60 * 24 * allowDays)
235
+ if (type && (this.validUntil === null || this.validUntil < new Date() || this.validUntil > allowFrom)) {
236
+ console.log('Skip sending expiration email for '+this.id)
237
+ return;
238
+ }
239
+
240
+ if (type) {
241
+ console.log('Sending expiration email for '+this.id, type)
242
+ if (STAMHOOFD.environment === "production") {
243
+ await this.sendEmailTemplate({
244
+ type
245
+ })
246
+ }
247
+ this.lastEmailAt = new Date()
248
+ } else {
249
+ console.log('Skip sending expiration email for '+this.id+' (no type)')
250
+ }
251
+
252
+ this.emailCount += 1
253
+ await this.save()
254
+ }
255
+
256
+ async sendEmailTemplate(data: {
257
+ type: EmailTemplateType,
258
+ replyTo?: string
259
+ }) {
260
+ // First fetch template
261
+ const templates = await EmailTemplate.where({ type: data.type, organizationId: null })
262
+
263
+ if (!templates || templates.length == 0) {
264
+ console.error("Could not find email template for type "+data.type)
265
+ return
266
+ }
267
+
268
+ const organization = await Organization.getByID(this.organizationId)
269
+
270
+ if (!organization) {
271
+ console.error("Could not find package organization "+this.id)
272
+ return
273
+ }
274
+
275
+ const template = templates[0]
276
+ const admins = await organization.getFullAdmins()
277
+
278
+ const recipients = admins.map(admin =>
279
+ Recipient.create({
280
+ firstName: admin.firstName,
281
+ lastName: admin.lastName,
282
+ email: admin.email,
283
+ replacements: [
284
+ Replacement.create({
285
+ token: "firstName",
286
+ value: admin.firstName ?? ""
287
+ }),
288
+ Replacement.create({
289
+ token: "organizationName",
290
+ value: organization.name
291
+ }),
292
+ Replacement.create({
293
+ token: "packageName",
294
+ value: this.meta.name ?? ""
295
+ }),
296
+ Replacement.create({
297
+ token: "validUntil",
298
+ value: this.validUntil ? Formatter.dateTime(this.validUntil) : "nooit"
299
+ }),
300
+ Replacement.create({
301
+ token: "validUntilDate",
302
+ value: this.validUntil ? Formatter.date(this.validUntil) : "nooit"
303
+ }),
304
+ Replacement.create({
305
+ token: "renewUrl",
306
+ value: "https://"+(STAMHOOFD.domains.dashboard ?? "stamhoofd.app")+"/"+organization.i18n.locale+"/settings/packages"
307
+ }),
308
+ ]
309
+ })
310
+ );
311
+
312
+
313
+ // Create e-mail builder
314
+ const builder = await getEmailBuilder(organization, {
315
+ recipients,
316
+ subject: template.subject,
317
+ html: template.html,
318
+ from: Email.getInternalEmailFor(organization.i18n),
319
+ replyTo: data.replyTo
320
+ })
321
+
322
+ Email.schedule(builder)
323
+ }
324
+ }
@@ -0,0 +1,308 @@
1
+ import { createMollieClient, SequenceType } from '@mollie/api-client';
2
+ import { column, ManyToOneRelation, Model } from "@simonbackx/simple-database";
3
+ import { SimpleError } from "@simonbackx/simple-errors";
4
+ import { Email } from "@stamhoofd/email";
5
+ import { calculateVATPercentage, PaymentMethod, PaymentProvider, PaymentStatus, STInvoiceItem, STInvoiceMeta, STPackage as STPackageStruct, STPricingType, Version } from '@stamhoofd/structures';
6
+ import { Formatter } from "@stamhoofd/utility";
7
+ import { v4 as uuidv4 } from "uuid";
8
+
9
+ import { InvoiceBuilder } from "../helpers/InvoiceBuilder";
10
+ import { MolliePayment, Organization, Payment, Registration, STCredit, STInvoice, STPackage } from './';
11
+
12
+ /**
13
+ * Things that should get paid, but are not yet invoiced yet because:
14
+ * - total price is too low
15
+ * - auto renewals waiting for payment
16
+ *
17
+ * When they are about to get paid, we create a new invoice model
18
+ * and if that model is marked as paid, it will remove the corresponding
19
+ * items in this pending invoice.
20
+ *
21
+ * So please make sure you don't edit existing items, unless you change the id
22
+ */
23
+ export class STPendingInvoice extends Model {
24
+ static table = "stamhoofd_pending_invoices";
25
+
26
+ // Columns
27
+ @column({
28
+ primary: true, type: "string", beforeSave(value) {
29
+ return value ?? uuidv4();
30
+ }
31
+ })
32
+ id!: string;
33
+
34
+ @column({ foreignKey: STPendingInvoice.organization, type: "string", nullable: true })
35
+ organizationId: string | null;
36
+
37
+ @column({ type: "json", decoder: STInvoiceMeta })
38
+ meta: STInvoiceMeta
39
+
40
+ /// We can only have one invoice at a time for the pending invoice items
41
+ /// So until this invoice is marked as 'failed', we don't create new invoices for this pending invoice
42
+ @column({ type: "string", nullable: true })
43
+ invoiceId: string | null = null
44
+
45
+ @column({
46
+ type: "datetime", beforeSave(old?: any) {
47
+ if (old !== undefined) {
48
+ return old;
49
+ }
50
+ const date = new Date()
51
+ date.setMilliseconds(0)
52
+ return date
53
+ }
54
+ })
55
+ createdAt: Date
56
+
57
+ @column({
58
+ type: "datetime", beforeSave() {
59
+ const date = new Date()
60
+ date.setMilliseconds(0)
61
+ return date
62
+ },
63
+ skipUpdate: true
64
+ })
65
+ updatedAt: Date
66
+
67
+ static organization = new ManyToOneRelation(Organization, "organization");
68
+
69
+ static async getForOrganization(organizationId: string): Promise<STPendingInvoice | undefined> {
70
+ const invoices = await STPendingInvoice.where({ organizationId })
71
+ return invoices[0] ?? undefined
72
+ }
73
+
74
+ /**
75
+ * Always run this in the queue!
76
+ */
77
+ static async addItems(organization: Organization, invoiceItems: STInvoiceItem[]): Promise<STPendingInvoice | undefined> {
78
+ // Get the pending invoice if it exists
79
+ const pendingInvoice = await STPendingInvoice.getForOrganization(organization.id)
80
+ return await this.addItemsTo(pendingInvoice, organization, invoiceItems)
81
+ }
82
+
83
+ /**
84
+ * Always run this in the queue!
85
+ */
86
+ static async addItemsTo(pendingInvoice: STPendingInvoice | undefined, organization: Organization, invoiceItems: STInvoiceItem[]): Promise<STPendingInvoice | undefined> {
87
+ if (invoiceItems.length > 0) {
88
+ if (!pendingInvoice) {
89
+ // Create one
90
+ pendingInvoice = new STPendingInvoice()
91
+ pendingInvoice.organizationId = organization.id
92
+ pendingInvoice.meta = STInvoiceMeta.create({
93
+ companyName: organization.meta.companyName ?? organization.name,
94
+ companyContact: organization.privateMeta.billingContact ?? "",
95
+ companyAddress: organization.meta.companyAddress ?? organization.address,
96
+ companyVATNumber: organization.meta.VATNumber,
97
+ VATPercentage: calculateVATPercentage(organization.meta.companyAddress ?? organization.address, organization.meta.VATNumber)
98
+ })
99
+ }
100
+ pendingInvoice.meta.items.push(...invoiceItems)
101
+
102
+ // Can we compress
103
+ if (pendingInvoice.invoiceId === null) {
104
+ console.log("Compressing pending invoice items "+pendingInvoice.id)
105
+ pendingInvoice.meta.items = STInvoiceItem.compress(pendingInvoice.meta.items)
106
+ }
107
+ await pendingInvoice.save()
108
+ }
109
+ return pendingInvoice
110
+ }
111
+
112
+ /**
113
+ * Always run this in the queue!
114
+ */
115
+ static async addAutomaticItems(organization: Organization): Promise<STPendingInvoice | undefined> {
116
+ // Get the pending invoice if it exists
117
+ const pendingInvoice = await STPendingInvoice.getForOrganization(organization.id)
118
+
119
+ // Generate temporary pending invoice items for the current state without adding them IRL
120
+ const notYetCreatedItems = await STPendingInvoice.createItems(organization.id, pendingInvoice)
121
+ return await this.addItemsTo(pendingInvoice, organization, notYetCreatedItems)
122
+ }
123
+
124
+ /**
125
+ * This method checks all the packages of the given organization and will return
126
+ * new invoice items that should get charged. You'll need to add them to
127
+ * the pending invoice yourself (always in a queue!)
128
+ */
129
+ static async createItems(organizationId: string, pendingInvoice?: STPendingInvoice) {
130
+ const packages = await STPackage.getForOrganization(organizationId)
131
+
132
+ // Always use midnight as a reference time (because this method should always return the same values if it called multiple times on the same day)
133
+ const today = new Date()
134
+ today.setHours(0, 0, 0, 0)
135
+
136
+ // But use now as reference for activation detection
137
+ const now = new Date()
138
+
139
+ let membersCount: number | null = null
140
+ const pendingItems: STInvoiceItem[] = []
141
+
142
+ for (const pack of packages) {
143
+ if (pack.meta.startDate > now) {
144
+ continue
145
+ }
146
+ if (pack.meta.pricingType === STPricingType.PerMember && (pack.validUntil === null || pack.validUntil >= today)) {
147
+
148
+ if (membersCount === null) {
149
+ membersCount = await Registration.getActiveMembers(organizationId)
150
+ }
151
+
152
+ // Calculate the items that are already pending and remove them
153
+ const pendingCount = pendingInvoice ? pendingInvoice.meta.items.reduce((c, item) => c + ((item.package && item.package.id === pack.id) ? item.amount : 0), 0) : 0
154
+ const item = STInvoiceItem.fromPackage(STPackageStruct.create(pack), membersCount, pendingCount, today)
155
+ if (item.price > 0) {
156
+ console.log('Adding item to pending invoice', item)
157
+ pendingItems.push(item)
158
+ }
159
+ } else if ((pack.validUntil === null || pack.validUntil >= today) && pack.meta.paidAmount < pack.meta.minimumAmount) {
160
+
161
+ // Check if paid amount matches at least one
162
+ const pendingCount = pendingInvoice ? pendingInvoice.meta.items.reduce((c, item) => c + ((item.package && item.package.id === pack.id) ? item.amount : 0), 0) : 0
163
+ const item = STInvoiceItem.fromPackage(STPackageStruct.create(pack), 0, pendingCount, today)
164
+ if (item.price > 0) {
165
+ console.log('Adding item to pending invoice', item)
166
+ pendingItems.push(item)
167
+ }
168
+ }
169
+ }
170
+
171
+ // Add all payments that are not yet charged
172
+
173
+ return pendingItems
174
+ }
175
+
176
+ static async charge(organization: Organization) {
177
+ const pendingInvoice = await this.getForOrganization(organization.id)
178
+
179
+ if (!pendingInvoice || pendingInvoice.meta.priceWithVAT === 0) {
180
+ throw new SimpleError({
181
+ code: "no_pending_invoice",
182
+ message: "No pending invoice",
183
+ human: "Je kan op dit moment niet afrekenen omdat er geen openstaand bedrag is."
184
+ })
185
+ }
186
+
187
+ if (pendingInvoice.invoiceId !== null) {
188
+ throw new SimpleError({
189
+ code: "payment_pending",
190
+ message: "Payment pending",
191
+ human: "Er is momenteel al een afrekening in behandeling (dit kan 3 werkdagen duren), wacht enkele dagen voor je het opnieuw probeert."
192
+ })
193
+ }
194
+
195
+ if (organization.serverMeta.mollieCustomerId === undefined) {
196
+ throw new SimpleError({
197
+ code: "no_mollie_customer",
198
+ message: "No connected mollie customer",
199
+ human: "Er is nog geen domiciliëring of automatische afrekening ingesteld"
200
+ })
201
+ }
202
+ // Step 1: create the invoice
203
+ const invoice = STInvoice.createFor(organization)
204
+
205
+ invoice.meta.items = pendingInvoice.meta.items.slice() // make a copy (needed to prevent mutating pending invoice and invoice at the same time)
206
+
207
+ if (invoice.meta.priceWithVAT == 0) {
208
+ throw new SimpleError({
209
+ code: "no_pending_invoice",
210
+ message: "No pending invoice",
211
+ human: "Je kan op dit moment niet afrekenen omdat er geen openstaand bedrag is."
212
+ })
213
+ }
214
+
215
+ await STCredit.applyCredits(organization.id, invoice, false)
216
+
217
+ const price = invoice.meta.priceWithVAT
218
+
219
+ // Create payment
220
+ const payment = new Payment()
221
+ payment.organizationId = null
222
+ payment.method = PaymentMethod.DirectDebit
223
+ payment.status = PaymentStatus.Created
224
+ payment.price = price
225
+ payment.paidAt = null
226
+ payment.provider = PaymentProvider.Mollie
227
+ await payment.save()
228
+ invoice.paymentId = payment.id
229
+ invoice.setRelation(STInvoice.payment, payment)
230
+ await invoice.save()
231
+
232
+ const description = "Stamhoofd - "+invoice.id
233
+
234
+ if (price <= 0) {
235
+ // Needs to happen before markPaid! (because the pending invoice will get modified)
236
+ pendingInvoice.invoiceId = invoice.id
237
+ await pendingInvoice.save()
238
+
239
+ await invoice.markPaid()
240
+ } else {
241
+ // Mollie payment is required
242
+ const apiKey = STAMHOOFD.MOLLIE_API_KEY
243
+ if (!apiKey) {
244
+ throw new SimpleError({
245
+ code: "",
246
+ message: "Betalingen zijn tijdelijk onbeschikbaar"
247
+ })
248
+ }
249
+ const mollieClient = createMollieClient({ apiKey });
250
+
251
+ const molliePayment = await mollieClient.payments.create({
252
+ amount: {
253
+ currency: 'EUR',
254
+ value: (price / 100).toFixed(2)
255
+ },
256
+ //method: molliePaymentMethod.directdebit,
257
+ description,
258
+ customerId: organization.serverMeta.mollieCustomerId,
259
+ sequenceType: SequenceType.recurring,
260
+ redirectUrl: "https://"+STAMHOOFD.domains.dashboard+'/settings/billing/payment?id='+encodeURIComponent(payment.id),
261
+ webhookUrl: 'https://'+STAMHOOFD.domains.api+"/v"+Version+"/billing/payments/"+encodeURIComponent(payment.id)+"?exchange=true",
262
+ metadata: {
263
+ invoiceId: invoice.id,
264
+ paymentId: payment.id,
265
+ }
266
+ });
267
+ console.log(molliePayment)
268
+ if (molliePayment.method === 'creditcard') {
269
+ console.log("Corrected payment method to creditcard")
270
+ payment.method = PaymentMethod.CreditCard
271
+ await payment.save();
272
+ }
273
+
274
+ // Save payment
275
+ const dbPayment = new MolliePayment()
276
+ dbPayment.paymentId = payment.id
277
+ dbPayment.mollieId = molliePayment.id
278
+ await dbPayment.save();
279
+
280
+ // Only if all went okay
281
+ pendingInvoice.invoiceId = invoice.id
282
+ await pendingInvoice.save()
283
+
284
+ const invoicingTo = await organization.getInvoicingToEmails()
285
+
286
+ if (invoicingTo && payment.method === PaymentMethod.DirectDebit) {
287
+ // Generate a temporary PDF file
288
+ const builder = new InvoiceBuilder(invoice)
289
+ const pdf = await builder.build()
290
+
291
+ // Send the e-mail
292
+ Email.sendInternal({
293
+ to: invoicingTo,
294
+ bcc: "simon@stamhoofd.be",
295
+ subject: "Pro-forma factuur voor "+organization.name,
296
+ text: "Dag "+organization.name+", \n\nBedankt voor jullie vertrouwen in Stamhoofd. Jullie hebben momenteel een openstaand bedrag van "+Formatter.price(price)+" in Stamhoofd (zie bijlage). Zoals eerder aangegeven zal dit via domiciliëring worden aangerekend (op dezelfde bankrekening waarmee de vorige betaling is gedaan). Hiervoor hoeven jullie dus niets te doen. Kijk eventueel na of er voldoende geld op jullie rekening staat. De betaling zal één van de komende drie werkdagen plaatsvinden. Wil je het rekeningnummer voor de volgende betaling wijzigen? Dan kan je de stappen volgen op https://"+organization.marketingDomain+"/docs/bankrekening-domiciliering-wijzigen/.\n\nNa betaling ontvangen jullie een definitieve factuur. Je kan in Stamhoofd altijd het openstaande bedrag nakijken bij Instellingen > Facturen en betalingen. Neem gerust contact met ons op (via "+organization.i18n.$t("shared.emails.general")+") als je denkt dat er iets fout is gegaan of als je nog bijkomende vragen zou hebben.\n\nMet vriendelijke groeten,\nStamhoofd\n\n",
297
+ attachments: [
298
+ {
299
+ filename: "pro-forma-factuur.pdf",
300
+ href: pdf.getPublicPath(),
301
+ contentType: "application/pdf"
302
+ }
303
+ ]
304
+ }, organization.i18n)
305
+ }
306
+ }
307
+ }
308
+ }