From 1f1575b0afd04113df6086d24d4e83c6b1cb3856 Mon Sep 17 00:00:00 2001 From: Claudio Schaad Date: Thu, 2 Jul 2026 22:04:12 +0200 Subject: [PATCH] PR M: log MatchOpenBankTransactions summary; drop dead injection Add ILogger and log the match-count summary at the end of MatchOpenBankTransactions: "Matched {Matched} of {Total} open bank transactions". Completes item 18. Also drop the ISettingsService [Inject] from Home.razor.cs that was declared but never referenced. Co-Authored-By: Claude Opus 4.7 --- IMPROVEMENT_PLAN.md | 1 + Schaad.Accounting.Services/ViewService.cs | 11 +++++++++-- Schaad.Accounting.Tests/ViewServiceTestShould.cs | 3 ++- Schaad.Accounting.UI/Components/Pages/Home.razor.cs | 5 +---- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/IMPROVEMENT_PLAN.md b/IMPROVEMENT_PLAN.md index 796a181..0e36629 100644 --- a/IMPROVEMENT_PLAN.md +++ b/IMPROVEMENT_PLAN.md @@ -108,3 +108,4 @@ Analysis and phased plan produced 2026-07-02. See conversation history for full - **PR J** — Phase 2 item 18 (second slice): thread `ILogger` through `BaseRepository` and every concrete repository so `BaseRepository.Save`'s catch block logs the failing file path and exception before rethrowing (previously the exception's origin was silently swallowed and only the stack trace at the callsite survived). Pulls `Microsoft.Extensions.Logging.Abstractions` into the Db project. `TransactionRepositoryTestShould` and `AccountRepositoryTestShould` use `NullLogger.Instance`. Remaining item 18 work (MatchOpenBankTransactions match-count summary in `ViewService`) still open. - **PR K** — Phase 5 item 27: introduce `IFxConverter.ConvertToChf(amount, fromCurrency)` and its `FxConverter` implementation. The vendor `IFxService` and the FixerIo API key are now hidden inside `FxConverter`; callers stop threading the API key through every method call. `ViewService` drops both `IFxService` and `ISettingsService` from its constructor and takes `IFxConverter` instead. Simplifies `GetAccountViewList` (no more per-call `settingsService.GetSettings()` reads) and `GetBalanceSheetView`. Two-test `FxConverterTestShould` locks in the target-currency and API-key routing. - **PR L** — Phase 2 item 10: drop the hand-rolled `Copy(target)` methods from `Account`, `BookingRule`, `BookingText`, `SubClass`, and `SplitPredefinition`; keep only a `Transaction.Clone()` for defensive-copy needs in `GetTransaction` / `ViewService.WithDisplaySign`. Every `SaveXxx` now uses `FindIndex` → in-place replace (or `Add` for new entries), moving the two "hidden" defaults (`Account.Currency = "CHF"` when unset, `Transaction.BookingDate = ValueDate` when unset) into the corresponding `SaveXxx` method where they belong. Fixes a pre-existing bug: `Transaction.Copy` never copied `RelatedParty`, so update-saves silently dropped it. Added `PreserveRelatedPartyWhenRoundTrippingTransaction` and `DefaultBookingDateToValueDateWhenBookingDateIsUnset` as regression tests. 42 tests total. +- **PR M** — Phase 2 item 18 (final slice): add `ILogger` and log a match-count summary from `MatchOpenBankTransactions` (`"Matched {Matched} of {Total} open bank transactions"`). Completes item 18 — statement imports (PR H), repository save failures (PR J), and match runs now all emit structured logs. Also removes a dead `ISettingsService` injection from `Home.razor.cs` (declared with `[Inject]` but never used anywhere in the file). diff --git a/Schaad.Accounting.Services/ViewService.cs b/Schaad.Accounting.Services/ViewService.cs index 481e0f7..2bff47a 100644 --- a/Schaad.Accounting.Services/ViewService.cs +++ b/Schaad.Accounting.Services/ViewService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Microsoft.Extensions.Logging; using Schaad.Accounting.Datasets; using Schaad.Accounting.Datasets.Reports; using Schaad.Accounting.Interfaces; @@ -17,6 +18,7 @@ namespace Schaad.Accounting.Services private readonly ISubclassRepository subclassRepository; private readonly ITransactionRepository transactionRepository; private readonly IFxConverter fxConverter; + private readonly ILogger logger; public ViewService( IAccountRepository accountRepository, @@ -24,7 +26,8 @@ namespace Schaad.Accounting.Services ITransactionRepository transactionRepository, ISubclassRepository subclassRepository, IBookingRuleRepository bookingRuleRepository, - IFxConverter fxConverter) + IFxConverter fxConverter, + ILogger logger) { this.accountRepository = accountRepository; this.bankTransactionRepository = bankTransactionRepository; @@ -32,6 +35,7 @@ namespace Schaad.Accounting.Services this.subclassRepository = subclassRepository; this.bookingRuleRepository = bookingRuleRepository; this.fxConverter = fxConverter; + this.logger = logger; } /// @@ -204,7 +208,7 @@ namespace Schaad.Accounting.Services var transactions = transactionRepository.GetTransactionList(); var accounts = accountRepository.GetAccountList(); var bookingRules = bookingRuleRepository.GetBookingRuleList(); - var bankTransactions = GetOpenBankTransactionList().OrderBy(t => t.ValueDate); + var bankTransactions = GetOpenBankTransactionList().OrderBy(t => t.ValueDate).ToList(); foreach (var bankTransaction in bankTransactions) { var trx = new Transaction(bankTransaction, accounts); @@ -213,6 +217,9 @@ namespace Schaad.Accounting.Services MatchBankTransactionBySameValueLastMonth(bankTransaction, trx, transactions); newTransactionList.Add(trx); } + + var matched = newTransactionList.Count(t => string.IsNullOrEmpty(t.Text) == false); + logger.LogInformation("Matched {Matched} of {Total} open bank transactions", matched, bankTransactions.Count); return newTransactionList; } diff --git a/Schaad.Accounting.Tests/ViewServiceTestShould.cs b/Schaad.Accounting.Tests/ViewServiceTestShould.cs index 7637ce3..46b5b79 100644 --- a/Schaad.Accounting.Tests/ViewServiceTestShould.cs +++ b/Schaad.Accounting.Tests/ViewServiceTestShould.cs @@ -1,3 +1,4 @@ +using Microsoft.Extensions.Logging.Abstractions; using NSubstitute; using Schaad.Accounting.Interfaces; using Schaad.Accounting.Models; @@ -28,7 +29,7 @@ public class ViewServiceTestShould } private ViewService BuildService() => - new(accountRepo, bankTransactionRepo, transactionRepo, subclassRepo, bookingRuleRepo, fxConverter); + new(accountRepo, bankTransactionRepo, transactionRepo, subclassRepo, bookingRuleRepo, fxConverter, NullLogger.Instance); // --- Balance math --------------------------------------------------------- diff --git a/Schaad.Accounting.UI/Components/Pages/Home.razor.cs b/Schaad.Accounting.UI/Components/Pages/Home.razor.cs index 5a7bbbd..3c2183d 100644 --- a/Schaad.Accounting.UI/Components/Pages/Home.razor.cs +++ b/Schaad.Accounting.UI/Components/Pages/Home.razor.cs @@ -21,10 +21,7 @@ public partial class Home : ComponentBase [Inject] private IDialogService dialogService { get; set; } = null!; - - [Inject] - private ISettingsService settingsService { get; set; } = null!; - + [Inject] private IFileService fileService { get; set; } = null!;