From 3367e2514d1d16a07a15c91e3da6e6caa8af3f25 Mon Sep 17 00:00:00 2001 From: Alexander Preibisch Date: Tue, 5 Mar 2024 17:09:24 +0100 Subject: [PATCH] Fix #224 and #225 --- CHANGELOG.md | 1 + OpenBudgeteer.API/Program.cs | 8 +- OpenBudgeteer.Blazor/Pages/Bucket.razor | 2 +- OpenBudgeteer.Blazor/Pages/Transaction.razor | 6 +- .../Pages/Transaction.razor.cs | 4 +- .../Shared/BucketDetailsDialog.razor | 2 +- .../Shared/RecurringTransactionDialog.razor | 11 ++- .../Shared/TransactionDialog.razor | 2 +- .../IRecurringBankTransactionService.cs | 2 + .../RecurringBankTransactionService.cs | 36 +++++++ .../RecurringTransactionRecurrenceType.cs | 18 ++++ .../EntityViewModels/AccountViewModel.cs | 10 ++ .../RecurringTransactionViewModel.cs | 93 ++++++------------- .../EntityViewModels/TransactionViewModel.cs | 60 +++++------- .../RecurringTransactionHandlerViewModel.cs | 2 +- 15 files changed, 139 insertions(+), 118 deletions(-) create mode 100644 OpenBudgeteer.Core/Common/Extensions/RecurringTransactionRecurrenceType.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 44f1e06..86f8825 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ * Adding a Mapping Rule to an existing Rule Set no longer fails [#200](https://github.com/TheAxelander/OpenBudgeteer/pull/200) Thanks [Lucaber](https://github.com/Lucaber) * Exception after canceling creation of a new Recurring Transactions [#210](https://github.com/TheAxelander/OpenBudgeteer/issues/210) * Guid issues using Sqlite database [#221](https://github.com/TheAxelander/OpenBudgeteer/issues/221) +* Fix `Expand All` button typo on Bucket Page [#224](https://github.com/TheAxelander/OpenBudgeteer/issues/224) ### :hammer: Maintenance diff --git a/OpenBudgeteer.API/Program.cs b/OpenBudgeteer.API/Program.cs index 161b824..16520dd 100644 --- a/OpenBudgeteer.API/Program.cs +++ b/OpenBudgeteer.API/Program.cs @@ -37,7 +37,6 @@ var versionSet = app.NewApiVersionSet() .HasApiVersion(1, 0) - .HasApiVersion(2, 0) // reporting api versions will return the headers // "api-supported-versions" and "api-deprecated-versions" .ReportApiVersions() @@ -91,7 +90,7 @@ transaction.MapGet("/fromAccount/{id:guid}", (Guid id, DateTime? start, DateTime? end, int? limit) => bankTransactionService.GetFromAccount(id, start, end, limit ?? 0)) .MapToApiVersion(1,0); -transaction.MapGet( "/withBucket/{id:guid}", (Guid id) => +transaction.MapGet( "/withEntities/{id:guid}", (Guid id) => bankTransactionService.GetWithEntities(id)) .MapToApiVersion(1,0); @@ -128,7 +127,10 @@ // GET recurring.MapGet("{id:guid}", (Guid id) => recurringTransactionService.Get(id)) .MapToApiVersion(1,0); -recurring.MapGet("/", () => recurringTransactionService.GetAll()) +recurring.MapGet("/", () => recurringTransactionService.GetAllWithEntities()) + .MapToApiVersion(1,0); +recurring.MapGet( "/withEntities/{id:guid}", (Guid id) => + recurringTransactionService.GetWithEntities(id)) .MapToApiVersion(1,0); recurring.MapGet("/pendingTransactions", async (DateTime yearMonth) => await recurringTransactionService.GetPendingBankTransactionAsync(yearMonth)) diff --git a/OpenBudgeteer.Blazor/Pages/Bucket.razor b/OpenBudgeteer.Blazor/Pages/Bucket.razor index cd27d96..b35cfcb 100644 --- a/OpenBudgeteer.Blazor/Pages/Bucket.razor +++ b/OpenBudgeteer.Blazor/Pages/Bucket.razor @@ -69,7 +69,7 @@ - + diff --git a/OpenBudgeteer.Blazor/Pages/Transaction.razor b/OpenBudgeteer.Blazor/Pages/Transaction.razor index bc65945..4b21f5c 100644 --- a/OpenBudgeteer.Blazor/Pages/Transaction.razor +++ b/OpenBudgeteer.Blazor/Pages/Transaction.razor @@ -56,7 +56,7 @@ @foreach (var account in transaction.AvailableAccounts) { @@ -174,7 +174,7 @@ { @transaction.TransactionDate.ToShortDateString() - @transaction.AccountName + @transaction.SelectedAccount.Name @transaction.Payee @transaction.Memo @transaction.Amount.ToString("C", CultureInfo.CurrentCulture) diff --git a/OpenBudgeteer.Blazor/Pages/Transaction.razor.cs b/OpenBudgeteer.Blazor/Pages/Transaction.razor.cs index 32e66c8..428f5b9 100644 --- a/OpenBudgeteer.Blazor/Pages/Transaction.razor.cs +++ b/OpenBudgeteer.Blazor/Pages/Transaction.razor.cs @@ -69,7 +69,7 @@ private void EditAllTransaction() private void NewTransactionAccount_SelectionChanged(string? value) { if (string.IsNullOrEmpty(value)) return; - _dataContext.NewTransaction!.UpdateSelectedAccount(Guid.Parse(value)); + _dataContext.NewTransaction!.SelectedAccount = _dataContext.NewTransaction!.AvailableAccounts.First(i => i.AccountId == Guid.Parse(value)); } private async Task ProposeBucketsAsync() @@ -84,7 +84,7 @@ private async Task ProposeBucketsAsync() private void TransactionAccount_SelectionChanged(string? value, TransactionViewModel transactionViewModel) { if (string.IsNullOrEmpty(value)) return; - transactionViewModel.UpdateSelectedAccount(Guid.Parse(value)); + transactionViewModel.SelectedAccount = transactionViewModel.AvailableAccounts.First(i => i.AccountId == Guid.Parse(value)); } private void SplitTransaction(TransactionViewModel transaction) => diff --git a/OpenBudgeteer.Blazor/Shared/BucketDetailsDialog.razor b/OpenBudgeteer.Blazor/Shared/BucketDetailsDialog.razor index 247fe02..dce5878 100644 --- a/OpenBudgeteer.Blazor/Shared/BucketDetailsDialog.razor +++ b/OpenBudgeteer.Blazor/Shared/BucketDetailsDialog.razor @@ -47,7 +47,7 @@ { @transaction.TransactionDate.ToShortDateString() - @transaction.AccountName + @transaction.SelectedAccount.Name @transaction.Payee @transaction.Memo @transaction.Amount.ToString("C", CultureInfo.CurrentCulture) diff --git a/OpenBudgeteer.Blazor/Shared/RecurringTransactionDialog.razor b/OpenBudgeteer.Blazor/Shared/RecurringTransactionDialog.razor index fe4ee1b..f4768e6 100644 --- a/OpenBudgeteer.Blazor/Shared/RecurringTransactionDialog.razor +++ b/OpenBudgeteer.Blazor/Shared/RecurringTransactionDialog.razor @@ -2,6 +2,7 @@ @using OpenBudgeteer.Core.ViewModels @using System.Drawing @using System.Globalization +@using OpenBudgeteer.Core.Common.Extensions @using OpenBudgeteer.Core.ViewModels.EntityViewModels @using OpenBudgeteer.Core.ViewModels.Helper @if (IsDialogVisible) @@ -53,9 +54,9 @@ @@ -83,7 +84,7 @@ @transaction.FirstOccurrenceDate.ToShortDateString() Every @transaction.RecurrenceAmount - @transaction.RecurrenceTypeOutput + @transaction.RecurrenceType.GetStringValue() @transaction.SelectedAccount.Name @transaction.Payee @transaction.Memo @@ -172,7 +173,9 @@ void TransactionRecurrenceType_SelectionChanged(string? value, RecurringTransactionViewModel transaction) { if (string.IsNullOrEmpty(value)) return; - transaction.RecurrenceType = (RecurringTransactionViewModel.RecurringTransactionRecurrenceType)Convert.ToInt32(value); + transaction.RecurrenceType = Enum.TryParse(typeof(RecurringTransactionRecurrenceType), value, out var result) + ? (RecurringTransactionRecurrenceType)result + : RecurringTransactionRecurrenceType.Weeks; } void TransactionAccount_SelectionChanged(string? value, RecurringTransactionViewModel transaction) diff --git a/OpenBudgeteer.Blazor/Shared/TransactionDialog.razor b/OpenBudgeteer.Blazor/Shared/TransactionDialog.razor index ee1d166..407dddc 100644 --- a/OpenBudgeteer.Blazor/Shared/TransactionDialog.razor +++ b/OpenBudgeteer.Blazor/Shared/TransactionDialog.razor @@ -34,7 +34,7 @@ { @transaction.TransactionDate.ToShortDateString() - @transaction.AccountName + @transaction.SelectedAccount.Name @transaction.Payee @transaction.Memo @transaction.Amount.ToString("C", CultureInfo.CurrentCulture) diff --git a/OpenBudgeteer.Core.Data.Contracts/Services/IRecurringBankTransactionService.cs b/OpenBudgeteer.Core.Data.Contracts/Services/IRecurringBankTransactionService.cs index 367c17b..e095ef2 100644 --- a/OpenBudgeteer.Core.Data.Contracts/Services/IRecurringBankTransactionService.cs +++ b/OpenBudgeteer.Core.Data.Contracts/Services/IRecurringBankTransactionService.cs @@ -4,6 +4,8 @@ namespace OpenBudgeteer.Core.Data.Contracts.Services; public interface IRecurringBankTransactionService : IBaseService { + public RecurringBankTransaction GetWithEntities(Guid id); + public IEnumerable GetAllWithEntities(); public Task> GetPendingBankTransactionAsync(DateTime yearMonth); public Task> CreatePendingBankTransactionAsync(DateTime yearMonth); } \ No newline at end of file diff --git a/OpenBudgeteer.Core.Data.Services/RecurringBankTransactionService.cs b/OpenBudgeteer.Core.Data.Services/RecurringBankTransactionService.cs index 8a3d26e..73c9202 100644 --- a/OpenBudgeteer.Core.Data.Services/RecurringBankTransactionService.cs +++ b/OpenBudgeteer.Core.Data.Services/RecurringBankTransactionService.cs @@ -12,6 +12,42 @@ internal RecurringBankTransactionService(DbContextOptions dbCon : base(dbContextOptions, new RecurringBankTransactionRepository(new DatabaseContext(dbContextOptions))) { } + + public RecurringBankTransaction GetWithEntities(Guid id) + { + try + { + using var dbContext = new DatabaseContext(DbContextOptions); + var repository = new RecurringBankTransactionRepository(dbContext); + + var result = repository.ByIdWithIncludedEntities(id); + if (result == null) throw new Exception($"{typeof(RecurringBankTransaction)} not found in database"); + return result; + } + catch (Exception e) + { + Console.WriteLine(e); + throw new Exception($"Error on querying database: {e.Message}"); + } + } + + public IEnumerable GetAllWithEntities() + { + try + { + using var dbContext = new DatabaseContext(DbContextOptions); + var repository = new RecurringBankTransactionRepository(dbContext); + + return repository + .AllWithIncludedEntities() + .ToList(); + } + catch (Exception e) + { + Console.WriteLine(e); + throw new Exception($"Error on querying database: {e.Message}"); + } + } public async Task> GetPendingBankTransactionAsync(DateTime yearMonth) { diff --git a/OpenBudgeteer.Core/Common/Extensions/RecurringTransactionRecurrenceType.cs b/OpenBudgeteer.Core/Common/Extensions/RecurringTransactionRecurrenceType.cs new file mode 100644 index 0000000..d96b27e --- /dev/null +++ b/OpenBudgeteer.Core/Common/Extensions/RecurringTransactionRecurrenceType.cs @@ -0,0 +1,18 @@ +using OpenBudgeteer.Core.ViewModels.EntityViewModels; + +namespace OpenBudgeteer.Core.Common.Extensions; + +/// +/// Identifier which kind of recurrence can be selected for a RecurringTransaction in +/// +public enum RecurringTransactionRecurrenceType +{ + [StringValue("Weeks")] + Weeks = 1, + [StringValue("Months")] + Months = 2, + [StringValue("Quarters")] + Quarters = 3, + [StringValue("Years")] + Years = 4, +} \ No newline at end of file diff --git a/OpenBudgeteer.Core/ViewModels/EntityViewModels/AccountViewModel.cs b/OpenBudgeteer.Core/ViewModels/EntityViewModels/AccountViewModel.cs index 7394031..f71f29d 100644 --- a/OpenBudgeteer.Core/ViewModels/EntityViewModels/AccountViewModel.cs +++ b/OpenBudgeteer.Core/ViewModels/EntityViewModels/AccountViewModel.cs @@ -86,6 +86,7 @@ protected AccountViewModel(IServiceManager serviceManager, Account? account) : b AccountId = account.Id; _name = account.Name ?? string.Empty; _isActive = account.IsActive != 0; + if (!IsActive) _name += " (Inactive)"; } } @@ -118,6 +119,15 @@ public static AccountViewModel CreateFromAccount(IServiceManager serviceManager, { return new AccountViewModel(serviceManager, account); } + + /// + /// Initialize a copy of the passed ViewModel + /// + /// Current ViewModel instance + public static AccountViewModel CreateAsCopy(AccountViewModel accountViewModel) + { + return new AccountViewModel(accountViewModel); + } #endregion diff --git a/OpenBudgeteer.Core/ViewModels/EntityViewModels/RecurringTransactionViewModel.cs b/OpenBudgeteer.Core/ViewModels/EntityViewModels/RecurringTransactionViewModel.cs index 8125efe..1766fa2 100644 --- a/OpenBudgeteer.Core/ViewModels/EntityViewModels/RecurringTransactionViewModel.cs +++ b/OpenBudgeteer.Core/ViewModels/EntityViewModels/RecurringTransactionViewModel.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Threading.Tasks; using OpenBudgeteer.Core.Common; +using OpenBudgeteer.Core.Common.Extensions; using OpenBudgeteer.Core.Data.Contracts.Services; using OpenBudgeteer.Core.Data.Entities.Models; @@ -13,29 +14,21 @@ public class RecurringTransactionViewModel : BaseEntityViewModel /// Database Id of the RecurringBankTransaction /// public readonly Guid RecurringTransactionId; - private Guid _accountId; + private AccountViewModel _selectedAccount; /// - /// Database Id of the Account assigned to this RecurringBankTransaction + /// ViewModel instance of the selected Account /// - public Guid AccountId - { - get => _accountId; - set => Set(ref _accountId, value); + public AccountViewModel SelectedAccount + { + get => _selectedAccount; + set => Set(ref _selectedAccount, value); } - + private RecurringTransactionRecurrenceType _recurrenceType; /// /// Recurrence Type that is selected for the Transaction @@ -46,24 +39,6 @@ public RecurringTransactionRecurrenceType RecurrenceType set => Set(ref _recurrenceType, value); } - /// - /// Output of used for display purposes - /// - public string RecurrenceTypeOutput - { - get - { - return RecurrenceType switch - { - RecurringTransactionRecurrenceType.Days => nameof(RecurringTransactionRecurrenceType.Days), - RecurringTransactionRecurrenceType.Months => nameof(RecurringTransactionRecurrenceType.Months), - RecurringTransactionRecurrenceType.Quarter => nameof(RecurringTransactionRecurrenceType.Quarter), - RecurringTransactionRecurrenceType.Years => nameof(RecurringTransactionRecurrenceType.Years), - _ => throw new ArgumentOutOfRangeException() - }; - } - } - private int _recurrenceAmount; /// /// How often the Transaction repeats in combination with @@ -114,16 +89,6 @@ public decimal Amount set => Set(ref _amount, value); } - private AccountViewModel _selectedAccount; - /// - /// Account where the Transaction is assigned to - /// - public AccountViewModel SelectedAccount - { - get => _selectedAccount; - set => Set(ref _selectedAccount, value); - } - private bool _inModification; /// /// Helper property to check if the Transaction is currently modified @@ -149,17 +114,6 @@ public bool IsHovered /// public readonly ObservableCollection AvailableAccounts; - /// - /// Helper collection to list all existing Recurrence Types - /// - public List> AvailableRecurrenceTypes => new() - { - new KeyValuePair(1, "Weeks"), - new KeyValuePair(2, "Months"), - new KeyValuePair(3, "Quarters"), - new KeyValuePair(4, "Years") - }; - private RecurringTransactionViewModel? _oldRecurringTransactionViewModelItem; #endregion @@ -192,18 +146,21 @@ protected RecurringTransactionViewModel(IServiceManager serviceManager, IEnumera IsActive = 1, Name = "No Account" }; - _selectedAccount = AccountViewModel.CreateFromAccount(serviceManager, noAccount); - AvailableAccounts.Add(_selectedAccount); - - _firstOccurrenceDate = DateTime.Today; - _recurrenceType = RecurringTransactionRecurrenceType.Days; + RecurringTransactionId = Guid.Empty; + _amount = 0; _payee = string.Empty; _memo = string.Empty; + _firstOccurrenceDate = DateTime.Today; + _recurrenceType = RecurringTransactionRecurrenceType.Weeks; + _recurrenceAmount = 0; + + // Add the "No Account" for pre-selection + _selectedAccount = AccountViewModel.CreateFromAccount(serviceManager, noAccount); + AvailableAccounts.Add(_selectedAccount); } else { RecurringTransactionId = transaction.Id; - _accountId = transaction.AccountId; _amount = transaction.Amount; _memo = transaction.Memo ?? string.Empty; _payee = transaction.Payee ?? string.Empty; @@ -211,9 +168,13 @@ protected RecurringTransactionViewModel(IServiceManager serviceManager, IEnumera _recurrenceType = (RecurringTransactionRecurrenceType)transaction.RecurrenceType; _recurrenceAmount = transaction.RecurrenceAmount; - // Make inactive Account available in Selection, will later fail during saving + // Handle Accounts _selectedAccount = AccountViewModel.CreateFromAccount(serviceManager, transaction.Account); - if (SelectedAccount.IsActive) AvailableAccounts.Add(_selectedAccount); + if (!SelectedAccount.IsActive) + { + // Make inactive Account available in selection, will later fail during saving + AvailableAccounts.Add(SelectedAccount); + } } } @@ -232,14 +193,13 @@ protected RecurringTransactionViewModel(RecurringTransactionViewModel viewModel) // Handle Transaction RecurringTransactionId = viewModel.RecurringTransactionId; - _accountId = viewModel.AccountId; + _selectedAccount = AccountViewModel.CreateAsCopy(viewModel.SelectedAccount); _recurrenceType = viewModel.RecurrenceType; _recurrenceAmount = viewModel.RecurrenceAmount; _firstOccurrenceDate = viewModel.FirstOccurrenceDate; _payee = viewModel.Payee; _memo = viewModel.Memo; _amount = viewModel.Amount; - _selectedAccount = viewModel.SelectedAccount; } /// @@ -318,7 +278,7 @@ internal override RecurringBankTransaction ConvertToDto() return new RecurringBankTransaction() { Id = RecurringTransactionId, - AccountId = AccountId, + AccountId = SelectedAccount.AccountId, RecurrenceType = (int)RecurrenceType, RecurrenceAmount = RecurrenceAmount, Payee = Payee, @@ -404,14 +364,13 @@ public void CancelModification() { if (_oldRecurringTransactionViewModelItem != null) { - AccountId = _oldRecurringTransactionViewModelItem.AccountId; + SelectedAccount = _oldRecurringTransactionViewModelItem.SelectedAccount; RecurrenceType = _oldRecurringTransactionViewModelItem.RecurrenceType; RecurrenceAmount = _oldRecurringTransactionViewModelItem.RecurrenceAmount; Payee = _oldRecurringTransactionViewModelItem.Payee; Memo = _oldRecurringTransactionViewModelItem.Memo; Amount = _oldRecurringTransactionViewModelItem.Amount; FirstOccurrenceDate = _oldRecurringTransactionViewModelItem.FirstOccurrenceDate; - SelectedAccount = _oldRecurringTransactionViewModelItem.SelectedAccount; } InModification = false; _oldRecurringTransactionViewModelItem = null; diff --git a/OpenBudgeteer.Core/ViewModels/EntityViewModels/TransactionViewModel.cs b/OpenBudgeteer.Core/ViewModels/EntityViewModels/TransactionViewModel.cs index bb2b37f..e2ba8ba 100644 --- a/OpenBudgeteer.Core/ViewModels/EntityViewModels/TransactionViewModel.cs +++ b/OpenBudgeteer.Core/ViewModels/EntityViewModels/TransactionViewModel.cs @@ -20,24 +20,14 @@ public class TransactionViewModel : BaseEntityViewModel /// public readonly Guid TransactionId; - private Guid _accountId; + private AccountViewModel _selectedAccount; /// - /// Database Id of the selected Account + /// ViewModel instance of the selected Account /// - public Guid AccountId - { - get => _accountId; - set => Set(ref _accountId, value); - } - - private string _accountName; - /// - /// Name of the selected Account - /// - public string AccountName - { - get => _accountName; - set => Set(ref _accountName, value); + public AccountViewModel SelectedAccount + { + get => _selectedAccount; + set => Set(ref _selectedAccount, value); } private DateTime _transactionDate; @@ -165,8 +155,10 @@ protected TransactionViewModel(IServiceManager serviceManager, IEnumerable i.AccountId == accountId).Name; - } - #endregion #region Misc @@ -653,7 +643,7 @@ string GetFieldValue(int comparisionField) { var fieldValue = comparisionField switch { - 1 => AccountName, + 1 => SelectedAccount.Name, 2 => Payee ?? "", 3 => Memo ?? "", 4 => Amount.ToString(CultureInfo.CurrentCulture), diff --git a/OpenBudgeteer.Core/ViewModels/Helper/RecurringTransactionHandlerViewModel.cs b/OpenBudgeteer.Core/ViewModels/Helper/RecurringTransactionHandlerViewModel.cs index b7ac5b1..323ba44 100644 --- a/OpenBudgeteer.Core/ViewModels/Helper/RecurringTransactionHandlerViewModel.cs +++ b/OpenBudgeteer.Core/ViewModels/Helper/RecurringTransactionHandlerViewModel.cs @@ -45,7 +45,7 @@ public async Task LoadDataAsync() .ToList(); var transactionTasks = ServiceManager.RecurringBankTransactionService - .GetAll() + .GetAllWithEntities() .Select(transaction => RecurringTransactionViewModel .CreateFromRecurringTransactionAsync(ServiceManager, availableAccounts, transaction)) .ToList();