@stamhoofd/backend 2.85.2 → 2.85.4

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.85.2",
3
+ "version": "2.85.4",
4
4
  "main": "./dist/index.js",
5
5
  "exports": {
6
6
  ".": {
@@ -43,14 +43,14 @@
43
43
  "@simonbackx/simple-encoding": "2.22.0",
44
44
  "@simonbackx/simple-endpoints": "1.20.1",
45
45
  "@simonbackx/simple-logging": "^1.0.1",
46
- "@stamhoofd/backend-i18n": "2.85.2",
47
- "@stamhoofd/backend-middleware": "2.85.2",
48
- "@stamhoofd/email": "2.85.2",
49
- "@stamhoofd/models": "2.85.2",
50
- "@stamhoofd/queues": "2.85.2",
51
- "@stamhoofd/sql": "2.85.2",
52
- "@stamhoofd/structures": "2.85.2",
53
- "@stamhoofd/utility": "2.85.2",
46
+ "@stamhoofd/backend-i18n": "2.85.4",
47
+ "@stamhoofd/backend-middleware": "2.85.4",
48
+ "@stamhoofd/email": "2.85.4",
49
+ "@stamhoofd/models": "2.85.4",
50
+ "@stamhoofd/queues": "2.85.4",
51
+ "@stamhoofd/sql": "2.85.4",
52
+ "@stamhoofd/structures": "2.85.4",
53
+ "@stamhoofd/utility": "2.85.4",
54
54
  "archiver": "^7.0.1",
55
55
  "axios": "1.6.8",
56
56
  "cookie": "^0.5.0",
@@ -69,5 +69,5 @@
69
69
  "publishConfig": {
70
70
  "access": "public"
71
71
  },
72
- "gitHead": "f709a6f3d90b3adb61d90522373b1dffebf9e8a0"
72
+ "gitHead": "ecceacc395d167a6761f1425e77cfc06a31fe8a9"
73
73
  }
@@ -17,6 +17,7 @@ import { SetupStepUpdater } from '../../../helpers/SetupStepUpdater';
17
17
  import { PlatformMembershipService } from '../../../services/PlatformMembershipService';
18
18
  import { RegistrationService } from '../../../services/RegistrationService';
19
19
  import { shouldCheckIfMemberIsDuplicateForPatch } from './shouldCheckIfMemberIsDuplicate';
20
+ import { MemberNumberService } from '../../../services/MemberNumberService';
20
21
 
21
22
  type Params = Record<string, never>;
22
23
  type Query = undefined;
@@ -534,6 +535,17 @@ export class PatchOrganizationMembersEndpoint extends Endpoint<Params, Query, Bo
534
535
  // Save if okay
535
536
  await membership.save();
536
537
 
538
+ if (member.details.memberNumber === null) {
539
+ try {
540
+ await MemberNumberService.assignMemberNumber(member, membership);
541
+ }
542
+ catch (error) {
543
+ console.error(`Failed to assign member number for id ${member.id}: ${error.message}`);
544
+ // If the assignment of the member number fails the membership is not created but the member is registered
545
+ continue;
546
+ }
547
+ }
548
+
537
549
  updateMembershipMemberIds.add(member.id);
538
550
  }
539
551
 
@@ -0,0 +1,22 @@
1
+ import { Migration } from '@simonbackx/simple-database';
2
+ import { Organization } from '@stamhoofd/models';
3
+
4
+ export async function startRecordsConfigurationMigration() {
5
+ for await (const organization of Organization.select().all()) {
6
+ await organization.save();
7
+ }
8
+ }
9
+
10
+ export default new Migration(async () => {
11
+ if (STAMHOOFD.environment === 'test') {
12
+ console.log('skipped in tests');
13
+ return;
14
+ }
15
+
16
+ if (STAMHOOFD.platformName.toLowerCase() !== 'stamhoofd') {
17
+ console.log('skipped for platform (only runs for Stamhoofd): ' + STAMHOOFD.platformName);
18
+ return;
19
+ }
20
+
21
+ await startRecordsConfigurationMigration();
22
+ });
@@ -182,29 +182,14 @@ export const BalanceItemService = {
182
182
 
183
183
  async markPaid(balanceItem: BalanceItem, payment: Payment | null, organization: Organization) {
184
184
  await this.markDue(balanceItem);
185
+ let shouldMarkUpdated = true;
185
186
 
186
- if (balanceItem.paidAt) {
187
- // Already ran side effects
188
- // If we for example deleted a related order or registration - and we still have the balance item, mark it as paid again, we don't want to reactivate the order or registration
189
- await this.markUpdated(balanceItem, payment, organization);
190
- return;
191
- }
192
-
193
- // It is possible this balance item was earlier paid
194
- // and later the regigstration / order has been canceled and it became a negative balance item - which as some point has been reembursed and marked as 'paid'
195
- // in that case, we should be careful not to mark the registration as valid again
196
-
197
- // If registration
198
- if (balanceItem.registrationId) {
199
- if (balanceItem.type === BalanceItemType.Registration) {
200
- await RegistrationService.markValid(balanceItem.registrationId);
201
- }
202
- }
203
-
204
- // If order
187
+ // For orders, we should always call markPaid on the order - it is safe to call this multiple times
188
+ // we need to call it multiple times, in case the order was previously marked unpaid, and then paid again - then we'll need to recreate the tickets
205
189
  if (balanceItem.orderId) {
206
190
  const order = await Order.getByID(balanceItem.orderId);
207
191
  if (order) {
192
+ shouldMarkUpdated = false;
208
193
  await order.markPaid(payment, organization);
209
194
 
210
195
  // Save number in balance description
@@ -219,6 +204,26 @@ export const BalanceItemService = {
219
204
  }
220
205
  }
221
206
 
207
+ if (balanceItem.paidAt) {
208
+ // Already ran side effects
209
+ // If we for example deleted a related order or registration - and we still have the balance item, mark it as paid again, we don't want to reactivate the order or registration
210
+ if (shouldMarkUpdated) {
211
+ await this.markUpdated(balanceItem, payment, organization);
212
+ }
213
+ return;
214
+ }
215
+
216
+ // It is possible this balance item was earlier paid
217
+ // and later the regigstration / order has been canceled and it became a negative balance item - which as some point has been reembursed and marked as 'paid'
218
+ // in that case, we should be careful not to mark the registration as valid again
219
+
220
+ // If registration
221
+ if (balanceItem.registrationId) {
222
+ if (balanceItem.type === BalanceItemType.Registration) {
223
+ await RegistrationService.markValid(balanceItem.registrationId);
224
+ }
225
+ }
226
+
222
227
  balanceItem.paidAt = new Date();
223
228
  await balanceItem.save();
224
229
  },
@@ -280,6 +280,18 @@ export class PlatformMembershipService {
280
280
  // Check if already have the same membership
281
281
  // if that is the case, we'll keep that one and update the price + dates if the organization matches the cheapest/earliest membership
282
282
  let didFind: MemberPlatformMembership | null = null;
283
+
284
+ // First, try to find any undeletable membership - use this as the priority one and delete all others that can be deleted
285
+ // Check if we do have the same membership for a different organization that cannot be deleted (locked)
286
+ // This is to prevent creating duplicate memberships
287
+ for (const m of activeMemberships) {
288
+ if (m.membershipTypeId === cheapestMembership.membership.id && m.locked) {
289
+ didFind = m;
290
+ break;
291
+ }
292
+ }
293
+
294
+ // Then update all memberships from the same organization for the selected registration date range
283
295
  for (const m of activeMemberships) {
284
296
  if (m.membershipTypeId === cheapestMembership.membership.id && m.organizationId === cheapestMembership.registration.organizationId) {
285
297
  if (!m.locked) {
@@ -295,12 +307,14 @@ export class PlatformMembershipService {
295
307
  }
296
308
  await m.save();
297
309
  }
298
- didFind = m;
299
- break;
310
+
311
+ if (!didFind) {
312
+ didFind = m;
313
+ }
300
314
  }
301
315
  }
302
316
 
303
- // Delete all other generated memberships that are not the cheapest one
317
+ // Delete all other generated memberships that are not the chosen one
304
318
  for (const m of activeMemberships) {
305
319
  if (m.id !== didFind?.id) {
306
320
  if (!m.locked && (m.generated || m.membershipTypeId === cheapestMembership.membership.id)) {
@@ -327,6 +341,7 @@ export class PlatformMembershipService {
327
341
  }
328
342
  }
329
343
 
344
+ // We already have a membership, don't create a new one
330
345
  if (didFind) {
331
346
  continue;
332
347
  }