@stamhoofd/backend 2.39.0 → 2.40.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 (198) hide show
  1. package/eslint.config.mjs +5 -0
  2. package/index.ts +81 -74
  3. package/jest.config.cjs +10 -0
  4. package/migrations.ts +16 -14
  5. package/package.json +11 -11
  6. package/src/crons/clear-excel-cache.test.ts +48 -50
  7. package/src/crons/clear-excel-cache.ts +18 -18
  8. package/src/crons/setup-steps.ts +2 -2
  9. package/src/crons.ts +325 -306
  10. package/src/decoders/StringArrayDecoder.ts +7 -7
  11. package/src/decoders/StringNullableDecoder.ts +1 -2
  12. package/src/email-recipient-loaders/members.ts +22 -22
  13. package/src/endpoints/admin/memberships/ChargeMembershipsEndpoint.ts +8 -9
  14. package/src/endpoints/admin/memberships/GetChargeMembershipsSummaryEndpoint.ts +39 -40
  15. package/src/endpoints/admin/organizations/GetOrganizationsCountEndpoint.ts +8 -8
  16. package/src/endpoints/admin/organizations/GetOrganizationsEndpoint.ts +44 -45
  17. package/src/endpoints/admin/organizations/PatchOrganizationsEndpoint.ts +58 -57
  18. package/src/endpoints/auth/CreateAdminEndpoint.ts +48 -45
  19. package/src/endpoints/auth/CreateTokenEndpoint.test.ts +31 -31
  20. package/src/endpoints/auth/CreateTokenEndpoint.ts +146 -147
  21. package/src/endpoints/auth/DeleteTokenEndpoint.ts +7 -7
  22. package/src/endpoints/auth/DeleteUserEndpoint.ts +15 -15
  23. package/src/endpoints/auth/ForgotPasswordEndpoint.ts +17 -18
  24. package/src/endpoints/auth/GetOtherUserEndpoint.ts +9 -10
  25. package/src/endpoints/auth/GetUserEndpoint.test.ts +32 -35
  26. package/src/endpoints/auth/GetUserEndpoint.ts +5 -6
  27. package/src/endpoints/auth/PatchApiUserEndpoint.ts +35 -33
  28. package/src/endpoints/auth/PatchUserEndpoint.ts +55 -52
  29. package/src/endpoints/auth/PollEmailVerificationEndpoint.ts +9 -9
  30. package/src/endpoints/auth/RetryEmailVerificationEndpoint.ts +8 -8
  31. package/src/endpoints/auth/SignupEndpoint.ts +37 -36
  32. package/src/endpoints/auth/VerifyEmailEndpoint.ts +29 -28
  33. package/src/endpoints/global/addresses/SearchRegionsEndpoint.ts +33 -33
  34. package/src/endpoints/global/addresses/ValidateAddressEndpoint.ts +7 -7
  35. package/src/endpoints/global/caddy/CheckDomainCertEndpoint.ts +37 -37
  36. package/src/endpoints/global/email/CreateEmailEndpoint.ts +30 -30
  37. package/src/endpoints/global/email/GetEmailAddressEndpoint.ts +13 -13
  38. package/src/endpoints/global/email/GetEmailEndpoint.ts +13 -13
  39. package/src/endpoints/global/email/ManageEmailAddressEndpoint.ts +16 -16
  40. package/src/endpoints/global/email/PatchEmailEndpoint.ts +25 -25
  41. package/src/endpoints/global/events/GetEventsEndpoint.ts +43 -44
  42. package/src/endpoints/global/events/PatchEventsEndpoint.ts +127 -172
  43. package/src/endpoints/global/files/ExportToExcelEndpoint.ts +49 -50
  44. package/src/endpoints/global/files/GetFileCache.ts +13 -13
  45. package/src/endpoints/global/files/UploadFile.ts +51 -54
  46. package/src/endpoints/global/files/UploadImage.ts +53 -53
  47. package/src/endpoints/global/groups/GetGroupsEndpoint.ts +25 -25
  48. package/src/endpoints/global/members/GetMemberFamilyEndpoint.ts +24 -23
  49. package/src/endpoints/global/members/GetMembersCountEndpoint.ts +8 -8
  50. package/src/endpoints/global/members/GetMembersEndpoint.ts +105 -102
  51. package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.ts +240 -239
  52. package/src/endpoints/global/organizations/CheckRegisterCodeEndpoint.ts +12 -14
  53. package/src/endpoints/global/organizations/CreateOrganizationEndpoint.test.ts +32 -33
  54. package/src/endpoints/global/organizations/CreateOrganizationEndpoint.ts +48 -57
  55. package/src/endpoints/global/organizations/GetOrganizationFromDomainEndpoint.test.ts +21 -22
  56. package/src/endpoints/global/organizations/GetOrganizationFromDomainEndpoint.ts +28 -28
  57. package/src/endpoints/global/organizations/GetOrganizationFromUriEndpoint.ts +18 -18
  58. package/src/endpoints/global/organizations/SearchOrganizationEndpoint.test.ts +20 -20
  59. package/src/endpoints/global/organizations/SearchOrganizationEndpoint.ts +17 -17
  60. package/src/endpoints/global/payments/StripeWebhookEndpoint.ts +81 -75
  61. package/src/endpoints/global/platform/GetPlatformAdminsEndpoint.ts +14 -14
  62. package/src/endpoints/global/platform/GetPlatformEnpoint.ts +11 -11
  63. package/src/endpoints/global/platform/PatchPlatformEnpoint.ts +71 -68
  64. package/src/endpoints/global/registration/GetPaymentRegistrations.ts +27 -27
  65. package/src/endpoints/global/registration/GetUserBillingStatusEndpoint.ts +30 -30
  66. package/src/endpoints/global/registration/GetUserDetailedBillingStatusEndpoint.ts +34 -34
  67. package/src/endpoints/global/registration/GetUserDocumentsEndpoint.ts +26 -26
  68. package/src/endpoints/global/registration/GetUserMembersEndpoint.ts +12 -12
  69. package/src/endpoints/global/registration/PatchUserMembersEndpoint.ts +90 -90
  70. package/src/endpoints/global/registration/RegisterMembersEndpoint.test.ts +118 -121
  71. package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +362 -350
  72. package/src/endpoints/global/registration-periods/GetRegistrationPeriodsEndpoint.ts +8 -9
  73. package/src/endpoints/global/registration-periods/PatchRegistrationPeriodsEndpoint.ts +21 -21
  74. package/src/endpoints/global/webshops/GetWebshopFromDomainEndpoint.ts +65 -65
  75. package/src/endpoints/organization/dashboard/billing/GetOrganizationBillingStatusEndpoint.ts +9 -9
  76. package/src/endpoints/organization/dashboard/billing/GetOrganizationDetailedBillingStatusEndpoint.ts +14 -14
  77. package/src/endpoints/organization/dashboard/documents/GetDocumentTemplateXML.ts +17 -17
  78. package/src/endpoints/organization/dashboard/documents/GetDocumentTemplatesEndpoint.ts +21 -21
  79. package/src/endpoints/organization/dashboard/documents/GetDocumentsEndpoint.ts +15 -15
  80. package/src/endpoints/organization/dashboard/documents/PatchDocumentEndpoint.ts +52 -52
  81. package/src/endpoints/organization/dashboard/documents/PatchDocumentTemplateEndpoint.ts +37 -37
  82. package/src/endpoints/organization/dashboard/email/CheckEmailBouncesEndpoint.ts +14 -14
  83. package/src/endpoints/organization/dashboard/email/EmailEndpoint.ts +113 -112
  84. package/src/endpoints/organization/dashboard/email-templates/GetEmailTemplatesEndpoint.ts +29 -29
  85. package/src/endpoints/organization/dashboard/email-templates/PatchEmailTemplatesEndpoint.ts +48 -47
  86. package/src/endpoints/organization/dashboard/mollie/CheckMollieEndpoint.ts +22 -21
  87. package/src/endpoints/organization/dashboard/mollie/ConnectMollieEndpoint.ts +13 -14
  88. package/src/endpoints/organization/dashboard/mollie/DisconnectMollieEndpoint.ts +12 -13
  89. package/src/endpoints/organization/dashboard/mollie/GetMollieDashboardEndpoint.ts +24 -24
  90. package/src/endpoints/organization/dashboard/nolt/CreateNoltTokenEndpoint.ts +10 -12
  91. package/src/endpoints/organization/dashboard/organization/GetOrganizationArchivedGroups.ts +14 -14
  92. package/src/endpoints/organization/dashboard/organization/GetOrganizationDeletedGroups.ts +13 -13
  93. package/src/endpoints/organization/dashboard/organization/GetOrganizationSSOEndpoint.ts +12 -12
  94. package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.test.ts +120 -124
  95. package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.ts +172 -173
  96. package/src/endpoints/organization/dashboard/organization/SetOrganizationDomainEndpoint.ts +88 -89
  97. package/src/endpoints/organization/dashboard/organization/SetOrganizationSSOEndpoint.ts +12 -12
  98. package/src/endpoints/organization/dashboard/payments/GetMemberBalanceEndpoint.ts +17 -17
  99. package/src/endpoints/organization/dashboard/payments/GetPaymentsCountEndpoint.ts +8 -8
  100. package/src/endpoints/organization/dashboard/payments/GetPaymentsEndpoint.ts +66 -67
  101. package/src/endpoints/organization/dashboard/payments/PatchBalanceItemsEndpoint.ts +47 -47
  102. package/src/endpoints/organization/dashboard/payments/PatchPaymentsEndpoint.ts +93 -91
  103. package/src/endpoints/organization/dashboard/registration-periods/GetOrganizationRegistrationPeriodsEndpoint.ts +16 -17
  104. package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.ts +170 -167
  105. package/src/endpoints/organization/dashboard/registration-periods/SetupStepReviewEndpoint.ts +25 -24
  106. package/src/endpoints/organization/dashboard/stripe/ConnectStripeEndpoint.ts +22 -23
  107. package/src/endpoints/organization/dashboard/stripe/DeleteStripeAccountEndpoint.ts +22 -22
  108. package/src/endpoints/organization/dashboard/stripe/GetStripeAccountLinkEndpoint.ts +17 -18
  109. package/src/endpoints/organization/dashboard/stripe/GetStripeAccountsEndpoint.ts +8 -9
  110. package/src/endpoints/organization/dashboard/stripe/GetStripeLoginLinkEndpoint.ts +17 -18
  111. package/src/endpoints/organization/dashboard/stripe/UpdateStripeAccountEndpoint.ts +14 -15
  112. package/src/endpoints/organization/dashboard/users/CreateApiUserEndpoint.ts +19 -19
  113. package/src/endpoints/organization/dashboard/users/DeleteUserEndpoint.ts +19 -19
  114. package/src/endpoints/organization/dashboard/users/GetApiUsersEndpoint.ts +14 -14
  115. package/src/endpoints/organization/dashboard/users/GetOrganizationAdminsEndpoint.ts +12 -12
  116. package/src/endpoints/organization/dashboard/webshops/CreateWebshopEndpoint.ts +103 -100
  117. package/src/endpoints/organization/dashboard/webshops/DeleteWebshopEndpoint.ts +11 -12
  118. package/src/endpoints/organization/dashboard/webshops/GetDiscountCodesEndpoint.ts +15 -15
  119. package/src/endpoints/organization/dashboard/webshops/GetWebshopOrdersEndpoint.ts +14 -14
  120. package/src/endpoints/organization/dashboard/webshops/GetWebshopTicketsEndpoint.ts +14 -14
  121. package/src/endpoints/organization/dashboard/webshops/GetWebshopUriAvailabilityEndpoint.ts +23 -23
  122. package/src/endpoints/organization/dashboard/webshops/PatchDiscountCodesEndpoint.ts +54 -52
  123. package/src/endpoints/organization/dashboard/webshops/PatchWebshopEndpoint.ts +84 -81
  124. package/src/endpoints/organization/dashboard/webshops/PatchWebshopOrdersEndpoint.ts +120 -111
  125. package/src/endpoints/organization/dashboard/webshops/PatchWebshopTicketsEndpoint.ts +24 -24
  126. package/src/endpoints/organization/dashboard/webshops/VerifyWebshopDomainEndpoint.ts +18 -18
  127. package/src/endpoints/organization/shared/ExchangePaymentEndpoint.ts +141 -130
  128. package/src/endpoints/organization/shared/GetDocumentHtml.ts +25 -25
  129. package/src/endpoints/organization/shared/GetPaymentEndpoint.ts +18 -18
  130. package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.test.ts +36 -37
  131. package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.ts +9 -9
  132. package/src/endpoints/organization/shared/auth/OpenIDConnectCallbackEndpoint.ts +11 -11
  133. package/src/endpoints/organization/shared/auth/OpenIDConnectStartEndpoint.ts +28 -27
  134. package/src/endpoints/organization/webshops/CheckWebshopDiscountCodesEndpoint.ts +20 -20
  135. package/src/endpoints/organization/webshops/GetOrderByPaymentEndpoint.ts +22 -22
  136. package/src/endpoints/organization/webshops/GetOrderEndpoint.ts +14 -14
  137. package/src/endpoints/organization/webshops/GetTicketsEndpoint.ts +57 -56
  138. package/src/endpoints/organization/webshops/GetWebshopEndpoint.test.ts +65 -66
  139. package/src/endpoints/organization/webshops/GetWebshopEndpoint.ts +18 -17
  140. package/src/endpoints/organization/webshops/PlaceOrderEndpoint.test.ts +124 -128
  141. package/src/endpoints/organization/webshops/PlaceOrderEndpoint.ts +154 -145
  142. package/src/excel-loaders/members.ts +102 -103
  143. package/src/excel-loaders/payments.ts +155 -156
  144. package/src/helpers/AddressValidator.test.ts +32 -32
  145. package/src/helpers/AddressValidator.ts +128 -122
  146. package/src/helpers/AdminPermissionChecker.ts +339 -236
  147. package/src/helpers/AuthenticatedStructures.ts +233 -134
  148. package/src/helpers/BuckarooHelper.ts +134 -134
  149. package/src/helpers/CheckSettlements.ts +94 -88
  150. package/src/helpers/Context.ts +87 -86
  151. package/src/helpers/CookieHelper.ts +23 -22
  152. package/src/helpers/EmailResumer.ts +10 -10
  153. package/src/helpers/FileCache.ts +62 -62
  154. package/src/helpers/ForwardHandler.test.ts +122 -124
  155. package/src/helpers/ForwardHandler.ts +76 -70
  156. package/src/helpers/MemberUserSyncer.ts +101 -96
  157. package/src/helpers/MembershipCharger.ts +69 -69
  158. package/src/helpers/MembershipHelper.ts +11 -12
  159. package/src/helpers/OpenIDConnectHelper.ts +85 -82
  160. package/src/helpers/PeriodHelper.ts +65 -70
  161. package/src/helpers/StripeHelper.ts +146 -137
  162. package/src/helpers/StripePayoutChecker.ts +51 -52
  163. package/src/helpers/ViesHelper.ts +46 -44
  164. package/src/helpers/fetchToAsyncIterator.ts +14 -14
  165. package/src/helpers/xlsxAddressTransformerColumnFactory.ts +50 -52
  166. package/src/middleware/ContextMiddleware.ts +5 -5
  167. package/src/migrations/1646578856-validate-addresses.ts +6 -9
  168. package/src/seeds/0000000000-example.ts +3 -5
  169. package/src/seeds/1715028563-user-permissions.ts +16 -18
  170. package/src/seeds/1722256498-group-update-occupancy.ts +12 -12
  171. package/src/seeds/1722344162-sync-member-users.ts +14 -15
  172. package/src/seeds/1722344162-update-membership.ts +6 -6
  173. package/src/seeds/1726055544-balance-item-paid.ts +4 -4
  174. package/src/seeds/1726055545-balance-item-pending.ts +4 -4
  175. package/src/seeds/1726494419-update-cached-outstanding-balance.ts +16 -16
  176. package/src/seeds/1726494420-update-cached-outstanding-balance-from-items.ts +12 -12
  177. package/src/seeds/1726572303-schedule-stock-updates.ts +12 -12
  178. package/src/seeds/1726847064-setup-steps.ts +16 -0
  179. package/src/sql-filters/balance-item-payments.ts +7 -7
  180. package/src/sql-filters/events.ts +14 -14
  181. package/src/sql-filters/members.ts +96 -96
  182. package/src/sql-filters/organizations.ts +139 -75
  183. package/src/sql-filters/payments.ts +28 -28
  184. package/src/sql-filters/registrations.ts +14 -14
  185. package/src/sql-sorters/events.ts +25 -25
  186. package/src/sql-sorters/members.ts +26 -26
  187. package/src/sql-sorters/organizations.ts +36 -36
  188. package/src/sql-sorters/payments.ts +26 -26
  189. package/tests/e2e/stock.test.ts +616 -621
  190. package/tests/e2e/tickets.test.ts +255 -260
  191. package/tests/helpers/StripeMocker.ts +177 -179
  192. package/tests/helpers/TestServer.ts +9 -9
  193. package/tests/jest.global.setup.ts +14 -13
  194. package/tests/jest.setup.ts +33 -32
  195. package/.eslintrc.js +0 -61
  196. package/jest.config.js +0 -11
  197. package/src/helpers/SetupStepsUpdater.ts +0 -359
  198. package/src/seeds/1724076679-setup-steps.ts +0 -16
@@ -1,38 +1,37 @@
1
- import {Order, Payment, StripeCheckoutSession, StripePaymentIntent} from "@stamhoofd/models";
2
- import { Settlement } from "@stamhoofd/structures";
3
- import Stripe from "stripe";
1
+ import { Order, Payment, StripeCheckoutSession, StripePaymentIntent } from '@stamhoofd/models';
2
+ import { Settlement } from '@stamhoofd/structures';
3
+ import Stripe from 'stripe';
4
4
 
5
5
  export class StripePayoutChecker {
6
6
  private stripe: Stripe;
7
7
  private stripePlatform: Stripe;
8
8
 
9
- constructor({secretKey, stripeAccount}: { secretKey: string, stripeAccount?: string}) {
9
+ constructor({ secretKey, stripeAccount }: { secretKey: string; stripeAccount?: string }) {
10
10
  this.stripe = new Stripe(
11
11
  secretKey, {
12
- apiVersion: '2024-06-20',
13
- typescript: true,
14
- maxNetworkRetries: 1,
12
+ apiVersion: '2024-06-20',
13
+ typescript: true,
14
+ maxNetworkRetries: 1,
15
15
  timeout: 10000,
16
- stripeAccount
17
- });
16
+ stripeAccount,
17
+ });
18
18
 
19
19
  this.stripePlatform = new Stripe(
20
20
  secretKey, {
21
- apiVersion: '2024-06-20',
22
- typescript: true,
23
- maxNetworkRetries: 1,
24
- timeout: 10000
25
- });
26
-
21
+ apiVersion: '2024-06-20',
22
+ typescript: true,
23
+ maxNetworkRetries: 1,
24
+ timeout: 10000,
25
+ });
27
26
  }
28
27
 
29
28
  async checkSettlements(checkAll = false) {
30
- // Check last 2 weeks + 3 day margin, unless we check them all
31
- const d = new Date()
32
- d.setDate(d.getDate() - 17)
29
+ // Check last 2 weeks + 3 day margin, unless we check them all
30
+ const d = new Date();
31
+ d.setDate(d.getDate() - 17);
33
32
 
34
33
  if (checkAll) {
35
- d.setFullYear(2022, 11, 1)
34
+ d.setFullYear(2022, 11, 1);
36
35
  }
37
36
 
38
37
  // Loop all payouts
@@ -41,26 +40,26 @@ export class StripePayoutChecker {
41
40
  for await (const payout of this.stripe.payouts.list({
42
41
  status: 'paid',
43
42
  arrival_date: {
44
- gte: Math.floor(d.getTime() / 1000)
45
- }
43
+ gte: Math.floor(d.getTime() / 1000),
44
+ },
46
45
  })) {
47
46
  // Get all payments for this payout
48
47
  await this.fetchBalanceItems(payout);
49
48
  }
50
-
51
- } catch (e) {
52
- console.error(e)
49
+ }
50
+ catch (e) {
51
+ console.error(e);
53
52
  }
54
53
  }
55
54
 
56
55
  private async fetchBalanceItems(payout: Stripe.Payout) {
57
56
  // For the given payout, fetch all balance items
58
57
  const params = {
59
- payout: payout.id,
58
+ payout: payout.id,
60
59
  // Via the Application Fee object, we can get the original payment metadata
61
60
  expand: ['data.source', 'data.source.application_fee', 'data.source.application_fee.originating_transaction'],
62
61
  // TODO: ALSO DO CARDS! (type: 'charge')
63
- //type: 'payment'
62
+ // type: 'payment'
64
63
  };
65
64
 
66
65
  for await (const balanceItem of this.stripe.balanceTransactions.list(params)) {
@@ -79,7 +78,7 @@ export class StripePayoutChecker {
79
78
  return;
80
79
  }
81
80
  if (balanceItem.source.object !== 'charge') {
82
- console.log("No payment id set for charge " + balanceItem.source.id)
81
+ console.log('No payment id set for charge ' + balanceItem.source.id);
83
82
  return;
84
83
  }
85
84
 
@@ -99,67 +98,68 @@ export class StripePayoutChecker {
99
98
  // Try to look it up by payment intent id
100
99
 
101
100
  if (originatingTransaction.payment_intent) {
102
- const paymentIntentId = typeof originatingTransaction.payment_intent === 'string' ? originatingTransaction.payment_intent : originatingTransaction.payment_intent.id
101
+ const paymentIntentId = typeof originatingTransaction.payment_intent === 'string' ? originatingTransaction.payment_intent : originatingTransaction.payment_intent.id;
103
102
  const stripePayments = await StripePaymentIntent.where({
104
- stripeIntentId: paymentIntentId
105
- }, {limit: 1});
103
+ stripeIntentId: paymentIntentId,
104
+ }, { limit: 1 });
106
105
 
107
106
  if (stripePayments.length === 1) {
108
107
  paymentId = stripePayments[0].paymentId;
109
- console.log("Found missing payment metadata for payment intent "+originatingTransaction.payment_intent, paymentId)
110
- } else {
108
+ console.log('Found missing payment metadata for payment intent ', originatingTransaction.payment_intent, paymentId);
109
+ }
110
+ else {
111
111
  // Probably a card payment
112
112
  // Search for the checkout session
113
113
  const checkoutSession = await this.stripePlatform.checkout.sessions.list({
114
- payment_intent: paymentIntentId
115
- })
114
+ payment_intent: paymentIntentId,
115
+ });
116
116
  if (checkoutSession.data.length === 1) {
117
117
  const session = checkoutSession.data[0];
118
- console.log("Found checkout session for payment intent ", paymentIntentId, session)
118
+ console.log('Found checkout session for payment intent ', paymentIntentId, session);
119
119
 
120
120
  // Search
121
121
  const stripeCheckoutSessions = await StripeCheckoutSession.where({
122
- stripeSessionId: session.id
123
- }, {limit: 1});
122
+ stripeSessionId: session.id,
123
+ }, { limit: 1 });
124
124
 
125
125
  if (stripeCheckoutSessions.length === 1) {
126
126
  paymentId = stripeCheckoutSessions[0].paymentId;
127
- console.log("Found missing payment metadata for payment intent "+originatingTransaction.payment_intent, paymentId)
128
- } else {
129
- console.log("No payment found for checkout session "+session.id)
127
+ console.log('Found missing payment metadata for payment intent ', originatingTransaction.payment_intent, paymentId);
128
+ }
129
+ else {
130
+ console.log('No payment found for checkout session ' + session.id);
130
131
  }
131
- } else {
132
- console.log("No Stripe Checkout Sessions found for payment intent "+paymentIntentId)
132
+ }
133
+ else {
134
+ console.log('No Stripe Checkout Sessions found for payment intent ' + paymentIntentId);
133
135
  }
134
136
  }
135
137
  }
136
138
  }
137
139
  }
138
-
139
-
140
140
  }
141
141
  }
142
142
 
143
143
  if (!paymentId) {
144
- console.log(balanceItem)
145
- console.log("No payment id set for charge " + balanceItem.source.id)
144
+ console.log(balanceItem);
145
+ console.log('No payment id set for charge ' + balanceItem.source.id);
146
146
  return;
147
147
  }
148
148
 
149
149
  const applicationFee = balanceItem.source.application_fee_amount;
150
- const otherFees = balanceItem.fee
150
+ const otherFees = balanceItem.fee;
151
151
  const totalFees = otherFees + (applicationFee ?? 0);
152
152
 
153
153
  // Cool, we can store this in the database now.
154
154
 
155
155
  const payment = await Payment.getByID(paymentId);
156
156
  if (!payment) {
157
- console.log("Invalid payment id set for charge " + balanceItem.source.id+': '+paymentId)
157
+ console.log('Invalid payment id set for charge ' + balanceItem.source.id + ': ' + paymentId);
158
158
  return;
159
159
  }
160
160
 
161
161
  if (payment.price !== balanceItem.amount) {
162
- console.log("Amount mismatch for payment " + payment.id+': '+payment.price+' !== '+balanceItem.amount)
162
+ console.log('Amount mismatch for payment ' + payment.id + ': ' + payment.price + ' !== ' + balanceItem.amount);
163
163
  return;
164
164
  }
165
165
 
@@ -169,7 +169,7 @@ export class StripePayoutChecker {
169
169
  settledAt: new Date(payout.arrival_date * 1000),
170
170
  amount: payout.amount,
171
171
  // Set only if application fee is witheld
172
- fee: totalFees
172
+ fee: totalFees,
173
173
  });
174
174
 
175
175
  payment.settlement = settlement;
@@ -177,7 +177,7 @@ export class StripePayoutChecker {
177
177
 
178
178
  // Force an updatedAt timestamp of the related order
179
179
  // Mark order as 'updated', or the frontend won't pull in the updates
180
- const order = await Order.getForPayment(null, payment.id)
180
+ const order = await Order.getForPayment(null, payment.id);
181
181
  if (order) {
182
182
  order.updatedAt = new Date();
183
183
  order.forceSaveProperty('updatedAt');
@@ -186,5 +186,4 @@ export class StripePayoutChecker {
186
186
 
187
187
  await payment.save();
188
188
  }
189
-
190
189
  }
@@ -7,26 +7,25 @@ import * as jsvat from 'jsvat-next'; // has no default export, so we need the wi
7
7
  export class ViesHelperStatic {
8
8
  testMode = false;
9
9
 
10
- async request(method: "GET" | "POST", url: string, content: any) {
10
+ async request(method: 'GET' | 'POST', url: string, content: any) {
11
+ const json = content ? JSON.stringify(content) : '';
11
12
 
12
- const json = content ? JSON.stringify(content) : "";
13
-
14
- console.log("[VIES REQUEST]", method, url, content ? "\n [VIES REQUEST] " : undefined, json)
13
+ console.log('[VIES REQUEST]', method, url, content ? '\n [VIES REQUEST] ' : undefined, json);
15
14
 
16
15
  const response = await axios.request({
17
16
  method,
18
17
  url,
19
18
  headers: {
20
- 'Content-Type': json.length > 0 ? 'application/json' : "text/plain",
19
+ 'Content-Type': json.length > 0 ? 'application/json' : 'text/plain',
21
20
  },
22
- data: json
23
-
24
- })
25
- console.log("[VIES RESPONSE]", method, url, "\n[VIES RESPONSE]", JSON.stringify(response.data))
26
- return response.data
21
+ data: json,
22
+
23
+ });
24
+ console.log('[VIES RESPONSE]', method, url, '\n[VIES RESPONSE]', JSON.stringify(response.data));
25
+ return response.data;
27
26
  }
28
27
 
29
- async checkCompany(company: Company, patch: AutoEncoderPatchType<Company>|Company) {
28
+ async checkCompany(company: Company, patch: AutoEncoderPatchType<Company> | Company) {
30
29
  if (!company.address) {
31
30
  // Not allowed to set
32
31
  patch.companyNumber = null;
@@ -36,32 +35,33 @@ export class ViesHelperStatic {
36
35
 
37
36
  if (company.VATNumber !== null) {
38
37
  // Changed VAT number
39
- patch.VATNumber = await ViesHelper.checkVATNumber(company.address.country, company.VATNumber)
38
+ patch.VATNumber = await ViesHelper.checkVATNumber(company.address.country, company.VATNumber);
40
39
 
41
40
  if (company.address.country === Country.Belgium) {
42
- patch.companyNumber = company.VATNumber
41
+ patch.companyNumber = company.VATNumber;
43
42
  }
44
43
  }
45
44
 
46
45
  if (company.companyNumber) {
47
46
  if (company.VATNumber !== null && company.address.country === Country.Belgium) {
48
47
  // Already validated
49
- } else {
48
+ }
49
+ else {
50
50
  // Need to validate
51
- const result = await ViesHelper.checkCompanyNumber(company.address.country, company.companyNumber)
52
- patch.companyNumber = result.companyNumber
51
+ const result = await ViesHelper.checkCompanyNumber(company.address.country, company.companyNumber);
52
+ patch.companyNumber = result.companyNumber;
53
53
  if (result.VATNumber !== undefined) {
54
- patch.VATNumber = result.VATNumber
54
+ patch.VATNumber = result.VATNumber;
55
55
  }
56
56
  }
57
57
  }
58
58
  }
59
59
 
60
- async checkCompanyNumber(country: Country, companyNumber: string): Promise<{companyNumber: string|null, VATNumber?: string|null}> {
60
+ async checkCompanyNumber(country: Country, companyNumber: string): Promise<{ companyNumber: string | null; VATNumber?: string | null }> {
61
61
  if (country !== Country.Belgium) {
62
62
  // Not supported
63
63
  return {
64
- companyNumber
64
+ companyNumber,
65
65
  };
66
66
  }
67
67
 
@@ -71,10 +71,10 @@ export class ViesHelperStatic {
71
71
 
72
72
  if (!result.isValid) {
73
73
  throw new SimpleError({
74
- "code": "invalid_field",
75
- "message": "Ongeldig ondernemingsnummer: " + companyNumber,
76
- "field": "companyNumber"
77
- })
74
+ code: 'invalid_field',
75
+ message: 'Ongeldig ondernemingsnummer: ' + companyNumber,
76
+ field: 'companyNumber',
77
+ });
78
78
  }
79
79
 
80
80
  // If this is a valid VAT number, we can assume it's a valid company number
@@ -84,12 +84,14 @@ export class ViesHelperStatic {
84
84
  // this is a VAT number, not a company number
85
85
  return {
86
86
  companyNumber: corrected,
87
- VATNumber: corrected
88
- }
89
- } catch (e) {
87
+ VATNumber: corrected,
88
+ };
89
+ }
90
+ catch (e) {
90
91
  if (isSimpleError(e) || isSimpleErrors(e)) {
91
92
  // Ignore: normal that it is not a valid VAT number
92
- } else {
93
+ }
94
+ else {
93
95
  // Other errors should be thrown
94
96
  throw e;
95
97
  }
@@ -99,7 +101,7 @@ export class ViesHelperStatic {
99
101
  companyNumber: result.value ?? companyNumber,
100
102
 
101
103
  // VATNumber should always be set to null if it is not a valid VAT number
102
- VATNumber: null
104
+ VATNumber: null,
103
105
  };
104
106
  }
105
107
 
@@ -108,34 +110,35 @@ export class ViesHelperStatic {
108
110
 
109
111
  if (!result.isValid) {
110
112
  throw new SimpleError({
111
- "code": "invalid_field",
112
- "message": "Ongeldig BTW-nummer: " + vatNumber,
113
- "field": "VATNumber"
114
- })
115
- }
113
+ code: 'invalid_field',
114
+ message: 'Ongeldig BTW-nummer: ' + vatNumber,
115
+ field: 'VATNumber',
116
+ });
117
+ }
116
118
 
117
119
  const formatted = result.value ?? vatNumber;
118
120
 
119
121
  try {
120
- const cleaned = formatted.substring(2).replace(/(\.\-\s)+/g, "")
121
- const response = await this.request("POST", "https://ec.europa.eu/taxation_customs/vies/rest-api/check-vat-number", {
122
+ const cleaned = formatted.substring(2).replace(/(\.-\s)+/g, '');
123
+ const response = await this.request('POST', 'https://ec.europa.eu/taxation_customs/vies/rest-api/check-vat-number', {
122
124
  countryCode: country,
123
- vatNumber: cleaned
125
+ vatNumber: cleaned,
124
126
  });
125
127
 
126
128
  if (typeof response !== 'object' || response === null || typeof response.valid !== 'boolean') {
127
129
  // APi error
128
- throw new Error("Invalid response from VIES")
130
+ throw new Error('Invalid response from VIES');
129
131
  }
130
-
132
+
131
133
  if (!response.valid) {
132
134
  throw new SimpleError({
133
- "code": "invalid_field",
134
- "message": "Het opgegeven BTW-nummer is ongeldig of niet BTW-plichtig: " + formatted,
135
- "field": "VATNumber"
136
- })
135
+ code: 'invalid_field',
136
+ message: 'Het opgegeven BTW-nummer is ongeldig of niet BTW-plichtig: ' + formatted,
137
+ field: 'VATNumber',
138
+ });
137
139
  }
138
- } catch (e) {
140
+ }
141
+ catch (e) {
139
142
  if (isSimpleError(e) || isSimpleErrors(e)) {
140
143
  throw e;
141
144
  }
@@ -145,7 +148,6 @@ export class ViesHelperStatic {
145
148
 
146
149
  return formatted;
147
150
  }
148
-
149
151
  }
150
152
 
151
153
  export const ViesHelper = new ViesHelperStatic();
@@ -1,33 +1,33 @@
1
- import { IPaginatedResponse, LimitedFilteredRequest } from "@stamhoofd/structures";
1
+ import { IPaginatedResponse, LimitedFilteredRequest } from '@stamhoofd/structures';
2
2
 
3
3
  export function fetchToAsyncIterator<T>(
4
- initialFilter: LimitedFilteredRequest,
4
+ initialFilter: LimitedFilteredRequest,
5
5
  loader: {
6
- fetch(request: LimitedFilteredRequest): Promise<IPaginatedResponse<T, LimitedFilteredRequest>>
7
- }
6
+ fetch(request: LimitedFilteredRequest): Promise<IPaginatedResponse<T, LimitedFilteredRequest>>;
7
+ },
8
8
  ): AsyncIterable<T> {
9
9
  return {
10
10
  [Symbol.asyncIterator]: function () {
11
- let request: LimitedFilteredRequest|null = initialFilter
11
+ let request: LimitedFilteredRequest | null = initialFilter;
12
12
 
13
13
  return {
14
14
  async next(): Promise<IteratorResult<T, undefined>> {
15
15
  if (!request) {
16
16
  return {
17
17
  done: true,
18
- value: undefined
19
- }
18
+ value: undefined,
19
+ };
20
20
  }
21
21
 
22
22
  const response = await loader.fetch(request);
23
23
  request = response.next ?? null;
24
-
24
+
25
25
  return {
26
26
  done: false,
27
- value: response.results
28
- }
29
- }
30
- }
31
- }
32
- }
27
+ value: response.results,
28
+ };
29
+ },
30
+ };
31
+ },
32
+ };
33
33
  }
@@ -1,14 +1,14 @@
1
- import { XlsxTransformerColumn } from "@stamhoofd/excel-writer";
2
- import { Address, CountryHelper, MemberWithRegistrationsBlob, Parent, ParentTypeHelper } from "@stamhoofd/structures";
1
+ import { XlsxTransformerColumn } from '@stamhoofd/excel-writer';
2
+ import { Address, CountryHelper, MemberWithRegistrationsBlob, Parent, ParentTypeHelper } from '@stamhoofd/structures';
3
3
 
4
4
  export class XlsxTransformerColumnHelper {
5
5
  static formatBoolean(value: boolean | undefined | null): string {
6
- if(value === true) {
7
- return "Ja";
6
+ if (value === true) {
7
+ return 'Ja';
8
8
  }
9
9
 
10
- if(value === false) {
11
- return 'Nee'
10
+ if (value === false) {
11
+ return 'Nee';
12
12
  }
13
13
 
14
14
  return '';
@@ -18,13 +18,13 @@ export class XlsxTransformerColumnHelper {
18
18
  return [
19
19
  ...this.createColumnsForParent(0),
20
20
  ...this.createColumnsForParent(1),
21
- ]
21
+ ];
22
22
  }
23
23
 
24
- static createColumnsForAddresses<T>({limit, getAddresses, matchIdStart, identifier}: {limit: number, getAddresses: (object: T) => Address[], matchIdStart: string, identifier: string}): XlsxTransformerColumn<unknown>[] {
24
+ static createColumnsForAddresses<T>({ limit, getAddresses, matchIdStart, identifier }: { limit: number; getAddresses: (object: T) => Address[]; matchIdStart: string; identifier: string }): XlsxTransformerColumn<unknown>[] {
25
25
  const result: XlsxTransformerColumn<unknown>[] = [];
26
26
 
27
- for(let i = 0; i <= limit; i++) {
27
+ for (let i = 0; i <= limit; i++) {
28
28
  const column = this.createAddressColumns({
29
29
  matchId: `${matchIdStart}.${i}`,
30
30
  getAddress: (object: T) => getAddresses(object)[i],
@@ -38,13 +38,13 @@ export class XlsxTransformerColumnHelper {
38
38
  }
39
39
 
40
40
  static createColumnsForParent(parentIndex: number): XlsxTransformerColumn<unknown>[] {
41
- const getParent = (member: MemberWithRegistrationsBlob): Parent | null | undefined => member.details.parents[parentIndex];
41
+ const getParent = (member: MemberWithRegistrationsBlob): Parent | null | undefined => member.details.parents[parentIndex];
42
42
 
43
43
  const parentNumber = parentIndex + 1;
44
44
 
45
- const identifier = `Ouder ${parentNumber}`
45
+ const identifier = `Ouder ${parentNumber}`;
46
46
  const getId = (value: string) => `parent.${parentIndex}.${value}`;
47
- const getName = (value: string) => `${identifier} - ${value}`
47
+ const getName = (value: string) => `${identifier} - ${value}`;
48
48
 
49
49
  return [
50
50
  {
@@ -55,61 +55,61 @@ export class XlsxTransformerColumnHelper {
55
55
  const parent = getParent(member);
56
56
 
57
57
  return {
58
- value: parent ? ParentTypeHelper.getName(parent.type) : ''
59
- }
60
- }
58
+ value: parent ? ParentTypeHelper.getName(parent.type) : '',
59
+ };
60
+ },
61
61
  },
62
62
  {
63
63
  id: getId('firstName'),
64
64
  name: getName('Voornaam'),
65
65
  width: 20,
66
66
  getValue: (member: MemberWithRegistrationsBlob) => ({
67
- value: getParent(member)?.firstName ?? ''
68
- })
67
+ value: getParent(member)?.firstName ?? '',
68
+ }),
69
69
  },
70
70
  {
71
71
  id: getId('lastName'),
72
72
  name: getName('Achternaam'),
73
73
  width: 20,
74
74
  getValue: (member: MemberWithRegistrationsBlob) => ({
75
- value: getParent(member)?.lastName ?? ''
76
- })
75
+ value: getParent(member)?.lastName ?? '',
76
+ }),
77
77
  },
78
78
  {
79
79
  id: getId('phone'),
80
80
  name: getName('Telefoonnummer'),
81
81
  width: 20,
82
82
  getValue: (member: MemberWithRegistrationsBlob) => ({
83
- value: getParent(member)?.phone ?? ''
84
- })
83
+ value: getParent(member)?.phone ?? '',
84
+ }),
85
85
  },
86
86
  {
87
87
  id: getId('email'),
88
88
  name: getName('E-mailadres'),
89
89
  width: 20,
90
90
  getValue: (member: MemberWithRegistrationsBlob) => ({
91
- value: getParent(member)?.email ?? ''
92
- })
91
+ value: getParent(member)?.email ?? '',
92
+ }),
93
93
  },
94
94
  XlsxTransformerColumnHelper.createAddressColumns<MemberWithRegistrationsBlob>({
95
95
  matchId: getId('address'),
96
- getAddress: (member) => getParent(member)?.address,
97
- identifier: getName('Adres')
96
+ getAddress: member => getParent(member)?.address,
97
+ identifier: getName('Adres'),
98
98
  }),
99
- ]
99
+ ];
100
100
  }
101
101
 
102
- static createAddressColumns<T>({matchId, identifier, getAddress} : {matchId: string, identifier?: string, getAddress: (object: T) => Address | null | undefined}): XlsxTransformerColumn<T> {
102
+ static createAddressColumns<T>({ matchId, identifier, getAddress }: { matchId: string; identifier?: string; getAddress: (object: T) => Address | null | undefined }): XlsxTransformerColumn<T> {
103
103
  const getId = (value: string) => matchId + '.' + value;
104
104
  const identifierText = identifier ? `${identifier} - ` : '';
105
105
  const getName = (value: string) => {
106
- const name =`${identifierText}${value}`;
106
+ const name = `${identifierText}${value}`;
107
107
  return name[0].toUpperCase() + name.slice(1);
108
108
  };
109
-
109
+
110
110
  return {
111
111
  match: (id) => {
112
- if(id === matchId) {
112
+ if (id === matchId) {
113
113
  return [
114
114
  {
115
115
  id: getId('street'),
@@ -118,9 +118,9 @@ export class XlsxTransformerColumnHelper {
118
118
  getValue: (object: T) => {
119
119
  const address = getAddress(object);
120
120
  return {
121
- value: address?.street || ''
122
- }
123
- }
121
+ value: address?.street || '',
122
+ };
123
+ },
124
124
  },
125
125
  {
126
126
  id: getId('number'),
@@ -129,9 +129,9 @@ export class XlsxTransformerColumnHelper {
129
129
  getValue: (object: T) => {
130
130
  const address = getAddress(object);
131
131
  return {
132
- value: address?.number || ''
133
- }
134
- }
132
+ value: address?.number || '',
133
+ };
134
+ },
135
135
  },
136
136
  {
137
137
  id: getId('postalCode'),
@@ -140,9 +140,9 @@ export class XlsxTransformerColumnHelper {
140
140
  getValue: (object: T) => {
141
141
  const address = getAddress(object);
142
142
  return {
143
- value: address?.postalCode || ''
144
- }
145
- }
143
+ value: address?.postalCode || '',
144
+ };
145
+ },
146
146
  },
147
147
  {
148
148
  id: getId('city'),
@@ -151,9 +151,9 @@ export class XlsxTransformerColumnHelper {
151
151
  getValue: (object: T) => {
152
152
  const address = getAddress(object);
153
153
  return {
154
- value: address?.city || ''
155
- }
156
- }
154
+ value: address?.city || '',
155
+ };
156
+ },
157
157
  },
158
158
  {
159
159
  id: getId('country'),
@@ -163,15 +163,13 @@ export class XlsxTransformerColumnHelper {
163
163
  const address = getAddress(object);
164
164
  const country = address?.country;
165
165
  return {
166
- value: country ? CountryHelper.getName(country) : ''
167
- }
168
- }
169
- }
170
- ]
166
+ value: country ? CountryHelper.getName(country) : '',
167
+ };
168
+ },
169
+ },
170
+ ];
171
171
  }
172
-
173
- }
174
- }
175
-
176
- }
172
+ },
173
+ };
174
+ }
177
175
  }