private void TryToResolveAmbiguousItems(TransactionDeltaSet delta, List <BasicTransaction> potentialExports) { var ambiguousItemsGroups = delta.GetDeltaByAction(DeltaAction.MultipleTargetsPossible); var toImportSplittedMemos = ambiguousItemsGroups .ToDictionary(t => t, t => new HashSet <string>(t.Source.Memo.Split(' '))); var exportSplittedMemos = potentialExports.ToDictionary(t => t, t => new HashSet <string>(t.Memo.Split(' '))); var toImportItemsByKey = ambiguousItemsGroups.ToLookup(t => t.Source.GetBankTransactionLookupKey()); var exportedItemsByKey = potentialExports.ToLookup(t => t.GetBankTransactionLookupKey()); foreach (var toImportKeyItems in toImportItemsByKey) { var key = toImportKeyItems.Key; var exportedKeyItems = exportedItemsByKey[key].ToList(); var suggestedResolution = new List <Tuple <TransactionDelta, BasicTransaction> >(); foreach (var importedKeyItem in toImportKeyItems) { var importedKeyItemWords = toImportSplittedMemos[importedKeyItem]; var nearest = exportedKeyItems .OrderByDescending(exportedKeyITem => exportSplittedMemos[exportedKeyITem].Intersect(importedKeyItemWords).Count()) .FirstOrDefault(); if (nearest != null) { exportedKeyItems.Remove(nearest); suggestedResolution.Add(Tuple.Create(importedKeyItem, nearest)); } } if (suggestedResolution.Count == toImportKeyItems.Count()) { foreach (var tuple in suggestedResolution) { delta.SetUpdateMemoAction(tuple.Item1, tuple.Item2); } } } }
public async Task <TransactionDeltaSet> DryRunImport(string accountId, string availableQifData) { var availableQifDom = QifMapper.ParseQifDom(availableQifData); var minDate = availableQifDom.BankTransactions.Min(t => t.Date.AddDays(-1)); var maxDate = availableQifDom.BankTransactions.Max(t => t.Date); var exportedQifData = await ExportQif(accountId, minDate, maxDate); var exportedQifDom = QifMapper.ParseQifDom(exportedQifData); var exportedByKey = exportedQifDom.BankTransactions.ToLookup(s => s.GetBankTransactionLookupKey()); var delta = new TransactionDeltaSet(); foreach (var availableBt in availableQifDom.BankTransactions) { var key = availableBt.GetBankTransactionLookupKey(); if (!exportedByKey.Contains(key)) { delta.SetAddAction(availableBt); } else { var exportedSimilars = exportedByKey[key].ToList(); if (exportedSimilars.Count > 1) { var exportedSimilar = exportedSimilars.FirstOrDefault(s => !delta.IsTargetProcessed(s) && s.Memo == availableBt.Memo); if (exportedSimilar != null) { delta.SetNothingAction(availableBt, exportedSimilar); } else { delta.SetMultipleTargetsPossibleAction(availableBt); } } else { var exportedItem = exportedSimilars.Single(); if (exportedItem.Memo != availableBt.Memo) { delta.SetUpdateMemoAction(availableBt, exportedItem); } else { delta.SetNothingAction(availableBt, exportedItem); } } } } var potentialExports = exportedQifDom.BankTransactions.Where(t => !delta.IsTargetProcessed(t)).ToList(); TryToResolveAmbiguousItems(delta, potentialExports); var toRemoveItems = exportedQifDom.BankTransactions.Where(t => !delta.IsTargetProcessed(t)); foreach (var exportedItem in toRemoveItems) { delta.SetRemoveAction(exportedItem); } return(delta); }