@stamhoofd/backend 2.101.0 → 2.103.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/package.json +10 -10
- package/src/crons.ts +21 -26
- package/src/email-recipient-loaders/receivable-balances.ts +18 -11
- package/src/endpoints/global/events/PatchEventsEndpoint.ts +1 -0
- package/src/endpoints/global/members/helpers/validateGroupFilter.ts +12 -8
- package/src/endpoints/global/registration/GetRegistrationsEndpoint.ts +30 -7
- package/src/endpoints/global/registration/GetUserPayableBalanceEndpoint.ts +4 -4
- package/src/endpoints/global/registration/RegisterMembersEndpoint.test.ts +382 -31
- package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +47 -23
- package/src/endpoints/organization/dashboard/billing/GetOrganizationPayableBalanceEndpoint.ts +2 -2
- package/src/endpoints/organization/dashboard/receivable-balances/GetReceivableBalanceEndpoint.ts +60 -8
- package/src/endpoints/organization/dashboard/receivable-balances/GetReceivableBalancesEndpoint.ts +6 -1
- package/src/endpoints/organization/dashboard/registration-periods/PatchOrganizationRegistrationPeriodsEndpoint.ts +12 -9
- package/src/endpoints/organization/webshops/PlaceOrderEndpoint.ts +4 -2
- package/src/excel-loaders/receivable-balances.ts +2 -2
- package/src/helpers/AdminPermissionChecker.ts +68 -10
- package/src/helpers/AuthenticatedStructures.ts +18 -10
- package/src/helpers/MemberUserSyncer.ts +2 -2
- package/src/seeds/{1735577912-update-cached-outstanding-balance-from-items.ts → 1760702454-update-cached-outstanding-balance-from-items.ts} +2 -0
- package/src/services/BalanceItemService.ts +12 -0
- package/src/services/PaymentService.ts +3 -0
- package/src/sql-filters/base-registration-filter-compilers.ts +59 -0
- package/src/sql-filters/orders.ts +97 -1
- package/src/sql-filters/receivable-balances.ts +7 -1
- package/tests/e2e/bundle-discounts.test.ts +327 -1
- package/tests/helpers/PayconiqMocker.ts +22 -0
- package/tests/init/index.ts +1 -0
- package/tests/init/initAdmin.ts +2 -2
- package/tests/init/initPermissionRole.ts +12 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Request } from '@simonbackx/simple-endpoints';
|
|
2
2
|
import { BalanceItem, BalanceItemFactory, GroupFactory, MemberFactory, Organization, OrganizationFactory, OrganizationRegistrationPeriodFactory, Registration, RegistrationFactory, RegistrationPeriod, RegistrationPeriodFactory, Token, UserFactory } from '@stamhoofd/models';
|
|
3
|
-
import { AppliedRegistrationDiscount, BalanceItemRelation, BalanceItemRelationType, BalanceItemStatus, BalanceItemType, BooleanStatus, GroupPriceDiscount, GroupPriceDiscountType, IDRegisterCart, IDRegisterCheckout, IDRegisterItem, PaymentMethod, PermissionLevel, Permissions, ReduceablePrice } from '@stamhoofd/structures';
|
|
3
|
+
import { AccessRight, AppliedRegistrationDiscount, BalanceItemRelation, BalanceItemRelationType, BalanceItemStatus, BalanceItemType, BooleanStatus, GroupPriceDiscount, GroupPriceDiscountType, IDRegisterCart, IDRegisterCheckout, IDRegisterItem, PaymentMethod, PermissionLevel, Permissions, PermissionsResourceType, ReduceablePrice, ResourcePermissions } from '@stamhoofd/structures';
|
|
4
4
|
import { STExpect, TestUtils } from '@stamhoofd/test-utils';
|
|
5
5
|
import { RegisterMembersEndpoint } from '../../src/endpoints/global/registration/RegisterMembersEndpoint';
|
|
6
6
|
import { assertBalances } from '../assertions/assertBalances';
|
|
@@ -9,6 +9,7 @@ import { initBundleDiscount } from '../init/initBundleDiscount';
|
|
|
9
9
|
import { initStripe } from '../init/initStripe';
|
|
10
10
|
import { initAdmin } from '../init/initAdmin';
|
|
11
11
|
import { BalanceItemService } from '../../src/services/BalanceItemService';
|
|
12
|
+
import { initPermissionRole } from '../init';
|
|
12
13
|
|
|
13
14
|
const baseUrl = `/members/register`;
|
|
14
15
|
|
|
@@ -3388,10 +3389,335 @@ describe('E2E.Bundle Discounts', () => {
|
|
|
3388
3389
|
const response2 = await post(checkout, organization, adminToken);
|
|
3389
3390
|
expect(response2.body.registrations.length).toBe(1);
|
|
3390
3391
|
|
|
3392
|
+
const registration2 = response2.body.registrations[0];
|
|
3393
|
+
expect(registration2.registeredAt).not.toBeNull();
|
|
3394
|
+
expect(registration2.discounts).toMatchMap(new Map()); // note: not super reliable, as this is permission checked
|
|
3395
|
+
|
|
3396
|
+
const registration2Model = (await Registration.getByID(registration2.id))!;
|
|
3397
|
+
expect(registration2).toBeDefined();
|
|
3398
|
+
expect(registration2Model.discounts).toMatchMap(new Map());
|
|
3399
|
+
|
|
3400
|
+
// Get registration 1 again, it should now have the bundle discount applied
|
|
3401
|
+
await registration1.refresh();
|
|
3402
|
+
expect(registration1.discounts).toMatchMap(new Map([
|
|
3403
|
+
[bundleDiscount.id, AppliedRegistrationDiscount.create({
|
|
3404
|
+
name: bundleDiscount.name,
|
|
3405
|
+
amount: 5_00,
|
|
3406
|
+
})],
|
|
3407
|
+
]));
|
|
3408
|
+
|
|
3409
|
+
await assertBalances({ member: otherMember }, [
|
|
3410
|
+
{
|
|
3411
|
+
type: BalanceItemType.Registration,
|
|
3412
|
+
registrationId: registration1.id,
|
|
3413
|
+
amount: 1,
|
|
3414
|
+
price: 25_00,
|
|
3415
|
+
status: BalanceItemStatus.Due,
|
|
3416
|
+
priceOpen: 25_00,
|
|
3417
|
+
pricePending: 0,
|
|
3418
|
+
userId: user.id,
|
|
3419
|
+
},
|
|
3420
|
+
{
|
|
3421
|
+
type: BalanceItemType.RegistrationBundleDiscount,
|
|
3422
|
+
registrationId: registration1.id,
|
|
3423
|
+
amount: 1,
|
|
3424
|
+
price: -5_00,
|
|
3425
|
+
status: BalanceItemStatus.Due,
|
|
3426
|
+
priceOpen: -5_00,
|
|
3427
|
+
pricePending: 0,
|
|
3428
|
+
userId: null,
|
|
3429
|
+
},
|
|
3430
|
+
]);
|
|
3431
|
+
|
|
3432
|
+
await assertBalances({ member }, [
|
|
3433
|
+
{
|
|
3434
|
+
type: BalanceItemType.Registration,
|
|
3435
|
+
registrationId: registration2.id,
|
|
3436
|
+
amount: 1,
|
|
3437
|
+
price: 15_00,
|
|
3438
|
+
status: BalanceItemStatus.Due,
|
|
3439
|
+
priceOpen: 15_00,
|
|
3440
|
+
pricePending: 0,
|
|
3441
|
+
userId: null,
|
|
3442
|
+
},
|
|
3443
|
+
]);
|
|
3444
|
+
});
|
|
3445
|
+
|
|
3446
|
+
test('Discounts work across family members when admins register members, even when the admin does not have access to the family members', async () => {
|
|
3447
|
+
const { organizationRegistrationPeriod, organization, member, token, user } = await initData();
|
|
3448
|
+
const bundleDiscount = await initBundleDiscount({
|
|
3449
|
+
organizationRegistrationPeriod,
|
|
3450
|
+
discount: {
|
|
3451
|
+
countWholeFamily: true,
|
|
3452
|
+
discounts: [
|
|
3453
|
+
{
|
|
3454
|
+
value: 20_00,
|
|
3455
|
+
type: GroupPriceDiscountType.Percentage,
|
|
3456
|
+
},
|
|
3457
|
+
],
|
|
3458
|
+
},
|
|
3459
|
+
});
|
|
3460
|
+
|
|
3461
|
+
const groups = [
|
|
3462
|
+
await new GroupFactory({
|
|
3463
|
+
organization,
|
|
3464
|
+
price: 25_00,
|
|
3465
|
+
bundleDiscount,
|
|
3466
|
+
}).create(),
|
|
3467
|
+
await new GroupFactory({
|
|
3468
|
+
organization,
|
|
3469
|
+
price: 15_00,
|
|
3470
|
+
bundleDiscount,
|
|
3471
|
+
}).create(),
|
|
3472
|
+
];
|
|
3473
|
+
|
|
3474
|
+
// Create an unrelated group and registration so admin has access to the member
|
|
3475
|
+
const randomGroup = await new GroupFactory({
|
|
3476
|
+
organization,
|
|
3477
|
+
price: 0,
|
|
3478
|
+
}).create();
|
|
3479
|
+
|
|
3480
|
+
await new RegistrationFactory({
|
|
3481
|
+
organization,
|
|
3482
|
+
member: member,
|
|
3483
|
+
group: randomGroup,
|
|
3484
|
+
}).create();
|
|
3485
|
+
|
|
3486
|
+
// Make sure the user has financial access so we can check the responses
|
|
3487
|
+
const role = await initPermissionRole({
|
|
3488
|
+
organization,
|
|
3489
|
+
accessRights: [
|
|
3490
|
+
AccessRight.MemberReadFinancialData,
|
|
3491
|
+
],
|
|
3492
|
+
});
|
|
3493
|
+
|
|
3494
|
+
const { adminToken } = await initAdmin({
|
|
3495
|
+
organization,
|
|
3496
|
+
permissions: Permissions.create({
|
|
3497
|
+
level: PermissionLevel.None,
|
|
3498
|
+
resources: new Map([[
|
|
3499
|
+
PermissionsResourceType.Groups, new Map([
|
|
3500
|
+
[
|
|
3501
|
+
randomGroup.id, ResourcePermissions.create({
|
|
3502
|
+
level: PermissionLevel.Write,
|
|
3503
|
+
}),
|
|
3504
|
+
], [
|
|
3505
|
+
groups[1].id, ResourcePermissions.create({
|
|
3506
|
+
level: PermissionLevel.Write,
|
|
3507
|
+
}),
|
|
3508
|
+
],
|
|
3509
|
+
// No permission for group 0
|
|
3510
|
+
]),
|
|
3511
|
+
]]),
|
|
3512
|
+
roles: [role],
|
|
3513
|
+
}),
|
|
3514
|
+
});
|
|
3515
|
+
|
|
3516
|
+
const otherMember = await new MemberFactory({
|
|
3517
|
+
organization,
|
|
3518
|
+
user,
|
|
3519
|
+
}).create();
|
|
3520
|
+
|
|
3521
|
+
// First register the otherMember for group 1. No discount should be applied yet
|
|
3522
|
+
const registration1 = await new RegistrationFactory({
|
|
3523
|
+
organization,
|
|
3524
|
+
member: otherMember,
|
|
3525
|
+
group: groups[0],
|
|
3526
|
+
}).create();
|
|
3527
|
+
|
|
3528
|
+
await new BalanceItemFactory({
|
|
3529
|
+
userId: user.id,
|
|
3530
|
+
memberId: otherMember.id,
|
|
3531
|
+
organizationId: organization.id,
|
|
3532
|
+
type: BalanceItemType.Registration,
|
|
3533
|
+
amount: 1,
|
|
3534
|
+
unitPrice: 25_00,
|
|
3535
|
+
status: BalanceItemStatus.Due,
|
|
3536
|
+
registrationId: registration1.id,
|
|
3537
|
+
}).create();
|
|
3538
|
+
|
|
3539
|
+
const checkout = IDRegisterCheckout.create({
|
|
3540
|
+
cart: IDRegisterCart.create({
|
|
3541
|
+
items: [
|
|
3542
|
+
IDRegisterItem.create({
|
|
3543
|
+
groupPrice: groups[1].settings.prices[0],
|
|
3544
|
+
groupId: groups[1].id,
|
|
3545
|
+
organizationId: organization.id,
|
|
3546
|
+
memberId: member.id,
|
|
3547
|
+
}),
|
|
3548
|
+
],
|
|
3549
|
+
}),
|
|
3550
|
+
totalPrice: 15_00, // Admin does not know there should be discount
|
|
3551
|
+
asOrganizationId: organization.id,
|
|
3552
|
+
});
|
|
3553
|
+
|
|
3554
|
+
const response2 = await post(checkout, organization, adminToken);
|
|
3555
|
+
expect(response2.body.registrations.length).toBe(1);
|
|
3556
|
+
|
|
3557
|
+
const registration2 = response2.body.registrations[0];
|
|
3558
|
+
expect(registration2.registeredAt).not.toBeNull();
|
|
3559
|
+
expect(registration2.discounts).toMatchMap(new Map());
|
|
3560
|
+
|
|
3561
|
+
const registration2Model = (await Registration.getByID(registration2.id))!;
|
|
3562
|
+
expect(registration2).toBeDefined();
|
|
3563
|
+
expect(registration2Model.discounts).toMatchMap(new Map());
|
|
3564
|
+
|
|
3565
|
+
// Get registration 1 again, it should now have the bundle discount applied
|
|
3566
|
+
await registration1.refresh();
|
|
3567
|
+
expect(registration1.discounts).toMatchMap(new Map([
|
|
3568
|
+
[bundleDiscount.id, AppliedRegistrationDiscount.create({
|
|
3569
|
+
name: bundleDiscount.name,
|
|
3570
|
+
amount: 5_00,
|
|
3571
|
+
})],
|
|
3572
|
+
]));
|
|
3573
|
+
|
|
3574
|
+
await assertBalances({ member: otherMember }, [
|
|
3575
|
+
{
|
|
3576
|
+
type: BalanceItemType.Registration,
|
|
3577
|
+
registrationId: registration1.id,
|
|
3578
|
+
amount: 1,
|
|
3579
|
+
price: 25_00,
|
|
3580
|
+
status: BalanceItemStatus.Due,
|
|
3581
|
+
priceOpen: 25_00,
|
|
3582
|
+
pricePending: 0,
|
|
3583
|
+
userId: user.id,
|
|
3584
|
+
},
|
|
3585
|
+
{
|
|
3586
|
+
type: BalanceItemType.RegistrationBundleDiscount,
|
|
3587
|
+
registrationId: registration1.id,
|
|
3588
|
+
amount: 1,
|
|
3589
|
+
price: -5_00,
|
|
3590
|
+
status: BalanceItemStatus.Due,
|
|
3591
|
+
priceOpen: -5_00,
|
|
3592
|
+
pricePending: 0,
|
|
3593
|
+
userId: null,
|
|
3594
|
+
},
|
|
3595
|
+
]);
|
|
3596
|
+
|
|
3597
|
+
await assertBalances({ member }, [
|
|
3598
|
+
{
|
|
3599
|
+
type: BalanceItemType.Registration,
|
|
3600
|
+
registrationId: registration2.id,
|
|
3601
|
+
amount: 1,
|
|
3602
|
+
price: 15_00,
|
|
3603
|
+
status: BalanceItemStatus.Due,
|
|
3604
|
+
priceOpen: 15_00,
|
|
3605
|
+
pricePending: 0,
|
|
3606
|
+
userId: null,
|
|
3607
|
+
},
|
|
3608
|
+
]);
|
|
3609
|
+
});
|
|
3610
|
+
|
|
3611
|
+
test('Discounts work across family members when admins register members, even when the admin does not have access to the family members nor financial access rights', async () => {
|
|
3612
|
+
const { organizationRegistrationPeriod, organization, member, token, user } = await initData();
|
|
3613
|
+
const bundleDiscount = await initBundleDiscount({
|
|
3614
|
+
organizationRegistrationPeriod,
|
|
3615
|
+
discount: {
|
|
3616
|
+
countWholeFamily: true,
|
|
3617
|
+
discounts: [
|
|
3618
|
+
{
|
|
3619
|
+
value: 20_00,
|
|
3620
|
+
type: GroupPriceDiscountType.Percentage,
|
|
3621
|
+
},
|
|
3622
|
+
],
|
|
3623
|
+
},
|
|
3624
|
+
});
|
|
3625
|
+
|
|
3626
|
+
const groups = [
|
|
3627
|
+
await new GroupFactory({
|
|
3628
|
+
organization,
|
|
3629
|
+
price: 25_00,
|
|
3630
|
+
bundleDiscount,
|
|
3631
|
+
}).create(),
|
|
3632
|
+
await new GroupFactory({
|
|
3633
|
+
organization,
|
|
3634
|
+
price: 15_00,
|
|
3635
|
+
bundleDiscount,
|
|
3636
|
+
}).create(),
|
|
3637
|
+
];
|
|
3638
|
+
|
|
3639
|
+
// Create an unrelated group and registration so admin has access to the member
|
|
3640
|
+
const randomGroup = await new GroupFactory({
|
|
3641
|
+
organization,
|
|
3642
|
+
price: 0,
|
|
3643
|
+
}).create();
|
|
3644
|
+
|
|
3645
|
+
await new RegistrationFactory({
|
|
3646
|
+
organization,
|
|
3647
|
+
member: member,
|
|
3648
|
+
group: randomGroup,
|
|
3649
|
+
}).create();
|
|
3650
|
+
|
|
3651
|
+
const { adminToken } = await initAdmin({
|
|
3652
|
+
organization,
|
|
3653
|
+
permissions: Permissions.create({
|
|
3654
|
+
level: PermissionLevel.None,
|
|
3655
|
+
resources: new Map([[
|
|
3656
|
+
PermissionsResourceType.Groups, new Map([
|
|
3657
|
+
[
|
|
3658
|
+
randomGroup.id, ResourcePermissions.create({
|
|
3659
|
+
level: PermissionLevel.Write,
|
|
3660
|
+
}),
|
|
3661
|
+
], [
|
|
3662
|
+
groups[1].id, ResourcePermissions.create({
|
|
3663
|
+
level: PermissionLevel.Write,
|
|
3664
|
+
}),
|
|
3665
|
+
],
|
|
3666
|
+
// No permission for group 0
|
|
3667
|
+
]),
|
|
3668
|
+
]]),
|
|
3669
|
+
}),
|
|
3670
|
+
});
|
|
3671
|
+
|
|
3672
|
+
const otherMember = await new MemberFactory({
|
|
3673
|
+
organization,
|
|
3674
|
+
user,
|
|
3675
|
+
}).create();
|
|
3676
|
+
|
|
3677
|
+
// First register the otherMember for group 1. No discount should be applied yet
|
|
3678
|
+
const registration1 = await new RegistrationFactory({
|
|
3679
|
+
organization,
|
|
3680
|
+
member: otherMember,
|
|
3681
|
+
group: groups[0],
|
|
3682
|
+
}).create();
|
|
3683
|
+
|
|
3684
|
+
await new BalanceItemFactory({
|
|
3685
|
+
userId: user.id,
|
|
3686
|
+
memberId: otherMember.id,
|
|
3687
|
+
organizationId: organization.id,
|
|
3688
|
+
type: BalanceItemType.Registration,
|
|
3689
|
+
amount: 1,
|
|
3690
|
+
unitPrice: 25_00,
|
|
3691
|
+
status: BalanceItemStatus.Due,
|
|
3692
|
+
registrationId: registration1.id,
|
|
3693
|
+
}).create();
|
|
3694
|
+
|
|
3695
|
+
const checkout = IDRegisterCheckout.create({
|
|
3696
|
+
cart: IDRegisterCart.create({
|
|
3697
|
+
items: [
|
|
3698
|
+
IDRegisterItem.create({
|
|
3699
|
+
groupPrice: groups[1].settings.prices[0],
|
|
3700
|
+
groupId: groups[1].id,
|
|
3701
|
+
organizationId: organization.id,
|
|
3702
|
+
memberId: member.id,
|
|
3703
|
+
}),
|
|
3704
|
+
],
|
|
3705
|
+
}),
|
|
3706
|
+
totalPrice: 15_00, // Admin does not know there should be discount
|
|
3707
|
+
asOrganizationId: organization.id,
|
|
3708
|
+
});
|
|
3709
|
+
|
|
3710
|
+
const response2 = await post(checkout, organization, adminToken);
|
|
3711
|
+
expect(response2.body.registrations.length).toBe(1);
|
|
3712
|
+
|
|
3391
3713
|
const registration2 = response2.body.registrations[0];
|
|
3392
3714
|
expect(registration2.registeredAt).not.toBeNull();
|
|
3393
3715
|
expect(registration2.discounts).toMatchMap(new Map());
|
|
3394
3716
|
|
|
3717
|
+
const registration2Model = (await Registration.getByID(registration2.id))!;
|
|
3718
|
+
expect(registration2).toBeDefined();
|
|
3719
|
+
expect(registration2Model.discounts).toMatchMap(new Map());
|
|
3720
|
+
|
|
3395
3721
|
// Get registration 1 again, it should now have the bundle discount applied
|
|
3396
3722
|
await registration1.refresh();
|
|
3397
3723
|
expect(registration1.discounts).toMatchMap(new Map([
|
|
@@ -44,6 +44,28 @@ export class PayconiqMocker {
|
|
|
44
44
|
checkout: {
|
|
45
45
|
href: 'https://payconiq.com/pay/2/5bdb1685b93d1c000bde96f2?token=530ea8a4ec8ded7d87620c8637354022cd965b143f257f8f8cb118e7f4a22d8f&returnUrl=https%3A%2F%2Fummy.webshop%2Fcheckout%2Fsuccess',
|
|
46
46
|
},
|
|
47
|
+
qrcode: {
|
|
48
|
+
href: 'https://payconiq.com/pay/2/5bdb1685b93d1c000bde96f2?token=530ea8a4ec8ded7d87620c8637354022cd965b143f257f8f8cb118e7f4a22d8f&returnUrl=https%3A%2F%2Fummy.webshop%2Fcheckout%2Fsuccess',
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
}];
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
nock('https://merchant.api.preprod.bancontact.net')
|
|
55
|
+
.persist()
|
|
56
|
+
.post('/v3/payments')
|
|
57
|
+
.reply((uri, body) => {
|
|
58
|
+
// todo: do something smarter with the body
|
|
59
|
+
|
|
60
|
+
return [200, {
|
|
61
|
+
paymentId: uuidv4(),
|
|
62
|
+
_links: {
|
|
63
|
+
checkout: {
|
|
64
|
+
href: 'https://payconiq.com/pay/2/5bdb1685b93d1c000bde96f2?token=530ea8a4ec8ded7d87620c8637354022cd965b143f257f8f8cb118e7f4a22d8f&returnUrl=https%3A%2F%2Fummy.webshop%2Fcheckout%2Fsuccess',
|
|
65
|
+
},
|
|
66
|
+
qrcode: {
|
|
67
|
+
href: 'https://payconiq.com/pay/2/5bdb1685b93d1c000bde96f2?token=530ea8a4ec8ded7d87620c8637354022cd965b143f257f8f8cb118e7f4a22d8f&returnUrl=https%3A%2F%2Fummy.webshop%2Fcheckout%2Fsuccess',
|
|
68
|
+
},
|
|
47
69
|
},
|
|
48
70
|
}];
|
|
49
71
|
});
|
package/tests/init/index.ts
CHANGED
package/tests/init/initAdmin.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Organization, Token, UserFactory } from '@stamhoofd/models';
|
|
2
2
|
import { PermissionLevel, Permissions } from '@stamhoofd/structures';
|
|
3
3
|
|
|
4
|
-
export async function initAdmin({ organization }: { organization: Organization }) {
|
|
4
|
+
export async function initAdmin({ organization, permissions }: { organization: Organization; permissions?: Permissions }) {
|
|
5
5
|
const admin = await new UserFactory({
|
|
6
6
|
organization,
|
|
7
|
-
permissions: Permissions.create({
|
|
7
|
+
permissions: permissions ?? Permissions.create({
|
|
8
8
|
level: PermissionLevel.Full,
|
|
9
9
|
}),
|
|
10
10
|
}).create();
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Organization } from '@stamhoofd/models';
|
|
2
|
+
import { AccessRight, PermissionRoleDetailed } from '@stamhoofd/structures';
|
|
3
|
+
|
|
4
|
+
export async function initPermissionRole({ organization, accessRights }: { organization: Organization; accessRights?: AccessRight[] }): Promise<PermissionRoleDetailed> {
|
|
5
|
+
const role = PermissionRoleDetailed.create({
|
|
6
|
+
name: 'Test role',
|
|
7
|
+
accessRights,
|
|
8
|
+
});
|
|
9
|
+
organization.privateMeta.roles.push(role);
|
|
10
|
+
await organization.save();
|
|
11
|
+
return role;
|
|
12
|
+
}
|