feat(giving): add reopen-and-edit flow + recent sessions list to offering page

This commit is contained in:
Chris Chen
2026-05-28 17:41:19 -07:00
parent a573179714
commit af21e50d9f
3 changed files with 78 additions and 6 deletions
@@ -1,6 +1,7 @@
import { Component, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { Observable } from 'rxjs';
import { GridModule } from '@progress/kendo-angular-grid';
import { InputsModule } from '@progress/kendo-angular-inputs';
import { ButtonsModule } from '@progress/kendo-angular-buttons';
@@ -13,6 +14,7 @@ import { MemberListItemDto, memberDisplayName } from '../../../members/models/me
import { MemberQuickAddDialogComponent } from '../../components/member-quick-add-dialog/member-quick-add-dialog.component';
import {
GivingCategoryDto, PaymentMethod, OfferingBufferLine, CreateOfferingSessionRequest,
OfferingSessionListItemDto, OfferingSessionDto,
} from '../../models/giving.model';
interface MemberOption { id: number; displayName: string; }
@@ -48,6 +50,9 @@ export class OfferingSessionPageComponent implements OnInit {
showQuickAdd = false;
submitting = false;
sessions: OfferingSessionListItemDto[] = [];
editingSessionId: number | null = null;
constructor(
private api: OfferingSessionApiService,
private categoryApi: GivingCategoryApiService,
@@ -60,6 +65,7 @@ export class OfferingSessionPageComponent implements OnInit {
this.entry.givingCategoryId = c[0]?.id ?? 0;
});
this.checkDate();
this.loadSessions();
}
get systemTotal(): number { return this.buffer.reduce((s, l) => s + (l.amount || 0), 0); }
@@ -69,6 +75,42 @@ export class OfferingSessionPageComponent implements OnInit {
this.api.checkDate(this.toIso(this.sessionDate)).subscribe(r => this.dateConflict = r.exists);
}
loadSessions(): void {
this.api.getPaged(1, 20).subscribe(r => this.sessions = r.items);
}
reopenAndEdit(s: OfferingSessionListItemDto): void {
if (s.status !== 'Submitted') return;
this.api.reopen(s.id).subscribe({
next: () => this.api.getById(s.id).subscribe(dto => this.loadIntoBuffer(dto)),
error: (err: { error?: { message?: string } }) => alert(err?.error?.message ?? 'Reopen failed.'),
});
}
private loadIntoBuffer(dto: OfferingSessionDto): void {
this.editingSessionId = dto.id;
this.sessionDate = new Date(dto.sessionDate + 'T00:00:00');
this.dateConflict = false;
this.cashTotal = dto.cashTotal;
this.checkTotal = dto.checkTotal;
this.notes = dto.notes;
this.buffer = dto.givings.map(g => ({
memberId: g.memberId, givingCategoryId: g.givingCategoryId, amount: g.amount,
paymentMethod: g.paymentMethod, checkNumber: g.checkNumber,
zelleReferenceCode: g.zelleReferenceCode, payPalTransactionId: g.payPalTransactionId,
isAnonymous: g.isAnonymous, notes: g.notes,
memberName: g.memberName, categoryName: g.categoryName,
}));
this.resetEntry();
}
cancelEdit(): void {
this.editingSessionId = null;
this.buffer = []; this.cashTotal = 0; this.checkTotal = 0; this.notes = null;
this.sessionDate = new Date();
this.checkDate();
}
onMemberFilter(term: string): void {
if (!term) { this.memberResults = []; return; }
this.memberApi.getPaged({ search: term, pageSize: 10 }).subscribe(r =>
@@ -123,7 +165,7 @@ export class OfferingSessionPageComponent implements OnInit {
}
submit(): void {
if (this.buffer.length === 0 || this.dateConflict) return;
if (this.buffer.length === 0 || (this.editingSessionId == null && this.dateConflict)) return;
this.submitting = true;
const req: CreateOfferingSessionRequest = {
sessionDate: this.toIso(this.sessionDate),
@@ -142,12 +184,18 @@ export class OfferingSessionPageComponent implements OnInit {
notes: l.notes,
})),
};
this.api.create(req).subscribe({
const obs: Observable<unknown> = this.editingSessionId != null
? this.api.replace(this.editingSessionId, req)
: this.api.create(req);
obs.subscribe({
next: () => {
this.submitting = false;
alert('Offering session submitted.');
alert(this.editingSessionId != null ? 'Offering session updated.' : 'Offering session submitted.');
this.editingSessionId = null;
this.buffer = []; this.cashTotal = 0; this.checkTotal = 0; this.notes = null;
this.sessionDate = new Date();
this.checkDate();
this.loadSessions();
},
error: (err: { error?: { message?: string } }) => {
this.submitting = false;