Skip to content

Commit c688e3f

Browse files
committed
feat: Add delete functionality for finance records with GraphQL mutation and UI integration
1 parent 6a8734b commit c688e3f

7 files changed

Lines changed: 57 additions & 7 deletions

File tree

PhantomDave.BankTracking.Api/Types/Mutations/FinanceRecordMutation.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,21 @@ public async Task<FinanceRecordType> UpdateFinanceRecord(
8484
.Build());
8585
return FinanceRecordType.FromFinanceRecord(updatedRecord);
8686
}
87+
88+
[Authorize]
89+
public async Task<bool> DeleteFinanceRecord(
90+
int id,
91+
[Service] FinanceRecordService financeRecordService)
92+
{
93+
var deletedRecord = await financeRecordService.DeleteFinanceRecordAsync(id);
94+
if (!deletedRecord)
95+
{
96+
throw new GraphQLException(
97+
ErrorBuilder.New()
98+
.SetMessage("Failed to delete finance record. Please check the provided data.")
99+
.SetCode("BAD_USER_INPUT")
100+
.Build());
101+
}
102+
return deletedRecord;
103+
}
87104
}

frontend/schema.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ type FinanceRecordType {
7171
type Mutation {
7272
createAccount(email: String!, password: String!): AccountType!
7373
createFinanceRecord(newRecord: FinanceRecordInput!): FinanceRecordType!
74+
deleteFinanceRecord(id: Int!): Boolean!
7475
login(email: String!, password: String!): AuthPayload!
7576
loginAccount(email: String!, password: String!): AccountType
7677
updateFinanceRecord(amount: Decimal, currency: String, date: DateTime, description: String, id: Int!, isRecurring: Boolean, name: String, recurrenceEndDate: DateTime, recurrenceFrequency: RecurrenceFrequency): FinanceRecordType!
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
<h1>Your Account Balance</h1>
22
<p>
3-
Your current balance is: <strong>{{ balance() | currency }}</strong>
3+
Your current balance is: <strong>{{ balance() | currency: defaultCurrency }}</strong>
44
</p>
55
<p>
66
Total Recurring Expenses:
7-
<strong>{{ totalRecurringExpenses() | currency }}</strong>
7+
<strong>{{ totalRecurringExpenses() | currency: defaultCurrency }}</strong>
88
</p>
99
<p>
1010
Predicted balance at the end of the month:
11-
<strong>{{ endOfMonthPrediction() | currency }}</strong>
11+
<strong>{{ endOfMonthPrediction() | currency: defaultCurrency }}</strong>
1212
</p>
1313
<p>
1414
Average daily expense this month:
15-
<strong>{{ averageDailyExpense() | currency }}</strong>
15+
<strong>{{ averageDailyExpense() | currency: defaultCurrency }}</strong>
1616
</p>
1717
<p>
1818
Average daily income this month:
19-
<strong>{{ averageDailyIncome() | currency }}</strong>
19+
<strong>{{ averageDailyIncome() | currency: defaultCurrency }}</strong>
2020
</p>
2121
<p>Last updated on: {{ lastUpdated() | date: 'short' }}</p>

frontend/src/app/balance/balance-component/balance-component.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ export class BalanceComponent implements OnInit {
1414
private readonly records = signal<readonly FinanceRecord[]>(
1515
this.financeRecordService.financeRecords(),
1616
);
17+
18+
readonly defaultCurrency = 'EUR';
19+
1720
readonly balance = computed(() => {
1821
const records = this.records();
1922
const total = records.reduce((sum, record) => sum + record.amount, 0);

frontend/src/app/components/tracking/monthly-recap-component/monthly-recap-component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ class MonthlyRecapComponent implements OnInit {
8181
});
8282
}
8383

84-
onDeleteClicked(record: FinanceRecord) {
85-
throw new Error('Method not implemented.');
84+
async onDeleteClicked(record: FinanceRecord) {
85+
await this.financeRecordService.deleteFinanceRecordAsync(record.id!);
8686
}
8787
onEditClicked(record: FinanceRecord) {
8888
const dialogRef = this.dialog.open(AddEntry, {

frontend/src/app/models/finance-record/finance-record-service.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { inject, Injectable, Signal, signal } from '@angular/core';
22
import { firstValueFrom, tap } from 'rxjs';
33
import {
44
CreateFinanceRecordGQL,
5+
DeleteFinanceRecordGQL,
56
GetFinanceRecordsGQL,
67
RecurrenceFrequency,
78
UpdateFinanceRecordGQL,
@@ -15,6 +16,7 @@ export class FinanceRecordService {
1516
private readonly createFinanceRecordGQL = inject(CreateFinanceRecordGQL);
1617
private readonly getFinanceRecordsGQL = inject(GetFinanceRecordsGQL);
1718
private readonly updateFinanceRecordGQL = inject(UpdateFinanceRecordGQL);
19+
private readonly deleteFinanceRecordGQL = inject(DeleteFinanceRecordGQL);
1820

1921
private readonly _selectedFinanceRecord = signal<FinanceRecord | null>(null);
2022
readonly selectedFinanceRecord: Signal<FinanceRecord | null> =
@@ -137,6 +139,30 @@ export class FinanceRecordService {
137139
}
138140
}
139141

142+
async deleteFinanceRecordAsync(id: number): Promise<void> {
143+
this._loading.set(true);
144+
this._error.set(null);
145+
146+
try {
147+
const result = await firstValueFrom(
148+
this.deleteFinanceRecordGQL.mutate({
149+
variables: {
150+
id,
151+
},
152+
}),
153+
);
154+
155+
if (result?.data?.deleteFinanceRecord) {
156+
this._selectedFinanceRecord.set(null);
157+
this._financeRecords.update((records) => records.filter((record) => record.id !== id));
158+
}
159+
} catch (_error) {
160+
this._error.set('Failed to fetch finance records');
161+
} finally {
162+
this._loading.set(false);
163+
}
164+
}
165+
140166
private mapToFinanceRecord(data: {
141167
id: number;
142168
name: string;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
mutation DeleteFinanceRecord($id: Int!) {
2+
deleteFinanceRecord(id: $id)
3+
}

0 commit comments

Comments
 (0)