@stamhoofd/backend 2.77.1 → 2.77.3

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stamhoofd/backend",
3
- "version": "2.77.1",
3
+ "version": "2.77.3",
4
4
  "main": "./dist/index.js",
5
5
  "exports": {
6
6
  ".": {
@@ -37,14 +37,14 @@
37
37
  "@simonbackx/simple-encoding": "2.20.0",
38
38
  "@simonbackx/simple-endpoints": "1.19.1",
39
39
  "@simonbackx/simple-logging": "^1.0.1",
40
- "@stamhoofd/backend-i18n": "2.77.1",
41
- "@stamhoofd/backend-middleware": "2.77.1",
42
- "@stamhoofd/email": "2.77.1",
43
- "@stamhoofd/models": "2.77.1",
44
- "@stamhoofd/queues": "2.77.1",
45
- "@stamhoofd/sql": "2.77.1",
46
- "@stamhoofd/structures": "2.77.1",
47
- "@stamhoofd/utility": "2.77.1",
40
+ "@stamhoofd/backend-i18n": "2.77.3",
41
+ "@stamhoofd/backend-middleware": "2.77.3",
42
+ "@stamhoofd/email": "2.77.3",
43
+ "@stamhoofd/models": "2.77.3",
44
+ "@stamhoofd/queues": "2.77.3",
45
+ "@stamhoofd/sql": "2.77.3",
46
+ "@stamhoofd/structures": "2.77.3",
47
+ "@stamhoofd/utility": "2.77.3",
48
48
  "archiver": "^7.0.1",
49
49
  "aws-sdk": "^2.885.0",
50
50
  "axios": "1.6.8",
@@ -64,5 +64,5 @@
64
64
  "publishConfig": {
65
65
  "access": "public"
66
66
  },
67
- "gitHead": "e6d9dce8ddfdfaf5380e98f3a0ffd113a3826955"
67
+ "gitHead": "73e6c9aec7a8e3feed99014f54fdae6890b346ce"
68
68
  }
@@ -492,7 +492,22 @@ export class PatchOrganizationMembersEndpoint extends Endpoint<Params, Query, Bo
492
492
  });
493
493
  }
494
494
 
495
- // Check duplicate memberships
495
+ const membership = new MemberPlatformMembership();
496
+ membership.id = put.id;
497
+ membership.memberId = member.id;
498
+ membership.membershipTypeId = put.membershipTypeId;
499
+ membership.organizationId = put.organizationId;
500
+ membership.periodId = put.periodId;
501
+
502
+ membership.startDate = put.startDate;
503
+ membership.endDate = put.endDate;
504
+ membership.expireDate = put.expireDate;
505
+ membership.locked = false;
506
+
507
+ // Correct price and dates
508
+ await membership.calculatePrice(member);
509
+
510
+ // Check duplicate memberships after correcting the dates
496
511
  const existing = await MemberPlatformMembership.select()
497
512
  .where('memberId', member.id)
498
513
  .where('membershipTypeId', put.membershipTypeId)
@@ -523,19 +538,7 @@ export class PatchOrganizationMembersEndpoint extends Endpoint<Params, Query, Bo
523
538
  });
524
539
  }
525
540
 
526
- const membership = new MemberPlatformMembership();
527
- membership.id = put.id;
528
- membership.memberId = member.id;
529
- membership.membershipTypeId = put.membershipTypeId;
530
- membership.organizationId = put.organizationId;
531
- membership.periodId = put.periodId;
532
-
533
- membership.startDate = new Date(Math.max(Date.now(), put.startDate.getTime()));
534
- membership.endDate = put.endDate;
535
- membership.expireDate = put.expireDate;
536
- membership.locked = false;
537
-
538
- await membership.calculatePrice(member);
541
+ // Save if okay
539
542
  await membership.save();
540
543
 
541
544
  updateMembershipMemberIds.add(member.id);
@@ -672,7 +675,7 @@ export class PatchOrganizationMembersEndpoint extends Endpoint<Params, Query, Bo
672
675
  }
673
676
 
674
677
  if (updateMembershipsForOrganizations.size) {
675
- QueueHandler.schedule('update-membership-prices', async () => {
678
+ QueueHandler.schedule('update-organization-membership-prices', async () => {
676
679
  for (const id of updateMembershipsForOrganizations) {
677
680
  await MembershipCharger.updatePrices(id);
678
681
  }
@@ -213,7 +213,10 @@ export class PatchPlatformEndpoint extends Endpoint<
213
213
  if (shouldUpdateMemberships) {
214
214
  if (!QueueHandler.isRunning('update-membership-prices')) {
215
215
  QueueHandler.schedule('update-membership-prices', async () => {
216
+ // Update all membership prices (required to update temporary memberships)
216
217
  await MembershipCharger.updatePrices();
218
+
219
+ // Update memberships of all members (note: this only updates non-day memberships)
217
220
  await PlatformMembershipService.updateAll();
218
221
  }).catch(console.error);
219
222
  }
@@ -138,9 +138,18 @@ export class PatchOrganizationEndpoint extends Endpoint<Params, Query, Body, Res
138
138
 
139
139
  // Apply payconiq patch
140
140
  if (request.body.privateMeta.payconiqAccounts !== undefined) {
141
+ const originalAccounts = organization.privateMeta.payconiqAccounts;
142
+
143
+ // Ignore patches of payconiq accounts which contain a placeholder key
141
144
  organization.privateMeta.payconiqAccounts = patchObject(organization.privateMeta.payconiqAccounts, cloneObject(request.body.privateMeta.payconiqAccounts as any));
142
145
 
143
146
  for (const account of organization.privateMeta.payconiqAccounts) {
147
+ if (account.apiKey === PayconiqAccount.placeholderApiKey) {
148
+ // Reset back to original
149
+ organization.privateMeta.payconiqAccounts = originalAccounts;
150
+ break;
151
+ }
152
+
144
153
  if (account.merchantId === null) {
145
154
  const payment = await PayconiqPayment.createTest(organization, account);
146
155
 
@@ -254,7 +254,7 @@ export class AuthenticatedStructures {
254
254
  result = OrganizationStruct.create({
255
255
  ...baseStruct,
256
256
  period,
257
- privateMeta: organization.privateMeta,
257
+ privateMeta: organization.privateMeta.removedPrivateKeys,
258
258
  webshops: webshopPreviews.get(organization.id)?.sort((a, b) => Sorter.byDateValue(b.createdAt, a.createdAt)),
259
259
  });
260
260
  }
@@ -164,7 +164,6 @@ export class PlatformMembershipService {
164
164
  // Every (not-locked) period can have a generated membership
165
165
  for (const period of periods) {
166
166
  const registrations = me.registrations.filter(r => r.group.periodId === period.id && r.registeredAt && !r.deactivatedAt);
167
- const now = new Date();
168
167
 
169
168
  const defaultMemberships = registrations.flatMap((r) => {
170
169
  if (!r.group.defaultAgeGroupId) {
@@ -248,12 +247,26 @@ export class PlatformMembershipService {
248
247
 
249
248
  const shouldApplyReducedPrice = me.details.shouldApplyReducedPrice;
250
249
 
250
+ // We'll by default give this member the most cheap membership it can get, and if the price is the same, the membership associated with the first registration
251
251
  const cheapestMembership = defaultMembershipsWithOrganization.sort((a, b) => {
252
252
  const tagIdsA = a.organization?.meta.tags ?? [];
253
253
  const tagIdsB = b.organization?.meta.tags ?? [];
254
- const diff = a.membership.getPrice(period.id, a.registration.startDate ?? a.registration.registeredAt ?? now, tagIdsA, shouldApplyReducedPrice)! - b.membership.getPrice(period.id, a.registration.startDate ?? a.registration.registeredAt ?? now, tagIdsB, shouldApplyReducedPrice)!;
254
+ const aPrice = a.membership.getPrice(
255
+ period.id,
256
+ a.registration.startDate ?? a.registration.registeredAt ?? a.registration.createdAt,
257
+ tagIdsA,
258
+ shouldApplyReducedPrice
259
+ ) ?? 10000000;
260
+ const bPrice = b.membership.getPrice(
261
+ period.id,
262
+ b.registration.startDate ?? b.registration.registeredAt ?? b.registration.createdAt,
263
+ tagIdsB,
264
+ shouldApplyReducedPrice
265
+ ) ?? 10000000;
266
+
267
+ const diff = aPrice - bPrice;
255
268
  if (diff === 0) {
256
- return Sorter.byDateValue(b.registration.startDate ?? b.registration.createdAt, a.registration.startDate ?? a.registration.createdAt);
269
+ return Sorter.byDateValue(b.registration.startDate ?? b.registration.registeredAt ?? b.registration.createdAt, a.registration.startDate ?? a.registration.registeredAt ?? a.registration.createdAt);
257
270
  }
258
271
  return diff;
259
272
  })[0];
@@ -264,6 +277,7 @@ export class PlatformMembershipService {
264
277
  }
265
278
 
266
279
  // Check if already have the same membership
280
+ // if that is the case, we'll keep that one and update the price + dates if the organization matches the cheapest/earliest membership
267
281
  let didFind = false;
268
282
  for (const m of activeMemberships) {
269
283
  if (m.membershipTypeId === cheapestMembership.membership.id && m.organizationId === cheapestMembership.registration.organizationId) {
@@ -303,6 +317,8 @@ export class PlatformMembershipService {
303
317
  membership.membershipTypeId = cheapestMembership.membership.id;
304
318
  membership.organizationId = cheapestMembership.registration.organizationId;
305
319
  membership.periodId = period.id;
320
+
321
+ // Note: the dates will get modified in the price calculation
306
322
  membership.startDate = periodConfig.startDate;
307
323
  membership.endDate = periodConfig.endDate;
308
324
  membership.expireDate = periodConfig.expireDate;
@@ -257,6 +257,7 @@ export const memberFilterCompilers: SQLFilterDefinitions = {
257
257
  organizationId: createSQLColumnFilterCompiler(SQL.column('member_platform_memberships', 'organizationId')),
258
258
  periodId: createSQLColumnFilterCompiler(SQL.column('member_platform_memberships', 'periodId')),
259
259
  price: createSQLColumnFilterCompiler(SQL.column('member_platform_memberships', 'price')),
260
+ priceWithoutDiscount: createSQLColumnFilterCompiler(SQL.column('member_platform_memberships', 'priceWithoutDiscount')),
260
261
  startDate: createSQLColumnFilterCompiler(SQL.column('member_platform_memberships', 'startDate')),
261
262
  endDate: createSQLColumnFilterCompiler(SQL.column('member_platform_memberships', 'endDate')),
262
263
  expireDate: createSQLColumnFilterCompiler(SQL.column('member_platform_memberships', 'expireDate')),