Skip to content

Commit ccd3e5d

Browse files
Merge pull request #9 from Alanzhoffmann/feat/mudblazor-ui
Rewrite UI in mudblazor
2 parents b372319 + 32ef11d commit ccd3e5d

43 files changed

Lines changed: 1574 additions & 391 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ jobs:
4747
run: dotnet build --no-restore --configuration Release
4848

4949
- name: Test
50-
run: dotnet test --no-build --configuration Release --results-directory ./TestResults --treenode-filter "/*/*/*/*[Category!=E2E]" --ignore-exit-code 8 -- --coverage --coverage-output-format cobertura --report-trx
50+
run: dotnet test --no-build --configuration Release --results-directory ./TestResults --treenode-filter "/*/*/*/*[Category!=E2E]" --ignore-exit-code 8 -- --coverage --coverage-output-format cobertura --coverage-settings coverage.settings.xml --report-trx
5151

5252
- name: Upload test results
5353
if: always()

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ _TeamCity*
174174
# Coverlet is a free, cross platform Code Coverage Tool
175175
coverage*.json
176176
coverage*.xml
177+
!coverage.settings.xml
177178
coverage*.info
178179

179180
# Visual Studio code coverage results

coverage.settings.xml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Configuration>
3+
<CodeCoverage>
4+
<ModulePathsExclude>
5+
<Exclude>.*Tests.*</Exclude>
6+
</ModulePathsExclude>
7+
<Sources>
8+
<Exclude>
9+
<Source>.*Migrations.*</Source>
10+
<Source>.*\.g\.cs</Source>
11+
</Exclude>
12+
</Sources>
13+
</CodeCoverage>
14+
</Configuration>

src/FinanceSplit.Api/Components/App.razor

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
77
<BasePath />
88
<ResourcePreloader />
9+
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel="stylesheet" />
10+
<link href="_content/MudBlazor/MudBlazor.min.css" rel="stylesheet" />
911
<link rel="stylesheet" href="@Assets["app.css"]" />
1012
<link rel="stylesheet" href="@Assets["FinanceSplit.Web.styles.css"]" />
1113
<ImportMap />
@@ -14,6 +16,7 @@
1416

1517
<body>
1618
<Routes @rendermode="InteractiveAuto" />
19+
<script src="_content/MudBlazor/MudBlazor.min.js"></script>
1720
<script src="@Assets["_framework/blazor.web.js"]"></script>
1821
</body>
1922

src/FinanceSplit.Api/Endpoints/TransactionEndpoints.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,24 @@ public static void MapTransactionEndpoints(this IEndpointRouteBuilder app)
5858
: Results.Created($"/api/transactions/{transaction.Id}", transaction);
5959
}
6060
);
61+
62+
group.MapPut(
63+
"/{id:guid}",
64+
async (Guid id, CreateTransactionRequest request, TransactionService service, CancellationToken ct) =>
65+
{
66+
var transaction = await service.UpdateTransactionAsync(
67+
id,
68+
request.Title,
69+
request.Amount,
70+
request.PaidById,
71+
request.SplitType,
72+
request.ParticipantIds,
73+
request.Date,
74+
ct
75+
);
76+
77+
return transaction is null ? Results.NotFound() : Results.Ok(transaction);
78+
}
79+
);
6180
}
6281
}

src/FinanceSplit.Api/FinanceSplit.Api.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
<Nullable>enable</Nullable>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<ContainerRepository>alanzhoffmann/finances-split</ContainerRepository>
7-
<ContainerUser>root</ContainerUser>
87
</PropertyGroup>
98

109
<ItemGroup>

src/FinanceSplit.Api/Program.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using FinanceSplit.Application;
55
using FinanceSplit.Data;
66
using FinanceSplit.Web.Services;
7+
using MudBlazor.Services;
78

89
var builder = WebApplication.CreateBuilder(args);
910

@@ -20,6 +21,7 @@
2021
var baseAddress = request is not null ? $"{request.Scheme}://{request.Host}" : "http://localhost";
2122
return new HttpClient { BaseAddress = new Uri(baseAddress) };
2223
});
24+
builder.Services.AddMudServices();
2325
builder.Services.AddRazorComponents().AddInteractiveServerComponents().AddInteractiveWebAssemblyComponents();
2426

2527
var app = builder.Build();

src/FinanceSplit.Application/Queries/ExpenseQueryService.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ namespace FinanceSplit.Application.Queries;
77

88
public class ExpenseQueryService(ITransactionRepository transactionRepository)
99
{
10-
private readonly ExpenseCalculator _calculator = new();
11-
1210
public async Task<MonthlyExpenseSummaryResponse> GetMonthlySummaryAsync(DateOnly month, CancellationToken ct = default)
1311
{
1412
var oneOff = await transactionRepository.GetByMonthAsync(month, ct);
@@ -20,7 +18,7 @@ public async Task<MonthlyExpenseSummaryResponse> GetMonthlySummaryAsync(DateOnly
2018
return new MonthlyExpenseSummaryResponse(Guid.Empty, month, [], new Dictionary<PersonResponse, decimal>(), []);
2119
}
2220

23-
var summary = _calculator.BuildMonthlySummary(month, allTransactions);
21+
var summary = ExpenseCalculator.BuildMonthlySummary(month, allTransactions);
2422
return summary.ToResponse();
2523
}
2624

@@ -35,7 +33,7 @@ public async Task<IReadOnlyCollection<ExpenseSettlementResponse>> GetSettlements
3533
return [];
3634
}
3735

38-
var settlements = _calculator.CalculateSettlements(month, allTransactions);
36+
var settlements = ExpenseCalculator.CalculateSettlements(month, allTransactions);
3937
return settlements.Select(s => s.ToResponse()).ToList();
4038
}
4139
}

src/FinanceSplit.Application/Services/ImportService.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,9 @@ private async Task<int> ImportTransactionsAsync(List<ImportTransaction> importTr
7777
continue;
7878
}
7979

80-
var date = new DateTime(importTx.Year, importTx.Month, 1, 0, 0, 0, DateTimeKind.Utc);
80+
// Transactions are paid from the previous month's salary, so place them in the next month
81+
var originalDate = new DateTime(importTx.Year, importTx.Month, 1, 0, 0, 0, DateTimeKind.Utc);
82+
var date = originalDate.AddMonths(1);
8183

8284
var exists = await db.Transactions.AnyAsync(t => t.Title == importTx.Name && t.Amount == importTx.Value && t.Date == date, ct);
8385

src/FinanceSplit.Application/Services/TransactionService.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,52 @@ public class TransactionService(ITransactionRepository transactionRepository, IP
5757
var transaction = await transactionRepository.GetByIdAsync(id, ct);
5858
return transaction?.ToResponse();
5959
}
60+
61+
public async Task<TransactionResponse?> UpdateTransactionAsync(
62+
Guid id,
63+
string title,
64+
decimal amount,
65+
Guid paidById,
66+
SplitType splitType,
67+
IReadOnlyList<Guid> participantIds,
68+
DateTime? date = null,
69+
CancellationToken ct = default
70+
)
71+
{
72+
var transaction = await transactionRepository.GetByIdAsync(id, ct);
73+
if (transaction is null)
74+
{
75+
return null;
76+
}
77+
78+
var paidBy = await personRepository.GetByIdAsync(paidById, ct);
79+
if (paidBy is null)
80+
{
81+
return null;
82+
}
83+
84+
var participants = new List<Person>();
85+
foreach (var pid in participantIds)
86+
{
87+
var p = await personRepository.GetByIdAsync(pid, ct);
88+
if (p is null)
89+
{
90+
return null;
91+
}
92+
93+
participants.Add(p);
94+
}
95+
96+
var splitPay = splitType switch
97+
{
98+
SplitType.None => SplitPay.CreateNoneSplit(paidBy),
99+
SplitType.Even => SplitPay.CreateEvenSplit(participants),
100+
SplitType.Ratio => SplitPay.CreateRatioSplit(participants),
101+
_ => SplitPay.CreateEvenSplit(participants),
102+
};
103+
104+
transaction.Update(title, amount, paidBy, splitPay, date);
105+
await transactionRepository.SaveChangesAsync(ct);
106+
return transaction.ToResponse();
107+
}
60108
}

0 commit comments

Comments
 (0)