@stamhoofd/backend 2.111.0 → 2.113.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/LICENSE.md +32 -0
  2. package/package.json +14 -11
  3. package/src/boot.ts +1 -0
  4. package/src/email-recipient-loaders/documents.ts +66 -0
  5. package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.test.ts +701 -4
  6. package/src/endpoints/global/members/PatchOrganizationMembersEndpoint.ts +21 -10
  7. package/src/endpoints/global/registration/PatchUserMembersEndpoint.test.ts +661 -4
  8. package/src/endpoints/global/registration/PatchUserMembersEndpoint.ts +17 -6
  9. package/src/endpoints/global/registration/RegisterMembersEndpoint.test.ts +291 -8
  10. package/src/endpoints/global/registration/RegisterMembersEndpoint.ts +24 -0
  11. package/src/endpoints/organization/dashboard/invoices/GetInvoicesCountEndpoint.ts +43 -0
  12. package/src/endpoints/organization/dashboard/invoices/GetInvoicesEndpoint.ts +219 -0
  13. package/src/endpoints/organization/dashboard/payments/PatchBalanceItemsEndpoint.ts +2 -2
  14. package/src/endpoints/organization/dashboard/payments/PatchPaymentsEndpoint.ts +73 -7
  15. package/src/endpoints/organization/dashboard/webshops/PatchWebshopOrdersEndpoint.ts +6 -4
  16. package/src/endpoints/organization/shared/GetUitpasNumberDetailsEndpoint.ts +72 -0
  17. package/src/endpoints/organization/webshops/PlaceOrderEndpoint.ts +10 -7
  18. package/src/endpoints/organization/webshops/RetrieveUitpasSocialTariffPriceEndpoint.ts +3 -2
  19. package/src/excel-loaders/members.ts +28 -28
  20. package/src/helpers/AdminPermissionChecker.ts +35 -11
  21. package/src/helpers/AuthenticatedStructures.ts +92 -66
  22. package/src/helpers/Context.ts +1 -1
  23. package/src/helpers/StripeHelper.ts +11 -1
  24. package/src/helpers/StripePayoutChecker.ts +7 -0
  25. package/src/helpers/UitpasTokenRepository.ts +13 -6
  26. package/src/helpers/passthroughFetch.ts +24 -0
  27. package/src/helpers/updateMemberDetailsUitpasNumber.ts +149 -0
  28. package/src/seeds/1769088653-uitpas-status.ts +127 -0
  29. package/src/seeds/data/default-email-templates.sql +2 -1
  30. package/src/services/InvoiceService.ts +2 -2
  31. package/src/services/PaymentService.ts +2 -3
  32. package/src/services/uitpas/PassholderEndpoints.ts +190 -0
  33. package/src/services/uitpas/UitpasService.ts +37 -12
  34. package/src/services/uitpas/checkUitpasNumbers.ts +16 -140
  35. package/src/services/uitpas/handleUitpasResponse.ts +89 -0
  36. package/src/sql-filters/invoiced-balance-items.ts +20 -0
  37. package/src/sql-filters/invoices.ts +122 -0
  38. package/src/sql-filters/payments.ts +11 -1
  39. package/src/sql-sorters/invoices.ts +83 -0
  40. package/src/sql-sorters/payments.ts +33 -0
  41. package/src/sql-sorters/registrations.ts +5 -1
  42. package/tests/e2e/bundle-discounts.test.ts +8 -8
  43. package/tests/e2e/tests-disable-net-connect.test.ts +5 -0
  44. package/tests/helpers/StripeMocker.ts +5 -5
  45. package/tests/helpers/UitpasApiMocker.ts +175 -0
  46. package/tests/helpers/index.ts +1 -0
  47. package/tests/helpers/resetNock.ts +7 -0
  48. package/tests/init/index.ts +1 -0
  49. package/tests/init/initPayconiq.ts +2 -2
  50. package/tests/init/initStripe.ts +1 -1
  51. package/tests/init/initUitpasApi.ts +14 -0
  52. package/tests/jest.global.setup.ts +6 -4
  53. package/tests/jest.setup.ts +12 -6
  54. package/LICENSE +0 -665
@@ -1,11 +1,12 @@
1
1
  import { Database } from '@simonbackx/simple-database';
2
2
  import { PatchableArray, PatchableArrayAutoEncoder, PatchMap } from '@simonbackx/simple-encoding';
3
3
  import { Endpoint, Request } from '@simonbackx/simple-endpoints';
4
- import { GroupFactory, MemberFactory, OrganizationFactory, OrganizationTagFactory, Platform, RegistrationFactory, Token, UserFactory } from '@stamhoofd/models';
5
- import { Address, Country, EmergencyContact, MemberDetails, MemberWithRegistrationsBlob, OrganizationMetaData, OrganizationRecordsConfiguration, Parent, PatchAnswers, PermissionLevel, Permissions, PermissionsResourceType, RecordCategory, RecordSettings, RecordTextAnswer, ResourcePermissions, ReviewTime, ReviewTimes, TranslatedString } from '@stamhoofd/structures';
4
+ import { GroupFactory, Member, MemberFactory, OrganizationFactory, OrganizationTagFactory, Platform, RegistrationFactory, Token, UserFactory } from '@stamhoofd/models';
5
+ import { Address, Country, EmergencyContact, MemberDetails, MemberWithRegistrationsBlob, OrganizationMetaData, OrganizationRecordsConfiguration, Parent, PatchAnswers, PermissionLevel, Permissions, PermissionsResourceType, RecordCategory, RecordSettings, RecordTextAnswer, ResourcePermissions, ReviewTime, ReviewTimes, TranslatedString, UitpasNumberDetails, UitpasSocialTariff, UitpasSocialTariffStatus } from '@stamhoofd/structures';
6
6
  import { STExpect, TestUtils } from '@stamhoofd/test-utils';
7
- import { testServer } from '../../../../tests/helpers/TestServer';
8
- import { PatchOrganizationMembersEndpoint } from './PatchOrganizationMembersEndpoint';
7
+ import { testServer } from '../../../../tests/helpers/TestServer.js';
8
+ import { initUitpasApi } from '../../../../tests/init/index.js';
9
+ import { PatchOrganizationMembersEndpoint } from './PatchOrganizationMembersEndpoint.js';
9
10
 
10
11
  const baseUrl = `/organization/members`;
11
12
  const endpoint = new PatchOrganizationMembersEndpoint();
@@ -2827,4 +2828,700 @@ describe('Endpoint.PatchOrganizationMembersEndpoint', () => {
2827
2828
  expect(member2.details.emergencyContacts).toEqual([expectedContact]);
2828
2829
  });
2829
2830
  });
2831
+
2832
+ describe('Member', () => {
2833
+ describe('Uitpas number', () => {
2834
+ describe('PUT', () => {
2835
+ // todo: test to check social tariff is updated correctly
2836
+
2837
+ test('Should not set socialTariff from request', async () => {
2838
+ initUitpasApi();
2839
+
2840
+ const organization = await new OrganizationFactory({ }).create();
2841
+
2842
+ const user = await new UserFactory({
2843
+ permissions: Permissions.create({ level: PermissionLevel.Full }),
2844
+ organization, // since we are in platform mode, this will only set the permissions for this organization
2845
+ }).create();
2846
+
2847
+ const token = await Token.createToken(user);
2848
+
2849
+ // patch uitpas number
2850
+ const arr: Body = new PatchableArray();
2851
+
2852
+ const member = MemberWithRegistrationsBlob.create({
2853
+ details: MemberDetails.create({
2854
+ firstName,
2855
+ lastName,
2856
+ uitpasNumberDetails: UitpasNumberDetails.create({
2857
+ // active number
2858
+ uitpasNumber: '0900011354819',
2859
+ socialTariff: UitpasSocialTariff.create({
2860
+ status: UitpasSocialTariffStatus.Active,
2861
+ endDate: new Date(2050, 0, 1),
2862
+ updatedAt: new Date(2040, 0, 1),
2863
+ }),
2864
+ }),
2865
+ }),
2866
+ });
2867
+
2868
+ arr.addPut(member);
2869
+
2870
+ const request = Request.buildJson('PATCH', baseUrl, organization.getApiHost(), arr);
2871
+ request.headers.authorization = 'Bearer ' + token.accessToken;
2872
+
2873
+ const result = await testServer.test(endpoint, request);
2874
+
2875
+ expect(result.status).toBe(200);
2876
+ expect(result.body.members.length).toBe(1);
2877
+ expect(result.body.members[0].details.uitpasNumberDetails?.socialTariff?.status).toBe(UitpasSocialTariffStatus.Active);
2878
+ expect(result.body.members[0].details.uitpasNumberDetails?.socialTariff?.endDate?.getTime()).not.toBe(new Date(2050, 0, 1).getTime());
2879
+ expect(result.body.members[0].details.uitpasNumberDetails?.socialTariff?.updatedAt?.getTime()).not.toBe(new Date(2040, 0, 1).getTime());
2880
+ });
2881
+ });
2882
+
2883
+ describe('PATCH', () => {
2884
+ test('Should update socialTariff if uitpasNumber changes', async () => {
2885
+ initUitpasApi();
2886
+
2887
+ const organization = await new OrganizationFactory({ }).create();
2888
+
2889
+ const user = await new UserFactory({
2890
+ permissions: Permissions.create({ level: PermissionLevel.Full }),
2891
+ organization, // since we are in platform mode, this will only set the permissions for this organization
2892
+ }).create();
2893
+
2894
+ const token = await Token.createToken(user);
2895
+
2896
+ // create member
2897
+ const member = await new MemberFactory({
2898
+ firstName,
2899
+ lastName,
2900
+ birthDay,
2901
+ generateData: false,
2902
+ // Give user access to this member
2903
+ user,
2904
+ details: MemberDetails.create({
2905
+ uitpasNumberDetails: UitpasNumberDetails.create({
2906
+ // expired
2907
+ uitpasNumber: '0900000095902',
2908
+ socialTariff: UitpasSocialTariff.create({
2909
+ status: UitpasSocialTariffStatus.None,
2910
+ updatedAt: new Date(2030, 0, 1),
2911
+ }),
2912
+ }),
2913
+ }),
2914
+ }).create();
2915
+
2916
+ // patch uitpas number
2917
+ const arr: Body = new PatchableArray();
2918
+
2919
+ arr.addPatch(MemberWithRegistrationsBlob.patch({
2920
+ id: member.id,
2921
+ details: MemberDetails.patch({
2922
+ uitpasNumberDetails: UitpasNumberDetails.patch({
2923
+ // active
2924
+ uitpasNumber: '0900011354819',
2925
+ }),
2926
+ }),
2927
+ }));
2928
+
2929
+ const request = Request.buildJson('PATCH', baseUrl, organization.getApiHost(), arr);
2930
+ request.headers.authorization = 'Bearer ' + token.accessToken;
2931
+
2932
+ const result = await testServer.test(endpoint, request);
2933
+
2934
+ expect(result.status).toBe(200);
2935
+ expect(result.body.members.length).toBe(1);
2936
+ expect(result.body.members[0].details.uitpasNumberDetails?.uitpasNumber).toEqual('0900011354819');
2937
+ expect(result.body.members[0].details.uitpasNumberDetails?.socialTariff?.status).toEqual(UitpasSocialTariffStatus.Active);
2938
+ expect(result.body.members[0].details.uitpasNumberDetails?.socialTariff?.updatedAt.getTime()).not.toEqual(new Date(2030, 0, 1).getTime());
2939
+ expect(result.body.members[0].details.uitpasNumberDetails?.socialTariff?.endDate).toBeDate();
2940
+ });
2941
+
2942
+ test('Should throw if invalid uitpas number', async () => {
2943
+ initUitpasApi();
2944
+
2945
+ const organization = await new OrganizationFactory({ }).create();
2946
+
2947
+ const user = await new UserFactory({
2948
+ permissions: Permissions.create({ level: PermissionLevel.Full }),
2949
+ organization, // since we are in platform mode, this will only set the permissions for this organization
2950
+ }).create();
2951
+
2952
+ const token = await Token.createToken(user);
2953
+
2954
+ // create member
2955
+ const member = await new MemberFactory({
2956
+ firstName,
2957
+ lastName,
2958
+ birthDay,
2959
+ generateData: false,
2960
+ // Give user access to this member
2961
+ user,
2962
+ details: MemberDetails.create({
2963
+ uitpasNumberDetails: UitpasNumberDetails.create({
2964
+ // expired
2965
+ uitpasNumber: '0900000095902',
2966
+ socialTariff: UitpasSocialTariff.create({
2967
+ status: UitpasSocialTariffStatus.None,
2968
+ updatedAt: new Date(2030, 0, 1),
2969
+ }),
2970
+ }),
2971
+ }),
2972
+ }).create();
2973
+
2974
+ // patch uitpas number
2975
+ const arr: Body = new PatchableArray();
2976
+
2977
+ arr.addPatch(MemberWithRegistrationsBlob.patch({
2978
+ id: member.id,
2979
+ details: MemberDetails.patch({
2980
+ uitpasNumberDetails: UitpasNumberDetails.patch({
2981
+ // invalid (too short)
2982
+ uitpasNumber: '094',
2983
+ }),
2984
+ }),
2985
+ }));
2986
+
2987
+ const request = Request.buildJson('PATCH', baseUrl, organization.getApiHost(), arr);
2988
+ request.headers.authorization = 'Bearer ' + token.accessToken;
2989
+
2990
+ await expect(testServer.test(endpoint, request))
2991
+ .rejects
2992
+ .toThrow(STExpect.errorWithCode('invalid_uitpas_number'));
2993
+ });
2994
+
2995
+ describe('unknown uitpas number', () => {
2996
+ test('Should throw if number changed', async () => {
2997
+ initUitpasApi();
2998
+
2999
+ const organization = await new OrganizationFactory({ }).create();
3000
+
3001
+ const user = await new UserFactory({
3002
+ permissions: Permissions.create({ level: PermissionLevel.Full }),
3003
+ organization, // since we are in platform mode, this will only set the permissions for this organization
3004
+ }).create();
3005
+
3006
+ const token = await Token.createToken(user);
3007
+
3008
+ // create member
3009
+ const member = await new MemberFactory({
3010
+ firstName,
3011
+ lastName,
3012
+ birthDay,
3013
+ generateData: false,
3014
+ // Give user access to this member
3015
+ user,
3016
+ details: MemberDetails.create({
3017
+ uitpasNumberDetails: UitpasNumberDetails.create({
3018
+ // expired
3019
+ uitpasNumber: '0900000095902',
3020
+ socialTariff: UitpasSocialTariff.create({
3021
+ status: UitpasSocialTariffStatus.None,
3022
+ updatedAt: new Date(2030, 0, 1),
3023
+ }),
3024
+ }),
3025
+ }),
3026
+ }).create();
3027
+
3028
+ // patch uitpas number
3029
+ const arr: Body = new PatchableArray();
3030
+
3031
+ arr.addPatch(MemberWithRegistrationsBlob.patch({
3032
+ id: member.id,
3033
+ details: MemberDetails.patch({
3034
+ uitpasNumberDetails: UitpasNumberDetails.patch({
3035
+ // unknown number
3036
+ uitpasNumber: '0900000095999',
3037
+ }),
3038
+ }),
3039
+ }));
3040
+
3041
+ const request = Request.buildJson('PATCH', baseUrl, organization.getApiHost(), arr);
3042
+ request.headers.authorization = 'Bearer ' + token.accessToken;
3043
+
3044
+ await expect(testServer.test(endpoint, request))
3045
+ .rejects
3046
+ .toThrow(STExpect.errorWithCode('https://api.publiq.be/probs/uitpas/pass-not-found'));
3047
+ });
3048
+
3049
+ test('Should throw and set status to unknown if number did not change', async () => {
3050
+ initUitpasApi();
3051
+
3052
+ const organization = await new OrganizationFactory({ }).create();
3053
+
3054
+ const user = await new UserFactory({
3055
+ permissions: Permissions.create({ level: PermissionLevel.Full }),
3056
+ organization, // since we are in platform mode, this will only set the permissions for this organization
3057
+ }).create();
3058
+
3059
+ const token = await Token.createToken(user);
3060
+
3061
+ // create member
3062
+ const member = await new MemberFactory({
3063
+ firstName,
3064
+ lastName,
3065
+ birthDay,
3066
+ generateData: false,
3067
+ // Give user access to this member
3068
+ user,
3069
+ details: MemberDetails.create({
3070
+ uitpasNumberDetails: UitpasNumberDetails.create({
3071
+ // unknown number
3072
+ uitpasNumber: '0900000095999',
3073
+ socialTariff: UitpasSocialTariff.create({
3074
+ status: UitpasSocialTariffStatus.None,
3075
+ updatedAt: new Date(2030, 0, 1),
3076
+ }),
3077
+ }),
3078
+ }),
3079
+ }).create();
3080
+
3081
+ // patch uitpas number
3082
+ const arr: Body = new PatchableArray();
3083
+
3084
+ arr.addPatch(MemberWithRegistrationsBlob.patch({
3085
+ id: member.id,
3086
+ details: MemberDetails.patch({
3087
+ uitpasNumberDetails: UitpasNumberDetails.patch({
3088
+ // same unknown number
3089
+ uitpasNumber: '0900000095999',
3090
+ }),
3091
+ }),
3092
+ }));
3093
+
3094
+ const request = Request.buildJson('PATCH', baseUrl, organization.getApiHost(), arr);
3095
+ request.headers.authorization = 'Bearer ' + token.accessToken;
3096
+
3097
+ await expect(testServer.test(endpoint, request))
3098
+ .rejects
3099
+ .toThrow(STExpect.errorWithCode('https://api.publiq.be/probs/uitpas/pass-not-found'));
3100
+
3101
+ const updatedMember = await Member.getByID(member.id);
3102
+ expect(updatedMember!.details.uitpasNumberDetails?.uitpasNumber).toEqual('0900000095999');
3103
+ expect(updatedMember!.details.uitpasNumberDetails?.socialTariff?.status).toEqual(UitpasSocialTariffStatus.Unknown);
3104
+ expect(updatedMember!.details.uitpasNumberDetails?.socialTariff?.updatedAt.getTime()).not.toEqual(new Date(2030, 0, 1).getTime());
3105
+ expect(updatedMember!.details.uitpasNumberDetails?.socialTariff?.endDate).toBeNull();
3106
+ });
3107
+ });
3108
+
3109
+ describe('Should not set socialTariff from request', () => {
3110
+ test('Only patch social tariff', async () => {
3111
+ initUitpasApi();
3112
+
3113
+ const organization = await new OrganizationFactory({ }).create();
3114
+
3115
+ const user = await new UserFactory({
3116
+ permissions: Permissions.create({ level: PermissionLevel.Full }),
3117
+ organization, // since we are in platform mode, this will only set the permissions for this organization
3118
+ }).create();
3119
+
3120
+ const token = await Token.createToken(user);
3121
+
3122
+ // create member
3123
+ const member = await new MemberFactory({
3124
+ firstName,
3125
+ lastName,
3126
+ birthDay,
3127
+ generateData: false,
3128
+ // Give user access to this member
3129
+ user,
3130
+ details: MemberDetails.create({
3131
+ uitpasNumberDetails: UitpasNumberDetails.create({
3132
+ uitpasNumber: '0900000095902',
3133
+ socialTariff: UitpasSocialTariff.create({
3134
+ status: UitpasSocialTariffStatus.None,
3135
+ updatedAt: new Date(2000, 0, 1),
3136
+ }),
3137
+ }),
3138
+ }),
3139
+ }).create();
3140
+
3141
+ // patch uitpas number
3142
+ const arr: Body = new PatchableArray();
3143
+
3144
+ arr.addPatch(MemberWithRegistrationsBlob.patch({
3145
+ id: member.id,
3146
+ details: MemberDetails.patch({
3147
+ uitpasNumberDetails: UitpasNumberDetails.patch({
3148
+ socialTariff: UitpasSocialTariff.create({
3149
+ status: UitpasSocialTariffStatus.Active,
3150
+ endDate: new Date(2050, 0, 1),
3151
+ updatedAt: new Date(2040, 0, 1),
3152
+ }),
3153
+ }),
3154
+ }),
3155
+ }));
3156
+
3157
+ const request = Request.buildJson('PATCH', baseUrl, organization.getApiHost(), arr);
3158
+ request.headers.authorization = 'Bearer ' + token.accessToken;
3159
+
3160
+ const result = await testServer.test(endpoint, request);
3161
+
3162
+ expect(result.status).toBe(200);
3163
+ expect(result.body.members.length).toBe(1);
3164
+ expect(result.body.members[0].details.uitpasNumberDetails?.socialTariff?.status).toEqual(UitpasSocialTariffStatus.None);
3165
+ expect(result.body.members[0].details.uitpasNumberDetails?.socialTariff?.updatedAt.getTime()).toEqual(new Date(2000, 0, 1).getTime());
3166
+ expect(result.body.members[0].details.uitpasNumberDetails?.socialTariff?.endDate).toBeNull();
3167
+ });
3168
+
3169
+ test('New uitpas number', async () => {
3170
+ initUitpasApi();
3171
+
3172
+ const organization = await new OrganizationFactory({ }).create();
3173
+
3174
+ const user = await new UserFactory({
3175
+ permissions: Permissions.create({ level: PermissionLevel.Full }),
3176
+ organization, // since we are in platform mode, this will only set the permissions for this organization
3177
+ }).create();
3178
+
3179
+ const token = await Token.createToken(user);
3180
+
3181
+ // create member
3182
+ const member = await new MemberFactory({
3183
+ firstName,
3184
+ lastName,
3185
+ birthDay,
3186
+ generateData: false,
3187
+ // Give user access to this member
3188
+ user,
3189
+ details: MemberDetails.create({
3190
+ uitpasNumberDetails: UitpasNumberDetails.create({
3191
+ socialTariff: UitpasSocialTariff.create({
3192
+ status: UitpasSocialTariffStatus.None,
3193
+ updatedAt: new Date(2000, 0, 1),
3194
+ }),
3195
+ }),
3196
+ }),
3197
+ }).create();
3198
+
3199
+ // patch uitpas number
3200
+ const arr: Body = new PatchableArray();
3201
+
3202
+ arr.addPatch(MemberWithRegistrationsBlob.patch({
3203
+ id: member.id,
3204
+ details: MemberDetails.patch({
3205
+ uitpasNumberDetails: UitpasNumberDetails.patch({
3206
+ // expired
3207
+ uitpasNumber: '0900000031618',
3208
+ socialTariff: UitpasSocialTariff.create({
3209
+ status: UitpasSocialTariffStatus.Active,
3210
+ endDate: new Date(2050, 0, 1),
3211
+ updatedAt: new Date(2040, 0, 1),
3212
+ }),
3213
+ }),
3214
+ }),
3215
+ }));
3216
+
3217
+ const request = Request.buildJson('PATCH', baseUrl, organization.getApiHost(), arr);
3218
+ request.headers.authorization = 'Bearer ' + token.accessToken;
3219
+
3220
+ const result = await testServer.test(endpoint, request);
3221
+
3222
+ expect(result.status).toBe(200);
3223
+ expect(result.body.members.length).toBe(1);
3224
+ expect(result.body.members[0].details.uitpasNumberDetails?.uitpasNumber).toEqual('0900000031618');
3225
+ expect(result.body.members[0].details.uitpasNumberDetails?.socialTariff?.status).toEqual(UitpasSocialTariffStatus.Expired);
3226
+ expect(result.body.members[0].details.uitpasNumberDetails?.socialTariff?.updatedAt.getTime()).not.toEqual(new Date(2040, 0, 1).getTime());
3227
+ expect(result.body.members[0].details.uitpasNumberDetails?.socialTariff?.endDate?.getTime()).not.toEqual(new Date(2050, 0, 1).getTime());
3228
+ });
3229
+
3230
+ test('Same uitpas number', async () => {
3231
+ initUitpasApi();
3232
+
3233
+ const organization = await new OrganizationFactory({ }).create();
3234
+
3235
+ const user = await new UserFactory({
3236
+ permissions: Permissions.create({ level: PermissionLevel.Full }),
3237
+ organization, // since we are in platform mode, this will only set the permissions for this organization
3238
+ }).create();
3239
+
3240
+ const token = await Token.createToken(user);
3241
+
3242
+ // create member
3243
+ const member = await new MemberFactory({
3244
+ firstName,
3245
+ lastName,
3246
+ birthDay,
3247
+ generateData: false,
3248
+ // Give user access to this member
3249
+ user,
3250
+ details: MemberDetails.create({
3251
+ uitpasNumberDetails: UitpasNumberDetails.create({
3252
+ // expired
3253
+ uitpasNumber: '0900000031618',
3254
+ socialTariff: UitpasSocialTariff.create({
3255
+ status: UitpasSocialTariffStatus.None,
3256
+ updatedAt: new Date(2000, 0, 1),
3257
+ }),
3258
+ }),
3259
+ }),
3260
+ }).create();
3261
+
3262
+ // patch uitpas number
3263
+ const arr: Body = new PatchableArray();
3264
+
3265
+ arr.addPatch(MemberWithRegistrationsBlob.patch({
3266
+ id: member.id,
3267
+ details: MemberDetails.patch({
3268
+ uitpasNumberDetails: UitpasNumberDetails.patch({
3269
+ // expired
3270
+ uitpasNumber: '0900000031618',
3271
+ socialTariff: UitpasSocialTariff.create({
3272
+ status: UitpasSocialTariffStatus.Active,
3273
+ endDate: new Date(2050, 0, 1),
3274
+ updatedAt: new Date(2040, 0, 1),
3275
+ }),
3276
+ }),
3277
+ }),
3278
+ }));
3279
+
3280
+ const request = Request.buildJson('PATCH', baseUrl, organization.getApiHost(), arr);
3281
+ request.headers.authorization = 'Bearer ' + token.accessToken;
3282
+
3283
+ const result = await testServer.test(endpoint, request);
3284
+
3285
+ expect(result.status).toBe(200);
3286
+ expect(result.body.members.length).toBe(1);
3287
+ expect(result.body.members[0].details.uitpasNumberDetails?.uitpasNumber).toEqual('0900000031618');
3288
+ expect(result.body.members[0].details.uitpasNumberDetails?.socialTariff?.status).toEqual(UitpasSocialTariffStatus.Expired);
3289
+ expect(result.body.members[0].details.uitpasNumberDetails?.socialTariff?.updatedAt.getTime()).not.toEqual(new Date(2000, 0, 1).getTime());
3290
+ expect(result.body.members[0].details.uitpasNumberDetails?.socialTariff?.updatedAt.getTime()).not.toEqual(new Date(2040, 0, 1).getTime());
3291
+ expect(result.body.members[0].details.uitpasNumberDetails?.socialTariff?.endDate?.getTime()).not.toEqual(new Date(2050, 0, 1).getTime());
3292
+ });
3293
+ });
3294
+
3295
+ test('Should not fail if uitpas api is down and number did not change', async () => {
3296
+ const mocker = initUitpasApi();
3297
+ mocker.forceFailure();
3298
+
3299
+ const organization = await new OrganizationFactory({ }).create();
3300
+
3301
+ const user = await new UserFactory({
3302
+ permissions: Permissions.create({ level: PermissionLevel.Full }),
3303
+ organization, // since we are in platform mode, this will only set the permissions for this organization
3304
+ }).create();
3305
+
3306
+ const token = await Token.createToken(user);
3307
+
3308
+ // create member
3309
+ const member = await new MemberFactory({
3310
+ firstName,
3311
+ lastName,
3312
+ birthDay,
3313
+ generateData: false,
3314
+ // Give user access to this member
3315
+ user,
3316
+ details: MemberDetails.create({
3317
+ uitpasNumberDetails: UitpasNumberDetails.create({
3318
+ // active
3319
+ uitpasNumber: '0900011354819',
3320
+ socialTariff: UitpasSocialTariff.create({
3321
+ status: UitpasSocialTariffStatus.Active,
3322
+ updatedAt: new Date(2000, 0, 1),
3323
+ endDate: new Date(2050, 0, 1),
3324
+ }),
3325
+ }),
3326
+ }),
3327
+ }).create();
3328
+
3329
+ // patch uitpas number
3330
+ const arr: Body = new PatchableArray();
3331
+
3332
+ arr.addPatch(MemberWithRegistrationsBlob.patch({
3333
+ id: member.id,
3334
+ details: MemberDetails.patch({
3335
+ uitpasNumberDetails: UitpasNumberDetails.patch({
3336
+ // same number
3337
+ uitpasNumber: '0900011354819',
3338
+ }),
3339
+ }),
3340
+ }));
3341
+
3342
+ const request = Request.buildJson('PATCH', baseUrl, organization.getApiHost(), arr);
3343
+ request.headers.authorization = 'Bearer ' + token.accessToken;
3344
+
3345
+ const result = await testServer.test(endpoint, request);
3346
+
3347
+ expect(result.status).toBe(200);
3348
+ expect(result.body.members.length).toBe(1);
3349
+ expect(result.body.members[0].details.uitpasNumberDetails?.uitpasNumber).toEqual('0900011354819');
3350
+ expect(result.body.members[0].details.uitpasNumberDetails?.socialTariff?.status).toEqual(UitpasSocialTariffStatus.Active);
3351
+ expect(result.body.members[0].details.uitpasNumberDetails?.socialTariff?.updatedAt.getTime()).toEqual(new Date(2000, 0, 1).getTime());
3352
+ expect(result.body.members[0].details.uitpasNumberDetails?.socialTariff?.endDate?.getTime()).toEqual(new Date(2050, 0, 1).getTime());
3353
+ });
3354
+
3355
+ test('Should remove memberDetails if member details null', async () => {
3356
+ const organization = await new OrganizationFactory({ }).create();
3357
+
3358
+ const user = await new UserFactory({
3359
+ permissions: Permissions.create({ level: PermissionLevel.Full }),
3360
+ organization, // since we are in platform mode, this will only set the permissions for this organization
3361
+ }).create();
3362
+
3363
+ const token = await Token.createToken(user);
3364
+
3365
+ // create member
3366
+ const member = await new MemberFactory({
3367
+ firstName,
3368
+ lastName,
3369
+ birthDay,
3370
+ generateData: false,
3371
+ // Give user access to this member
3372
+ user,
3373
+ details: MemberDetails.create({
3374
+ uitpasNumberDetails: UitpasNumberDetails.create({
3375
+ // expired
3376
+ uitpasNumber: '0900000095902',
3377
+ socialTariff: UitpasSocialTariff.create({
3378
+ status: UitpasSocialTariffStatus.None,
3379
+ updatedAt: new Date(2030, 0, 1),
3380
+ }),
3381
+ }),
3382
+ }),
3383
+ }).create();
3384
+
3385
+ // patch uitpas number
3386
+ const arr: Body = new PatchableArray();
3387
+
3388
+ arr.addPatch(MemberWithRegistrationsBlob.patch({
3389
+ id: member.id,
3390
+ details: MemberDetails.patch({
3391
+ uitpasNumberDetails: null,
3392
+ }),
3393
+ }));
3394
+
3395
+ const request = Request.buildJson('PATCH', baseUrl, organization.getApiHost(), arr);
3396
+ request.headers.authorization = 'Bearer ' + token.accessToken;
3397
+
3398
+ const result = await testServer.test(endpoint, request);
3399
+
3400
+ expect(result.status).toBe(200);
3401
+ expect(result.body.members.length).toBe(1);
3402
+ expect(result.body.members[0].details.uitpasNumberDetails).toBeNull();
3403
+ });
3404
+
3405
+ test('Should update social tariff if uitpas review changed', async () => {
3406
+ initUitpasApi();
3407
+ const organization = await new OrganizationFactory({ }).create();
3408
+
3409
+ const user = await new UserFactory({
3410
+ permissions: Permissions.create({ level: PermissionLevel.Full }),
3411
+ organization, // since we are in platform mode, this will only set the permissions for this organization
3412
+ }).create();
3413
+
3414
+ const token = await Token.createToken(user);
3415
+
3416
+ // create member
3417
+ const member = await new MemberFactory({
3418
+ firstName,
3419
+ lastName,
3420
+ birthDay,
3421
+ generateData: false,
3422
+ // Give user access to this member
3423
+ user,
3424
+ details: MemberDetails.create({
3425
+ uitpasNumberDetails: UitpasNumberDetails.create({
3426
+ // expired (but active on last check)
3427
+ uitpasNumber: '0900000031618',
3428
+ socialTariff: UitpasSocialTariff.create({
3429
+ status: UitpasSocialTariffStatus.Active,
3430
+ updatedAt: new Date(2020, 0, 1),
3431
+ endDate: new Date(2050, 0, 1),
3432
+ }),
3433
+ }),
3434
+ }),
3435
+ }).create();
3436
+
3437
+ // set uitpas review
3438
+ member.details.reviewTimes.markReviewed('uitpasNumber', new Date(2020, 0, 1));
3439
+ await member.save();
3440
+
3441
+ // patch uitpas number review
3442
+ const arr: Body = new PatchableArray();
3443
+
3444
+ const timesClone = member.details.reviewTimes.clone();
3445
+ timesClone.markReviewed('uitpasNumber', new Date(2020, 0, 2));
3446
+
3447
+ arr.addPatch(MemberWithRegistrationsBlob.patch({
3448
+ id: member.id,
3449
+ details: MemberDetails.patch({
3450
+ reviewTimes: timesClone,
3451
+ }),
3452
+ }));
3453
+
3454
+ const request = Request.buildJson('PATCH', baseUrl, organization.getApiHost(), arr);
3455
+ request.headers.authorization = 'Bearer ' + token.accessToken;
3456
+
3457
+ const result = await testServer.test(endpoint, request);
3458
+
3459
+ expect(result.status).toBe(200);
3460
+ expect(result.body.members.length).toBe(1);
3461
+ expect(result.body.members[0].details.uitpasNumberDetails?.socialTariff?.status).toEqual(UitpasSocialTariffStatus.Expired);
3462
+ expect(result.body.members[0].details.uitpasNumberDetails?.socialTariff?.updatedAt.getTime()).not.toEqual(new Date(2020, 0, 1).getTime());
3463
+ expect(result.body.members[0].details.uitpasNumberDetails?.socialTariff?.endDate?.getTime()).not.toEqual(new Date(2050, 0, 1).getTime());
3464
+ });
3465
+
3466
+ test('Should update social tariff if uitpas review patched with same date', async () => {
3467
+ initUitpasApi();
3468
+ const organization = await new OrganizationFactory({ }).create();
3469
+
3470
+ const user = await new UserFactory({
3471
+ permissions: Permissions.create({ level: PermissionLevel.Full }),
3472
+ organization, // since we are in platform mode, this will only set the permissions for this organization
3473
+ }).create();
3474
+
3475
+ const token = await Token.createToken(user);
3476
+
3477
+ // create member
3478
+ const member = await new MemberFactory({
3479
+ firstName,
3480
+ lastName,
3481
+ birthDay,
3482
+ generateData: false,
3483
+ // Give user access to this member
3484
+ user,
3485
+ details: MemberDetails.create({
3486
+ uitpasNumberDetails: UitpasNumberDetails.create({
3487
+ // expired (but active on last check)
3488
+ uitpasNumber: '0900000031618',
3489
+ socialTariff: UitpasSocialTariff.create({
3490
+ status: UitpasSocialTariffStatus.Active,
3491
+ updatedAt: new Date(2020, 0, 1),
3492
+ endDate: new Date(2050, 0, 1),
3493
+ }),
3494
+ }),
3495
+ }),
3496
+ }).create();
3497
+
3498
+ // set uitpas review
3499
+ member.details.reviewTimes.markReviewed('uitpasNumber', new Date(2020, 0, 1));
3500
+ await member.save();
3501
+
3502
+ // patch uitpas number review
3503
+ const arr: Body = new PatchableArray();
3504
+
3505
+ const timesClone = member.details.reviewTimes.clone();
3506
+ timesClone.markReviewed('uitpasNumber', new Date(2020, 0, 1));
3507
+
3508
+ arr.addPatch(MemberWithRegistrationsBlob.patch({
3509
+ id: member.id,
3510
+ details: MemberDetails.patch({
3511
+ reviewTimes: timesClone,
3512
+ }),
3513
+ }));
3514
+
3515
+ const request = Request.buildJson('PATCH', baseUrl, organization.getApiHost(), arr);
3516
+ request.headers.authorization = 'Bearer ' + token.accessToken;
3517
+
3518
+ const result = await testServer.test(endpoint, request);
3519
+
3520
+ expect(result.status).toBe(200);
3521
+ expect(result.body.members.length).toBe(1);
3522
+ expect(result.body.members[0].details.uitpasNumberDetails?.socialTariff?.status).toEqual(UitpasSocialTariffStatus.Active);
3523
+ });
3524
+ });
3525
+ });
3526
+ });
2830
3527
  });