@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,134 @@
1
+ import { column, Model } from "@simonbackx/simple-database";
2
+ import { STInvoiceItem } from "@stamhoofd/structures";
3
+ import { v4 as uuidv4 } from "uuid";
4
+
5
+ import { STInvoice } from "./";
6
+
7
+ export class STCredit extends Model {
8
+ static table = "stamhoofd_credits";
9
+
10
+ // Columns
11
+ @column({
12
+ primary: true, type: "string", beforeSave(value) {
13
+ return value ?? uuidv4();
14
+ }
15
+ })
16
+ id!: string;
17
+
18
+ @column({ type: "string" })
19
+ organizationId: string;
20
+
21
+ @column({ type: "string" })
22
+ description: string;
23
+
24
+ @column({ type: "integer" })
25
+ change: number;
26
+
27
+ @column({ type: "boolean" })
28
+ allowTransactions = 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({ type: "datetime", nullable: true })
43
+ expireAt: Date | null = null
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
+ static async getForOrganization(organizationId: string) {
56
+ return await STCredit.where({ organizationId }, {
57
+ sort: [{
58
+ column: "createdAt",
59
+ direction: "DESC"
60
+ }]
61
+ })
62
+ }
63
+
64
+ static async getBalance(organizationId: string) {
65
+ const now = new Date()
66
+ const credits = await this.getForOrganization(organizationId)
67
+ credits.reverse()
68
+ let balance = 0
69
+ let balanceTransactions = 0
70
+
71
+ for (const credit of credits) {
72
+ if (credit.expireAt !== null && credit.expireAt <= now) {
73
+ continue
74
+ }
75
+ // TODO: we can expire credits here
76
+ balance += credit.change
77
+ if (balance < 0) {
78
+ // This is needed to make deleting credit and expiring credit work.
79
+ // At no point in time, the credits can get negative.
80
+ // E.g. Getting credits, using them, and later expiring 'getting the credits' won't have impact on future credits
81
+ balance = 0
82
+ }
83
+
84
+ if (credit.allowTransactions || credit.change < 0) {
85
+ balanceTransactions += credit.change
86
+
87
+ // No point in time we can have more balance for transactions
88
+ balanceTransactions = Math.min(Math.max(balanceTransactions, 0), balance)
89
+ }
90
+ }
91
+
92
+ return {balance: balance - balanceTransactions, balanceTransactions}
93
+ }
94
+
95
+ static async applyCredits(organizationId: string, invoice: STInvoice, dryRun: boolean) {
96
+ // Apply credits
97
+ const {balance, balanceTransactions} = await STCredit.getBalance(organizationId)
98
+ if (balance > 0 || balanceTransactions > 0) {
99
+ // Loop all items where you can use credits for
100
+ const maxCredits = invoice.meta.items.filter(i => i.canUseCredits).reduce((price, item) => price + item.price, 0)
101
+ let applyValue = Math.min(maxCredits, balance)
102
+
103
+ if (balanceTransactions > 0) {
104
+ // Can apply to all items
105
+ const maxTransactionsCredits = invoice.meta.items.reduce((price, item) => price + item.price, 0) - applyValue
106
+ applyValue += Math.min(maxTransactionsCredits, balanceTransactions)
107
+ }
108
+
109
+ if (applyValue > 0) {
110
+ invoice.meta.items.push(STInvoiceItem.create({
111
+ name: "Gebruikt tegoed",
112
+ unitPrice: -applyValue,
113
+ amount: 1,
114
+ date: new Date()
115
+ }))
116
+
117
+ if (!dryRun) {
118
+ const credit = new STCredit()
119
+ credit.organizationId = organizationId
120
+ credit.change = -applyValue
121
+ credit.description = "Tijdelijk vrijgehouden voor lopende betaling"
122
+
123
+ // Reserve for one week (direct debit can take a while)
124
+ credit.expireAt = new Date()
125
+ credit.expireAt.setDate(credit.expireAt.getDate() + 7)
126
+ credit.expireAt.setMilliseconds(0)
127
+
128
+ await credit.save()
129
+ invoice.creditId = credit.id
130
+ }
131
+ }
132
+ }
133
+ }
134
+ }
@@ -0,0 +1,507 @@
1
+ import { column, ManyToOneRelation, Model } from "@simonbackx/simple-database";
2
+ import { Email } from "@stamhoofd/email";
3
+ import { QueueHandler } from "@stamhoofd/queues";
4
+ import { calculateVATPercentage, Payment as PaymentStruct, PaymentMethod, STBillingStatus, STCredit as STCreditStruct, STInvoice as STInvoiceStruct, STInvoiceItem, STInvoiceMeta, STPackage as STPackageStruct, STPackageType, STPendingInvoice as STPendingInvoiceStruct } from '@stamhoofd/structures';
5
+ import { Sorter } from "@stamhoofd/utility";
6
+ import { v4 as uuidv4 } from "uuid";
7
+
8
+ import { InvoiceBuilder } from "../helpers/InvoiceBuilder";
9
+ import { Organization, Payment, STCredit, STPackage, STPendingInvoice, UsedRegisterCode } from './';
10
+
11
+ export class STInvoice extends Model {
12
+ static table = "stamhoofd_invoices";
13
+
14
+ private static numberCache: number | null = null
15
+
16
+ // Columns
17
+ @column({
18
+ primary: true, type: "string", beforeSave(value) {
19
+ return value ?? uuidv4();
20
+ }
21
+ })
22
+ id!: string;
23
+
24
+ /**
25
+ * Is null for deleted organizations
26
+ */
27
+ @column({ foreignKey: STInvoice.organization, type: "string", nullable: true })
28
+ organizationId: string | null;
29
+
30
+ /**
31
+ * An associated STCredit, that was used to remove credits from the user's credits.
32
+ * If the invoice is marked as failed, we need to delete this one
33
+ */
34
+ @column({ type: "string", nullable: true })
35
+ creditId: string | null = null
36
+
37
+ /**
38
+ * Note: always create a new invoice for failed payments. We never create an actual invoice until we received the payment
39
+ */
40
+ @column({ type: "string", nullable: true, foreignKey: STInvoice.payment })
41
+ paymentId: string | null = null
42
+
43
+ @column({ type: "json", decoder: STInvoiceMeta })
44
+ meta: STInvoiceMeta
45
+
46
+ /**
47
+ * If the number is null, no invoice is generated yet. Its still a WIP invoice (not an official one!)
48
+ */
49
+ @column({ type: "integer", nullable: true })
50
+ number: number | null = null
51
+
52
+ @column({ type: "datetime", nullable: true })
53
+ paidAt: Date | null = null
54
+
55
+ @column({
56
+ type: "datetime", beforeSave(old?: any) {
57
+ if (old !== undefined) {
58
+ return old;
59
+ }
60
+ const date = new Date()
61
+ date.setMilliseconds(0)
62
+ return date
63
+ }
64
+ })
65
+ createdAt: Date
66
+
67
+ @column({
68
+ type: "datetime", beforeSave() {
69
+ const date = new Date()
70
+ date.setMilliseconds(0)
71
+ return date
72
+ },
73
+ skipUpdate: true
74
+ })
75
+ updatedAt: Date
76
+
77
+ @column({ type: "string", nullable: true })
78
+ reference: string | null = null
79
+
80
+ static organization = new ManyToOneRelation(Organization, "organization");
81
+ static payment = new ManyToOneRelation(Payment, "payment");
82
+
83
+ static createFor(organization: Organization): STInvoice {
84
+ const invoice = new STInvoice()
85
+ invoice.organizationId = organization.id
86
+
87
+ const date = new Date()
88
+ invoice.meta = STInvoiceMeta.create({
89
+ date,
90
+ companyName: organization.meta.companyName ?? organization.name,
91
+ companyContact: organization.privateMeta.billingContact ?? "",
92
+ companyAddress: organization.meta.companyAddress ?? organization.address,
93
+ companyVATNumber: organization.meta.VATNumber,
94
+ companyNumber: organization.meta.companyNumber,
95
+ VATPercentage: calculateVATPercentage(organization.meta.companyAddress ?? organization.address, organization.meta.VATNumber)
96
+ })
97
+
98
+ return invoice
99
+ }
100
+
101
+ async getStructure() {
102
+ let payment: Payment | undefined
103
+ if (this.paymentId) {
104
+ payment = await Payment.getByID(this.paymentId)
105
+ }
106
+ return STInvoiceStruct.create(Object.assign({}, this, {
107
+ payment: payment ? PaymentStruct.create(payment) : null
108
+ }))
109
+ }
110
+
111
+ async getPackages(): Promise<STPackage[]> {
112
+ const ids = new Set<string>()
113
+
114
+ for (const item of this.meta.items) {
115
+ if (item.package) {
116
+ ids.add(item.package.id)
117
+ }
118
+ }
119
+
120
+ if (ids.size > 0) {
121
+ const packages = await STPackage.getByIDs(...ids)
122
+
123
+ if (packages.length !== ids.size) {
124
+ console.warn("Invoice contains invalid package ids "+this.id)
125
+ }
126
+ return packages
127
+ }
128
+
129
+ return []
130
+ }
131
+
132
+ async getOrganizationActivePackages(): Promise<STPackage[]> {
133
+ return this.organizationId ? (await STPackage.getForOrganization(this.organizationId)) : []
134
+ }
135
+
136
+ async activatePackages(paymentSucceeded = false) {
137
+ const packages = await this.getPackages()
138
+
139
+ // Search for all packages and activate them if needed (might be possible that they are already validated)
140
+ for (const p of packages) {
141
+ // It is possible that the meta of the package has changed in the previous loop call (in pack.activate), so we need to refetch it otherwise we get 'meta' conflicts
142
+ const pack = (await STPackage.getByID(p.id)) ?? p
143
+ console.log("Activating package "+pack.id)
144
+
145
+ // We'll never have multiple invoices for the same package that are awaiting payments
146
+ if (paymentSucceeded) {
147
+ pack.meta.firstFailedPayment = null;
148
+ pack.meta.paymentFailedCount = 0;
149
+ }
150
+
151
+ await pack.activate()
152
+
153
+ // Activate doesn't save always, so save if needed:
154
+ await pack.save()
155
+
156
+ // Deactivate demo packages
157
+ const remove: STPackageType[] = []
158
+ if (pack.meta.type === STPackageType.Members) {
159
+ // Remove demo
160
+ remove.push(STPackageType.TrialMembers)
161
+ }
162
+
163
+ if (pack.meta.type === STPackageType.SingleWebshop || pack.meta.type === STPackageType.Webshops) {
164
+ // Remove demo
165
+ remove.push(STPackageType.TrialWebshops)
166
+ }
167
+
168
+ if (remove.length > 0 && this.organizationId) {
169
+ // Get all packages
170
+ const all = await STPackage.getForOrganization(this.organizationId)
171
+ for (const pack of all) {
172
+ if (remove.includes(pack.meta.type)) {
173
+ console.log("Disabling demo package "+pack.id+" because package is bought.")
174
+ // Stop
175
+ pack.removeAt = new Date()
176
+ pack.removeAt.setTime(pack.removeAt.getTime() - 1000)
177
+ await pack.save()
178
+ }
179
+ }
180
+ }
181
+ }
182
+ }
183
+
184
+ /**
185
+ * WARNING: only call this in the correct queue!
186
+ */
187
+ async markPaid({sendEmail} = { sendEmail: true }) {
188
+ // Schule on the queue because we are modifying pending invoices
189
+ if (this.paidAt !== null) {
190
+ return
191
+ }
192
+
193
+ this.paidAt = new Date()
194
+
195
+ if (this.meta.priceWithoutVAT > 0) {
196
+ // Only assign a number if it was an non empty invoice
197
+ await this.assignNextNumber()
198
+ }
199
+
200
+ if (this.creditId !== null) {
201
+ const credit = await STCredit.getByID(this.creditId)
202
+ if (credit) {
203
+ // This credit was used to pay this invoice (partially)
204
+ credit.description = this.number !== null ? "Factuur "+this.number : "Betaling "+this.id
205
+ credit.expireAt = null;
206
+ await credit.save()
207
+ }
208
+ }
209
+
210
+ const packages = await this.getPackages()
211
+
212
+ // Increase paid amounts and paid prices
213
+ for (const item of this.meta.items) {
214
+ if (item.package) {
215
+ const pack = packages.find(p => p.id === item.package?.id)
216
+
217
+ if (pack) {
218
+ // Increase paid amount
219
+ pack.meta.paidPrice += item.price
220
+ pack.meta.paidAmount += item.amount
221
+ await pack.save();
222
+ }
223
+ }
224
+ }
225
+
226
+ // Search for all packages and activate them if needed (might be possible that they are already validated)
227
+ await this.activatePackages(true)
228
+
229
+ if (packages.length === 0) {
230
+ // Mark payments succeeded
231
+ const orgPackages = await this.getOrganizationActivePackages()
232
+ for (const p of orgPackages) {
233
+ if (p.meta.firstFailedPayment) {
234
+ const pack = (await STPackage.getByID(p.id)) ?? p
235
+ pack.meta.firstFailedPayment = null;
236
+ pack.meta.paymentFailedCount = 0;
237
+ await pack.save()
238
+ }
239
+ }
240
+ }
241
+
242
+ // If needed: remove the invoice items from the pending invoice
243
+ if (this.organizationId) {
244
+ const pendingInvoice = await STPendingInvoice.getForOrganization(this.organizationId)
245
+ if (pendingInvoice) {
246
+ // Remove all invoice items that were paid
247
+ const newItems: STInvoiceItem[] = []
248
+ for (const item of pendingInvoice.meta.items) {
249
+ const found = this.meta.items.find(i => i.id === item.id)
250
+ if (!found) {
251
+ newItems.push(item)
252
+ } else {
253
+ console.log("Removed invoice item "+item.id+" from pending invoice "+pendingInvoice.id)
254
+ }
255
+ }
256
+ pendingInvoice.meta.items = newItems
257
+
258
+ if (pendingInvoice.invoiceId === this.id) {
259
+ // Unlock the pending invoice: we allow new invoices to get created
260
+ pendingInvoice.invoiceId = null
261
+ }
262
+ await pendingInvoice.save()
263
+ }
264
+
265
+ // Force regeneration of organization meta data
266
+ await STPackage.updateOrganizationPackages(this.organizationId)
267
+ }
268
+
269
+ if (this.number !== null && !this.meta.pdf) {
270
+ await this.generatePdf()
271
+ }
272
+
273
+ if (this.organizationId && this.meta.pdf && this.number !== null && sendEmail) {
274
+ const organization = await Organization.getByID(this.organizationId)
275
+ if (organization) {
276
+ const invoicingTo = await organization.getInvoicingToEmails()
277
+
278
+ if (invoicingTo) {
279
+ // Send the e-mail
280
+ Email.sendInternal({
281
+ to: invoicingTo,
282
+ bcc: "simon@stamhoofd.be",
283
+ subject: "Stamhoofd Factuur " + this.number + " voor " + organization.name,
284
+ text: "Dag "+organization.name+", \n\nBedankt voor jullie vertrouwen in Stamhoofd. In bijlage vinden jullie factuur "+ this.number +" voor jullie administratie. Deze werd al betaald, je hoeft dus geen actie meer te ondernemen. 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",
285
+ attachments: [
286
+ {
287
+ filename: "factuur-"+this.number+".pdf",
288
+ href: this.meta.pdf.getPublicPath(),
289
+ contentType: "application/pdf"
290
+ }
291
+ ]
292
+ }, organization.i18n)
293
+ }
294
+ }
295
+ }
296
+
297
+ // Reward if we have an open register code
298
+ if (this.meta.priceWithVAT >= 100 && this.organizationId) {
299
+ // We spend some money
300
+ const code = await UsedRegisterCode.getFor(this.organizationId)
301
+ if (code && !code.creditId) {
302
+ console.log("Rewarding code "+code.id+" for payment")
303
+
304
+ // Deze code werd nog niet beloond
305
+ await code.reward()
306
+ }
307
+ }
308
+ }
309
+
310
+ async assignNextNumber() {
311
+ return await QueueHandler.schedule("billing/invoice-numbers", async () => {
312
+ // Get clone
313
+ const refreshed = await STInvoice.getByID(this.id)
314
+ if (!refreshed || refreshed.number !== null) {
315
+ return
316
+ }
317
+ // Removed the cache because not working across multiple instances
318
+ // if (STInvoice.numberCache) {
319
+ // this.number = STInvoice.numberCache + 1
320
+ // await this.save()
321
+ //
322
+ // // If save succeeded: increase it
323
+ // STInvoice.numberCache++;
324
+ // return
325
+ // }
326
+ const lastInvoice = await STInvoice.where({ number: { value: null, sign: "!=" }}, { sort: [{ column: "number", direction: "DESC"}], limit: 1 })
327
+ STInvoice.numberCache = lastInvoice[0]?.number ?? 0
328
+
329
+ this.number = STInvoice.numberCache + 1
330
+ this.meta.date = new Date()
331
+ await this.save()
332
+
333
+ // If save succeeded: increase it
334
+ STInvoice.numberCache++;
335
+ return
336
+ })
337
+ }
338
+
339
+ async generatePdf() {
340
+ const builder = new InvoiceBuilder(this)
341
+ this.meta.pdf = await builder.build()
342
+ await this.save()
343
+ }
344
+
345
+ /**
346
+ * WARNGING: only call this method in the correct queue!
347
+ */
348
+ async markFailed(payment: Payment, markFailed = true) {
349
+ console.log("Mark invoice as failed", this.id)
350
+
351
+ const packages = await this.getPackages()
352
+
353
+ if (markFailed && (payment.method === PaymentMethod.DirectDebit || payment.method === PaymentMethod.Transfer)) {
354
+ // Only mark failed payments for background payments
355
+ for (const pack of packages) {
356
+ console.log("Marking package with failed payment "+pack.id)
357
+
358
+ pack.meta.firstFailedPayment = pack.meta.firstFailedPayment ?? new Date()
359
+ pack.meta.paymentFailedCount++;
360
+ await pack.save()
361
+
362
+ }
363
+
364
+ if (packages.length == 0) {
365
+ // Mark all active packages as failed
366
+ const activePackages = await this.getOrganizationActivePackages()
367
+ for (const pack of activePackages) {
368
+ console.log("Marking package with failed payment "+pack.id)
369
+
370
+ pack.meta.firstFailedPayment = pack.meta.firstFailedPayment ?? new Date()
371
+ pack.meta.paymentFailedCount++;
372
+ await pack.save()
373
+ }
374
+ }
375
+ }
376
+
377
+
378
+ if (this.organizationId) {
379
+ const pendingInvoice = await STPendingInvoice.getForOrganization(this.organizationId)
380
+ if (pendingInvoice && pendingInvoice.invoiceId === this.id) {
381
+ pendingInvoice.invoiceId = null
382
+
383
+ // Also update the packages in the pending invoice itself
384
+ for (const item of pendingInvoice.meta.items) {
385
+ const pack = item.package
386
+ if (pack) {
387
+ const pp = packages.find(p => p.id === pack.id)
388
+ if (pp) {
389
+ console.log("Updated package "+pp.id+" in pending invoice")
390
+ // Update reference to include new failed counts
391
+ item.package = STPackageStruct.create(pp)
392
+ }
393
+ }
394
+ }
395
+
396
+ await pendingInvoice.save()
397
+ }
398
+
399
+ // Force regeneration of organization meta data
400
+ await STPackage.updateOrganizationPackages(this.organizationId)
401
+ }
402
+
403
+ if (this.creditId !== null) {
404
+ const credit = await STCredit.getByID(this.creditId)
405
+ if (credit && (credit.expireAt === null || credit.expireAt > new Date())) {
406
+ // Expire usage (do not delete to keep the relation for debugging and recovery)
407
+ credit.expireAt = new Date(new Date().getTime() - 1000);
408
+ await credit.save()
409
+ }
410
+ }
411
+
412
+ if (markFailed && this.organizationId && payment.method === PaymentMethod.DirectDebit) {
413
+ const organization = await Organization.getByID(this.organizationId)
414
+ if (organization) {
415
+ const invoicingTo = await organization.getInvoicingToEmails()
416
+
417
+ if (invoicingTo) {
418
+ // Send the e-mail
419
+ Email.sendInternal({
420
+ to: invoicingTo,
421
+ bcc: "simon@stamhoofd.be",
422
+ subject: "Betaling mislukt voor "+organization.name,
423
+ text: "Dag "+organization.name+", \n\nDe automatische betaling via domiciliëring van jullie openstaande bedrag is mislukt (zie daarvoor onze vorige e-mail). Kijk even na wat er fout ging en betaal het openstaande bedrag manueel om te vermijden dat bepaalde diensten tijdelijk worden uitgeschakeld. Betalen kan via Stamhoofd > Instellingen > Facturen en betalingen > Openstaand bedrag > Afrekenen. Neem gerust contact met ons op als je bijkomende vragen hebt.\n\nMet vriendelijke groeten,\nStamhoofd\n\n",
424
+ }, organization.i18n)
425
+ }
426
+ }
427
+ }
428
+
429
+ if (markFailed && this.organizationId && payment.method === PaymentMethod.Transfer) {
430
+ const organization = await Organization.getByID(this.organizationId)
431
+ if (organization) {
432
+ const invoicingTo = await organization.getInvoicingToEmails()
433
+
434
+ if (invoicingTo) {
435
+ // Send the e-mail
436
+ Email.sendInternal({
437
+ to: invoicingTo,
438
+ bcc: "simon@stamhoofd.be",
439
+ subject: "Betaling mislukt voor "+organization.name,
440
+ text: "Dag "+organization.name+", \n\nBij nazicht blijkt dat we geen overschrijving hebben ontvangen voor jullie aankoop. Kijk even na wat er fout ging en betaal het openstaande bedrag om te vermijden dat de diensten worden uitgeschakeld. Betalen kan via Stamhoofd > Instellingen > Facturen en betalingen > Openstaand bedrag > Afrekenen. Neem gerust contact met ons op als je bijkomende vragen hebt.\n\nMet vriendelijke groeten,\nStamhoofd\n\n",
441
+ }, organization.i18n)
442
+ }
443
+ }
444
+ }
445
+ }
446
+
447
+
448
+ static async getBillingStatus(organization: Organization, hideExpired = true): Promise<STBillingStatus> {
449
+ // Get all packages
450
+ const packages = hideExpired ? (await STPackage.getForOrganization(organization.id)) : (await STPackage.getForOrganizationIncludingExpired(organization.id))
451
+
452
+ // GEt all invoices
453
+ const invoices = await STInvoice.where({ organizationId: organization.id, number: { sign: "!=", value: null }})
454
+
455
+ // Get the pending invoice if it exists
456
+ const pendingInvoice = await STPendingInvoice.getForOrganization(organization.id)
457
+
458
+ // Generate temporary pending invoice items for the current state without adding them IRL
459
+ let notYetCreatedItems: STInvoiceItem[] = []
460
+ try {
461
+ notYetCreatedItems = await STPendingInvoice.createItems(organization.id, pendingInvoice)
462
+ } catch (e) {
463
+ console.error(e)
464
+ }
465
+ const pendingInvoiceStruct = pendingInvoice ? STPendingInvoiceStruct.create(pendingInvoice) : (notYetCreatedItems.length > 0 ? STPendingInvoiceStruct.create({
466
+ meta: STInvoiceMeta.create({
467
+ companyName: organization.meta.companyName ?? organization.name,
468
+ companyContact: organization.privateMeta.billingContact ?? "",
469
+ companyAddress: organization.meta.companyAddress ?? organization.address,
470
+ companyVATNumber: organization.meta.VATNumber,
471
+ VATPercentage: calculateVATPercentage(organization.meta.companyAddress ?? organization.address, organization.meta.VATNumber)
472
+ })
473
+ }) : null)
474
+
475
+ if (notYetCreatedItems.length > 0 && pendingInvoiceStruct) {
476
+ pendingInvoiceStruct.meta.items.push(...notYetCreatedItems)
477
+ }
478
+
479
+ if (pendingInvoiceStruct) {
480
+ // Compress
481
+ pendingInvoiceStruct.meta.items = STInvoiceItem.compress(pendingInvoiceStruct.meta.items)
482
+ }
483
+
484
+
485
+ if (pendingInvoice?.invoiceId && pendingInvoiceStruct) {
486
+ const invoice = await STInvoice.getByID(pendingInvoice?.invoiceId)
487
+ if (invoice) {
488
+ pendingInvoiceStruct.invoice = await invoice.getStructure()
489
+ }
490
+ }
491
+ invoices.sort((a, b) => Sorter.byDateValue(a.createdAt, b.createdAt))
492
+
493
+ const invoiceStructures: STInvoiceStruct[] = []
494
+ for (const invoice of invoices) {
495
+ invoiceStructures.push(await invoice.getStructure())
496
+ }
497
+
498
+ const credits = await STCredit.getForOrganization(organization.id)
499
+
500
+ return STBillingStatus.create({
501
+ packages: packages.map(pack => STPackageStruct.create(pack)),
502
+ invoices: invoiceStructures,
503
+ pendingInvoice: pendingInvoiceStruct,
504
+ credits: credits.map(c => STCreditStruct.create(c))
505
+ });
506
+ }
507
+ }