public void Process(IList <Transaction> transactions) { bool processed; // Prepare for processing by loading the entries and current periods. initializeForProcessing(); if ((mProcessingRules != null) && (transactions != null)) { var changedYears = new List <int>(); foreach (var transaction in transactions) { processed = false; foreach (var rule in mProcessingRules) { if (rule.AppliesTo(transaction)) { // When the entry is null then the transaction should be ignored. if (rule.Entry != null) { var entryPeriod = getEntryPeriodForTransaction(transaction, rule); if (entryPeriod == null) { // A new period and entry-period combination need to be created first. mPeriodDataService.AddUsingTransactionDate(transaction.Date); // Reload the list of entry-date combinations. getEntryPeriodList(); // Now get the brand new EntryPeriod combination. entryPeriod = getEntryPeriodForTransaction(transaction, rule); } transaction.EntryPeriodKey = entryPeriod.Key; transaction.EntryPeriod = entryPeriod; entryPeriod.TotalAmount += transaction.Amount; mTransactionDataService.Update(transaction); mEntryPeriodDataService.Update(entryPeriod); // Update the parent (total) entries updateParentTotals(entryPeriod, transaction.Amount); // We're done. mLogFile.Info( $"Transaction: {transaction} is added to entry {entryPeriod.Entry.Description}, period {entryPeriod.Period}, due to rule {rule.Priority.ToString()}"); mTransactionProcessedCount++; } else { mTransactionsIgnoredCount++; } processed = true; signalDataProcessed(); break; } } if (processed) { if (!changedYears.Contains(transaction.Date.Year)) { changedYears.Add(transaction.Date.Year); } } else { mLogFile.Warning($"There is no rule to process transaction: {transaction}"); } } mEventAggregator.GetEvent <DataChangedEvent>().Publish(new DataChangedEventArgs(changedYears)); } }