@myclub_se/data-access 3.7.1 → 3.7.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.
@@ -2027,9 +2027,11 @@ const leaderActivityFactory = (apiLeaderActivity) => new LeaderActivity(apiLeade
2027
2027
 
2028
2028
  const guestFactory = (apiGuest) => new Guest(apiGuest.id, apiGuest.name, apiGuest.comment, apiGuest.activity_invite_id);
2029
2029
 
2030
+ const searchMemberInvoiceFactory = (apiSearchMemberInvoice) => new SearchMemberInvoice(apiSearchMemberInvoice.id, apiSearchMemberInvoice.amount, apiSearchMemberInvoice.amount_paid, apiSearchMemberInvoice.balance, apiSearchMemberInvoice.club_bill_id, apiSearchMemberInvoice.date_paid, apiSearchMemberInvoice.due_date, apiSearchMemberInvoice.is_paid, apiSearchMemberInvoice.member_id);
2031
+
2030
2032
  const activityInviteFactory = (apiActivityInvite) => new ActivityInvite(apiActivityInvite.id, activityFactory(apiActivityInvite.activity), apiActivityInvite.comment, apiActivityInvite.created, apiActivityInvite.has_unpaid_invoices, apiActivityInvite.last_invite, apiActivityInvite.leader, searchMemberFactory(apiActivityInvite.member), apiActivityInvite.member_invoice_id, apiActivityInvite.next_invite, [], apiActivityInvite.payment_link, apiActivityInvite.public_payment_link, apiActivityInvite.reminded, apiActivityInvite.response_date, [], apiActivityInvite.status, apiActivityInvite.token, apiActivityInvite.unpaid_invoices && apiActivityInvite.unpaid_invoices.length ? apiActivityInvite.unpaid_invoices.map((apiUnpaidInvoice) => unpaidInvoiceFactory(apiUnpaidInvoice)) : [], apiActivityInvite.updated, (apiActivityInvite.guests && apiActivityInvite.guests.length)
2031
2033
  ? apiActivityInvite.guests.map((g) => guestFactory(g))
2032
- : []);
2034
+ : [], apiActivityInvite.member_invoice ? searchMemberInvoiceFactory(apiActivityInvite.member_invoice) : null);
2033
2035
 
2034
2036
  const activityLocationTagFactory = (apiActivityLocationTag) => {
2035
2037
  return new ActivityLocationTag(apiActivityLocationTag.id, apiActivityLocationTag.club_id, apiActivityLocationTag.section_id, apiActivityLocationTag.name, apiActivityLocationTag.location_names);
@@ -2256,8 +2258,6 @@ const searchClubFactory = (apiSearchClub) => new SearchClub(apiSearchClub.id, ap
2256
2258
 
2257
2259
  const searchMemberCardFactory = (apiSearchMemberCard) => new SearchMemberCard(apiSearchMemberCard.id, apiSearchMemberCard.name, apiSearchMemberCard.notification_count, apiSearchMemberCard.pdf_url);
2258
2260
 
2259
- const searchMemberInvoiceFactory = (apiSearchMemberInvoice) => new SearchMemberInvoice(apiSearchMemberInvoice.id, apiSearchMemberInvoice.amount, apiSearchMemberInvoice.amount_paid, apiSearchMemberInvoice.balance, apiSearchMemberInvoice.club_bill_id, apiSearchMemberInvoice.date_paid, apiSearchMemberInvoice.due_date, apiSearchMemberInvoice.is_paid, apiSearchMemberInvoice.member_id);
2260
-
2261
2261
  const searchMemberTeamThroughFactory = (apiMemberTeamThrough) => new MemberTeamThrough(apiMemberTeamThrough.id, apiMemberTeamThrough.created, apiMemberTeamThrough.date_hidden, apiMemberTeamThrough.image, apiMemberTeamThrough.leader, searchMemberFactory(apiMemberTeamThrough.member), apiMemberTeamThrough.role_id, apiMemberTeamThrough.show_on_web, apiMemberTeamThrough.updated);
2262
2262
 
2263
2263
  const swishIncidentFactory = (apiSwishIncident) => new SwishIncident(apiSwishIncident.id, apiSwishIncident.name, apiSwishIncident.swish_id, apiSwishIncident.status, apiSwishIncident.status_display, apiSwishIncident.page_status, apiSwishIncident.page_status_display, apiSwishIncident.message, apiSwishIncident.created, apiSwishIncident.updated);
@@ -2562,7 +2562,8 @@ class ActivityInvite {
2562
2562
  unpaid_invoices;
2563
2563
  updated;
2564
2564
  guests;
2565
- constructor(id, activity, comment, created, has_unpaid_invoices, last_invite, leader, member, member_invoice_id, next_invite, optional_fees, payment_link, public_payment_link, reminded, response_date, responses, status, token, unpaid_invoices, updated, guests = []) {
2565
+ member_invoice;
2566
+ constructor(id, activity, comment, created, has_unpaid_invoices, last_invite, leader, member, member_invoice_id, next_invite, optional_fees, payment_link, public_payment_link, reminded, response_date, responses, status, token, unpaid_invoices, updated, guests = [], member_invoice = null) {
2566
2567
  this.id = id;
2567
2568
  this.activity = activity;
2568
2569
  this.comment = comment;
@@ -2584,6 +2585,7 @@ class ActivityInvite {
2584
2585
  this.unpaid_invoices = unpaid_invoices;
2585
2586
  this.updated = updated;
2586
2587
  this.guests = guests;
2588
+ this.member_invoice = member_invoice;
2587
2589
  }
2588
2590
  }
2589
2591
 
@@ -5732,7 +5734,7 @@ class ActivityService {
5732
5734
  activityId
5733
5735
  });
5734
5736
  }
5735
- signUpMemberOpenActivity(memberId, activityId, comment, optionalFees, responses) {
5737
+ signUpMemberOpenActivity(memberId, activityId, comment, optionalFees, responses, guests = []) {
5736
5738
  return this.apiService
5737
5739
  .updateResource(openActivityFactory, Role.MemberAdmin, MEMBER_OPEN_ACTIVITY_RESPOND_WITH_DATA_PATH, {
5738
5740
  memberId,
@@ -5740,17 +5742,19 @@ class ActivityService {
5740
5742
  }, {
5741
5743
  comment,
5742
5744
  optional_fees: optionalFees,
5743
- responses
5745
+ responses,
5746
+ guests
5744
5747
  });
5745
5748
  }
5746
- signUpPublicOpenActivity(activityId, comment, optionalFees, responses) {
5749
+ signUpPublicOpenActivity(activityId, comment, optionalFees, responses, guests = []) {
5747
5750
  return this.apiService
5748
5751
  .updateResource(openActivityFactory, Role.Public, PUBLIC_OPEN_ACTIVITY_RESPOND_WITH_DATA_PATH, {
5749
5752
  activityId
5750
5753
  }, {
5751
5754
  comment,
5752
5755
  optional_fees: optionalFees,
5753
- responses
5756
+ responses,
5757
+ guests
5754
5758
  });
5755
5759
  }
5756
5760
  updateMemberActivity(memberId, activityInviteId, activityInvite) {
@@ -8826,61 +8830,45 @@ class ActivityEffects extends ExtraMembersMixin {
8826
8830
  }
8827
8831
  }), catchError((error) => of(updateMemberActivityAttendanceFailureAction({ payload: error })))))));
8828
8832
  updateMemberActivityInvite$ = createEffect(() => this.actions$
8829
- .pipe(ofType(updateMemberActivityInviteAction), exhaustMap(({ payload }) => this.activityService.updateMemberActivity(payload.memberId, payload.activityInvite.id, payload.activityInvite)
8830
- .pipe(mergeMap((activityInvite) => {
8831
- const guests = payload.guests ?? [];
8832
- const existingGuests = activityInvite.guests ?? [];
8833
- return reconcileMemberGuests(payload.memberId, activityInvite.id, guests, existingGuests, this.activityService)
8834
- .pipe(catchError(() => of(null)), mergeMap(() => this.activityService.getMemberActivityInvite(payload.memberId, activityInvite.id)), catchError(() => of(activityInvite)), map((updatedInvite) => updateMemberActivityInviteSuccessAction({ payload: updatedInvite })));
8835
- }), catchError((error) => of(updateMemberActivityInviteFailureAction({ payload: error })))))));
8833
+ .pipe(ofType(updateMemberActivityInviteAction), exhaustMap(({ payload }) => {
8834
+ // New guests are sent inline with the respond request so the backend can
8835
+ // include their guest fees in the invoice it creates on accept. Existing
8836
+ // guests are reconciled (update/delete) before responding, so removed
8837
+ // guests are not invoiced.
8838
+ const existingGuests = payload.activityInvite.guests ?? [];
8839
+ const reconcile$ = payload.guests
8840
+ ? reconcileMemberGuests(payload.memberId, payload.activityInvite.id, payload.guests, existingGuests, this.activityService)
8841
+ .pipe(catchError(() => of(null)))
8842
+ : of(null);
8843
+ return reconcile$.pipe(mergeMap(() => this.activityService.updateMemberActivity(payload.memberId, payload.activityInvite.id, { ...payload.activityInvite, guests: newGuests(payload.guests) })
8844
+ .pipe(map((activityInvite) => updateMemberActivityInviteSuccessAction({ payload: activityInvite })), catchError((error) => of(updateMemberActivityInviteFailureAction({ payload: error }))))));
8845
+ })));
8836
8846
  updateMemberOpenActivity$ = createEffect(() => this.actions$
8837
- .pipe(ofType(updateMemberOpenActivityAction), exhaustMap(({ payload }) => this.activityService.signUpMemberOpenActivity(payload.memberId, payload.activityId, payload.comment, payload.optional_fees, payload.responses)
8838
- .pipe(mergeMap((openActivity) => {
8839
- const guests = payload.guests ?? [];
8840
- if (guests.length === 0) {
8841
- return of(updateMemberOpenActivitySuccessAction({ payload: openActivity }));
8842
- }
8843
- // Step 2: fetch activity to find member's invite ID, then add guests
8844
- return this.activityService.getMemberActivity(payload.memberId, openActivity.id)
8845
- .pipe(mergeMap((activity) => {
8846
- const memberInvite = activity.invited_members.find(m => m.member_id === payload.memberId);
8847
- if (!memberInvite) {
8848
- return of(updateMemberOpenActivitySuccessAction({ payload: openActivity }));
8849
- }
8850
- const guestOps = guests.map(g => this.activityService.addMemberActivityGuest(payload.memberId, memberInvite.id, { name: g.name, comment: g.comment ?? undefined }));
8851
- return forkJoin(guestOps).pipe(catchError(() => of(null)), map(() => updateMemberOpenActivitySuccessAction({ payload: openActivity })));
8852
- }), catchError(() => of(updateMemberOpenActivitySuccessAction({ payload: openActivity }))));
8853
- }), catchError((error) => of(updateMemberOpenActivityFailureAction({ payload: error })))))));
8847
+ .pipe(ofType(updateMemberOpenActivityAction), exhaustMap(({ payload }) => this.activityService.signUpMemberOpenActivity(payload.memberId, payload.activityId, payload.comment, payload.optional_fees, payload.responses, newGuests(payload.guests))
8848
+ .pipe(map((openActivity) => updateMemberOpenActivitySuccessAction({ payload: openActivity })), catchError((error) => of(updateMemberOpenActivityFailureAction({ payload: error })))))));
8854
8849
  updatePublicActivityInvite$ = createEffect(() => this.actions$
8855
- .pipe(ofType(updatePublicActivityInviteAction), exhaustMap(({ payload }) => this.activityService.updatePublicActivityInvite(payload.activityInvite.id, payload.token, payload.activityInvite)
8856
- .pipe(mergeMap((activityInvite) => {
8857
- const guests = payload.guests ?? [];
8858
- const existingGuests = activityInvite.guests ?? [];
8859
- return reconcilePublicTokenGuests(activityInvite.id, payload.token, guests, existingGuests, this.activityService)
8860
- .pipe(catchError(() => of(null)), mergeMap(() => this.activityService.getPublicActivityInvite(activityInvite.id, payload.token)), catchError(() => of(activityInvite)), map((updatedInvite) => updatePublicActivityInviteSuccessAction({ payload: updatedInvite })));
8861
- }), catchError((error) => of(updatePublicActivityInviteFailureAction({ payload: error })))))));
8850
+ .pipe(ofType(updatePublicActivityInviteAction), exhaustMap(({ payload }) => {
8851
+ const existingGuests = payload.activityInvite.guests ?? [];
8852
+ const reconcile$ = payload.guests
8853
+ ? reconcilePublicTokenGuests(payload.activityInvite.id, payload.token, payload.guests, existingGuests, this.activityService)
8854
+ .pipe(catchError(() => of(null)))
8855
+ : of(null);
8856
+ return reconcile$.pipe(mergeMap(() => this.activityService.updatePublicActivityInvite(payload.activityInvite.id, payload.token, { ...payload.activityInvite, guests: newGuests(payload.guests) })
8857
+ .pipe(map((activityInvite) => updatePublicActivityInviteSuccessAction({ payload: activityInvite })), catchError((error) => of(updatePublicActivityInviteFailureAction({ payload: error }))))));
8858
+ })));
8862
8859
  updatePublicMemberActivityInvite$ = createEffect(() => this.actions$
8863
- .pipe(ofType(updatePublicMemberActivityInviteAction), exhaustMap(({ payload }) => this.activityService.updatePublicMemberActivityInvite(payload.activityInvite.id, payload.activityInvite)
8864
- .pipe(mergeMap((activityInvite) => {
8865
- const guests = payload.guests ?? [];
8866
- const existingGuests = activityInvite.guests ?? [];
8867
- return reconcilePublicTokenGuests(activityInvite.id, activityInvite.token, guests, existingGuests, this.activityService)
8868
- .pipe(catchError(() => of(null)), mergeMap(() => this.activityService.getPublicMemberActivityInvite(activityInvite.id)), catchError(() => of(activityInvite)), map((updatedInvite) => updatePublicMemberActivityInviteSuccessAction({ payload: updatedInvite })));
8869
- }), catchError((error) => of(updatePublicMemberActivityInviteFailureAction({ payload: error })))))));
8860
+ .pipe(ofType(updatePublicMemberActivityInviteAction), exhaustMap(({ payload }) => {
8861
+ const existingGuests = payload.activityInvite.guests ?? [];
8862
+ const reconcile$ = payload.guests
8863
+ ? reconcilePublicTokenGuests(payload.activityInvite.id, payload.activityInvite.token, payload.guests, existingGuests, this.activityService)
8864
+ .pipe(catchError(() => of(null)))
8865
+ : of(null);
8866
+ return reconcile$.pipe(mergeMap(() => this.activityService.updatePublicMemberActivityInvite(payload.activityInvite.id, { ...payload.activityInvite, guests: newGuests(payload.guests) })
8867
+ .pipe(map((activityInvite) => updatePublicMemberActivityInviteSuccessAction({ payload: activityInvite })), catchError((error) => of(updatePublicMemberActivityInviteFailureAction({ payload: error }))))));
8868
+ })));
8870
8869
  updatePublicMemberOpenActivity$ = createEffect(() => this.actions$
8871
- .pipe(ofType(updatePublicMemberOpenActivityAction), exhaustMap(({ payload }) => this.activityService.signUpPublicOpenActivity(payload.activityId, payload.comment, payload.optional_fees, payload.responses)
8872
- .pipe(mergeMap((openActivity) => {
8873
- const guests = payload.guests ?? [];
8874
- if (guests.length === 0) {
8875
- return of(updatePublicMemberOpenActivitySuccessAction({ payload: openActivity }));
8876
- }
8877
- return this.activityService.getPublicOpenActivityGuests(payload.activityId)
8878
- .pipe(mergeMap((existingCollection) => {
8879
- const existingGuests = existingCollection.toArray();
8880
- return reconcilePublicOpenActivityGuests(payload.activityId, guests, existingGuests, this.activityService)
8881
- .pipe(catchError(() => of(null)), map(() => updatePublicMemberOpenActivitySuccessAction({ payload: openActivity })));
8882
- }), catchError(() => of(updatePublicMemberOpenActivitySuccessAction({ payload: openActivity }))));
8883
- }), catchError((error) => of(updatePublicMemberOpenActivityFailureAction({ payload: error })))))));
8870
+ .pipe(ofType(updatePublicMemberOpenActivityAction), exhaustMap(({ payload }) => this.activityService.signUpPublicOpenActivity(payload.activityId, payload.comment, payload.optional_fees, payload.responses, newGuests(payload.guests))
8871
+ .pipe(map((openActivity) => updatePublicMemberOpenActivitySuccessAction({ payload: openActivity })), catchError((error) => of(updatePublicMemberOpenActivityFailureAction({ payload: error })))))));
8884
8872
  updateTeamActivity = createEffect(() => this.actions$
8885
8873
  .pipe(ofType(updateTeamActivityAction), exhaustMap(({ payload }) => this.activityService.updateTeamActivity(payload.teamId, payload.activity)
8886
8874
  .pipe(map((activity) => updateTeamActivitySuccessAction({ payload: activity })), catchError((error) => of(updateTeamActivityFailureAction({ payload: error })))))));
@@ -8899,11 +8887,17 @@ class ActivityEffects extends ExtraMembersMixin {
8899
8887
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: ActivityEffects, decorators: [{
8900
8888
  type: Injectable
8901
8889
  }] });
8890
+ // New guests (no id yet) are sent inline with the respond request, so the
8891
+ // backend creates them before the invoice and includes their guest fees.
8892
+ function newGuests(guests) {
8893
+ return (guests ?? []).filter(g => !g.id).map(g => ({ name: g.name, comment: g.comment ?? undefined }));
8894
+ }
8895
+ // Updates and deletes of existing guests still use the dedicated guest
8896
+ // endpoints; new guests are sent inline with the respond request instead.
8902
8897
  function reconcileMemberGuests(memberId, inviteId, desiredGuests, existingGuests, activityService) {
8903
8898
  const existingById = new Map(existingGuests.map(g => [g.id, g]));
8904
8899
  const desiredIds = new Set(desiredGuests.filter(g => g.id).map(g => g.id));
8905
8900
  const toDelete = existingGuests.filter(g => !desiredIds.has(g.id));
8906
- const toAdd = desiredGuests.filter(g => !g.id);
8907
8901
  const toUpdate = desiredGuests.filter(g => {
8908
8902
  if (!g.id)
8909
8903
  return false;
@@ -8912,7 +8906,6 @@ function reconcileMemberGuests(memberId, inviteId, desiredGuests, existingGuests
8912
8906
  });
8913
8907
  const ops = [
8914
8908
  ...toDelete.map(g => activityService.deleteMemberActivityGuest(memberId, inviteId, g.id)),
8915
- ...toAdd.map(g => activityService.addMemberActivityGuest(memberId, inviteId, { name: g.name, comment: g.comment ?? undefined })),
8916
8909
  ...toUpdate.map(g => activityService.updateMemberActivityGuest(memberId, inviteId, g.id, { name: g.name, comment: g.comment ?? undefined })),
8917
8910
  ];
8918
8911
  return ops.length > 0 ? forkJoin(ops) : of(null);
@@ -8921,7 +8914,6 @@ function reconcilePublicTokenGuests(id, token, desiredGuests, existingGuests, ac
8921
8914
  const existingById = new Map(existingGuests.map(g => [g.id, g]));
8922
8915
  const desiredIds = new Set(desiredGuests.filter(g => g.id).map(g => g.id));
8923
8916
  const toDelete = existingGuests.filter(g => !desiredIds.has(g.id));
8924
- const toAdd = desiredGuests.filter(g => !g.id);
8925
8917
  const toUpdate = desiredGuests.filter(g => {
8926
8918
  if (!g.id)
8927
8919
  return false;
@@ -8930,29 +8922,10 @@ function reconcilePublicTokenGuests(id, token, desiredGuests, existingGuests, ac
8930
8922
  });
8931
8923
  const ops = [
8932
8924
  ...toDelete.map(g => activityService.deletePublicActivityGuestByToken(id, token, g.id)),
8933
- ...toAdd.map(g => activityService.addPublicActivityGuestByToken(id, token, { name: g.name, comment: g.comment ?? undefined })),
8934
8925
  ...toUpdate.map(g => activityService.updatePublicActivityGuestByToken(id, token, g.id, { name: g.name, comment: g.comment ?? undefined })),
8935
8926
  ];
8936
8927
  return ops.length > 0 ? forkJoin(ops) : of(null);
8937
8928
  }
8938
- function reconcilePublicOpenActivityGuests(activityId, desiredGuests, existingGuests, activityService) {
8939
- const existingById = new Map(existingGuests.map(g => [g.id, g]));
8940
- const desiredIds = new Set(desiredGuests.filter(g => g.id).map(g => g.id));
8941
- const toDelete = existingGuests.filter(g => !desiredIds.has(g.id));
8942
- const toAdd = desiredGuests.filter(g => !g.id);
8943
- const toUpdate = desiredGuests.filter(g => {
8944
- if (!g.id)
8945
- return false;
8946
- const existing = existingById.get(g.id);
8947
- return existing && (existing.name !== g.name || existing.comment !== g.comment);
8948
- });
8949
- const ops = [
8950
- ...toDelete.map(g => activityService.deletePublicOpenActivityGuest(activityId, g.id)),
8951
- ...toAdd.map(g => activityService.addPublicOpenActivityGuest(activityId, { name: g.name, comment: g.comment ?? undefined })),
8952
- ...toUpdate.map(g => activityService.updatePublicOpenActivityGuest(activityId, g.id, { name: g.name, comment: g.comment ?? undefined })),
8953
- ];
8954
- return ops.length > 0 ? forkJoin(ops) : of(null);
8955
- }
8956
8929
 
8957
8930
  class AuthEffects {
8958
8931
  actions$ = inject(Actions);
@@ -11434,7 +11407,7 @@ on(updateMemberOpenActivitySuccessAction, (state, { payload }) => {
11434
11407
  if (invite.activity.id === payload.id) {
11435
11408
  const invitedMember = payload.invited_members.find((invitedMember) => invitedMember.id === invite.id);
11436
11409
  if (invitedMember) {
11437
- return new ActivityInvite(invite.id, invite.activity, invitedMember.comment, invite.created, invite.has_unpaid_invoices, invitedMember.last_invite || '', invite.leader, invite.member, invite.member_invoice_id, invitedMember.next_invite, [], invite.payment_link, invite.public_payment_link, invite.reminded, invitedMember.response_date, [], invitedMember.status, invite.token, invite.unpaid_invoices, invite.updated);
11410
+ return new ActivityInvite(invite.id, invite.activity, invitedMember.comment, invite.created, invite.has_unpaid_invoices, invitedMember.last_invite || '', invite.leader, invite.member, invite.member_invoice_id, invitedMember.next_invite, [], invite.payment_link, invite.public_payment_link, invite.reminded, invitedMember.response_date, [], invitedMember.status, invite.token, invite.unpaid_invoices, invite.updated, invite.guests, invite.member_invoice);
11438
11411
  }
11439
11412
  else {
11440
11413
  return invite;