@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,9 +1,8 @@
1
- /* eslint-disable @typescript-eslint/no-unsafe-argument */
2
1
  import { Decoder } from '@simonbackx/simple-encoding';
3
2
  import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
4
3
  import { SimpleError } from '@simonbackx/simple-errors';
5
4
  import { Payment } from '@stamhoofd/models';
6
- import { SQL, compileToSQLFilter, compileToSQLSorter } from "@stamhoofd/sql";
5
+ import { SQL, compileToSQLFilter, compileToSQLSorter } from '@stamhoofd/sql';
7
6
  import { CountFilteredRequest, LimitedFilteredRequest, PaginatedResponse, PaymentGeneral, StamhoofdFilter, assertSort, getSortFilter } from '@stamhoofd/structures';
8
7
 
9
8
  import { AuthenticatedStructures } from '../../../../helpers/AuthenticatedStructures';
@@ -14,20 +13,20 @@ import { paymentSorters } from '../../../../sql-sorters/payments';
14
13
  type Params = Record<string, never>;
15
14
  type Query = LimitedFilteredRequest;
16
15
  type Body = undefined;
17
- type ResponseBody = PaginatedResponse<PaymentGeneral[], LimitedFilteredRequest>
16
+ type ResponseBody = PaginatedResponse<PaymentGeneral[], LimitedFilteredRequest>;
18
17
 
19
- const filterCompilers = paymentFilterCompilers
20
- const sorters = paymentSorters
18
+ const filterCompilers = paymentFilterCompilers;
19
+ const sorters = paymentSorters;
21
20
 
22
21
  export class GetPaymentsEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
23
- queryDecoder = LimitedFilteredRequest as Decoder<LimitedFilteredRequest>
22
+ queryDecoder = LimitedFilteredRequest as Decoder<LimitedFilteredRequest>;
24
23
 
25
24
  protected doesMatch(request: Request): [true, Params] | [false] {
26
- if (request.method != "GET") {
25
+ if (request.method !== 'GET') {
27
26
  return [false];
28
27
  }
29
28
 
30
- const params = Endpoint.parseParameters(request.url, "/payments", {});
29
+ const params = Endpoint.parseParameters(request.url, '/payments', {});
31
30
 
32
31
  if (params) {
33
32
  return [true, params as Params];
@@ -35,71 +34,71 @@ export class GetPaymentsEndpoint extends Endpoint<Params, Query, Body, ResponseB
35
34
  return [false];
36
35
  }
37
36
 
38
- static async buildQuery(q: CountFilteredRequest|LimitedFilteredRequest) {
39
- const organization = Context.organization
40
- let scopeFilter: StamhoofdFilter|undefined = undefined;
37
+ static async buildQuery(q: CountFilteredRequest | LimitedFilteredRequest) {
38
+ const organization = Context.organization;
39
+ let scopeFilter: StamhoofdFilter | undefined = undefined;
41
40
 
42
41
  if (!organization) {
43
- throw Context.auth.error()
42
+ throw Context.auth.error();
44
43
  }
45
44
 
46
45
  if (!await Context.auth.canManagePayments(organization.id)) {
47
- throw Context.auth.error()
46
+ throw Context.auth.error();
48
47
  }
49
48
 
50
49
  scopeFilter = {
51
- organizationId: organization.id
50
+ organizationId: organization.id,
52
51
  };
53
-
52
+
54
53
  const query = SQL
55
54
  .select()
56
55
  .from(
57
- SQL.table('payments')
56
+ SQL.table('payments'),
58
57
  );
59
-
58
+
60
59
  if (scopeFilter) {
61
- query.where(compileToSQLFilter(scopeFilter, filterCompilers))
60
+ query.where(compileToSQLFilter(scopeFilter, filterCompilers));
62
61
  }
63
62
 
64
63
  if (q.filter) {
65
- query.where(compileToSQLFilter(q.filter, filterCompilers))
64
+ query.where(compileToSQLFilter(q.filter, filterCompilers));
66
65
  }
67
66
 
68
67
  if (q.search) {
69
68
  // todo
70
69
 
71
- let searchFilter: StamhoofdFilter|null = null
70
+ let searchFilter: StamhoofdFilter | null = null;
72
71
  searchFilter = {
73
72
  $or: [
74
73
  {
75
74
  customer: {
76
75
  name: {
77
- $contains: q.search
78
- }
79
- }
76
+ $contains: q.search,
77
+ },
78
+ },
80
79
  },
81
80
  {
82
81
  customer: {
83
82
  company: {
84
83
  name: {
85
- $contains: q.search
86
- }
87
- }
88
- }
84
+ $contains: q.search,
85
+ },
86
+ },
87
+ },
89
88
  },
90
89
  {
91
90
  balanceItemPayments: {
92
91
  $elemMatch: {
93
92
  balanceItem: {
94
93
  description: {
95
- $contains: q.search
96
- }
97
- }
98
- }
99
- }
100
- }
101
- ]
102
- }
94
+ $contains: q.search,
95
+ },
96
+ },
97
+ },
98
+ },
99
+ },
100
+ ],
101
+ };
103
102
 
104
103
  if (q.search.includes('@')) {
105
104
  searchFilter = {
@@ -107,48 +106,48 @@ export class GetPaymentsEndpoint extends Endpoint<Params, Query, Body, ResponseB
107
106
  {
108
107
  customer: {
109
108
  email: {
110
- $contains: q.search
111
- }
112
- }
109
+ $contains: q.search,
110
+ },
111
+ },
113
112
  },
114
113
  {
115
114
  customer: {
116
115
  company: {
117
116
  administrationEmail: {
118
- $contains: q.search
119
- }
120
- }
121
- }
117
+ $contains: q.search,
118
+ },
119
+ },
120
+ },
122
121
  },
123
- ]
124
- }
125
- }
122
+ ],
123
+ };
124
+ }
126
125
 
127
126
  if (searchFilter) {
128
- query.where(compileToSQLFilter(searchFilter, filterCompilers))
127
+ query.where(compileToSQLFilter(searchFilter, filterCompilers));
129
128
  }
130
129
  }
131
130
 
132
131
  if (q instanceof LimitedFilteredRequest) {
133
132
  if (q.pageFilter) {
134
- query.where(compileToSQLFilter(q.pageFilter, filterCompilers))
133
+ query.where(compileToSQLFilter(q.pageFilter, filterCompilers));
135
134
  }
136
135
 
137
- q.sort = assertSort(q.sort, [{key: 'id'}])
138
- query.orderBy(compileToSQLSorter(q.sort, sorters))
139
- query.limit(q.limit)
136
+ q.sort = assertSort(q.sort, [{ key: 'id' }]);
137
+ query.orderBy(compileToSQLSorter(q.sort, sorters));
138
+ query.limit(q.limit);
140
139
  }
141
-
142
- return query
140
+
141
+ return query;
143
142
  }
144
143
 
145
144
  static async buildData(requestQuery: LimitedFilteredRequest) {
146
- const query = await this.buildQuery(requestQuery)
147
- const data = await query.fetch()
148
-
149
- const payments = Payment.fromRows(data, 'payments')
145
+ const query = await this.buildQuery(requestQuery);
146
+ const data = await query.fetch();
150
147
 
151
- let next: LimitedFilteredRequest|undefined;
148
+ const payments = Payment.fromRows(data, 'payments');
149
+
150
+ let next: LimitedFilteredRequest | undefined;
152
151
 
153
152
  if (payments.length >= requestQuery.limit) {
154
153
  const lastObject = payments[payments.length - 1];
@@ -159,8 +158,8 @@ export class GetPaymentsEndpoint extends Endpoint<Params, Query, Body, ResponseB
159
158
  pageFilter: nextFilter,
160
159
  sort: requestQuery.sort,
161
160
  limit: requestQuery.limit,
162
- search: requestQuery.search
163
- })
161
+ search: requestQuery.search,
162
+ });
164
163
 
165
164
  if (JSON.stringify(nextFilter) === JSON.stringify(requestQuery.pageFilter)) {
166
165
  console.error('Found infinite loading loop for', requestQuery);
@@ -170,13 +169,13 @@ export class GetPaymentsEndpoint extends Endpoint<Params, Query, Body, ResponseB
170
169
 
171
170
  return new PaginatedResponse<PaymentGeneral[], LimitedFilteredRequest>({
172
171
  results: await AuthenticatedStructures.paymentsGeneral(payments, true),
173
- next
172
+ next,
174
173
  });
175
174
  }
176
175
 
177
176
  async handle(request: DecodedRequest<Params, Query, Body>) {
178
177
  await Context.setOrganizationScope();
179
- await Context.authenticate()
178
+ await Context.authenticate();
180
179
 
181
180
  const maxLimit = Context.auth.hasSomePlatformAccess() ? 1000 : 100;
182
181
 
@@ -184,20 +183,20 @@ export class GetPaymentsEndpoint extends Endpoint<Params, Query, Body, ResponseB
184
183
  throw new SimpleError({
185
184
  code: 'invalid_field',
186
185
  field: 'limit',
187
- message: 'Limit can not be more than ' + maxLimit
188
- })
186
+ message: 'Limit can not be more than ' + maxLimit,
187
+ });
189
188
  }
190
189
 
191
190
  if (request.query.limit < 1) {
192
191
  throw new SimpleError({
193
192
  code: 'invalid_field',
194
193
  field: 'limit',
195
- message: 'Limit can not be less than 1'
196
- })
194
+ message: 'Limit can not be less than 1',
195
+ });
197
196
  }
198
-
197
+
199
198
  return new Response(
200
- await GetPaymentsEndpoint.buildData(request.query)
199
+ await GetPaymentsEndpoint.buildData(request.query),
201
200
  );
202
201
  }
203
202
  }
@@ -1,27 +1,26 @@
1
1
  import { AutoEncoderPatchType, Decoder, PatchableArrayAutoEncoder, PatchableArrayDecoder, StringDecoder } from '@simonbackx/simple-encoding';
2
- import { DecodedRequest, Endpoint, Request, Response } from "@simonbackx/simple-endpoints";
3
- import { SimpleError } from "@simonbackx/simple-errors";
2
+ import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
3
+ import { SimpleError } from '@simonbackx/simple-errors';
4
4
  import { BalanceItem, Member, Order, User } from '@stamhoofd/models';
5
5
  import { QueueHandler } from '@stamhoofd/queues';
6
- import { BalanceItemStatus, BalanceItemType, BalanceItemWithPayments, PermissionLevel } from "@stamhoofd/structures";
6
+ import { BalanceItemStatus, BalanceItemType, BalanceItemWithPayments, PermissionLevel } from '@stamhoofd/structures';
7
7
 
8
8
  import { Context } from '../../../../helpers/Context';
9
9
 
10
-
11
10
  type Params = Record<string, never>;
12
11
  type Query = undefined;
13
- type Body = PatchableArrayAutoEncoder<BalanceItemWithPayments>
14
- type ResponseBody = BalanceItemWithPayments[]
12
+ type Body = PatchableArrayAutoEncoder<BalanceItemWithPayments>;
13
+ type ResponseBody = BalanceItemWithPayments[];
15
14
 
16
15
  export class PatchBalanceItemsEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
17
- bodyDecoder = new PatchableArrayDecoder(BalanceItemWithPayments as Decoder<BalanceItemWithPayments>, BalanceItemWithPayments.patchType() as Decoder<AutoEncoderPatchType<BalanceItemWithPayments>>, StringDecoder)
16
+ bodyDecoder = new PatchableArrayDecoder(BalanceItemWithPayments as Decoder<BalanceItemWithPayments>, BalanceItemWithPayments.patchType() as Decoder<AutoEncoderPatchType<BalanceItemWithPayments>>, StringDecoder);
18
17
 
19
18
  protected doesMatch(request: Request): [true, Params] | [false] {
20
- if (request.method != "PATCH") {
19
+ if (request.method !== 'PATCH') {
21
20
  return [false];
22
21
  }
23
22
 
24
- const params = Endpoint.parseParameters(request.url, "/organization/balance", {});
23
+ const params = Endpoint.parseParameters(request.url, '/organization/balance', {});
25
24
 
26
25
  if (params) {
27
26
  return [true, params as Params];
@@ -31,30 +30,30 @@ export class PatchBalanceItemsEndpoint extends Endpoint<Params, Query, Body, Res
31
30
 
32
31
  async handle(request: DecodedRequest<Params, Query, Body>) {
33
32
  const organization = await Context.setOrganizationScope();
34
- await Context.authenticate()
33
+ await Context.authenticate();
35
34
 
36
35
  if (!await Context.auth.hasSomeAccess(organization.id)) {
37
- throw Context.auth.error()
36
+ throw Context.auth.error();
38
37
  }
39
38
 
40
39
  if (request.body.changes.length == 0) {
41
40
  return new Response([]);
42
41
  }
43
42
 
44
- const returnedModels: BalanceItem[] = []
45
- const updateOutstandingBalance: BalanceItem[] = []
43
+ const returnedModels: BalanceItem[] = [];
44
+ const updateOutstandingBalance: BalanceItem[] = [];
46
45
 
47
46
  // Keep track of updates
48
- const memberIds: string[] = []
49
- const registrationIds: string[] = []
47
+ const memberIds: string[] = [];
48
+ const registrationIds: string[] = [];
50
49
 
51
- await QueueHandler.schedule("balance-item-update/"+organization.id, async () => {
52
- for (const {put} of request.body.getPuts()) {
50
+ await QueueHandler.schedule('balance-item-update/' + organization.id, async () => {
51
+ for (const { put } of request.body.getPuts()) {
53
52
  // Create a new balance item
54
53
  const model = new BalanceItem();
55
54
  model.description = put.description;
56
55
  model.amount = put.amount;
57
- model.type = BalanceItemType.Other
56
+ model.type = BalanceItemType.Other;
58
57
  model.unitPrice = put.unitPrice;
59
58
  model.amount = put.amount;
60
59
  model.organizationId = organization.id;
@@ -67,61 +66,61 @@ export class PatchBalanceItemsEndpoint extends Endpoint<Params, Query, Body, Res
67
66
 
68
67
  if (put.memberId) {
69
68
  model.memberId = (await this.validateMemberId(put.memberId)).id;
70
- memberIds.push(model.memberId)
69
+ memberIds.push(model.memberId);
71
70
  }
72
71
 
73
72
  if (!model.userId && !model.memberId) {
74
73
  throw new SimpleError({
75
74
  code: 'invalid_field',
76
75
  message: 'No user or member provided',
77
- field: 'userId'
78
- })
76
+ field: 'userId',
77
+ });
79
78
  }
80
79
 
81
80
  await model.save();
82
81
  returnedModels.push(model);
83
82
 
84
- updateOutstandingBalance.push(model)
83
+ updateOutstandingBalance.push(model);
85
84
  }
86
85
 
87
86
  for (const patch of request.body.getPatches()) {
88
87
  // Create a new balance item
89
- const model = await BalanceItem.getByID(patch.id)
88
+ const model = await BalanceItem.getByID(patch.id);
90
89
  if (!model || !(await Context.auth.canAccessBalanceItems([model], PermissionLevel.Write))) {
91
90
  throw new SimpleError({
92
91
  code: 'invalid_field',
93
- message: 'BalanceItem not found'
94
- })
92
+ message: 'BalanceItem not found',
93
+ });
95
94
  }
96
95
 
97
96
  if (patch.unitPrice !== undefined) {
98
97
  throw new SimpleError({
99
98
  code: 'invalid_field',
100
99
  message: 'You cannot change the unit price of a balance item',
101
- human: 'Het is niet mogelijk om de eenheidsprijs van een openstaande schuld te wijzigen. Je kan de openstaande schuld verwijderen en opnieuw aanmaken indien noodzakelijk.'
102
- })
100
+ human: 'Het is niet mogelijk om de eenheidsprijs van een openstaande schuld te wijzigen. Je kan de openstaande schuld verwijderen en opnieuw aanmaken indien noodzakelijk.',
101
+ });
103
102
  }
104
103
 
105
104
  // Check permissions
106
105
  if (model.memberId) {
107
106
  // Update old
108
- memberIds.push(model.memberId)
107
+ memberIds.push(model.memberId);
109
108
  }
110
109
 
111
110
  if (patch.memberId) {
112
111
  model.memberId = (await this.validateMemberId(patch.memberId)).id;
113
112
 
114
113
  // Update new
115
- memberIds.push(model.memberId)
114
+ memberIds.push(model.memberId);
116
115
  }
117
116
 
118
117
  if (model.registrationId) {
119
118
  // Update old
120
- registrationIds.push(model.registrationId)
119
+ registrationIds.push(model.registrationId);
121
120
  }
122
-
121
+
123
122
  if (patch.createdAt) {
124
- model.createdAt = patch.createdAt
123
+ model.createdAt = patch.createdAt;
125
124
  }
126
125
 
127
126
  model.description = patch.description ?? model.description;
@@ -130,47 +129,48 @@ export class PatchBalanceItemsEndpoint extends Endpoint<Params, Query, Body, Res
130
129
 
131
130
  if (model.orderId) {
132
131
  // Not allowed to change this
133
- const order = await Order.getByID(model.orderId)
132
+ const order = await Order.getByID(model.orderId);
134
133
  if (order) {
135
- model.unitPrice = order.totalToPay
136
- model.amount = 1
134
+ model.unitPrice = order.totalToPay;
135
+ model.amount = 1;
137
136
  }
138
137
  }
139
138
 
140
139
  if (patch.status && patch.status === BalanceItemStatus.Hidden) {
141
140
  if (model.pricePaid === 0) {
142
- model.status = BalanceItemStatus.Hidden
141
+ model.status = BalanceItemStatus.Hidden;
143
142
  }
144
- } else if (patch.status) {
143
+ }
144
+ else if (patch.status) {
145
145
  model.status = model.pricePaid >= model.price ? BalanceItemStatus.Paid : BalanceItemStatus.Pending;
146
146
  }
147
147
 
148
148
  await model.save();
149
149
  returnedModels.push(model);
150
-
150
+
151
151
  if (patch.unitPrice || patch.amount || patch.status) {
152
- updateOutstandingBalance.push(model)
152
+ updateOutstandingBalance.push(model);
153
153
  }
154
154
  }
155
155
  });
156
156
 
157
- await BalanceItem.updateOutstanding(updateOutstandingBalance)
157
+ await BalanceItem.updateOutstanding(updateOutstandingBalance);
158
158
 
159
- return new Response(
160
- await BalanceItem.getStructureWithPayments(returnedModels)
159
+ return new Response(
160
+ await BalanceItem.getStructureWithPayments(returnedModels),
161
161
  );
162
162
  }
163
163
 
164
164
  async validateMemberId(memberId: string) {
165
- const member = (await Member.getWithRegistrations(memberId))
165
+ const member = (await Member.getWithRegistrations(memberId));
166
166
 
167
167
  if (!member || !(await Context.auth.canLinkBalanceItemToMember(member))) {
168
168
  throw new SimpleError({
169
169
  code: 'permission_denied',
170
170
  message: 'No permission to link balanace items to this member',
171
171
  human: 'Je hebt geen toegang om aanrekeningen te maken verbonden met dit lid',
172
- field: 'memberId'
173
- })
172
+ field: 'memberId',
173
+ });
174
174
  }
175
175
 
176
176
  return member;
@@ -183,8 +183,8 @@ export class PatchBalanceItemsEndpoint extends Endpoint<Params, Query, Body, Res
183
183
  code: 'permission_denied',
184
184
  message: 'No permission to link balanace items to this user',
185
185
  human: 'Je hebt geen toegang om aanrekeningen te maken verbonden met deze gebruiker',
186
- field: 'userId'
187
- })
186
+ field: 'userId',
187
+ });
188
188
  }
189
189
 
190
190
  return user;