@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.
- package/eslint.config.mjs +5 -0
- package/index.ts +81 -74
- package/jest.config.cjs +10 -0
- package/migrations.ts +16 -14
- package/package.json +11 -11
- package/src/crons/clear-excel-cache.test.ts +48 -50
- package/src/crons/clear-excel-cache.ts +18 -18
- package/src/crons/setup-steps.ts +2 -2
- package/src/crons.ts +325 -306
- package/src/decoders/StringArrayDecoder.ts +7 -7
- package/src/decoders/StringNullableDecoder.ts +1 -2
- package/src/email-recipient-loaders/members.ts +22 -22
- package/src/endpoints/admin/memberships/ChargeMembershipsEndpoint.ts +8 -9
- package/src/endpoints/admin/memberships/GetChargeMembershipsSummaryEndpoint.ts +39 -40
- package/src/endpoints/admin/organizations/GetOrganizationsCountEndpoint.ts +8 -8
- package/src/endpoints/admin/organizations/GetOrganizationsEndpoint.ts +44 -45
- package/src/endpoints/admin/organizations/PatchOrganizationsEndpoint.ts +58 -57
- package/src/endpoints/auth/CreateAdminEndpoint.ts +48 -45
- package/src/endpoints/auth/CreateTokenEndpoint.test.ts +31 -31
- package/src/endpoints/auth/CreateTokenEndpoint.ts +146 -147
- package/src/endpoints/auth/DeleteTokenEndpoint.ts +7 -7
- package/src/endpoints/auth/DeleteUserEndpoint.ts +15 -15
- package/src/endpoints/auth/ForgotPasswordEndpoint.ts +17 -18
- package/src/endpoints/auth/GetOtherUserEndpoint.ts +9 -10
- package/src/endpoints/auth/GetUserEndpoint.test.ts +32 -35
- package/src/endpoints/auth/GetUserEndpoint.ts +5 -6
- package/src/endpoints/auth/PatchApiUserEndpoint.ts +35 -33
- package/src/endpoints/auth/PatchUserEndpoint.ts +55 -52
- package/src/endpoints/auth/PollEmailVerificationEndpoint.ts +9 -9
- package/src/endpoints/auth/RetryEmailVerificationEndpoint.ts +8 -8
- package/src/endpoints/auth/SignupEndpoint.ts +37 -36
- package/src/endpoints/auth/VerifyEmailEndpoint.ts +29 -28
- package/src/endpoints/global/addresses/SearchRegionsEndpoint.ts +33 -33
- package/src/endpoints/global/addresses/ValidateAddressEndpoint.ts +7 -7
- package/src/endpoints/global/caddy/CheckDomainCertEndpoint.ts +37 -37
- package/src/endpoints/global/email/CreateEmailEndpoint.ts +30 -30
- package/src/endpoints/global/email/GetEmailAddressEndpoint.ts +13 -13
- package/src/endpoints/global/email/GetEmailEndpoint.ts +13 -13
- package/src/endpoints/global/email/ManageEmailAddressEndpoint.ts +16 -16
- package/src/endpoints/global/email/PatchEmailEndpoint.ts +25 -25
- package/src/endpoints/global/events/GetEventsEndpoint.ts +43 -44
- package/src/endpoints/global/events/PatchEventsEndpoint.ts +127 -172
- package/src/endpoints/global/files/ExportToExcelEndpoint.ts +49 -50
- package/src/endpoints/global/files/GetFileCache.ts +13 -13
- package/src/endpoints/global/files/UploadFile.ts +51 -54
- package/src/endpoints/global/files/UploadImage.ts +53 -53
- package/src/endpoints/global/groups/GetGroupsEndpoint.ts +25 -25
- package/src/endpoints/global/members/GetMemberFamilyEndpoint.ts +24 -23
- package/src/endpoints/global/members/GetMembersCountEndpoint.ts +8 -8
- package/src/endpoints/global/members/GetMembersEndpoint.ts +105 -102
- package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.ts +240 -239
- package/src/endpoints/global/organizations/CheckRegisterCodeEndpoint.ts +12 -14
- package/src/endpoints/global/organizations/CreateOrganizationEndpoint.test.ts +32 -33
- package/src/endpoints/global/organizations/CreateOrganizationEndpoint.ts +48 -57
- package/src/endpoints/global/organizations/GetOrganizationFromDomainEndpoint.test.ts +21 -22
- package/src/endpoints/global/organizations/GetOrganizationFromDomainEndpoint.ts +28 -28
- package/src/endpoints/global/organizations/GetOrganizationFromUriEndpoint.ts +18 -18
- package/src/endpoints/global/organizations/SearchOrganizationEndpoint.test.ts +20 -20
- package/src/endpoints/global/organizations/SearchOrganizationEndpoint.ts +17 -17
- package/src/endpoints/global/payments/StripeWebhookEndpoint.ts +81 -75
- package/src/endpoints/global/platform/GetPlatformAdminsEndpoint.ts +14 -14
- package/src/endpoints/global/platform/GetPlatformEnpoint.ts +11 -11
- package/src/endpoints/global/platform/PatchPlatformEnpoint.ts +71 -68
- package/src/endpoints/global/registration/GetPaymentRegistrations.ts +27 -27
- package/src/endpoints/global/registration/GetUserBillingStatusEndpoint.ts +30 -30
- package/src/endpoints/global/registration/GetUserDetailedBillingStatusEndpoint.ts +34 -34
- package/src/endpoints/global/registration/GetUserDocumentsEndpoint.ts +26 -26
- package/src/endpoints/global/registration/GetUserMembersEndpoint.ts +12 -12
- package/src/endpoints/global/registration/PatchUserMembersEndpoint.ts +90 -90
- package/src/endpoints/global/registration/RegisterMembersEndpoint.test.ts +118 -121
- package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +362 -350
- package/src/endpoints/global/registration-periods/GetRegistrationPeriodsEndpoint.ts +8 -9
- package/src/endpoints/global/registration-periods/PatchRegistrationPeriodsEndpoint.ts +21 -21
- package/src/endpoints/global/webshops/GetWebshopFromDomainEndpoint.ts +65 -65
- package/src/endpoints/organization/dashboard/billing/GetOrganizationBillingStatusEndpoint.ts +9 -9
- package/src/endpoints/organization/dashboard/billing/GetOrganizationDetailedBillingStatusEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/documents/GetDocumentTemplateXML.ts +17 -17
- package/src/endpoints/organization/dashboard/documents/GetDocumentTemplatesEndpoint.ts +21 -21
- package/src/endpoints/organization/dashboard/documents/GetDocumentsEndpoint.ts +15 -15
- package/src/endpoints/organization/dashboard/documents/PatchDocumentEndpoint.ts +52 -52
- package/src/endpoints/organization/dashboard/documents/PatchDocumentTemplateEndpoint.ts +37 -37
- package/src/endpoints/organization/dashboard/email/CheckEmailBouncesEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/email/EmailEndpoint.ts +113 -112
- package/src/endpoints/organization/dashboard/email-templates/GetEmailTemplatesEndpoint.ts +29 -29
- package/src/endpoints/organization/dashboard/email-templates/PatchEmailTemplatesEndpoint.ts +48 -47
- package/src/endpoints/organization/dashboard/mollie/CheckMollieEndpoint.ts +22 -21
- package/src/endpoints/organization/dashboard/mollie/ConnectMollieEndpoint.ts +13 -14
- package/src/endpoints/organization/dashboard/mollie/DisconnectMollieEndpoint.ts +12 -13
- package/src/endpoints/organization/dashboard/mollie/GetMollieDashboardEndpoint.ts +24 -24
- package/src/endpoints/organization/dashboard/nolt/CreateNoltTokenEndpoint.ts +10 -12
- package/src/endpoints/organization/dashboard/organization/GetOrganizationArchivedGroups.ts +14 -14
- package/src/endpoints/organization/dashboard/organization/GetOrganizationDeletedGroups.ts +13 -13
- package/src/endpoints/organization/dashboard/organization/GetOrganizationSSOEndpoint.ts +12 -12
- package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.test.ts +120 -124
- package/src/endpoints/organization/dashboard/organization/PatchOrganizationEndpoint.ts +172 -173
- package/src/endpoints/organization/dashboard/organization/SetOrganizationDomainEndpoint.ts +88 -89
- package/src/endpoints/organization/dashboard/organization/SetOrganizationSSOEndpoint.ts +12 -12
- package/src/endpoints/organization/dashboard/payments/GetMemberBalanceEndpoint.ts +17 -17
- package/src/endpoints/organization/dashboard/payments/GetPaymentsCountEndpoint.ts +8 -8
- package/src/endpoints/organization/dashboard/payments/GetPaymentsEndpoint.ts +66 -67
- package/src/endpoints/organization/dashboard/payments/PatchBalanceItemsEndpoint.ts +47 -47
- package/src/endpoints/organization/dashboard/payments/PatchPaymentsEndpoint.ts +93 -91
- package/src/endpoints/organization/dashboard/registration-periods/GetOrganizationRegistrationPeriodsEndpoint.ts +16 -17
- package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.ts +170 -167
- package/src/endpoints/organization/dashboard/registration-periods/SetupStepReviewEndpoint.ts +25 -24
- package/src/endpoints/organization/dashboard/stripe/ConnectStripeEndpoint.ts +22 -23
- package/src/endpoints/organization/dashboard/stripe/DeleteStripeAccountEndpoint.ts +22 -22
- package/src/endpoints/organization/dashboard/stripe/GetStripeAccountLinkEndpoint.ts +17 -18
- package/src/endpoints/organization/dashboard/stripe/GetStripeAccountsEndpoint.ts +8 -9
- package/src/endpoints/organization/dashboard/stripe/GetStripeLoginLinkEndpoint.ts +17 -18
- package/src/endpoints/organization/dashboard/stripe/UpdateStripeAccountEndpoint.ts +14 -15
- package/src/endpoints/organization/dashboard/users/CreateApiUserEndpoint.ts +19 -19
- package/src/endpoints/organization/dashboard/users/DeleteUserEndpoint.ts +19 -19
- package/src/endpoints/organization/dashboard/users/GetApiUsersEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/users/GetOrganizationAdminsEndpoint.ts +12 -12
- package/src/endpoints/organization/dashboard/webshops/CreateWebshopEndpoint.ts +103 -100
- package/src/endpoints/organization/dashboard/webshops/DeleteWebshopEndpoint.ts +11 -12
- package/src/endpoints/organization/dashboard/webshops/GetDiscountCodesEndpoint.ts +15 -15
- package/src/endpoints/organization/dashboard/webshops/GetWebshopOrdersEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/webshops/GetWebshopTicketsEndpoint.ts +14 -14
- package/src/endpoints/organization/dashboard/webshops/GetWebshopUriAvailabilityEndpoint.ts +23 -23
- package/src/endpoints/organization/dashboard/webshops/PatchDiscountCodesEndpoint.ts +54 -52
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopEndpoint.ts +84 -81
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopOrdersEndpoint.ts +120 -111
- package/src/endpoints/organization/dashboard/webshops/PatchWebshopTicketsEndpoint.ts +24 -24
- package/src/endpoints/organization/dashboard/webshops/VerifyWebshopDomainEndpoint.ts +18 -18
- package/src/endpoints/organization/shared/ExchangePaymentEndpoint.ts +141 -130
- package/src/endpoints/organization/shared/GetDocumentHtml.ts +25 -25
- package/src/endpoints/organization/shared/GetPaymentEndpoint.ts +18 -18
- package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.test.ts +36 -37
- package/src/endpoints/organization/shared/auth/GetOrganizationEndpoint.ts +9 -9
- package/src/endpoints/organization/shared/auth/OpenIDConnectCallbackEndpoint.ts +11 -11
- package/src/endpoints/organization/shared/auth/OpenIDConnectStartEndpoint.ts +28 -27
- package/src/endpoints/organization/webshops/CheckWebshopDiscountCodesEndpoint.ts +20 -20
- package/src/endpoints/organization/webshops/GetOrderByPaymentEndpoint.ts +22 -22
- package/src/endpoints/organization/webshops/GetOrderEndpoint.ts +14 -14
- package/src/endpoints/organization/webshops/GetTicketsEndpoint.ts +57 -56
- package/src/endpoints/organization/webshops/GetWebshopEndpoint.test.ts +65 -66
- package/src/endpoints/organization/webshops/GetWebshopEndpoint.ts +18 -17
- package/src/endpoints/organization/webshops/PlaceOrderEndpoint.test.ts +124 -128
- package/src/endpoints/organization/webshops/PlaceOrderEndpoint.ts +154 -145
- package/src/excel-loaders/members.ts +102 -103
- package/src/excel-loaders/payments.ts +155 -156
- package/src/helpers/AddressValidator.test.ts +32 -32
- package/src/helpers/AddressValidator.ts +128 -122
- package/src/helpers/AdminPermissionChecker.ts +339 -236
- package/src/helpers/AuthenticatedStructures.ts +233 -134
- package/src/helpers/BuckarooHelper.ts +134 -134
- package/src/helpers/CheckSettlements.ts +94 -88
- package/src/helpers/Context.ts +87 -86
- package/src/helpers/CookieHelper.ts +23 -22
- package/src/helpers/EmailResumer.ts +10 -10
- package/src/helpers/FileCache.ts +62 -62
- package/src/helpers/ForwardHandler.test.ts +122 -124
- package/src/helpers/ForwardHandler.ts +76 -70
- package/src/helpers/MemberUserSyncer.ts +101 -96
- package/src/helpers/MembershipCharger.ts +69 -69
- package/src/helpers/MembershipHelper.ts +11 -12
- package/src/helpers/OpenIDConnectHelper.ts +85 -82
- package/src/helpers/PeriodHelper.ts +65 -70
- package/src/helpers/StripeHelper.ts +146 -137
- package/src/helpers/StripePayoutChecker.ts +51 -52
- package/src/helpers/ViesHelper.ts +46 -44
- package/src/helpers/fetchToAsyncIterator.ts +14 -14
- package/src/helpers/xlsxAddressTransformerColumnFactory.ts +50 -52
- package/src/middleware/ContextMiddleware.ts +5 -5
- package/src/migrations/1646578856-validate-addresses.ts +6 -9
- package/src/seeds/0000000000-example.ts +3 -5
- package/src/seeds/1715028563-user-permissions.ts +16 -18
- package/src/seeds/1722256498-group-update-occupancy.ts +12 -12
- package/src/seeds/1722344162-sync-member-users.ts +14 -15
- package/src/seeds/1722344162-update-membership.ts +6 -6
- package/src/seeds/1726055544-balance-item-paid.ts +4 -4
- package/src/seeds/1726055545-balance-item-pending.ts +4 -4
- package/src/seeds/1726494419-update-cached-outstanding-balance.ts +16 -16
- package/src/seeds/1726494420-update-cached-outstanding-balance-from-items.ts +12 -12
- package/src/seeds/1726572303-schedule-stock-updates.ts +12 -12
- package/src/seeds/1726847064-setup-steps.ts +16 -0
- package/src/sql-filters/balance-item-payments.ts +7 -7
- package/src/sql-filters/events.ts +14 -14
- package/src/sql-filters/members.ts +96 -96
- package/src/sql-filters/organizations.ts +139 -75
- package/src/sql-filters/payments.ts +28 -28
- package/src/sql-filters/registrations.ts +14 -14
- package/src/sql-sorters/events.ts +25 -25
- package/src/sql-sorters/members.ts +26 -26
- package/src/sql-sorters/organizations.ts +36 -36
- package/src/sql-sorters/payments.ts +26 -26
- package/tests/e2e/stock.test.ts +616 -621
- package/tests/e2e/tickets.test.ts +255 -260
- package/tests/helpers/StripeMocker.ts +177 -179
- package/tests/helpers/TestServer.ts +9 -9
- package/tests/jest.global.setup.ts +14 -13
- package/tests/jest.setup.ts +33 -32
- package/.eslintrc.js +0 -61
- package/jest.config.js +0 -11
- package/src/helpers/SetupStepsUpdater.ts +0 -359
- 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
|
|
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
|
|
25
|
+
if (request.method !== 'GET') {
|
|
27
26
|
return [false];
|
|
28
27
|
}
|
|
29
28
|
|
|
30
|
-
const params = Endpoint.parseParameters(request.url,
|
|
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
|
-
|
|
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
|
|
3
|
-
import { SimpleError } from
|
|
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
|
|
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
|
|
19
|
+
if (request.method !== 'PATCH') {
|
|
21
20
|
return [false];
|
|
22
21
|
}
|
|
23
22
|
|
|
24
|
-
const params = Endpoint.parseParameters(request.url,
|
|
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(
|
|
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
|
-
}
|
|
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
|
-
|
|
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;
|