@stamhoofd/models 2.120.6 → 2.122.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) hide show
  1. package/dist/factories/GroupFactory.d.ts.map +1 -1
  2. package/dist/factories/GroupFactory.js +1 -1
  3. package/dist/factories/GroupFactory.js.map +1 -1
  4. package/dist/factories/OrganizationFactory.d.ts +2 -1
  5. package/dist/factories/OrganizationFactory.d.ts.map +1 -1
  6. package/dist/factories/OrganizationFactory.js +9 -1
  7. package/dist/factories/OrganizationFactory.js.map +1 -1
  8. package/dist/factories/RegistrationInvitationFactory.d.ts +15 -0
  9. package/dist/factories/RegistrationInvitationFactory.d.ts.map +1 -0
  10. package/dist/factories/RegistrationInvitationFactory.js +18 -0
  11. package/dist/factories/RegistrationInvitationFactory.js.map +1 -0
  12. package/dist/factories/STPackageFactory.js.map +1 -1
  13. package/dist/factories/UserFactory.d.ts.map +1 -1
  14. package/dist/factories/UserFactory.js +2 -2
  15. package/dist/factories/UserFactory.js.map +1 -1
  16. package/dist/factories/index.d.ts +1 -0
  17. package/dist/factories/index.d.ts.map +1 -1
  18. package/dist/factories/index.js +1 -0
  19. package/dist/factories/index.js.map +1 -1
  20. package/dist/helpers/EmailBuilder.d.ts.map +1 -1
  21. package/dist/helpers/EmailBuilder.js +8 -8
  22. package/dist/helpers/EmailBuilder.js.map +1 -1
  23. package/dist/helpers/Handlebars.d.ts.map +1 -1
  24. package/dist/helpers/Handlebars.js +10 -1
  25. package/dist/helpers/Handlebars.js.map +1 -1
  26. package/dist/helpers/InvoiceCounter.d.ts +24 -0
  27. package/dist/helpers/InvoiceCounter.d.ts.map +1 -0
  28. package/dist/helpers/InvoiceCounter.js +133 -0
  29. package/dist/helpers/InvoiceCounter.js.map +1 -0
  30. package/dist/index.d.ts +0 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +0 -1
  33. package/dist/index.js.map +1 -1
  34. package/dist/migrations/1605262045-import-postcodes.d.ts.map +1 -1
  35. package/dist/migrations/1605262045-import-postcodes.js +58 -24
  36. package/dist/migrations/1605262045-import-postcodes.js.map +1 -1
  37. package/dist/migrations/1605262046-import-postcodes-nl.d.ts.map +1 -1
  38. package/dist/migrations/1605262046-import-postcodes-nl.js +54 -17
  39. package/dist/migrations/1605262046-import-postcodes-nl.js.map +1 -1
  40. package/dist/migrations/1719567881-organization-periodId.sql +2 -0
  41. package/dist/migrations/1719567882-groups-periodId.sql +2 -0
  42. package/dist/migrations/1720080975-convert-charset.d.ts +4 -0
  43. package/dist/migrations/1720080975-convert-charset.d.ts.map +1 -0
  44. package/dist/migrations/1720080975-convert-charset.js +26 -0
  45. package/dist/migrations/1720080975-convert-charset.js.map +1 -0
  46. package/dist/migrations/1720080976-convert-charset-leads.d.ts.map +1 -1
  47. package/dist/migrations/1720080976-convert-charset-leads.js +11 -10
  48. package/dist/migrations/1720080976-convert-charset-leads.js.map +1 -1
  49. package/dist/migrations/1721400546-users-memberId.sql +2 -0
  50. package/dist/migrations/1722269236-group-waitinglist-id.sql +2 -1
  51. package/dist/migrations/1722525785-balance-item-paying-organization-id.sql +2 -0
  52. package/dist/migrations/1722525787-depending-balance-item.sql +2 -0
  53. package/dist/migrations/1722963554-registration-group-price-and-options.sql +1 -1
  54. package/dist/migrations/1723652797-payments-paying-organization-id-fk.sql +2 -0
  55. package/dist/migrations/1733317908-added-missing-organization-fk-on-registrations.sql +2 -0
  56. package/dist/migrations/1733317910-paying-organization-id-fk.sql +2 -0
  57. package/dist/migrations/1733504881-negative-invoice-id.sql +6 -0
  58. package/dist/migrations/1733994455-balance-item-status-open.d.ts +4 -0
  59. package/dist/migrations/1733994455-balance-item-status-open.d.ts.map +1 -0
  60. package/dist/migrations/1733994455-balance-item-status-open.js +28 -0
  61. package/dist/migrations/1733994455-balance-item-status-open.js.map +1 -0
  62. package/dist/migrations/1763216320-bigint-balance-item-payments.sql +2 -0
  63. package/dist/migrations/1763216320-bigint-balance-items.sql +5 -0
  64. package/dist/migrations/1763216320-bigint-orders.sql +2 -0
  65. package/dist/migrations/1763216320-bigint-payments.sql +2 -0
  66. package/dist/migrations/1763216332-bigint-balance-item-price-total.sql +2 -0
  67. package/dist/migrations/1769087808-corrected-invoice-user-agent.sql +2 -0
  68. package/dist/migrations/1769087809-payments-invoice-id.sql +2 -0
  69. package/dist/migrations/1772033555-balance-item-package-id.sql +2 -0
  70. package/dist/migrations/1776873089-create-registration-invitations-table.sql +13 -0
  71. package/dist/migrations/1778657958-payments-create-mandate.sql +2 -0
  72. package/dist/migrations/1778657959-payments-mandate-id.sql +2 -0
  73. package/dist/migrations/1778796615-payments-reversing-payment-id.sql +5 -0
  74. package/dist/migrations/1778950642-price-invoiced.sql +2 -0
  75. package/dist/migrations/1779443446-transfer-fees.sql +3 -0
  76. package/dist/migrations/1779709174-used-register-code-balance-item-id.sql +5 -0
  77. package/dist/migrations/1779968328-payments-admin-user-id.sql +5 -0
  78. package/dist/migrations/1779970611-payments-refunded-amount.sql +2 -0
  79. package/dist/migrations/1779972640-balance-items-failed-at.sql +2 -0
  80. package/dist/migrations/1780328285-document-template-locked.sql +2 -0
  81. package/dist/migrations/1780328286-document-locked.sql +2 -0
  82. package/dist/migrations/1780412083-documents-set-locked.d.ts +4 -0
  83. package/dist/migrations/1780412083-documents-set-locked.d.ts.map +1 -0
  84. package/dist/migrations/1780412083-documents-set-locked.js +14 -0
  85. package/dist/migrations/1780412083-documents-set-locked.js.map +1 -0
  86. package/dist/migrations/1780928401-v1-groups-migration-data.d.ts +4 -0
  87. package/dist/migrations/1780928401-v1-groups-migration-data.d.ts.map +1 -0
  88. package/dist/migrations/1780928401-v1-groups-migration-data.js +44 -0
  89. package/dist/migrations/1780928401-v1-groups-migration-data.js.map +1 -0
  90. package/dist/models/BalanceItem.d.ts +14 -1
  91. package/dist/models/BalanceItem.d.ts.map +1 -1
  92. package/dist/models/BalanceItem.js +91 -41
  93. package/dist/models/BalanceItem.js.map +1 -1
  94. package/dist/models/CachedBalance.d.ts +6 -1
  95. package/dist/models/CachedBalance.d.ts.map +1 -1
  96. package/dist/models/CachedBalance.js +3 -2
  97. package/dist/models/CachedBalance.js.map +1 -1
  98. package/dist/models/Document.d.ts +4 -0
  99. package/dist/models/Document.d.ts.map +1 -1
  100. package/dist/models/Document.js +26 -3
  101. package/dist/models/Document.js.map +1 -1
  102. package/dist/models/DocumentTemplate.d.ts +4 -0
  103. package/dist/models/DocumentTemplate.d.ts.map +1 -1
  104. package/dist/models/DocumentTemplate.js +37 -1
  105. package/dist/models/DocumentTemplate.js.map +1 -1
  106. package/dist/models/Email.d.ts.map +1 -1
  107. package/dist/models/Email.js +1 -1
  108. package/dist/models/Email.js.map +1 -1
  109. package/dist/models/EmailVerificationCode.d.ts.map +1 -1
  110. package/dist/models/EmailVerificationCode.js +3 -13
  111. package/dist/models/EmailVerificationCode.js.map +1 -1
  112. package/dist/models/Event.d.ts +2 -1
  113. package/dist/models/Event.d.ts.map +1 -1
  114. package/dist/models/Event.js +3 -0
  115. package/dist/models/Event.js.map +1 -1
  116. package/dist/models/EventNotification.d.ts.map +1 -1
  117. package/dist/models/EventNotification.js +5 -5
  118. package/dist/models/EventNotification.js.map +1 -1
  119. package/dist/models/Group.d.ts +4 -0
  120. package/dist/models/Group.d.ts.map +1 -1
  121. package/dist/models/Group.js +17 -0
  122. package/dist/models/Group.js.map +1 -1
  123. package/dist/models/Invoice.d.ts +1 -0
  124. package/dist/models/Invoice.d.ts.map +1 -1
  125. package/dist/models/Invoice.js +8 -8
  126. package/dist/models/Invoice.js.map +1 -1
  127. package/dist/models/MemberPlatformMembership.d.ts.map +1 -1
  128. package/dist/models/MemberPlatformMembership.js +9 -0
  129. package/dist/models/MemberPlatformMembership.js.map +1 -1
  130. package/dist/models/MollieToken.d.ts +4 -8
  131. package/dist/models/MollieToken.d.ts.map +1 -1
  132. package/dist/models/MollieToken.js +37 -90
  133. package/dist/models/MollieToken.js.map +1 -1
  134. package/dist/models/Order.d.ts.map +1 -1
  135. package/dist/models/Order.js +1 -0
  136. package/dist/models/Order.js.map +1 -1
  137. package/dist/models/Organization.d.ts +30 -23
  138. package/dist/models/Organization.d.ts.map +1 -1
  139. package/dist/models/Organization.js +113 -61
  140. package/dist/models/Organization.js.map +1 -1
  141. package/dist/models/PasswordToken.d.ts +5 -1
  142. package/dist/models/PasswordToken.d.ts.map +1 -1
  143. package/dist/models/PasswordToken.js +18 -17
  144. package/dist/models/PasswordToken.js.map +1 -1
  145. package/dist/models/Payment.d.ts +35 -3
  146. package/dist/models/Payment.d.ts.map +1 -1
  147. package/dist/models/Payment.js +66 -3
  148. package/dist/models/Payment.js.map +1 -1
  149. package/dist/models/Registration.d.ts +1 -0
  150. package/dist/models/Registration.d.ts.map +1 -1
  151. package/dist/models/Registration.js +4 -3
  152. package/dist/models/Registration.js.map +1 -1
  153. package/dist/models/RegistrationInvitation.d.ts +14 -0
  154. package/dist/models/RegistrationInvitation.d.ts.map +1 -0
  155. package/dist/models/RegistrationInvitation.js +45 -0
  156. package/dist/models/RegistrationInvitation.js.map +1 -0
  157. package/dist/models/STCredit.d.ts +4 -0
  158. package/dist/models/STCredit.d.ts.map +1 -1
  159. package/dist/models/STCredit.js +28 -0
  160. package/dist/models/STCredit.js.map +1 -1
  161. package/dist/models/STInvoice.d.ts +7 -1
  162. package/dist/models/STInvoice.d.ts.map +1 -1
  163. package/dist/models/STInvoice.js +9 -0
  164. package/dist/models/STInvoice.js.map +1 -1
  165. package/dist/models/STPackage.d.ts +4 -0
  166. package/dist/models/STPackage.d.ts.map +1 -1
  167. package/dist/models/STPackage.js +12 -1
  168. package/dist/models/STPackage.js.map +1 -1
  169. package/dist/models/UsedRegisterCode.d.ts +9 -0
  170. package/dist/models/UsedRegisterCode.d.ts.map +1 -1
  171. package/dist/models/UsedRegisterCode.js +31 -0
  172. package/dist/models/UsedRegisterCode.js.map +1 -1
  173. package/dist/models/User.d.ts +1 -1
  174. package/dist/models/User.d.ts.map +1 -1
  175. package/dist/models/User.js +1 -1
  176. package/dist/models/User.js.map +1 -1
  177. package/dist/models/_relations.js +25 -0
  178. package/dist/models/_relations.js.map +1 -1
  179. package/dist/models/addresses/City.d.ts +4 -4
  180. package/dist/models/addresses/City.d.ts.map +1 -1
  181. package/dist/models/addresses/City.js +6 -6
  182. package/dist/models/addresses/City.js.map +1 -1
  183. package/dist/models/addresses/PostalCode.d.ts +2 -2
  184. package/dist/models/addresses/PostalCode.d.ts.map +1 -1
  185. package/dist/models/addresses/PostalCode.js +4 -3
  186. package/dist/models/addresses/PostalCode.js.map +1 -1
  187. package/dist/models/addresses/Street.d.ts +3 -3
  188. package/dist/models/addresses/Street.d.ts.map +1 -1
  189. package/dist/models/addresses/Street.js +4 -4
  190. package/dist/models/addresses/Street.js.map +1 -1
  191. package/dist/models/index.d.ts +2 -0
  192. package/dist/models/index.d.ts.map +1 -1
  193. package/dist/models/index.js +2 -0
  194. package/dist/models/index.js.map +1 -1
  195. package/dist/models/v1GroupMigrationData.d.ts +22 -0
  196. package/dist/models/v1GroupMigrationData.d.ts.map +1 -0
  197. package/dist/models/v1GroupMigrationData.js +48 -0
  198. package/dist/models/v1GroupMigrationData.js.map +1 -0
  199. package/package.json +41 -13
  200. package/src/factories/GroupFactory.ts +4 -6
  201. package/src/factories/OrganizationFactory.ts +12 -4
  202. package/src/factories/RegistrationInvitationFactory.ts +24 -0
  203. package/src/factories/STPackageFactory.ts +2 -2
  204. package/src/factories/UserFactory.ts +4 -5
  205. package/src/factories/index.ts +1 -0
  206. package/src/helpers/EmailBuilder.ts +19 -28
  207. package/src/helpers/Handlebars.ts +10 -1
  208. package/src/helpers/InvoiceCounter.test.ts +220 -0
  209. package/src/helpers/InvoiceCounter.ts +162 -0
  210. package/src/index.ts +0 -1
  211. package/src/migrations/1605262045-import-postcodes.ts +62 -25
  212. package/src/migrations/1605262046-import-postcodes-nl.ts +58 -17
  213. package/src/migrations/1719567881-organization-periodId.sql +2 -0
  214. package/src/migrations/1719567882-groups-periodId.sql +2 -0
  215. package/src/migrations/1720080975-convert-charset.ts +34 -0
  216. package/src/migrations/1720080976-convert-charset-leads.ts +16 -13
  217. package/src/migrations/1721400546-users-memberId.sql +2 -0
  218. package/src/migrations/1722269236-group-waitinglist-id.sql +2 -1
  219. package/src/migrations/1722525785-balance-item-paying-organization-id.sql +2 -0
  220. package/src/migrations/1722525787-depending-balance-item.sql +2 -0
  221. package/src/migrations/1722963554-registration-group-price-and-options.sql +1 -1
  222. package/src/migrations/1723652797-payments-paying-organization-id-fk.sql +2 -0
  223. package/src/migrations/1733317908-added-missing-organization-fk-on-registrations.sql +2 -0
  224. package/src/migrations/1733317910-paying-organization-id-fk.sql +2 -0
  225. package/src/migrations/1733504881-negative-invoice-id.sql +6 -0
  226. package/src/migrations/1733994455-balance-item-status-open.ts +30 -0
  227. package/src/migrations/1763216320-bigint-balance-item-payments.sql +2 -0
  228. package/src/migrations/1763216320-bigint-balance-items.sql +5 -0
  229. package/src/migrations/1763216320-bigint-orders.sql +2 -0
  230. package/src/migrations/1763216320-bigint-payments.sql +2 -0
  231. package/src/migrations/1763216332-bigint-balance-item-price-total.sql +2 -0
  232. package/src/migrations/1769087808-corrected-invoice-user-agent.sql +2 -0
  233. package/src/migrations/1769087809-payments-invoice-id.sql +2 -0
  234. package/src/migrations/1772033555-balance-item-package-id.sql +2 -0
  235. package/src/migrations/1776873089-create-registration-invitations-table.sql +13 -0
  236. package/src/migrations/1778657958-payments-create-mandate.sql +2 -0
  237. package/src/migrations/1778657959-payments-mandate-id.sql +2 -0
  238. package/src/migrations/1778796615-payments-reversing-payment-id.sql +5 -0
  239. package/src/migrations/1778950642-price-invoiced.sql +2 -0
  240. package/src/migrations/1779443446-transfer-fees.sql +3 -0
  241. package/src/migrations/1779709174-used-register-code-balance-item-id.sql +5 -0
  242. package/src/migrations/1779968328-payments-admin-user-id.sql +5 -0
  243. package/src/migrations/1779970611-payments-refunded-amount.sql +2 -0
  244. package/src/migrations/1779972640-balance-items-failed-at.sql +2 -0
  245. package/src/migrations/1780328285-document-template-locked.sql +2 -0
  246. package/src/migrations/1780328286-document-locked.sql +2 -0
  247. package/src/migrations/1780412083-documents-set-locked.ts +18 -0
  248. package/src/migrations/1780928401-v1-groups-migration-data.ts +50 -0
  249. package/src/models/BalanceItem.ts +98 -43
  250. package/src/models/CachedBalance.test.ts +46 -46
  251. package/src/models/CachedBalance.ts +7 -7
  252. package/src/models/Document.ts +34 -13
  253. package/src/models/DocumentTemplate.ts +56 -17
  254. package/src/models/Email.test.ts +3 -3
  255. package/src/models/Email.ts +28 -49
  256. package/src/models/EmailVerificationCode.ts +8 -22
  257. package/src/models/Event.ts +6 -4
  258. package/src/models/EventNotification.ts +6 -6
  259. package/src/models/Group.ts +24 -3
  260. package/src/models/Invoice.ts +10 -9
  261. package/src/models/MemberPlatformMembership.test.ts +70 -0
  262. package/src/models/MemberPlatformMembership.ts +16 -12
  263. package/src/models/MollieToken.ts +42 -102
  264. package/src/models/Order.ts +14 -26
  265. package/src/models/Organization.ts +143 -86
  266. package/src/models/PasswordToken.ts +21 -21
  267. package/src/models/Payment.ts +61 -4
  268. package/src/models/Registration.ts +6 -5
  269. package/src/models/RegistrationInvitation.ts +40 -0
  270. package/src/models/STCredit.ts +32 -0
  271. package/src/models/STInvoice.ts +11 -5
  272. package/src/models/STPackage.ts +19 -14
  273. package/src/models/UsedRegisterCode.ts +34 -0
  274. package/src/models/User.ts +6 -7
  275. package/src/models/_relations.ts +29 -0
  276. package/src/models/addresses/City.ts +8 -6
  277. package/src/models/addresses/PostalCode.test.ts +1 -0
  278. package/src/models/addresses/PostalCode.ts +5 -3
  279. package/src/models/addresses/Street.ts +6 -4
  280. package/src/models/index.ts +3 -0
  281. package/src/models/v1GroupMigrationData.ts +43 -0
  282. package/dist/helpers/MemberMerger.d.ts +0 -14
  283. package/dist/helpers/MemberMerger.d.ts.map +0 -1
  284. package/dist/helpers/MemberMerger.js +0 -364
  285. package/dist/helpers/MemberMerger.js.map +0 -1
  286. package/dist/migrations/1720080975-convert-charset.sql +0 -85
  287. package/dist/migrations/1723202126-member-number-index.sql +0 -2
  288. package/dist/models/OneTimeToken.d.ts +0 -38
  289. package/dist/models/OneTimeToken.d.ts.map +0 -1
  290. package/dist/models/OneTimeToken.js +0 -125
  291. package/dist/models/OneTimeToken.js.map +0 -1
  292. package/src/helpers/MemberMerger.test.ts +0 -782
  293. package/src/helpers/MemberMerger.ts +0 -577
  294. package/src/migrations/1720080975-convert-charset.sql +0 -85
  295. package/src/migrations/1723202126-member-number-index.sql +0 -2
  296. package/src/models/OneTimeToken.ts +0 -133
@@ -0,0 +1,5 @@
1
+ ALTER TABLE `balance_items`
2
+ CHANGE `unitPrice` `unitPrice` bigint NOT NULL DEFAULT '0',
3
+ CHANGE `pricePaid` `pricePaid` bigint NOT NULL DEFAULT '0',
4
+ CHANGE `pricePending` `pricePending` bigint NOT NULL DEFAULT '0',
5
+ CHANGE `priceOpen` `priceOpen` bigint NOT NULL DEFAULT '0';
@@ -0,0 +1,2 @@
1
+ ALTER TABLE `webshop_orders`
2
+ CHANGE `totalPrice` `totalPrice` bigint NULL;
@@ -0,0 +1,2 @@
1
+ ALTER TABLE `payments`
2
+ CHANGE `price` `price` bigint NOT NULL DEFAULT '0';
@@ -0,0 +1,2 @@
1
+ ALTER TABLE `balance_items`
2
+ CHANGE `priceTotal` `priceTotal` bigint NOT NULL DEFAULT '0';
@@ -0,0 +1,2 @@
1
+ ALTER TABLE `invoices`
2
+ CHANGE `userAgent` `userAgent` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL;
@@ -1,3 +1,5 @@
1
+ SET FOREIGN_KEY_CHECKS=0;
1
2
  ALTER TABLE `payments`
2
3
  ADD COLUMN `invoiceId` varchar(36) NULL AFTER `customer`,
3
4
  ADD FOREIGN KEY (`invoiceId`) REFERENCES `invoices` (`id`) ON UPDATE CASCADE ON DELETE SET NULL;
5
+ SET FOREIGN_KEY_CHECKS=1;
@@ -1,3 +1,5 @@
1
+ SET FOREIGN_KEY_CHECKS=0;
1
2
  ALTER TABLE `balance_items`
2
3
  ADD COLUMN `packageId` varchar(36) NULL AFTER `memberId`,
3
4
  ADD FOREIGN KEY (`packageId`) REFERENCES `stamhoofd_packages` (`id`) ON UPDATE CASCADE ON DELETE SET NULL;
5
+ SET FOREIGN_KEY_CHECKS=1;
@@ -0,0 +1,13 @@
1
+ CREATE TABLE `registration_invitations` (
2
+ `id` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
3
+ `memberId` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
4
+ `groupId` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
5
+ `organizationId` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
6
+ `createdAt` datetime NOT NULL,
7
+ PRIMARY KEY (`id`),
8
+ UNIQUE KEY `uk_member_group` (`memberId`, `groupId`),
9
+ KEY `idx_memberId` (`memberId`) USING BTREE,
10
+ CONSTRAINT `registration_invitations_ibfk_1` FOREIGN KEY (`memberId`) REFERENCES `members` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
11
+ CONSTRAINT `registration_invitations_ibfk_2` FOREIGN KEY (`groupId`) REFERENCES `groups` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
12
+ CONSTRAINT `registration_invitations_ibfk_3` FOREIGN KEY (`organizationId`) REFERENCES `organizations` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
13
+ ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
@@ -0,0 +1,2 @@
1
+ ALTER TABLE `payments`
2
+ ADD COLUMN `createMandate` json NULL AFTER `stripeAccountId`;
@@ -0,0 +1,2 @@
1
+ ALTER TABLE `payments`
2
+ ADD COLUMN `mandateId` varchar(36) NULL AFTER `stripeAccountId`;
@@ -0,0 +1,5 @@
1
+ SET FOREIGN_KEY_CHECKS=0;
2
+ ALTER TABLE `payments`
3
+ ADD COLUMN `reversingPaymentId` varchar(36) NULL AFTER `invoiceId`,
4
+ ADD FOREIGN KEY (`reversingPaymentId`) REFERENCES `payments` (`id`) ON UPDATE CASCADE ON DELETE SET NULL;
5
+ SET FOREIGN_KEY_CHECKS=1;
@@ -0,0 +1,2 @@
1
+ ALTER TABLE `balance_items`
2
+ ADD COLUMN `priceInvoiced` int NOT NULL DEFAULT '0' AFTER `priceOpen`;
@@ -0,0 +1,3 @@
1
+ ALTER TABLE `payments`
2
+ ADD COLUMN `transferFeeManual` int NOT NULL DEFAULT '0' AFTER `transferFee`,
3
+ ADD COLUMN `transferFeeManualCharged` int NOT NULL DEFAULT '0' AFTER `transferFeeManual`;
@@ -0,0 +1,5 @@
1
+ SET FOREIGN_KEY_CHECKS=0;
2
+ ALTER TABLE `used_register_codes`
3
+ ADD COLUMN `balanceItemId` varchar(36) NULL AFTER `code`,
4
+ ADD FOREIGN KEY (`balanceItemId`) REFERENCES `balance_items` (`id`) ON UPDATE CASCADE ON DELETE SET NULL;
5
+ SET FOREIGN_KEY_CHECKS=1;
@@ -0,0 +1,5 @@
1
+ SET FOREIGN_KEY_CHECKS=0;
2
+ ALTER TABLE `payments`
3
+ ADD COLUMN `adminUserId` varchar(36) NULL AFTER `organizationId`,
4
+ ADD FOREIGN KEY (`adminUserId`) REFERENCES `users` (`id`) ON UPDATE CASCADE ON DELETE SET NULL;
5
+ SET FOREIGN_KEY_CHECKS=1;
@@ -0,0 +1,2 @@
1
+ ALTER TABLE `payments`
2
+ ADD COLUMN `refundedAmount` bigint NOT NULL DEFAULT '0' AFTER `price`;
@@ -0,0 +1,2 @@
1
+ ALTER TABLE `balance_items`
2
+ ADD COLUMN `failedAt` datetime NULL AFTER `paidAt`;
@@ -0,0 +1,2 @@
1
+ ALTER TABLE `document_templates`
2
+ ADD COLUMN `isLocked` tinyint(1) NOT NULL DEFAULT '0' AFTER `publishedAt`;
@@ -0,0 +1,2 @@
1
+ ALTER TABLE `documents`
2
+ ADD COLUMN `isLocked` tinyint(1) NOT NULL DEFAULT '0' AFTER `number`;
@@ -0,0 +1,18 @@
1
+ import { Database, Migration } from '@simonbackx/simple-database';
2
+
3
+ export default new Migration(async () => {
4
+ process.stdout.write('\n');
5
+
6
+ if (STAMHOOFD.userMode === 'platform') {
7
+ console.log('Skipped set documents locked for userMode platform.');
8
+ return Promise.resolve();
9
+ }
10
+
11
+ console.log('Start locking document templates.');
12
+ await Database.statement(`update document_templates set isLocked = 1 where status = 'Published';`);
13
+
14
+ console.log('Start locking documents.');
15
+ await Database.statement(`update documents set isLocked = 1 where status = 'Published';`);
16
+
17
+ return Promise.resolve();
18
+ });
@@ -0,0 +1,50 @@
1
+ import { Database, Migration } from '@simonbackx/simple-database';
2
+ export default new Migration(async () => {
3
+ if (STAMHOOFD.environment === 'test') {
4
+ console.log('skipped in tests');
5
+ return;
6
+ }
7
+
8
+ if (STAMHOOFD.userMode === 'platform') {
9
+ console.log('skipped for userMode platform');
10
+ return;
11
+ }
12
+
13
+ console.log('start create v1_groups_migration_data table');
14
+
15
+ // create table to keep track of which combination of group id and cycle has been migrated to a new group after the migration from Stamhoofd v1 to v2
16
+ const groupsQuery = `CREATE TABLE \`v1_groups_migration_data\` (
17
+ \`newGroupId\` varchar(36) NOT NULL,
18
+ \`oldGroupId\` varchar(36) NOT NULL,
19
+ \`oldCycle\` int NOT NULL DEFAULT '0',
20
+ PRIMARY KEY (\`newGroupId\`),
21
+ UNIQUE KEY \`oldKey\` (\`oldGroupId\`,\`oldCycle\`) USING BTREE,
22
+ CONSTRAINT \`v1_groups_migration_data_ibfk_1\` FOREIGN KEY (\`newGroupId\`) REFERENCES \`groups\` (\`id\`) ON DELETE CASCADE ON UPDATE CASCADE
23
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;`;
24
+
25
+ await Database.statement(groupsQuery);
26
+ console.log('finished create v1_groups_migration_data table');
27
+
28
+ console.log('start create v1_waiting_list_migration_data table');
29
+ // create table to keep track of which combination of waiting list group id and cycle has been migrated to a new group after the migration from Stamhoofd v1 to v2
30
+ const waitingListsQuery = `CREATE TABLE \`v1_waiting_list_migration_data\` (
31
+ \`newGroupId\` varchar(36) NOT NULL,
32
+ \`oldGroupId\` varchar(36) NOT NULL,
33
+ \`oldCycle\` int NOT NULL DEFAULT '0',
34
+ PRIMARY KEY (\`newGroupId\`),
35
+ UNIQUE KEY \`oldKey\` (\`oldGroupId\`,\`oldCycle\`) USING BTREE,
36
+ CONSTRAINT \`v1_waiting_list_migration_data_ibfk_1\` FOREIGN KEY (\`newGroupId\`) REFERENCES \`groups\` (\`id\`) ON DELETE CASCADE ON UPDATE CASCADE
37
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;`;
38
+ await Database.statement(waitingListsQuery);
39
+
40
+ console.log('finished create v1_waiting_list_migration_data table');
41
+ });
42
+
43
+ // CREATE TABLE `v1_groups_migration_data` (
44
+ // `newGroupId` varchar(36) NOT NULL,
45
+ // `oldGroupId` varchar(36) NOT NULL,
46
+ // `oldCycle` int NOT NULL DEFAULT '0',
47
+ // PRIMARY KEY (`newGroupId`),
48
+ // UNIQUE KEY `oldKey` (`oldGroupId`,`oldCycle`) USING BTREE,
49
+ // CONSTRAINT `groups_ibfk_1` FOREIGN KEY (`newGroupId`) REFERENCES `groups` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
50
+ // ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
@@ -5,7 +5,8 @@ import { Formatter, STMath } from '@stamhoofd/utility';
5
5
  import { v4 as uuidv4 } from 'uuid';
6
6
 
7
7
  import { EnumDecoder, MapDecoder } from '@simonbackx/simple-encoding';
8
- import { QueryableModel } from '@stamhoofd/sql';
8
+ import { SimpleError } from '@simonbackx/simple-errors';
9
+ import { QueryableModel, SQL } from '@stamhoofd/sql';
9
10
  import { Payment } from './Payment.js';
10
11
 
11
12
  /**
@@ -186,6 +187,12 @@ export class BalanceItem extends QueryableModel {
186
187
  })
187
188
  priceOpen = 0;
188
189
 
190
+ /**
191
+ * Cached value, for optimizations
192
+ */
193
+ @column({ type: 'integer' })
194
+ priceInvoiced = 0;
195
+
189
196
  /**
190
197
  * todo: deprecate ('pending' and 'paid') + 'hidden' status and replace with 'due' + 'hidden'
191
198
  * -> maybe add 'due' (due if dueAt is null or <= now), 'hidden' (never due), 'future' (= not due until dueAt - but not possible to pay earlier)
@@ -206,6 +213,12 @@ export class BalanceItem extends QueryableModel {
206
213
  @column({ type: 'datetime', nullable: true })
207
214
  paidAt: Date | null = null;
208
215
 
216
+ /**
217
+ * Marking a balance item as 'failed' can have side effects. To prevent executing these side effects multiple times, we store it in here.
218
+ */
219
+ @column({ type: 'datetime', nullable: true })
220
+ failedAt: Date | null = null;
221
+
209
222
  @column({
210
223
  type: 'datetime', beforeSave(old?: any) {
211
224
  if (old !== undefined) {
@@ -544,6 +557,49 @@ export class BalanceItem extends QueryableModel {
544
557
  await Database.update(query, params);
545
558
  }
546
559
 
560
+ /**
561
+ * Update the outstanding balance of multiple members in one go (or all members)
562
+ */
563
+ static async updateInvoiced(balanceItemIds: string[] | 'all') {
564
+ if (balanceItemIds !== 'all' && balanceItemIds.length === 0) {
565
+ return 0;
566
+ }
567
+
568
+ const params: any[] = [];
569
+ let firstWhere = '';
570
+ let secondWhere = '';
571
+
572
+ if (balanceItemIds !== 'all') {
573
+ firstWhere = ` AND balanceItemId IN (?)`;
574
+ params.push(balanceItemIds);
575
+ params.push(balanceItemIds);
576
+
577
+ secondWhere = `WHERE balance_items.id IN (?)`;
578
+ params.push(balanceItemIds);
579
+ }
580
+
581
+ // Note: this query only works in MySQL because of the SET assignment behaviour allowing to reference newly set values
582
+ const query = `
583
+ UPDATE
584
+ balance_items
585
+ LEFT JOIN (
586
+ SELECT
587
+ balanceItemId,
588
+ sum(invoiced_balance_items.balanceInvoicedAmount) AS invoiced
589
+ FROM
590
+ invoiced_balance_items
591
+ LEFT JOIN invoices ON invoices.id = invoiced_balance_items.invoiceId
592
+ WHERE
593
+ invoices.number is not null${firstWhere}
594
+ GROUP BY
595
+ balanceItemId
596
+ ) invoiced ON invoiced.balanceItemId = balance_items.id
597
+ SET balance_items.priceInvoiced = coalesce(invoiced.invoiced, 0)
598
+ ${secondWhere}`;
599
+
600
+ return (await Database.update(query, params))[0].affectedRows;
601
+ }
602
+
547
603
  static async loadPayments(items: (BalanceItem | { id: string })[]) {
548
604
  if (items.length == 0) {
549
605
  return { balanceItemPayments: [], payments: [] };
@@ -613,61 +669,60 @@ export class BalanceItem extends QueryableModel {
613
669
  }
614
670
 
615
671
  static async balanceItemsForUsersAndMembers(organizationId: string | null, userIds: string[], memberIds: string[]): Promise<BalanceItem[]> {
616
- if (memberIds.length == 0 && userIds.length == 0) {
672
+ if (memberIds.length === 0 && userIds.length === 0) {
617
673
  return [];
618
674
  }
619
675
 
620
- const params: any[] = [];
621
- const where: string[] = [];
676
+ const base = BalanceItem.select()
677
+ .whereNot('status', BalanceItemStatus.Hidden);
622
678
 
623
- if (memberIds.length) {
624
- if (memberIds.length == 1) {
625
- where.push(`memberId = ?`);
626
- params.push(memberIds[0]);
627
- }
628
- else {
629
- where.push(`memberId IN (?)`);
630
- params.push(memberIds);
631
- }
679
+ if (organizationId) {
680
+ base.andWhere('organizationId', organizationId);
632
681
  }
633
682
 
634
- // Note here, we don't search for memberId IS NULL restriction in MySQL because it slows down the query too much (500ms)
635
- // Better if we do it in code here
636
- if (userIds.length) {
637
- if (userIds.length == 1) {
638
- where.push('userId = ?');
639
- params.push(userIds[0]);
640
- }
641
- else {
642
- where.push('userId IN (?)');
643
- params.push(userIds);
644
- }
683
+ if (memberIds.length && userIds.length) {
684
+ // Don't include other members than the provided members
685
+ base.andWhere(
686
+ SQL.where('memberId', memberIds)
687
+ // Include null member
688
+ .or(
689
+ // Don't include balances of other members, even when userId matches
690
+ // this allows removing access for a member
691
+ SQL.where('userId', userIds)
692
+ .and('memberId', null),
693
+ ),
694
+ );
695
+ } else if (memberIds.length) {
696
+ base.andWhere('memberId', memberIds);
697
+ } else if (userIds.length) {
698
+ base.andWhere('userId', userIds);
645
699
  }
646
700
 
647
- const requiredWhere: string[] = [];
648
-
649
- if (organizationId) {
650
- requiredWhere.push('organizationId = ?');
651
- params.push(organizationId);
652
- }
701
+ base.andWhere('priceOpen', '!=', 0);
653
702
 
654
- const query = `SELECT ${BalanceItem.getDefaultSelect()} FROM ${BalanceItem.table} WHERE (${where.join(' OR ')}) ${requiredWhere.length ? (' AND ' + requiredWhere.join(' AND ')) : ''} AND ${BalanceItem.table}.status != ?`;
655
- params.push(BalanceItemStatus.Hidden);
703
+ return await base.fetch();
704
+ }
656
705
 
657
- const [rows] = await Database.select(query, params);
658
- const balanceItems = BalanceItem.fromRows(rows, BalanceItem.table);
706
+ static async balanceItemsForOrganization(payingOrganizationId: string, organizationId?: string): Promise<BalanceItem[]> {
707
+ const base = BalanceItem.select()
708
+ .where('payingOrganizationId', payingOrganizationId)
709
+ .whereNot('status', BalanceItemStatus.Hidden);
659
710
 
660
- // Filter out items of other members
661
- if (memberIds.length) {
662
- return balanceItems.filter(b => !b.memberId || memberIds.includes(b.memberId));
711
+ if (organizationId) {
712
+ base.where('organizationId', organizationId);
663
713
  }
664
- return balanceItems;
714
+
715
+ return await base.fetch();
665
716
  }
666
717
 
667
- static async balanceItemsForOrganization(organizationId: string): Promise<BalanceItem[]> {
668
- return await BalanceItem.select()
669
- .where('payingOrganizationId', organizationId)
670
- .whereNot('status', BalanceItemStatus.Hidden)
671
- .fetch();
718
+ override save(...args: Parameters<QueryableModel['save']>): Promise<boolean> {
719
+ if (this.unitPrice % 100 !== 0) {
720
+ throw new SimpleError({
721
+ statusCode: 500,
722
+ code: 'unrounded_balance_item',
723
+ message: 'Balance item unitPrices should be rounded up to 1 cent',
724
+ });
725
+ }
726
+ return super.save(...args);
672
727
  }
673
728
  }