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); }
public async Task <string> WaitExportAvailability(string accountId, string lastImportedQifData, int secondsToWait = 20) { var sw = Stopwatch.StartNew(); bool available; var importedQifDom = QifMapper.ParseQifDom(lastImportedQifData); var importedByKey = importedQifDom.BankTransactions.ToLookup(s => s.GetBankTransactionLookupKey()); var importedKeys = new HashSet <string>(importedByKey.Select(i => i.Key)); string exportedQifData; QifDom lastExportedQifDom; do { exportedQifData = await ExportQif( accountId, importedQifDom.BankTransactions.Min(t => t.Date).AddDays(-1), importedQifDom.BankTransactions.Max(t => t.Date)); lastExportedQifDom = QifMapper.ParseQifDom(exportedQifData); var exportedbyKey = lastExportedQifDom.BankTransactions.ToLookup(s => s.GetBankTransactionLookupKey()); available = exportedbyKey.Select(s => s.Key).Where(importedKeys.Contains).Intersect(importedKeys).Count() == importedKeys.Count; if (!available) { _logger.Warn("number of imported items do not match number exported items yet"); } else { foreach (var importedKeyItems in importedByKey) { var exported = exportedbyKey[importedKeyItems.Key].ToList(); foreach (var importedKeyItem in importedKeyItems) { available = exported.Any(exportedKeyItem => string.Equals(importedKeyItem.Memo, exportedKeyItem.Memo, StringComparison.InvariantCultureIgnoreCase)); if (!available) { _logger.Warn($"item not available in export yet :{importedKeyItem.Number} - {importedKeyItem.Memo}"); break; } } if (!available) { break; } } } if (!available) { await Task.Delay(TimeSpan.FromMilliseconds(500)); } }while (sw.Elapsed.TotalSeconds < secondsToWait && !available); if (!available) { var rawExport = string.Join(Environment.NewLine, lastExportedQifDom.BankTransactions.Select( s => $"{s.GetBankTransactionLookupKey()} - {s.Amount} - {s.Memo}")); _logger.Debug($"Last received export{Environment.NewLine}{rawExport}"); throw new Exception($"Timeout, could not detect export availability during {secondsToWait} seconds"); } return(exportedQifData); }