Skip to content

Commit

Permalink
- Fix bugs in finding potential duplicate transactions to merge.
Browse files Browse the repository at this point in the history
- Fix bug in keeping correct selection after merging duplicates.
  • Loading branch information
clovett committed Apr 3, 2022
1 parent 58b5f88 commit dfe3048
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 14 deletions.
38 changes: 26 additions & 12 deletions Source/WPF/MyMoney/Database/Money.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8524,9 +8524,8 @@ public static bool IsRecurring(Transaction t, Transaction u, IList<Transaction>
// same (or similar) TimeSpan then this might be a recurring transaction.
TimeSpan span = t.Date - u.Date;
decimal days = (decimal)Math.Abs(span.TotalDays);
if (days == 0 || t.Amount == 0)
if (days == 0)
{
// unlikely to have a recurring payment on the same day or for zero dollars!
return false;
}

Expand All @@ -8540,7 +8539,8 @@ public static bool IsRecurring(Transaction t, Transaction u, IList<Transaction>
i = j;
}

List<double> daysBetween = new List<double>();
// create a new list so we can sort by date, since 'tc' is not necessarily yet.
List<Transaction> similarTransactions = new List<Transaction>();
for (--i; i > 0; i--)
{
Transaction w = tc[i];
Expand All @@ -8553,19 +8553,34 @@ public static bool IsRecurring(Transaction t, Transaction u, IList<Transaction>
// then it is probably a recurring instance.
if (w.PayeeName == t.PayeeName && Math.Abs((w.Amount - t.Amount) * 100 / t.Amount) < amountDeltaPercent)
{
TimeSpan diff = start.Date - w.Date;
similarTransactions.Add(w);
if (similarTransactions.Count > 10)
{
break; // should be enough.
}
}
}

if (similarTransactions.Count < recurringCount)
{
return false;
}

similarTransactions.Sort((x, y) => { return x.Date.CompareTo(y.Date); });

List<double> daysBetween = new List<double>();
Transaction previous = null;
foreach (Transaction s in similarTransactions) {
if (previous != null)
{
TimeSpan diff = s.Date - previous.Date;
double diffDays = Math.Abs(diff.TotalDays);
if (diffDays > 0)
{ // weed out duplicate payments.
{
daysBetween.Add(diffDays);
if (daysBetween.Count > 10)
{
// that should be enough to see the pattern.
break;
}
start.Date = w.Date;
}
}
previous = s;
}

var filtered = MathHelpers.RemoveOutliers(daysBetween, 1);
Expand All @@ -8591,7 +8606,6 @@ private static bool IsPotentialDuplicate(Transaction t, Transaction u, int dayRa
// and if they are investment transactions the stock type and unit quanities have to be the same
IsPotentialDuplicate(t.Investment, u.Investment) &&
// if they both have unique FITID fields, then the bank is telling us these are not duplicates.
(string.IsNullOrEmpty(t.FITID) || string.IsNullOrEmpty(u.FITID) || t.FITID == u.FITID) &&
// they can't be both reconciled, because then we can't merge them!
(u.Status != TransactionStatus.Reconciled || t.Status != TransactionStatus.Reconciled) &&
// within specified date range
Expand Down
2 changes: 2 additions & 0 deletions Source/WPF/MyMoney/Setup/changes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
<change version="2.0.0.4" date="3/23/2022">
- Add a way to link downloaded .pdf bank statements with your reconciled accounts during balancing
- Add "Goto Statement" on transactions that automatically find and open any linked .pdf statement.
- Fix bugs in finding potential duplicate transactions to merge.
- Fix bug in keeping correct selection after merging duplicates.
</change>
<change version="2.0.0.3" date="3/23/2022">
- A few minor dark theme fixes, the save popup link color and message box icons.
Expand Down
31 changes: 29 additions & 2 deletions Source/WPF/MyMoney/View Selectors/AccountsControl.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ public AccountViewModel Selected
#endregion

#region EVENTS

private bool hideEvents;
public event EventHandler SelectionChanged;
public event EventHandler<ChangeEventArgs> BalanceAccount;
public event EventHandler<ChangeEventArgs> SyncAccount;
Expand Down Expand Up @@ -342,6 +342,7 @@ void Rebind()
{
UpdateContextMenuView();

this.hideEvents = true;
if (myMoney != null)
{
//---------------------------------------------------------
Expand Down Expand Up @@ -396,6 +397,7 @@ void Rebind()
{
this.items.Clear();
}
this.hideEvents = false;
}


Expand Down Expand Up @@ -479,7 +481,13 @@ void RaiseSelectionEvent(AccountViewModel selected, bool force)
if ((force || this.selected != selected) && SelectionChanged != null)
{
SetSelected(selected);
SelectionChanged(this, EventArgs.Empty);

// checked it really is a different account (could be different object
// but the same account because of a rebind).
if (!hideEvents)
{
SelectionChanged(this, EventArgs.Empty);
}
}
}

Expand Down Expand Up @@ -878,6 +886,15 @@ public AccountItemViewModel(Account a)
this.account.PropertyChanged -= OnPropertyChanged;
}

public override bool Equals(object obj)
{
if (obj is AccountItemViewModel m)
{
return m.account == this.account;
}
return false;
}

protected override void OnSelectedChanged()
{
OnPropertyChanged("NameForeground");
Expand Down Expand Up @@ -1080,6 +1097,16 @@ public string Name

public string Title { get; set; }

public override bool Equals(object obj)
{
if (obj is AccountSectionHeader m)
{
return m.Title == this.Title;
}
return false;
}


public decimal BalanceInNormalizedCurrencyValue {
get => balanceNormalized;
set {
Expand Down

0 comments on commit dfe3048

Please sign in to comment.