@stamhoofd/backend 2.39.1 → 2.40.1
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 +275 -273
- 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 +58 -60
- 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,30 +1,30 @@
|
|
|
1
|
-
import { DecodedRequest, Endpoint, Request, Response } from
|
|
2
|
-
import { GroupPrivateSettings, Group as GroupStruct, GroupType, OrganizationRegistrationPeriod as OrganizationRegistrationPeriodStruct, PermissionLevel, PermissionsResourceType, ResourcePermissions, Version } from
|
|
1
|
+
import { DecodedRequest, Endpoint, Request, Response } from '@simonbackx/simple-endpoints';
|
|
2
|
+
import { GroupPrivateSettings, Group as GroupStruct, GroupType, OrganizationRegistrationPeriod as OrganizationRegistrationPeriodStruct, PermissionLevel, PermissionsResourceType, ResourcePermissions, Version } from '@stamhoofd/structures';
|
|
3
3
|
|
|
4
|
-
import { AutoEncoderPatchType, Decoder, PatchableArrayAutoEncoder, PatchableArrayDecoder, StringDecoder } from
|
|
5
|
-
import { SimpleError } from
|
|
6
|
-
import { Group, Member, Organization, OrganizationRegistrationPeriod, Platform, RegistrationPeriod } from
|
|
7
|
-
import { AuthenticatedStructures } from
|
|
8
|
-
import { Context } from
|
|
4
|
+
import { AutoEncoderPatchType, Decoder, PatchableArrayAutoEncoder, PatchableArrayDecoder, StringDecoder } from '@simonbackx/simple-encoding';
|
|
5
|
+
import { SimpleError } from '@simonbackx/simple-errors';
|
|
6
|
+
import { Group, Member, Organization, OrganizationRegistrationPeriod, Platform, RegistrationPeriod } from '@stamhoofd/models';
|
|
7
|
+
import { AuthenticatedStructures } from '../../../../helpers/AuthenticatedStructures';
|
|
8
|
+
import { Context } from '../../../../helpers/Context';
|
|
9
9
|
|
|
10
10
|
type Params = Record<string, never>;
|
|
11
11
|
type Query = undefined;
|
|
12
|
-
type Body = PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct
|
|
13
|
-
type ResponseBody = OrganizationRegistrationPeriodStruct[]
|
|
12
|
+
type Body = PatchableArrayAutoEncoder<OrganizationRegistrationPeriodStruct>;
|
|
13
|
+
type ResponseBody = OrganizationRegistrationPeriodStruct[];
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* One endpoint to create, patch and delete members and their registrations and payments
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
export class PatchOrganizationRegistrationPeriodsEndpoint extends Endpoint<Params, Query, Body, ResponseBody> {
|
|
20
|
-
bodyDecoder = new PatchableArrayDecoder(OrganizationRegistrationPeriodStruct as Decoder<OrganizationRegistrationPeriodStruct>, OrganizationRegistrationPeriodStruct.patchType() as Decoder<AutoEncoderPatchType<OrganizationRegistrationPeriodStruct>>, StringDecoder)
|
|
20
|
+
bodyDecoder = new PatchableArrayDecoder(OrganizationRegistrationPeriodStruct as Decoder<OrganizationRegistrationPeriodStruct>, OrganizationRegistrationPeriodStruct.patchType() as Decoder<AutoEncoderPatchType<OrganizationRegistrationPeriodStruct>>, StringDecoder);
|
|
21
21
|
|
|
22
22
|
protected doesMatch(request: Request): [true, Params] | [false] {
|
|
23
|
-
if (request.method
|
|
23
|
+
if (request.method !== 'PATCH') {
|
|
24
24
|
return [false];
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
const params = Endpoint.parseParameters(request.url,
|
|
27
|
+
const params = Endpoint.parseParameters(request.url, '/organization/registration-periods', {});
|
|
28
28
|
|
|
29
29
|
if (params) {
|
|
30
30
|
return [true, params as Params];
|
|
@@ -34,17 +34,17 @@ export class PatchOrganizationRegistrationPeriodsEndpoint extends Endpoint<Param
|
|
|
34
34
|
|
|
35
35
|
async handle(request: DecodedRequest<Params, Query, Body>) {
|
|
36
36
|
const organization = await Context.setOrganizationScope();
|
|
37
|
-
await Context.authenticate()
|
|
37
|
+
await Context.authenticate();
|
|
38
38
|
|
|
39
39
|
if (!await Context.auth.hasFullAccess(organization.id)) {
|
|
40
|
-
throw Context.auth.error()
|
|
40
|
+
throw Context.auth.error();
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
const periods: OrganizationRegistrationPeriod[] = [];
|
|
44
44
|
|
|
45
|
-
for (const {put} of request.body.getPuts()) {
|
|
45
|
+
for (const { put } of request.body.getPuts()) {
|
|
46
46
|
if (!await Context.auth.hasFullAccess(organization.id)) {
|
|
47
|
-
throw Context.auth.error()
|
|
47
|
+
throw Context.auth.error();
|
|
48
48
|
}
|
|
49
49
|
periods.push(await PatchOrganizationRegistrationPeriodsEndpoint.createOrganizationPeriod(organization, put));
|
|
50
50
|
}
|
|
@@ -53,143 +53,144 @@ export class PatchOrganizationRegistrationPeriodsEndpoint extends Endpoint<Param
|
|
|
53
53
|
const organizationPeriod = await OrganizationRegistrationPeriod.getByID(patch.id);
|
|
54
54
|
if (!organizationPeriod || organizationPeriod.organizationId !== organization.id) {
|
|
55
55
|
throw new SimpleError({
|
|
56
|
-
code:
|
|
57
|
-
message:
|
|
58
|
-
statusCode: 404
|
|
59
|
-
})
|
|
56
|
+
code: 'not_found',
|
|
57
|
+
message: 'Period not found',
|
|
58
|
+
statusCode: 404,
|
|
59
|
+
});
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
const period = await RegistrationPeriod.getByID(organizationPeriod.periodId);
|
|
63
63
|
|
|
64
64
|
if (!period) {
|
|
65
65
|
throw new SimpleError({
|
|
66
|
-
code:
|
|
67
|
-
message:
|
|
68
|
-
statusCode: 404
|
|
69
|
-
})
|
|
66
|
+
code: 'not_found',
|
|
67
|
+
message: 'Period not found',
|
|
68
|
+
statusCode: 404,
|
|
69
|
+
});
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
if (period.locked) {
|
|
73
73
|
throw new SimpleError({
|
|
74
|
-
code:
|
|
75
|
-
message:
|
|
74
|
+
code: 'not_found',
|
|
75
|
+
message: 'Period not found',
|
|
76
76
|
human: 'Je kan geen wijzigingen meer aanbrengen in ' + period.getStructure().name + ' omdat deze is afgesloten',
|
|
77
|
-
statusCode: 404
|
|
78
|
-
})
|
|
77
|
+
statusCode: 404,
|
|
78
|
+
});
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
let deleteUnreachable = false
|
|
82
|
-
const allowedIds: string[] = []
|
|
81
|
+
let deleteUnreachable = false;
|
|
82
|
+
const allowedIds: string[] = [];
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
// #region prevent patch category lock if no full platform access
|
|
85
85
|
const originalCategories = organizationPeriod.settings.categories;
|
|
86
86
|
|
|
87
87
|
if (await Context.auth.hasFullAccess(organization.id)) {
|
|
88
88
|
if (patch.settings) {
|
|
89
|
-
if(patch.settings.categories) {
|
|
89
|
+
if (patch.settings.categories) {
|
|
90
90
|
deleteUnreachable = true;
|
|
91
91
|
}
|
|
92
92
|
organizationPeriod.settings.patchOrPut(patch.settings);
|
|
93
93
|
}
|
|
94
|
-
}
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
95
96
|
/// Only allow editing category group ids
|
|
96
97
|
if (patch.settings) {
|
|
97
98
|
// Only allow adding groups if we have create permissions in a given category group
|
|
98
99
|
if (patch.settings.categories && !Array.isArray(patch.settings.categories)) {
|
|
99
100
|
for (const pp of patch.settings.categories.getPatches()) {
|
|
100
|
-
const category = organizationPeriod.settings.categories.find(c => c.id === pp.id)
|
|
101
|
+
const category = organizationPeriod.settings.categories.find(c => c.id === pp.id);
|
|
101
102
|
if (!category) {
|
|
102
103
|
// Fail silently
|
|
103
|
-
continue
|
|
104
|
+
continue;
|
|
104
105
|
}
|
|
105
|
-
|
|
106
|
+
|
|
106
107
|
if (!await Context.auth.canCreateGroupInCategory(organization.id, category)) {
|
|
107
|
-
throw Context.auth.error('Je hebt geen toegangsrechten om groepen toe te voegen in deze categorie')
|
|
108
|
+
throw Context.auth.error('Je hebt geen toegangsrechten om groepen toe te voegen in deze categorie');
|
|
108
109
|
}
|
|
109
|
-
|
|
110
|
+
|
|
110
111
|
// Only process puts
|
|
111
|
-
const ids = pp.groupIds.getPuts().map(p => p.put)
|
|
112
|
-
allowedIds.push(...ids)
|
|
113
|
-
category.groupIds.push(...ids)
|
|
112
|
+
const ids = pp.groupIds.getPuts().map(p => p.put);
|
|
113
|
+
allowedIds.push(...ids);
|
|
114
|
+
category.groupIds.push(...ids);
|
|
114
115
|
}
|
|
115
|
-
|
|
116
|
+
|
|
116
117
|
if (allowedIds.length > 0) {
|
|
117
|
-
deleteUnreachable = true
|
|
118
|
+
deleteUnreachable = true;
|
|
118
119
|
}
|
|
119
120
|
}
|
|
120
121
|
}
|
|
121
122
|
}
|
|
122
123
|
|
|
123
|
-
|
|
124
|
-
if(!Context.auth.hasPlatformFullAccess()) {
|
|
124
|
+
// #region handle locked categories
|
|
125
|
+
if (!Context.auth.hasPlatformFullAccess()) {
|
|
125
126
|
const categoriesAfterPatch = organizationPeriod.settings.categories;
|
|
126
127
|
|
|
127
|
-
for(const categoryBefore of originalCategories) {
|
|
128
|
+
for (const categoryBefore of originalCategories) {
|
|
128
129
|
const locked = categoryBefore.settings.locked;
|
|
129
130
|
|
|
130
|
-
if(locked) {
|
|
131
|
+
if (locked) {
|
|
131
132
|
// todo: use existing function, now a category could still be deleted if the category is moved to another category and that catetory is deleted
|
|
132
133
|
const categoryId = categoryBefore.id;
|
|
133
134
|
const refCountBefore = originalCategories.filter(c => c.categoryIds.includes(categoryId)).length;
|
|
134
135
|
const refCountAfter = categoriesAfterPatch.filter(c => c.categoryIds.includes(categoryId)).length;
|
|
135
136
|
const isDeleted = refCountAfter < refCountBefore;
|
|
136
137
|
|
|
137
|
-
if(isDeleted) {
|
|
138
|
-
throw Context.auth.error('Je hebt geen toegangsrechten om deze vergrendelde categorie te verwijderen.')
|
|
138
|
+
if (isDeleted) {
|
|
139
|
+
throw Context.auth.error('Je hebt geen toegangsrechten om deze vergrendelde categorie te verwijderen.');
|
|
139
140
|
}
|
|
140
141
|
}
|
|
141
142
|
|
|
142
143
|
const categoryAfter = categoriesAfterPatch.find(c => c.id === categoryBefore.id);
|
|
143
|
-
|
|
144
|
-
if(!categoryAfter) {
|
|
145
|
-
if(locked) {
|
|
146
|
-
throw Context.auth.error('Je hebt geen toegangsrechten om deze vergrendelde categorie te verwijderen.')
|
|
144
|
+
|
|
145
|
+
if (!categoryAfter) {
|
|
146
|
+
if (locked) {
|
|
147
|
+
throw Context.auth.error('Je hebt geen toegangsrechten om deze vergrendelde categorie te verwijderen.');
|
|
147
148
|
}
|
|
148
|
-
}
|
|
149
|
-
|
|
149
|
+
}
|
|
150
|
+
else if (locked !== categoryAfter.settings.locked) {
|
|
151
|
+
throw Context.auth.error('Je hebt geen toegangsrechten om deze categorie te vergrendelen of ontgrendelen.');
|
|
150
152
|
}
|
|
151
153
|
|
|
152
|
-
if(!locked || !categoryAfter) {
|
|
154
|
+
if (!locked || !categoryAfter) {
|
|
153
155
|
continue;
|
|
154
156
|
}
|
|
155
157
|
|
|
156
158
|
const settingsBefore = categoryBefore.settings;
|
|
157
159
|
const settingsAfter = categoryAfter.settings;
|
|
158
160
|
|
|
159
|
-
if(settingsBefore.name !== settingsAfter.name) {
|
|
160
|
-
throw Context.auth.error('Je hebt geen toegangsrechten de naam van deze vergrendelde categorie te wijzigen.')
|
|
161
|
+
if (settingsBefore.name !== settingsAfter.name) {
|
|
162
|
+
throw Context.auth.error('Je hebt geen toegangsrechten de naam van deze vergrendelde categorie te wijzigen.');
|
|
161
163
|
}
|
|
162
164
|
}
|
|
163
165
|
}
|
|
164
|
-
|
|
166
|
+
// #endregion
|
|
165
167
|
|
|
166
168
|
await organizationPeriod.save();
|
|
167
169
|
|
|
168
170
|
// Check changes to groups
|
|
169
|
-
const deleteGroups = patch.groups.getDeletes()
|
|
171
|
+
const deleteGroups = patch.groups.getDeletes();
|
|
170
172
|
if (deleteGroups.length > 0) {
|
|
171
173
|
for (const id of deleteGroups) {
|
|
172
|
-
await PatchOrganizationRegistrationPeriodsEndpoint.deleteGroup(id)
|
|
173
|
-
deleteUnreachable = true
|
|
174
|
+
await PatchOrganizationRegistrationPeriodsEndpoint.deleteGroup(id);
|
|
175
|
+
deleteUnreachable = true;
|
|
174
176
|
}
|
|
175
177
|
}
|
|
176
178
|
|
|
177
179
|
for (const groupPut of patch.groups.getPuts()) {
|
|
178
|
-
await PatchOrganizationRegistrationPeriodsEndpoint.createGroup(groupPut.put, organization.id, period, {allowedIds})
|
|
179
|
-
deleteUnreachable = true
|
|
180
|
+
await PatchOrganizationRegistrationPeriodsEndpoint.createGroup(groupPut.put, organization.id, period, { allowedIds });
|
|
181
|
+
deleteUnreachable = true;
|
|
180
182
|
}
|
|
181
183
|
|
|
182
184
|
for (const struct of patch.groups.getPatches()) {
|
|
183
|
-
await PatchOrganizationRegistrationPeriodsEndpoint.patchGroup(struct, period)
|
|
185
|
+
await PatchOrganizationRegistrationPeriodsEndpoint.patchGroup(struct, period);
|
|
184
186
|
}
|
|
185
187
|
|
|
186
|
-
|
|
187
188
|
if (deleteUnreachable) {
|
|
188
|
-
const groups = await Group.getAll(organization.id, organizationPeriod.periodId)
|
|
189
|
+
const groups = await Group.getAll(organization.id, organizationPeriod.periodId);
|
|
189
190
|
|
|
190
191
|
// Delete unreachable categories first
|
|
191
192
|
await organizationPeriod.cleanCategories(groups);
|
|
192
|
-
await Group.deleteUnreachable(organization.id, organizationPeriod, groups)
|
|
193
|
+
await Group.deleteUnreachable(organization.id, organizationPeriod, groups);
|
|
193
194
|
}
|
|
194
195
|
|
|
195
196
|
periods.push(organizationPeriod);
|
|
@@ -200,22 +201,22 @@ export class PatchOrganizationRegistrationPeriodsEndpoint extends Endpoint<Param
|
|
|
200
201
|
);
|
|
201
202
|
}
|
|
202
203
|
|
|
203
|
-
static async validateDefaultGroupId(id: string|null): Promise<string|null> {
|
|
204
|
+
static async validateDefaultGroupId(id: string | null): Promise<string | null> {
|
|
204
205
|
if (id === null) {
|
|
205
206
|
return id;
|
|
206
207
|
}
|
|
207
|
-
const platform = await Platform.getSharedStruct()
|
|
208
|
+
const platform = await Platform.getSharedStruct();
|
|
208
209
|
|
|
209
210
|
if (platform.config.defaultAgeGroups.find(g => g.id === id)) {
|
|
210
211
|
return id;
|
|
211
212
|
}
|
|
212
213
|
|
|
213
214
|
throw new SimpleError({
|
|
214
|
-
code:
|
|
215
|
-
message:
|
|
216
|
-
human:
|
|
217
|
-
statusCode: 400
|
|
218
|
-
})
|
|
215
|
+
code: 'invalid_default_age_group',
|
|
216
|
+
message: 'Invalid default age group',
|
|
217
|
+
human: 'De standaard leeftijdsgroep is ongeldig',
|
|
218
|
+
statusCode: 400,
|
|
219
|
+
});
|
|
219
220
|
}
|
|
220
221
|
|
|
221
222
|
static async createOrganizationPeriod(organization: Organization, struct: OrganizationRegistrationPeriodStruct) {
|
|
@@ -223,10 +224,10 @@ export class PatchOrganizationRegistrationPeriodsEndpoint extends Endpoint<Param
|
|
|
223
224
|
|
|
224
225
|
if (!period || period.locked) {
|
|
225
226
|
throw new SimpleError({
|
|
226
|
-
code:
|
|
227
|
-
message:
|
|
228
|
-
statusCode: 404
|
|
229
|
-
})
|
|
227
|
+
code: 'not_found',
|
|
228
|
+
message: 'Period not found',
|
|
229
|
+
statusCode: 404,
|
|
230
|
+
});
|
|
230
231
|
}
|
|
231
232
|
|
|
232
233
|
const organizationPeriod = new OrganizationRegistrationPeriod();
|
|
@@ -237,75 +238,75 @@ export class PatchOrganizationRegistrationPeriodsEndpoint extends Endpoint<Param
|
|
|
237
238
|
await organizationPeriod.save();
|
|
238
239
|
|
|
239
240
|
for (const s of struct.groups) {
|
|
240
|
-
await PatchOrganizationRegistrationPeriodsEndpoint.createGroup(s, organization.id, period)
|
|
241
|
+
await PatchOrganizationRegistrationPeriodsEndpoint.createGroup(s, organization.id, period);
|
|
241
242
|
}
|
|
242
|
-
const groups = await Group.getAll(organization.id, organizationPeriod.periodId)
|
|
243
|
+
const groups = await Group.getAll(organization.id, organizationPeriod.periodId);
|
|
243
244
|
|
|
244
245
|
// Delete unreachable categories first
|
|
245
246
|
await organizationPeriod.cleanCategories(groups);
|
|
246
|
-
await Group.deleteUnreachable(organization.id, organizationPeriod, groups)
|
|
247
|
+
await Group.deleteUnreachable(organization.id, organizationPeriod, groups);
|
|
247
248
|
|
|
248
|
-
return organizationPeriod
|
|
249
|
+
return organizationPeriod;
|
|
249
250
|
}
|
|
250
251
|
|
|
251
252
|
static async deleteGroup(id: string) {
|
|
252
|
-
const model = await Group.getByID(id)
|
|
253
|
+
const model = await Group.getByID(id);
|
|
253
254
|
if (!model || !await Context.auth.canAccessGroup(model, PermissionLevel.Full)) {
|
|
254
|
-
throw Context.auth.error('Je hebt geen toegangsrechten om deze groep te verwijderen')
|
|
255
|
+
throw Context.auth.error('Je hebt geen toegangsrechten om deze groep te verwijderen');
|
|
255
256
|
}
|
|
256
257
|
|
|
257
|
-
model.deletedAt = new Date()
|
|
258
|
-
await model.save()
|
|
259
|
-
Member.updateMembershipsForGroupId(id)
|
|
258
|
+
model.deletedAt = new Date();
|
|
259
|
+
await model.save();
|
|
260
|
+
Member.updateMembershipsForGroupId(id);
|
|
260
261
|
}
|
|
261
262
|
|
|
262
263
|
static async patchGroup(struct: AutoEncoderPatchType<GroupStruct>, period?: RegistrationPeriod | null) {
|
|
263
|
-
const model = await Group.getByID(struct.id)
|
|
264
|
+
const model = await Group.getByID(struct.id);
|
|
264
265
|
|
|
265
266
|
if (!model || !await Context.auth.canAccessGroup(model, PermissionLevel.Full)) {
|
|
266
|
-
throw Context.auth.error('Je hebt geen toegangsrechten om deze groep te wijzigen')
|
|
267
|
+
throw Context.auth.error('Je hebt geen toegangsrechten om deze groep te wijzigen');
|
|
267
268
|
}
|
|
268
269
|
|
|
269
270
|
if (struct.settings) {
|
|
270
|
-
struct.settings.period = undefined // Not allowed to patch manually
|
|
271
|
-
model.settings.patchOrPut(struct.settings)
|
|
271
|
+
struct.settings.period = undefined; // Not allowed to patch manually
|
|
272
|
+
model.settings.patchOrPut(struct.settings);
|
|
272
273
|
}
|
|
273
274
|
|
|
274
275
|
if (struct.status) {
|
|
275
|
-
model.status = struct.status
|
|
276
|
+
model.status = struct.status;
|
|
276
277
|
}
|
|
277
|
-
|
|
278
|
+
|
|
278
279
|
if (struct.privateSettings) {
|
|
279
|
-
model.privateSettings.patchOrPut(struct.privateSettings)
|
|
280
|
+
model.privateSettings.patchOrPut(struct.privateSettings);
|
|
280
281
|
|
|
281
282
|
if (!await Context.auth.canAccessGroup(model, PermissionLevel.Full)) {
|
|
282
283
|
throw new SimpleError({
|
|
283
|
-
code:
|
|
284
|
-
message:
|
|
285
|
-
human:
|
|
286
|
-
})
|
|
284
|
+
code: 'missing_permissions',
|
|
285
|
+
message: 'You cannot restrict your own permissions',
|
|
286
|
+
human: 'Je kan je eigen volledige toegang tot deze inschrijvingsgroep niet verwijderen. Vraag aan een hoofdbeheerder om jouw toegang te verwijderen.',
|
|
287
|
+
});
|
|
287
288
|
}
|
|
288
289
|
}
|
|
289
290
|
|
|
290
291
|
if (struct.cycle !== undefined) {
|
|
291
|
-
model.cycle = struct.cycle
|
|
292
|
+
model.cycle = struct.cycle;
|
|
292
293
|
}
|
|
293
294
|
|
|
294
295
|
if (struct.deletedAt !== undefined) {
|
|
295
|
-
model.deletedAt = struct.deletedAt
|
|
296
|
+
model.deletedAt = struct.deletedAt;
|
|
296
297
|
}
|
|
297
298
|
|
|
298
299
|
if (struct.defaultAgeGroupId !== undefined) {
|
|
299
|
-
model.defaultAgeGroupId = await this.validateDefaultGroupId(struct.defaultAgeGroupId)
|
|
300
|
+
model.defaultAgeGroupId = await this.validateDefaultGroupId(struct.defaultAgeGroupId);
|
|
300
301
|
}
|
|
301
302
|
|
|
302
303
|
if (!period && !model.settings.period) {
|
|
303
|
-
period = await RegistrationPeriod.getByID(model.periodId)
|
|
304
|
+
period = await RegistrationPeriod.getByID(model.periodId);
|
|
304
305
|
}
|
|
305
306
|
|
|
306
307
|
if (period) {
|
|
307
|
-
model.periodId = period.id
|
|
308
|
-
model.settings.period = period.getBaseStructure()
|
|
308
|
+
model.periodId = period.id;
|
|
309
|
+
model.settings.period = period.getBaseStructure();
|
|
309
310
|
}
|
|
310
311
|
|
|
311
312
|
const patch = struct;
|
|
@@ -317,34 +318,35 @@ export class PatchOrganizationRegistrationPeriodsEndpoint extends Endpoint<Param
|
|
|
317
318
|
// await PatchOrganizationRegistrationPeriodsEndpoint.deleteGroup(model.waitingListId)
|
|
318
319
|
model.waitingListId = null;
|
|
319
320
|
}
|
|
320
|
-
|
|
321
|
-
|
|
321
|
+
}
|
|
322
|
+
else if (patch.waitingList.isPatch()) {
|
|
322
323
|
if (!model.waitingListId) {
|
|
323
324
|
throw new SimpleError({
|
|
324
325
|
code: 'invalid_field',
|
|
325
326
|
field: 'waitingList',
|
|
326
|
-
message: 'Cannot patch waiting list before it is created'
|
|
327
|
-
})
|
|
327
|
+
message: 'Cannot patch waiting list before it is created',
|
|
328
|
+
});
|
|
328
329
|
}
|
|
329
|
-
patch.waitingList.id = model.waitingListId
|
|
330
|
-
patch.waitingList.type = GroupType.WaitingList
|
|
331
|
-
await PatchOrganizationRegistrationPeriodsEndpoint.patchGroup(patch.waitingList, period)
|
|
332
|
-
}
|
|
330
|
+
patch.waitingList.id = model.waitingListId;
|
|
331
|
+
patch.waitingList.type = GroupType.WaitingList;
|
|
332
|
+
await PatchOrganizationRegistrationPeriodsEndpoint.patchGroup(patch.waitingList, period);
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
333
335
|
if (model.waitingListId) {
|
|
334
336
|
// for now don't delete, as waiting lists can be shared between multiple groups
|
|
335
337
|
// await PatchOrganizationRegistrationPeriodsEndpoint.deleteGroup(model.waitingListId)
|
|
336
338
|
model.waitingListId = null;
|
|
337
339
|
}
|
|
338
|
-
patch.waitingList.type = GroupType.WaitingList
|
|
340
|
+
patch.waitingList.type = GroupType.WaitingList;
|
|
339
341
|
|
|
340
|
-
const existing = await Group.getByID(patch.waitingList.id)
|
|
342
|
+
const existing = await Group.getByID(patch.waitingList.id);
|
|
341
343
|
if (existing) {
|
|
342
344
|
if (existing.organizationId !== model.organizationId) {
|
|
343
345
|
throw new SimpleError({
|
|
344
346
|
code: 'invalid_field',
|
|
345
347
|
field: 'waitingList',
|
|
346
|
-
message: 'Waiting list group is already used in another organization'
|
|
347
|
-
})
|
|
348
|
+
message: 'Waiting list group is already used in another organization',
|
|
349
|
+
});
|
|
348
350
|
}
|
|
349
351
|
|
|
350
352
|
if (existing.periodId !== model.periodId) {
|
|
@@ -352,111 +354,112 @@ export class PatchOrganizationRegistrationPeriodsEndpoint extends Endpoint<Param
|
|
|
352
354
|
code: 'invalid_field',
|
|
353
355
|
field: 'waitingList',
|
|
354
356
|
message: 'Waiting list group is already used in another period',
|
|
355
|
-
human: 'Een wachtlijst kan momenteel niet gedeeld worden tussen verschillende werkjaren'
|
|
356
|
-
})
|
|
357
|
+
human: 'Een wachtlijst kan momenteel niet gedeeld worden tussen verschillende werkjaren',
|
|
358
|
+
});
|
|
357
359
|
}
|
|
358
360
|
|
|
359
|
-
model.waitingListId = existing.id
|
|
360
|
-
}
|
|
361
|
-
|
|
361
|
+
model.waitingListId = existing.id;
|
|
362
|
+
}
|
|
363
|
+
else {
|
|
364
|
+
const requiredPeriod = period ?? await RegistrationPeriod.getByID(model.periodId);
|
|
362
365
|
|
|
363
366
|
if (!requiredPeriod) {
|
|
364
|
-
throw new Error('Unexpected missing period when creating waiting list')
|
|
367
|
+
throw new Error('Unexpected missing period when creating waiting list');
|
|
365
368
|
}
|
|
366
369
|
const group = await PatchOrganizationRegistrationPeriodsEndpoint.createGroup(
|
|
367
370
|
patch.waitingList,
|
|
368
371
|
model.organizationId,
|
|
369
|
-
requiredPeriod
|
|
370
|
-
)
|
|
371
|
-
model.waitingListId = group.id
|
|
372
|
+
requiredPeriod,
|
|
373
|
+
);
|
|
374
|
+
model.waitingListId = group.id;
|
|
372
375
|
}
|
|
373
376
|
}
|
|
374
377
|
}
|
|
375
378
|
|
|
376
|
-
|
|
377
|
-
await model.updateOccupancy()
|
|
379
|
+
await model.updateOccupancy();
|
|
378
380
|
await model.save();
|
|
379
381
|
|
|
380
382
|
if (struct.deletedAt !== undefined || struct.defaultAgeGroupId !== undefined) {
|
|
381
|
-
Member.updateMembershipsForGroupId(model.id)
|
|
383
|
+
Member.updateMembershipsForGroupId(model.id);
|
|
382
384
|
}
|
|
383
385
|
}
|
|
384
386
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
const allowedIds = options?.allowedIds ?? []
|
|
387
|
+
static async createGroup(struct: GroupStruct, organizationId: string, period: RegistrationPeriod, options?: { allowedIds?: string[] }): Promise<Group> {
|
|
388
|
+
const allowedIds = options?.allowedIds ?? [];
|
|
388
389
|
|
|
389
390
|
if (!await Context.auth.hasFullAccess(organizationId)) {
|
|
390
391
|
if (allowedIds.includes(struct.id)) {
|
|
391
392
|
// Ok
|
|
392
|
-
}
|
|
393
|
-
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
throw Context.auth.error('Je hebt geen toegangsrechten om groepen toe te voegen');
|
|
394
396
|
}
|
|
395
397
|
}
|
|
396
398
|
|
|
397
|
-
const user = Context.auth.user
|
|
399
|
+
const user = Context.auth.user;
|
|
398
400
|
|
|
399
|
-
const model = new Group()
|
|
400
|
-
model.id = struct.id
|
|
401
|
-
model.organizationId = organizationId
|
|
402
|
-
model.defaultAgeGroupId = await this.validateDefaultGroupId(struct.defaultAgeGroupId)
|
|
403
|
-
model.periodId = period.id
|
|
404
|
-
model.settings = struct.settings
|
|
405
|
-
model.privateSettings = struct.privateSettings ?? GroupPrivateSettings.create({})
|
|
406
|
-
model.status = struct.status
|
|
407
|
-
model.type = struct.type
|
|
408
|
-
model.settings.period = period.getBaseStructure()
|
|
401
|
+
const model = new Group();
|
|
402
|
+
model.id = struct.id;
|
|
403
|
+
model.organizationId = organizationId;
|
|
404
|
+
model.defaultAgeGroupId = await this.validateDefaultGroupId(struct.defaultAgeGroupId);
|
|
405
|
+
model.periodId = period.id;
|
|
406
|
+
model.settings = struct.settings;
|
|
407
|
+
model.privateSettings = struct.privateSettings ?? GroupPrivateSettings.create({});
|
|
408
|
+
model.status = struct.status;
|
|
409
|
+
model.type = struct.type;
|
|
410
|
+
model.settings.period = period.getBaseStructure();
|
|
409
411
|
|
|
410
412
|
if (!await Context.auth.canAccessGroup(model, PermissionLevel.Full)) {
|
|
411
413
|
// Create a temporary permission role for this user
|
|
412
|
-
const organizationPermissions = user.permissions?.organizationPermissions?.get(organizationId)
|
|
414
|
+
const organizationPermissions = user.permissions?.organizationPermissions?.get(organizationId);
|
|
413
415
|
if (!organizationPermissions) {
|
|
414
|
-
throw new Error('Unexpected missing permissions')
|
|
416
|
+
throw new Error('Unexpected missing permissions');
|
|
415
417
|
}
|
|
416
418
|
const resourcePermissions = ResourcePermissions.create({
|
|
417
419
|
resourceName: model.settings.name,
|
|
418
|
-
level: PermissionLevel.Full
|
|
419
|
-
})
|
|
420
|
-
const patch = resourcePermissions.createInsertPatch(PermissionsResourceType.Groups, model.id, organizationPermissions)
|
|
421
|
-
user.permissions!.organizationPermissions.set(organizationId, organizationPermissions.patch(patch))
|
|
422
|
-
console.log('Automatically granted author full permissions to resource', 'group', model.id, 'user', user.id, 'patch', patch.encode({version: Version}))
|
|
423
|
-
await user.save()
|
|
420
|
+
level: PermissionLevel.Full,
|
|
421
|
+
});
|
|
422
|
+
const patch = resourcePermissions.createInsertPatch(PermissionsResourceType.Groups, model.id, organizationPermissions);
|
|
423
|
+
user.permissions!.organizationPermissions.set(organizationId, organizationPermissions.patch(patch));
|
|
424
|
+
console.log('Automatically granted author full permissions to resource', 'group', model.id, 'user', user.id, 'patch', patch.encode({ version: Version }));
|
|
425
|
+
await user.save();
|
|
424
426
|
}
|
|
425
427
|
|
|
426
428
|
// Check if current user has permissions to this new group -> else fail with error
|
|
427
429
|
if (!await Context.auth.canAccessGroup(model, PermissionLevel.Full)) {
|
|
428
430
|
throw new SimpleError({
|
|
429
|
-
code:
|
|
430
|
-
message:
|
|
431
|
-
human:
|
|
432
|
-
})
|
|
431
|
+
code: 'missing_permissions',
|
|
432
|
+
message: 'You cannot restrict your own permissions',
|
|
433
|
+
human: 'Je kan geen inschrijvingsgroep maken zonder dat je zelf volledige toegang hebt tot de nieuwe groep',
|
|
434
|
+
});
|
|
433
435
|
}
|
|
434
436
|
|
|
435
437
|
if (struct.waitingList) {
|
|
436
|
-
const existing = await Group.getByID(struct.waitingList.id)
|
|
438
|
+
const existing = await Group.getByID(struct.waitingList.id);
|
|
437
439
|
if (existing) {
|
|
438
440
|
if (existing.organizationId !== model.organizationId) {
|
|
439
441
|
throw new SimpleError({
|
|
440
442
|
code: 'invalid_field',
|
|
441
443
|
field: 'waitingList',
|
|
442
|
-
message: 'Waiting list group is already used in another organization'
|
|
443
|
-
})
|
|
444
|
+
message: 'Waiting list group is already used in another organization',
|
|
445
|
+
});
|
|
444
446
|
}
|
|
445
447
|
|
|
446
|
-
model.waitingListId = existing.id
|
|
447
|
-
}
|
|
448
|
-
|
|
448
|
+
model.waitingListId = existing.id;
|
|
449
|
+
}
|
|
450
|
+
else {
|
|
451
|
+
struct.waitingList.type = GroupType.WaitingList;
|
|
449
452
|
const group = await PatchOrganizationRegistrationPeriodsEndpoint.createGroup(
|
|
450
453
|
struct.waitingList,
|
|
451
454
|
model.organizationId,
|
|
452
|
-
period
|
|
453
|
-
)
|
|
454
|
-
model.waitingListId = group.id
|
|
455
|
+
period,
|
|
456
|
+
);
|
|
457
|
+
model.waitingListId = group.id;
|
|
455
458
|
}
|
|
456
459
|
}
|
|
457
460
|
|
|
458
461
|
await model.save();
|
|
462
|
+
await model.updateOccupancy({ isNew: true }); // Force update steps
|
|
459
463
|
return model;
|
|
460
464
|
}
|
|
461
|
-
|
|
462
465
|
}
|