diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b24db5..8ad060e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 1.9.1 (2025-01-11) + +### :beetle: Bug Fixes + +* Unable to move a Bucket Group [#282](https://github.com/TheAxelander/OpenBudgeteer/issues/282) +* Data Inconsistency Check for incomplete Bucket assignments didn't cover Transactions without any assignment [#283](https://github.com/TheAxelander/OpenBudgeteer/issues/283) + ## 1.9 (2025-01-04) ### :gear: Features & Enhancements diff --git a/OpenBudgeteer.Blazor/Shared/MainLayout.razor b/OpenBudgeteer.Blazor/Shared/MainLayout.razor index 36b0fba..da8e97e 100644 --- a/OpenBudgeteer.Blazor/Shared/MainLayout.razor +++ b/OpenBudgeteer.Blazor/Shared/MainLayout.razor @@ -16,7 +16,7 @@ OpenBudgeteer Database: @CurrentDatabase - Version: 1.9.0 (Change Log) + Version: 1.9.1 (Change Log)
diff --git a/OpenBudgeteer.Core.Data.Services/Generic/GenericBucketGroupService.cs b/OpenBudgeteer.Core.Data.Services/Generic/GenericBucketGroupService.cs index 9b915e8..7ee8cbb 100644 --- a/OpenBudgeteer.Core.Data.Services/Generic/GenericBucketGroupService.cs +++ b/OpenBudgeteer.Core.Data.Services/Generic/GenericBucketGroupService.cs @@ -103,31 +103,33 @@ public override void Delete(Guid id) public BucketGroup Move(Guid bucketGroupId, int positions) { - var bucketGroup = Get(bucketGroupId); - if (positions == 0) return bucketGroup; - - // Create in an interim List for later use + // Create in an interim list to handle position updates var existingBucketGroups = new ObservableCollection(); foreach (var group in GetAll().ToList()) { existingBucketGroups.Add(group); } + + // Re-use existing reference in interim list of passed Bucket Group (see #282) + var bucketGroup = existingBucketGroups.First(i => i.Id == bucketGroupId); + if (positions == 0) return bucketGroup; + + // Calculate new target position var bucketGroupCount = existingBucketGroups.Count(); var targetPosition = bucketGroup.Position + positions; if (targetPosition < 1) targetPosition = 1; if (targetPosition > bucketGroupCount) targetPosition = bucketGroupCount; if (targetPosition == bucketGroup.Position) return bucketGroup; // Group is already at the end or top. No further action - // Move Group in interim List + // Move Group in interim list existingBucketGroups.Move(bucketGroup.Position - 1, targetPosition - 1); - // Update Position number + // Update Position number for each group var newPosition = 1; foreach (var group in existingBucketGroups) { group.Position = newPosition; _bucketGroupRepository.Update(group); - if (group.Id == bucketGroupId) bucketGroup = group; // Use correct object reference for final return newPosition++; } diff --git a/OpenBudgeteer.Core/ViewModels/PageViewModels/DataConsistencyPageViewModel.cs b/OpenBudgeteer.Core/ViewModels/PageViewModels/DataConsistencyPageViewModel.cs index 6a5cd3f..bd1c428 100644 --- a/OpenBudgeteer.Core/ViewModels/PageViewModels/DataConsistencyPageViewModel.cs +++ b/OpenBudgeteer.Core/ViewModels/PageViewModels/DataConsistencyPageViewModel.cs @@ -134,6 +134,33 @@ public async Task CheckBankTransactionIncompleteBuck { const string checkName = "Transactions with incomplete bucket assignment"; var results = new List>(); + + // Check on Transactions which have overall no Bucket assignments + var unassignedTransactions = ServiceManager.BankTransactionService + .GetAll(DateTime.MinValue, DateTime.MaxValue) + .GroupJoin( + ServiceManager.BudgetedTransactionService.GetAll(DateTime.MinValue, DateTime.MaxValue), + transaction => transaction.Id, + budgetedTransaction => budgetedTransaction.TransactionId, + (bankTransaction, budgetedTransactions) => new + { BankTransaction = bankTransaction, BudgetedTransactions = budgetedTransactions }) + .Where(i => !i.BudgetedTransactions.Any()) + .Select(i => i.BankTransaction) + .ToList(); + + foreach (var unassignedTransaction in unassignedTransactions) + { + results.Add(new( + DataConsistencyCheckResult.StatusCode.Warning, + [ + unassignedTransaction.TransactionDate.ToShortDateString(), + unassignedTransaction.Memo ?? string.Empty, + unassignedTransaction.Amount.ToString("C", CultureInfo.CurrentCulture), + new decimal(0).ToString("C", CultureInfo.CurrentCulture) + ])); + } + + // Check on incomplete assignments var findings = // Get all BudgetedTransaction which are not 1:1 budgeted (Missing Assignments or Split Transaction) ServiceManager.BudgetedTransactionService.GetAll(DateTime.MinValue, DateTime.MaxValue) @@ -158,14 +185,13 @@ public async Task CheckBankTransactionIncompleteBuck foreach (var finding in findings) { results.Add(new( - DataConsistencyCheckResult.StatusCode.Warning, - new[] - { + DataConsistencyCheckResult.StatusCode.Warning, + [ finding.Transaction.TransactionDate.ToShortDateString(), finding.Transaction.Memo ?? string.Empty, finding.TransactionAmount.ToString("C", CultureInfo.CurrentCulture), finding.BudgetedAmount.ToString("C", CultureInfo.CurrentCulture) - })); + ])); } if (!results.Any()) diff --git a/SECURITY.md b/SECURITY.md index 010337f..bde2f49 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -4,9 +4,9 @@ | Version | Supported | |-------------| ------------------ | -| 1.9 | :white_check_mark: | +| 1.9.1 | :white_check_mark: | | pre-release | :white_check_mark: | -| < 1.9 | :x: | +| < 1.9.1 | :x: | ## Reporting a Vulnerability