From ece9618f093d44032b3dc57b77f160a2793ec41f Mon Sep 17 00:00:00 2001 From: Claudio Schaad Date: Mon, 5 May 2025 21:08:06 +0200 Subject: [PATCH] Add transaction dialog and enhance transaction view --- .../Datasets/TransactionDataset.cs | 2 +- .../Interfaces/ITransactionRepository.cs | 1 + .../Models/Transaction.cs | 7 +- .../Repositories/TransactionRepository.cs | 10 +++ Schaad.Accounting.Services/ViewService.cs | 17 ++++- .../Components/MyHeader.razor.cs | 2 +- .../Pages/Dialogs/TransactionDialog.razor | 56 +++++++++++++++ .../Pages/Dialogs/TransactionDialog.razor.cs | 50 +++++++++++++ .../Components/Pages/Transactions.razor | 34 ++++++--- .../Components/Pages/Transactions.razor.cs | 71 ++++++++++++++++++- .../Components/Pages/Transactions.razor.css | 3 + .../Components/_Imports.razor | 1 + .../Schaad.Accounting.UI.csproj | 5 ++ 13 files changed, 240 insertions(+), 19 deletions(-) create mode 100644 Schaad.Accounting.UI/Components/Pages/Dialogs/TransactionDialog.razor create mode 100644 Schaad.Accounting.UI/Components/Pages/Dialogs/TransactionDialog.razor.cs create mode 100644 Schaad.Accounting.UI/Components/Pages/Transactions.razor.css diff --git a/Schaad.Accounting.Common/Datasets/TransactionDataset.cs b/Schaad.Accounting.Common/Datasets/TransactionDataset.cs index b080b64..7d28f92 100644 --- a/Schaad.Accounting.Common/Datasets/TransactionDataset.cs +++ b/Schaad.Accounting.Common/Datasets/TransactionDataset.cs @@ -3,7 +3,7 @@ using Schaad.Accounting.Models; namespace Schaad.Accounting.Datasets { - public class TransactionDataset : Transaction + public record TransactionDataset : Transaction { public Account OriginAccount { get; set; } diff --git a/Schaad.Accounting.Common/Interfaces/ITransactionRepository.cs b/Schaad.Accounting.Common/Interfaces/ITransactionRepository.cs index 23a66ad..30cfdc0 100644 --- a/Schaad.Accounting.Common/Interfaces/ITransactionRepository.cs +++ b/Schaad.Accounting.Common/Interfaces/ITransactionRepository.cs @@ -10,5 +10,6 @@ namespace Schaad.Accounting.Interfaces void SaveTransaction(Transaction transaction); Transaction GetTransaction(string id); + void DeleteTransaction(string id); } } \ No newline at end of file diff --git a/Schaad.Accounting.Common/Models/Transaction.cs b/Schaad.Accounting.Common/Models/Transaction.cs index 485788b..dabbe07 100644 --- a/Schaad.Accounting.Common/Models/Transaction.cs +++ b/Schaad.Accounting.Common/Models/Transaction.cs @@ -5,7 +5,7 @@ using System.Linq; namespace Schaad.Accounting.Models { - public class Transaction + public record Transaction { public string Id { get; set; } public string BankTransactionId { get; set; } @@ -18,21 +18,26 @@ namespace Schaad.Accounting.Models public string RelatedParty { get; set; } [Display(Name = "Valuta")] + [Required] public DateTime ValueDate { get; set; } [Display(Name = "Buchung")] public DateTime BookingDate { get; set; } [Display(Name = "Buchungstext")] + [Required] public string Text { get; set; } [Display(Name = "Betrag")] + [Required] public decimal Value { get; set; } [Display(Name = "Habenkonto")] + [Required] public string OriginAccountId { get; set; } [Display(Name = "Sollkonto")] + [Required] public string TargetAccountId { get; set; } [Display(Name = "Währungskurs")] diff --git a/Schaad.Accounting.Db/Repositories/TransactionRepository.cs b/Schaad.Accounting.Db/Repositories/TransactionRepository.cs index bafceb5..973cc92 100644 --- a/Schaad.Accounting.Db/Repositories/TransactionRepository.cs +++ b/Schaad.Accounting.Db/Repositories/TransactionRepository.cs @@ -76,5 +76,15 @@ namespace Schaad.Accounting.Repositories return transaction; } + + /// + /// Delete transaction + /// + public void DeleteTransaction(string id) + { + var transactions = GetTransactionList(); + transactions.RemoveAll(t => t.Id == id); + Save(transactions, TRANSACTIONS); + } } } \ No newline at end of file diff --git a/Schaad.Accounting.Services/ViewService.cs b/Schaad.Accounting.Services/ViewService.cs index a207c86..aca1643 100644 --- a/Schaad.Accounting.Services/ViewService.cs +++ b/Schaad.Accounting.Services/ViewService.cs @@ -136,8 +136,7 @@ namespace Schaad.Accounting.Services new TransactionDataset( t, accountList.Single(a => a.Id == t.OriginAccountId), - accountList.Single(a => a.Id == t.TargetAccountId) - ) + accountList.Single(a => a.Id == t.TargetAccountId)) ) .ToList(); @@ -155,7 +154,7 @@ namespace Schaad.Accounting.Services var transactionViewList = transactionList.Select( t => new TransactionDataset( - t, + Prepare(t), accountList.Single(a => a.Id == t.OriginAccountId), accountList.Single(a => a.Id == t.TargetAccountId) ) @@ -163,6 +162,18 @@ namespace Schaad.Accounting.Services .ToList(); return transactionViewList; + + Transaction Prepare(Transaction t) + { + var account = accountList.Single(a => a.Id == t.OriginAccountId); + + if (account.Class == ClassIds.Activa && accountId == t.OriginAccountId ) + { + return t with { Value = -t.Value }; + } + + return t; + } } diff --git a/Schaad.Accounting.UI/Components/MyHeader.razor.cs b/Schaad.Accounting.UI/Components/MyHeader.razor.cs index f3258f7..8dee923 100644 --- a/Schaad.Accounting.UI/Components/MyHeader.razor.cs +++ b/Schaad.Accounting.UI/Components/MyHeader.razor.cs @@ -12,7 +12,7 @@ public partial class MyHeader : ComponentBase private int selectedYear; private List mandators = new (); - private string selectedMandator; + private string selectedMandator = null!; protected override Task OnInitializedAsync() { diff --git a/Schaad.Accounting.UI/Components/Pages/Dialogs/TransactionDialog.razor b/Schaad.Accounting.UI/Components/Pages/Dialogs/TransactionDialog.razor new file mode 100644 index 0000000..7a48be1 --- /dev/null +++ b/Schaad.Accounting.UI/Components/Pages/Dialogs/TransactionDialog.razor @@ -0,0 +1,56 @@ +@using Schaad.Accounting.Models +@implements IDialogContentComponent +@rendermode InteractiveServer + + + + + + @Dialog.Instance.Parameters.Title + + + + + + + + + + + + + +
+ +
+
+
+ + + + Abbrechen + + + Speichern + + \ No newline at end of file diff --git a/Schaad.Accounting.UI/Components/Pages/Dialogs/TransactionDialog.razor.cs b/Schaad.Accounting.UI/Components/Pages/Dialogs/TransactionDialog.razor.cs new file mode 100644 index 0000000..716fbc0 --- /dev/null +++ b/Schaad.Accounting.UI/Components/Pages/Dialogs/TransactionDialog.razor.cs @@ -0,0 +1,50 @@ +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Forms; +using Microsoft.FluentUI.AspNetCore.Components; +using Schaad.Accounting.Interfaces; +using Schaad.Accounting.Models; + +namespace Schaad.Accounting.UI.Components.Pages.Dialogs; + +public partial class TransactionDialog : ComponentBase +{ + private EditContext editContext = null!; + + [CascadingParameter] + public FluentDialog Dialog { get; set; } = null!; + + [Parameter] + public Transaction Content { get; set; } = null!; + + [Inject] + private ITransactionRepository transactionRepository { get; set; } = null!; + + [Inject] + private IViewService viewService { get; set; } = null!; + + private IReadOnlyList accounts = []; + private DateTime? SelectedValue; + + protected override void OnInitialized() + { + SelectedValue = Content.ValueDate; + editContext = new EditContext(Content); + accounts = viewService.GetAccountViewList(); + } + + private async Task SaveAsync() + { + if (editContext.Validate()) + { + Content.ValueDate = SelectedValue!.Value; + Content.BookingDate = SelectedValue!.Value; + transactionRepository.SaveTransaction(Content); + await Dialog.CloseAsync(Content); + } + } + + private async Task CancelAsync() + { + await Dialog.CancelAsync(); + } +} \ No newline at end of file diff --git a/Schaad.Accounting.UI/Components/Pages/Transactions.razor b/Schaad.Accounting.UI/Components/Pages/Transactions.razor index ad40e01..ddb84f6 100644 --- a/Schaad.Accounting.UI/Components/Pages/Transactions.razor +++ b/Schaad.Accounting.UI/Components/Pages/Transactions.razor @@ -17,7 +17,7 @@
- @account.BalanceCHF.ToString("C2") + @Math.Abs(account.BalanceCHF).ToString("C2")
@@ -29,21 +29,35 @@ - - - - - - + + + @selectedAccount.Name + + + Total @Math.Abs(selectedAccount.Balance).ToString("C2") in @transactionList?.Count() Transaktionen + + + Neue Transaktion hinzufügen + + + + + + + + @GetAccountName(context) - - + + + + + + - @code diff --git a/Schaad.Accounting.UI/Components/Pages/Transactions.razor.cs b/Schaad.Accounting.UI/Components/Pages/Transactions.razor.cs index 2e4f9a6..ed69ab1 100644 --- a/Schaad.Accounting.UI/Components/Pages/Transactions.razor.cs +++ b/Schaad.Accounting.UI/Components/Pages/Transactions.razor.cs @@ -1,6 +1,9 @@ using Microsoft.AspNetCore.Components; +using Microsoft.FluentUI.AspNetCore.Components; using Schaad.Accounting.Datasets; using Schaad.Accounting.Interfaces; +using Schaad.Accounting.Models; +using Schaad.Accounting.UI.Components.Pages.Dialogs; namespace Schaad.Accounting.UI.Components.Pages; @@ -8,21 +11,30 @@ public partial class Transactions : ComponentBase { [Inject] private IViewService viewService { get; set; } = null!; + + [Inject] + private ITransactionRepository transactionRepository { get; set; } = null!; + + [Inject] + private IDialogService dialogService { get; set; } = null!; private IReadOnlyList accounts = null!; private IQueryable? transactionList; - private string? selectedAccountId; + private string selectedAccountId = null!; + private AccountDataset selectedAccount = null!; protected override Task OnInitializedAsync() { - accounts = viewService.GetAccountViewList(); - return base.OnInitializedAsync(); + accounts = viewService.GetAccountViewList(); + ShowTransactions(accounts.First().Id); + return base.OnInitializedAsync(); } private void ShowTransactions(string accountId) { selectedAccountId = accountId; + selectedAccount = accounts.Single(a => a.Id == accountId); transactionList = viewService.GetTransactionViewList(accountId).AsQueryable(); } @@ -35,4 +47,57 @@ public partial class Transactions : ComponentBase return transaction.OriginAccount.Name; } + + private async Task AddAsync() + { + var data = new Transaction + { + ValueDate = DateTime.Now, + BookingDate = DateTime.Now, + TargetAccountId = selectedAccountId + }; + var dialog = await dialogService.ShowDialogAsync(data, new DialogParameters() + { + Height = "500px", + Title = "Transaktion", + PreventDismissOnOverlayClick = true, + PreventScroll = true, + }); + + var result = await dialog.Result; + if (!result.Cancelled && result.Data != null) + { + transactionList = viewService.GetTransactionViewList(selectedAccountId).AsQueryable(); + } + } + + private async Task EditAsync(string id) + { + var data = transactionRepository.GetTransaction(id); + var dialog = await dialogService.ShowDialogAsync(data, new DialogParameters() + { + Height = "500px", + Title = "Transaktion", + PreventDismissOnOverlayClick = true, + PreventScroll = true, + }); + + var result = await dialog.Result; + if (!result.Cancelled && result.Data != null) + { + transactionList = viewService.GetTransactionViewList(selectedAccountId).AsQueryable(); + } + } + + private async Task DeleteAsync(string id) + { + var transaction = transactionRepository.GetTransaction(id); + var dialog = await dialogService.ShowConfirmationAsync($"Transaction '{transaction.Text}' mit Betrag {transaction.Value} wirklich löschen?", "Ja", "Nein", "Transaktion löschen"); + var result = await dialog.Result; + if (!result.Cancelled) + { + transactionRepository.DeleteTransaction(id); + transactionList = viewService.GetTransactionViewList(selectedAccountId).AsQueryable(); + } + } } \ No newline at end of file diff --git a/Schaad.Accounting.UI/Components/Pages/Transactions.razor.css b/Schaad.Accounting.UI/Components/Pages/Transactions.razor.css new file mode 100644 index 0000000..2208e6b --- /dev/null +++ b/Schaad.Accounting.UI/Components/Pages/Transactions.razor.css @@ -0,0 +1,3 @@ +.title { + font-size: 16pt; +} diff --git a/Schaad.Accounting.UI/Components/_Imports.razor b/Schaad.Accounting.UI/Components/_Imports.razor index d5f412e..792f27f 100644 --- a/Schaad.Accounting.UI/Components/_Imports.razor +++ b/Schaad.Accounting.UI/Components/_Imports.razor @@ -1,6 +1,7 @@ @using System.ComponentModel.DataAnnotations @using System.Net.Http @using System.Net.Http.Json +@using Microsoft.FluentUI.AspNetCore.Components.Extensions @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web diff --git a/Schaad.Accounting.UI/Schaad.Accounting.UI.csproj b/Schaad.Accounting.UI/Schaad.Accounting.UI.csproj index cd0cc2a..2e84a9a 100644 --- a/Schaad.Accounting.UI/Schaad.Accounting.UI.csproj +++ b/Schaad.Accounting.UI/Schaad.Accounting.UI.csproj @@ -27,4 +27,9 @@ + + + + +