@stamhoofd/backend 2.39.1 → 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,24 +1,24 @@
|
|
|
1
|
-
import { Decoder } from
|
|
2
|
-
import { DecodedRequest, Endpoint, Request, Response } from
|
|
1
|
+
import { Decoder } from '@simonbackx/simple-encoding';
|
|
2
|
+
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
3
3
|
import { Order, Webshop } from '@stamhoofd/models';
|
|
4
|
-
import { PaginatedResponse, PermissionLevel, PrivateOrder, WebshopOrdersQuery } from
|
|
4
|
+
import { PaginatedResponse, PermissionLevel, PrivateOrder, WebshopOrdersQuery } from '@stamhoofd/structures';
|
|
5
5
|
|
|
6
|
-
import { Context } from
|
|
6
|
+
import { Context } from '../../../../helpers/Context';
|
|
7
7
|
|
|
8
8
|
type Params = { id: string };
|
|
9
|
-
type Query = WebshopOrdersQuery
|
|
10
|
-
type Body = undefined
|
|
11
|
-
type ResponseBody = PaginatedResponse<PrivateOrder[], Query
|
|
9
|
+
type Query = WebshopOrdersQuery;
|
|
10
|
+
type Body = undefined;
|
|
11
|
+
type ResponseBody = PaginatedResponse<PrivateOrder[], Query>;
|
|
12
12
|
|
|
13
13
|
export class GetWebshopOrdersEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
14
|
-
queryDecoder = WebshopOrdersQuery as Decoder<WebshopOrdersQuery
|
|
14
|
+
queryDecoder = WebshopOrdersQuery as Decoder<WebshopOrdersQuery>;
|
|
15
15
|
|
|
16
16
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
17
|
-
if (request.method
|
|
17
|
+
if (request.method !== 'GET') {
|
|
18
18
|
return [false];
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
const params = Endpoint.parseParameters(request.url,
|
|
21
|
+
const params = Endpoint.parseParameters(request.url, '/webshop/@id/orders', { id: String });
|
|
22
22
|
|
|
23
23
|
if (params) {
|
|
24
24
|
return [true, params as Params];
|
|
@@ -29,7 +29,7 @@ export class GetWebshopOrdersEndpoint extends Endpoint<Params, Query, Body, Resp
|
|
|
29
29
|
async handle(_: DecodedRequest<Params, Query, Body>): Promise<Response<ResponseBody>> {
|
|
30
30
|
await Promise.resolve();
|
|
31
31
|
throw new Error('Not implemented');
|
|
32
|
-
/*const organization = await Context.setOrganizationScope();
|
|
32
|
+
/* const organization = await Context.setOrganizationScope();
|
|
33
33
|
await Context.authenticate()
|
|
34
34
|
|
|
35
35
|
// Fast throw first (more in depth checking for patches later)
|
|
@@ -71,15 +71,15 @@ export class GetWebshopOrdersEndpoint extends Endpoint<Params, Query, Body, Resp
|
|
|
71
71
|
//}
|
|
72
72
|
|
|
73
73
|
const structures = await Order.getPrivateStructures(orders)
|
|
74
|
-
|
|
74
|
+
|
|
75
75
|
return new Response(
|
|
76
|
-
new PaginatedResponse({
|
|
76
|
+
new PaginatedResponse({
|
|
77
77
|
results: structures,
|
|
78
78
|
next: orders.length >= limit ? WebshopOrdersQuery.create({
|
|
79
79
|
updatedSince: orders[orders.length - 1].updatedAt ?? undefined,
|
|
80
80
|
afterNumber: orders[orders.length - 1].number ?? undefined
|
|
81
81
|
}) : undefined
|
|
82
82
|
})
|
|
83
|
-
)
|
|
83
|
+
); */
|
|
84
84
|
}
|
|
85
85
|
}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { Decoder } from
|
|
2
|
-
import { DecodedRequest, Endpoint, Request, Response } from
|
|
1
|
+
import { Decoder } from '@simonbackx/simple-encoding';
|
|
2
|
+
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
3
3
|
import { Ticket, Webshop } from '@stamhoofd/models';
|
|
4
|
-
import { PaginatedResponse, PermissionLevel, TicketPrivate, WebshopTicketsQuery } from
|
|
4
|
+
import { PaginatedResponse, PermissionLevel, TicketPrivate, WebshopTicketsQuery } from '@stamhoofd/structures';
|
|
5
5
|
|
|
6
|
-
import { Context } from
|
|
6
|
+
import { Context } from '../../../../helpers/Context';
|
|
7
7
|
|
|
8
8
|
type Params = { id: string };
|
|
9
|
-
type Query = WebshopTicketsQuery
|
|
10
|
-
type Body = undefined
|
|
11
|
-
type ResponseBody = PaginatedResponse<TicketPrivate[], Query
|
|
9
|
+
type Query = WebshopTicketsQuery;
|
|
10
|
+
type Body = undefined;
|
|
11
|
+
type ResponseBody = PaginatedResponse<TicketPrivate[], Query>;
|
|
12
12
|
|
|
13
13
|
export class GetWebshopTicketsEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
14
|
-
queryDecoder = WebshopTicketsQuery as Decoder<WebshopTicketsQuery
|
|
14
|
+
queryDecoder = WebshopTicketsQuery as Decoder<WebshopTicketsQuery>;
|
|
15
15
|
|
|
16
16
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
17
|
-
if (request.method
|
|
17
|
+
if (request.method !== 'GET') {
|
|
18
18
|
return [false];
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
const params = Endpoint.parseParameters(request.url,
|
|
21
|
+
const params = Endpoint.parseParameters(request.url, '/webshop/@id/tickets/private', { id: String });
|
|
22
22
|
|
|
23
23
|
if (params) {
|
|
24
24
|
return [true, params as Params];
|
|
@@ -29,7 +29,7 @@ export class GetWebshopTicketsEndpoint extends Endpoint<Params, Query, Body, Res
|
|
|
29
29
|
async handle(_: DecodedRequest<Params, Query, Body>): Promise<Response<ResponseBody>> {
|
|
30
30
|
await Promise.resolve();
|
|
31
31
|
throw new Error('Not implemented');
|
|
32
|
-
/*const organization = await Context.setOrganizationScope();
|
|
32
|
+
/* const organization = await Context.setOrganizationScope();
|
|
33
33
|
await Context.authenticate()
|
|
34
34
|
|
|
35
35
|
// Fast throw first (more in depth checking for patches later)
|
|
@@ -41,7 +41,7 @@ export class GetWebshopTicketsEndpoint extends Endpoint<Params, Query, Body, Res
|
|
|
41
41
|
if (!webshop || !await Context.auth.canAccessWebshopTickets(webshop, PermissionLevel.Read)) {
|
|
42
42
|
throw Context.auth.notFoundOrNoAccess("Je hebt geen toegang tot de tickets van deze webshop")
|
|
43
43
|
}
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
let tickets: Ticket[] | undefined = undefined
|
|
46
46
|
const limit = 150
|
|
47
47
|
|
|
@@ -58,13 +58,13 @@ export class GetWebshopTicketsEndpoint extends Endpoint<Params, Query, Body, Res
|
|
|
58
58
|
const supportsDeletedTickets = request.request.getVersion() >= 229
|
|
59
59
|
|
|
60
60
|
return new Response(
|
|
61
|
-
new PaginatedResponse({
|
|
61
|
+
new PaginatedResponse({
|
|
62
62
|
results: tickets.map(ticket => TicketPrivate.create(ticket)).filter(ticket => supportsDeletedTickets || !ticket.deletedAt),
|
|
63
63
|
next: tickets.length >= limit ? WebshopTicketsQuery.create({
|
|
64
64
|
updatedSince: tickets[tickets.length - 1].updatedAt ?? undefined,
|
|
65
65
|
lastId: tickets[tickets.length - 1].id ?? undefined
|
|
66
66
|
}) : undefined
|
|
67
67
|
})
|
|
68
|
-
)
|
|
68
|
+
); */
|
|
69
69
|
}
|
|
70
70
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AutoEncoder, Decoder, field, StringDecoder } from '@simonbackx/simple-encoding';
|
|
2
|
-
import { DecodedRequest, Endpoint, Request, Response } from
|
|
2
|
+
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
3
3
|
import { Webshop } from '@stamhoofd/models';
|
|
4
|
-
import { PermissionLevel, WebshopUriAvailabilityResponse } from
|
|
4
|
+
import { PermissionLevel, WebshopUriAvailabilityResponse } from '@stamhoofd/structures';
|
|
5
5
|
|
|
6
6
|
import { Context } from '../../../../helpers/Context';
|
|
7
7
|
|
|
@@ -18,14 +18,14 @@ type ResponseBody = WebshopUriAvailabilityResponse;
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
20
|
export class GetWebshopUriAvailabilityEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
21
|
-
queryDecoder = Query as Decoder<Query
|
|
21
|
+
queryDecoder = Query as Decoder<Query>;
|
|
22
22
|
|
|
23
23
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
24
|
-
if (request.method
|
|
24
|
+
if (request.method !== 'GET') {
|
|
25
25
|
return [false];
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
const params = Endpoint.parseParameters(request.url,
|
|
28
|
+
const params = Endpoint.parseParameters(request.url, '/webshop/@id/check-uri', { id: String });
|
|
29
29
|
|
|
30
30
|
if (params) {
|
|
31
31
|
return [true, params as Params];
|
|
@@ -35,35 +35,35 @@ export class GetWebshopUriAvailabilityEndpoint extends Endpoint<Params, Query, B
|
|
|
35
35
|
|
|
36
36
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
37
37
|
const organization = await Context.setOrganizationScope();
|
|
38
|
-
await Context.authenticate()
|
|
38
|
+
await Context.authenticate();
|
|
39
39
|
|
|
40
40
|
// Fast throw first (more in depth checking for patches later)
|
|
41
41
|
if (!await Context.auth.hasSomeAccess(organization.id)) {
|
|
42
|
-
throw Context.auth.error()
|
|
42
|
+
throw Context.auth.error();
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
const webshop = await Webshop.getByID(request.params.id)
|
|
45
|
+
const webshop = await Webshop.getByID(request.params.id);
|
|
46
46
|
if (!webshop || !await Context.auth.canAccessWebshop(webshop, PermissionLevel.Full)) {
|
|
47
|
-
throw Context.auth.notFoundOrNoAccess()
|
|
47
|
+
throw Context.auth.notFoundOrNoAccess();
|
|
48
48
|
}
|
|
49
|
-
|
|
50
|
-
const q = await Webshop.where({
|
|
51
|
-
uri: request.query.uri,
|
|
49
|
+
|
|
50
|
+
const q = await Webshop.where({
|
|
51
|
+
uri: request.query.uri,
|
|
52
52
|
id: {
|
|
53
|
-
sign:
|
|
54
|
-
value: request.params.id
|
|
55
|
-
}
|
|
56
|
-
}, {
|
|
57
|
-
limit: 1,
|
|
58
|
-
select:
|
|
59
|
-
})
|
|
53
|
+
sign: '!=',
|
|
54
|
+
value: request.params.id,
|
|
55
|
+
},
|
|
56
|
+
}, {
|
|
57
|
+
limit: 1,
|
|
58
|
+
select: 'id',
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const available = q.length == 0;
|
|
60
62
|
|
|
61
|
-
const available = q.length == 0
|
|
62
|
-
|
|
63
63
|
return new Response(
|
|
64
64
|
WebshopUriAvailabilityResponse.create({
|
|
65
|
-
available
|
|
66
|
-
})
|
|
65
|
+
available,
|
|
66
|
+
}),
|
|
67
67
|
);
|
|
68
68
|
}
|
|
69
69
|
}
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import { AutoEncoderPatchType, Decoder, PatchableArrayAutoEncoder, PatchableArrayDecoder, patchObject, StringDecoder } from
|
|
2
|
-
import { DecodedRequest, Endpoint, Request, Response } from
|
|
1
|
+
import { AutoEncoderPatchType, Decoder, PatchableArrayAutoEncoder, PatchableArrayDecoder, patchObject, StringDecoder } from '@simonbackx/simple-encoding';
|
|
2
|
+
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
3
3
|
import { SimpleError } from '@simonbackx/simple-errors';
|
|
4
4
|
import { Webshop, WebshopDiscountCode } from '@stamhoofd/models';
|
|
5
|
-
import { QueueHandler } from
|
|
6
|
-
import { DiscountCode, PermissionLevel } from
|
|
5
|
+
import { QueueHandler } from '@stamhoofd/queues';
|
|
6
|
+
import { DiscountCode, PermissionLevel } from '@stamhoofd/structures';
|
|
7
7
|
|
|
8
|
-
import { Context } from
|
|
8
|
+
import { Context } from '../../../../helpers/Context';
|
|
9
9
|
|
|
10
10
|
type Params = { id: string };
|
|
11
|
-
type Query = undefined
|
|
12
|
-
type Body = PatchableArrayAutoEncoder<DiscountCode
|
|
13
|
-
type ResponseBody = DiscountCode[]
|
|
11
|
+
type Query = undefined;
|
|
12
|
+
type Body = PatchableArrayAutoEncoder<DiscountCode>;
|
|
13
|
+
type ResponseBody = DiscountCode[];
|
|
14
14
|
|
|
15
15
|
export class PatchWebshopDiscountCodesEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
16
|
-
bodyDecoder = new PatchableArrayDecoder(DiscountCode as Decoder<DiscountCode>, DiscountCode.patchType() as Decoder<AutoEncoderPatchType<DiscountCode>>, StringDecoder)
|
|
16
|
+
bodyDecoder = new PatchableArrayDecoder(DiscountCode as Decoder<DiscountCode>, DiscountCode.patchType() as Decoder<AutoEncoderPatchType<DiscountCode>>, StringDecoder);
|
|
17
17
|
|
|
18
18
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
19
|
-
if (request.method
|
|
19
|
+
if (request.method !== 'PATCH') {
|
|
20
20
|
return [false];
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
const params = Endpoint.parseParameters(request.url,
|
|
23
|
+
const params = Endpoint.parseParameters(request.url, '/webshop/@id/discount-codes', { id: String });
|
|
24
24
|
|
|
25
25
|
if (params) {
|
|
26
26
|
return [true, params as Params];
|
|
@@ -30,96 +30,98 @@ export class PatchWebshopDiscountCodesEndpoint extends Endpoint<Params, Query, B
|
|
|
30
30
|
|
|
31
31
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
32
32
|
const organization = await Context.setOrganizationScope();
|
|
33
|
-
await Context.authenticate()
|
|
33
|
+
await Context.authenticate();
|
|
34
34
|
|
|
35
35
|
// Fast throw first (more in depth checking for patches later)
|
|
36
36
|
if (!await Context.auth.hasSomeAccess(organization.id)) {
|
|
37
|
-
throw Context.auth.error()
|
|
37
|
+
throw Context.auth.error();
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
const webshop = await Webshop.getByID(request.params.id)
|
|
40
|
+
const webshop = await Webshop.getByID(request.params.id);
|
|
41
41
|
if (!webshop || !await Context.auth.canAccessWebshop(webshop, PermissionLevel.Full)) {
|
|
42
|
-
throw Context.auth.notFoundOrNoAccess()
|
|
42
|
+
throw Context.auth.notFoundOrNoAccess();
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
const discountCodes: WebshopDiscountCode[] = []
|
|
45
|
+
const discountCodes: WebshopDiscountCode[] = [];
|
|
46
46
|
|
|
47
47
|
// Updating discoutn codes should happen in the stock queue (because they are also edited when placing orders)
|
|
48
|
-
await QueueHandler.schedule(
|
|
48
|
+
await QueueHandler.schedule('webshop-stock/' + request.params.id, async () => {
|
|
49
49
|
// TODO: handle order creation here
|
|
50
50
|
for (const put of request.body.getPuts()) {
|
|
51
|
-
const struct = put.put
|
|
52
|
-
const model = new WebshopDiscountCode()
|
|
51
|
+
const struct = put.put;
|
|
52
|
+
const model = new WebshopDiscountCode();
|
|
53
53
|
model.code = struct.code;
|
|
54
|
-
model.description = struct.description
|
|
55
|
-
model.webshopId = webshop.id
|
|
56
|
-
model.organizationId = webshop.organizationId
|
|
57
|
-
model.discounts = struct.discounts
|
|
58
|
-
model.maximumUsage = struct.maximumUsage
|
|
54
|
+
model.description = struct.description;
|
|
55
|
+
model.webshopId = webshop.id;
|
|
56
|
+
model.organizationId = webshop.organizationId;
|
|
57
|
+
model.discounts = struct.discounts;
|
|
58
|
+
model.maximumUsage = struct.maximumUsage;
|
|
59
59
|
|
|
60
60
|
try {
|
|
61
|
-
await model.save()
|
|
62
|
-
}
|
|
61
|
+
await model.save();
|
|
62
|
+
}
|
|
63
|
+
catch (e) {
|
|
63
64
|
// Duplicate key probably
|
|
64
|
-
if (e.code && e.code ==
|
|
65
|
+
if (e.code && e.code == 'ER_DUP_ENTRY') {
|
|
65
66
|
throw new SimpleError({
|
|
66
67
|
code: 'used_code',
|
|
67
68
|
message: 'Discount code already in use',
|
|
68
|
-
human: 'Er bestaat al een kortingscode met de code ' + struct.code+', een code moet uniek zijn.'
|
|
69
|
-
})
|
|
69
|
+
human: 'Er bestaat al een kortingscode met de code ' + struct.code + ', een code moet uniek zijn.',
|
|
70
|
+
});
|
|
70
71
|
}
|
|
71
72
|
throw e;
|
|
72
73
|
}
|
|
73
74
|
|
|
74
|
-
discountCodes.push(model)
|
|
75
|
+
discountCodes.push(model);
|
|
75
76
|
}
|
|
76
77
|
|
|
77
78
|
for (const patch of request.body.getPatches()) {
|
|
78
|
-
const model = await WebshopDiscountCode.getByID(patch.id)
|
|
79
|
+
const model = await WebshopDiscountCode.getByID(patch.id);
|
|
79
80
|
if (!model || model.webshopId !== webshop.id) {
|
|
80
81
|
throw new SimpleError({
|
|
81
|
-
code:
|
|
82
|
-
message:
|
|
83
|
-
})
|
|
82
|
+
code: 'not_found',
|
|
83
|
+
message: 'Discount code with id ' + patch.id + ' does not exist',
|
|
84
|
+
});
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
model.code = patchObject(model.code, patch.code)
|
|
87
|
-
model.description = patchObject(model.description, patch.description)
|
|
88
|
-
model.discounts = patchObject(model.discounts, patch.discounts)
|
|
89
|
-
model.maximumUsage = patchObject(model.maximumUsage, patch.maximumUsage)
|
|
90
|
-
|
|
87
|
+
model.code = patchObject(model.code, patch.code);
|
|
88
|
+
model.description = patchObject(model.description, patch.description);
|
|
89
|
+
model.discounts = patchObject(model.discounts, patch.discounts);
|
|
90
|
+
model.maximumUsage = patchObject(model.maximumUsage, patch.maximumUsage);
|
|
91
|
+
|
|
91
92
|
try {
|
|
92
|
-
await model.save()
|
|
93
|
-
}
|
|
93
|
+
await model.save();
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
94
96
|
// Duplicate key probably
|
|
95
|
-
if (e.code && e.code ==
|
|
97
|
+
if (e.code && e.code == 'ER_DUP_ENTRY') {
|
|
96
98
|
throw new SimpleError({
|
|
97
99
|
code: 'used_code',
|
|
98
100
|
message: 'Discount code already in use',
|
|
99
|
-
human: 'Er bestaat al een kortingscode met de code ' + model.code+', een code moet uniek zijn.'
|
|
100
|
-
})
|
|
101
|
+
human: 'Er bestaat al een kortingscode met de code ' + model.code + ', een code moet uniek zijn.',
|
|
102
|
+
});
|
|
101
103
|
}
|
|
102
104
|
throw e;
|
|
103
105
|
}
|
|
104
106
|
|
|
105
|
-
discountCodes.push(model)
|
|
107
|
+
discountCodes.push(model);
|
|
106
108
|
}
|
|
107
109
|
|
|
108
110
|
for (const id of request.body.getDeletes()) {
|
|
109
|
-
const model = await WebshopDiscountCode.getByID(id)
|
|
111
|
+
const model = await WebshopDiscountCode.getByID(id);
|
|
110
112
|
if (!model || model.webshopId !== webshop.id) {
|
|
111
113
|
throw new SimpleError({
|
|
112
|
-
code:
|
|
113
|
-
message:
|
|
114
|
-
})
|
|
114
|
+
code: 'not_found',
|
|
115
|
+
message: 'Discount code with id ' + id + ' does not exist',
|
|
116
|
+
});
|
|
115
117
|
}
|
|
116
118
|
|
|
117
|
-
|
|
119
|
+
await model.delete();
|
|
118
120
|
}
|
|
119
121
|
});
|
|
120
|
-
|
|
122
|
+
|
|
121
123
|
return new Response(
|
|
122
|
-
discountCodes.map(d => d.getStructure())
|
|
124
|
+
discountCodes.map(d => d.getStructure()),
|
|
123
125
|
);
|
|
124
126
|
}
|
|
125
127
|
}
|