public void TestIntialise() { this.mockRuleService = new Mock<ITransactionRuleService>(MockBehavior.Strict); this.mockReconciliationConsistency = new Mock<IReconciliationConsistency>(); this.bucketRepo = new BucketBucketRepoAlwaysFind(); this.testDataBudgets = BudgetModelTestData.CreateCollectionWith1And2(); this.testDataBudgetContext = new BudgetCurrencyContext(this.testDataBudgets, this.testDataBudgets.CurrentActiveBudget); this.testDataStatement = new StatementModelBuilder() .TestData5() .AppendTransaction(new Transaction { Account = StatementModelTestData.ChequeAccount, Amount = -23.56M, BudgetBucket = StatementModelTestData.RegoBucket, Date = ReconcileDate.Date.AddDays(-1), TransactionType = new NamedTransaction("Foo"), Description = "Last transaction" }) .Build(); this.testDataToDoList = new List<ToDoTask>(); this.subject = new ReconciliationManager(this.mockRuleService.Object, this.mockReconciliationConsistency.Object, new FakeLogger()); this.testDataLedgerBook = LedgerBookTestData.TestData5(() => new LedgerBookTestHarness(new Mock<IReconciliationBuilder>().Object)); this.mockReconciliationConsistency.Setup(m => m.EnsureConsistency(It.IsAny<LedgerBook>())).Returns(new Mock<IDisposable>().Object); }
public void TestIntialise() { this.mockRuleService = new Mock <ITransactionRuleService>(MockBehavior.Strict); this.mockReconciliationConsistency = new Mock <IReconciliationConsistency>(); this.bucketRepo = new BucketBucketRepoAlwaysFind(); this.testDataBudgets = BudgetModelTestData.CreateCollectionWith1And2(); this.testDataBudgetContext = new BudgetCurrencyContext(this.testDataBudgets, this.testDataBudgets.CurrentActiveBudget); this.testDataStatement = new StatementModelBuilder() .TestData5() .AppendTransaction(new Transaction { Account = StatementModelTestData.ChequeAccount, Amount = -23.56M, BudgetBucket = StatementModelTestData.RegoBucket, Date = ReconcileDate.Date.AddDays(-1), TransactionType = new NamedTransaction("Foo"), Description = "Last transaction" }) .Build(); this.testDataToDoList = new List <ToDoTask>(); this.subject = new ReconciliationCreationManager(this.mockRuleService.Object, this.mockReconciliationConsistency.Object, new FakeLogger()); this.testDataLedgerBook = LedgerBookTestData.TestData5(() => new LedgerBookTestHarness(new Mock <IReconciliationBuilder>().Object)); this.mockReconciliationConsistency.Setup(m => m.EnsureConsistency(It.IsAny <LedgerBook>())).Returns(new Mock <IDisposable>().Object); }
private int SearchForOtherNonLedgerBookOverspentBuckets( StatementModel statement, GlobalFilterCriteria filter, IBudgetCurrencyContext budget, IDictionary <BudgetBucket, decimal> overspendingSummary) { var warnings = 0; List <Transaction> transactions = statement.Transactions.Where(t => t.Date < filter.BeginDate?.Date.AddMonths(1)).ToList(); foreach (var expense in budget.Model.Expenses.Where(e => e.Bucket is BillToPayExpenseBucket)) { if (overspendingSummary.ContainsKey(expense.Bucket)) { continue; } var bucketBalance = expense.Amount + transactions.Where(t => t.BudgetBucket == expense.Bucket).Sum(t => t.Amount); overspendingSummary.Add(expense.Bucket, bucketBalance); if (bucketBalance < -Tolerance) { warnings++; } } return(warnings); }
public LedgerEntryLine MonthEndReconciliation( LedgerBook ledgerBook, DateTime reconciliationDate, IBudgetCurrencyContext budgetContext, StatementModel statement, bool ignoreWarnings, params BankBalance[] balances) { var reconResult = this.reconciliationManager.MonthEndReconciliation(ledgerBook, reconciliationDate, budgetContext, statement, ignoreWarnings, balances); ReconciliationToDoList.Clear(); reconResult.Tasks.ToList().ForEach(ReconciliationToDoList.Add); return(reconResult.Reconciliation); }
public static void Output(this IBudgetCurrencyContext instance) { Debug.WriteLine(string.Empty); Debug.WriteLine($"Budget Currency Context: {instance.FileName} Budget Name: {instance.Model.Name} Effective From: {instance.Model.EffectiveFrom:d} Effective Until: {instance.EffectiveUntil:d}"); if (instance.BudgetActive) { Debug.WriteLine("Budget is ACTIVE."); } else if (instance.BudgetArchived) { Debug.WriteLine("Budget is ARCHIVED."); } else if (instance.BudgetInFuture) { Debug.WriteLine("Budget is FUTURE."); } instance.Model.Output(false); }
private void ActOnTestData5(StatementModel statementModelTestData = null, bool ignoreWarnings = false) { this.testDataLedgerBook = LedgerBookTestData.TestData5(() => new LedgerBookTestHarness(new Mock <IReconciliationBuilder>().Object)); this.testDataBudgets = new BudgetCollection(new[] { BudgetModelTestData.CreateTestData5() }); this.testDataBudgetContext = new BudgetCurrencyContext(this.testDataBudgets, this.testDataBudgets.CurrentActiveBudget); this.testDataStatement = statementModelTestData ?? StatementModelTestData.TestData5(); Console.WriteLine("********************** BEFORE RUNNING RECONCILIATION *******************************"); this.testDataStatement.Output(ReconcileDate.AddMonths(-1)); this.testDataLedgerBook.Output(true); Act(bankBalances: new[] { new BankBalance(StatementModelTestData.ChequeAccount, 1850.5M), new BankBalance(StatementModelTestData.SavingsAccount, 1200M) }, ignoreWarnings: ignoreWarnings); Console.WriteLine(); Console.WriteLine("********************** AFTER RUNNING RECONCILIATION *******************************"); this.testDataLedgerBook.Output(true); }
public void TestInitialise() { this.bucketRepo = new BucketBucketRepoAlwaysFind(); this.subject = new RemainingSurplusWidget(); this.criteriaTestData = new GlobalFilterCriteria { BeginDate = new DateTime(2015, 10, 20), EndDate = new DateTime(2015, 11, 19) }; StatementModelTestDataForThisTest.AccountTypeRepo = new InMemoryAccountTypeRepository(); StatementModelTestDataForThisTest.BudgetBucketRepo = this.bucketRepo; this.statementTestData = StatementModelTestDataForThisTest.TestDataGenerated(); BudgetModel budgetModel = BudgetModelTestData.CreateTestData1(); this.budgetTestData = new BudgetCurrencyContext(new BudgetCollection(budgetModel), budgetModel); this.ledgerBookTestData = new LedgerBookBuilder { StorageKey = "RemainingSurplusWidgetTest.xml", Modified = new DateTime(2015, 11, 23), Name = "Smith Budget 2015" } .IncludeLedger(LedgerBookTestData.PhoneLedger, 130M) .IncludeLedger(LedgerBookTestData.CarMtcLedger, 90M) .IncludeLedger(LedgerBookTestData.PowerLedger) .AppendReconciliation( new DateTime(2015, 10, 20), new BankBalance(LedgerBookTestData.ChequeAccount, 4502.75M)) .WithReconciliationEntries( entryBuilder => { entryBuilder.WithLedger(LedgerBookTestData.PhoneLedger).HasNoTransactions(); entryBuilder.WithLedger(LedgerBookTestData.CarMtcLedger).HasNoTransactions(); entryBuilder.WithLedger(LedgerBookTestData.PowerLedger) .AppendTransactions(txnBuilder => { txnBuilder.WithCredit(3000M, "Oct Savings", new DateTime(2015, 10, 20), "automatchref12"); }); }) .Build(); this.ledgerCalculation = new LedgerCalculation(new FakeLogger()); }
public void TestInitialise() { this.subject = new BudgetBucketMonitorWidget(); this.subject.BucketCode = StatementModelTestData.PhoneBucket.Code; this.bucketRepo = new BucketBucketRepoAlwaysFind(); this.criteriaTestData = new GlobalFilterCriteria { BeginDate = new DateTime(2015, 10, 20), EndDate = new DateTime(2015, 11, 19) }; CreateStatementTestData(); BudgetModel budgetModel = BudgetModelTestData.CreateTestData5(); this.budgetTestData = new BudgetCurrencyContext(new BudgetCollection(budgetModel), budgetModel); CreateLedgerBookTestData(); this.ledgerCalculation = new LedgerCalculation(new FakeLogger()); }
public BudgetReadyMessage(IBudgetCurrencyContext activeBudget, BudgetCollection budgets = null) { ActiveBudget = activeBudget; Budgets = budgets; }
private int SearchForOtherNonLedgerBookOverspentBuckets( StatementModel statement, GlobalFilterCriteria filter, IBudgetCurrencyContext budget, IDictionary<BudgetBucket, decimal> overspendingSummary) { var warnings = 0; List<Transaction> transactions = statement.Transactions.Where(t => t.Date < filter.BeginDate?.Date.AddMonths(1)).ToList(); foreach (var expense in budget.Model.Expenses.Where(e => e.Bucket is BillToPayExpenseBucket)) { if (overspendingSummary.ContainsKey(expense.Bucket)) { continue; } var bucketBalance = expense.Amount + transactions.Where(t => t.BudgetBucket == expense.Bucket).Sum(t => t.Amount); overspendingSummary.Add(expense.Bucket, bucketBalance); if (bucketBalance < -Tolerance) { warnings++; } } return warnings; }
public ReconciliationResult MonthEndReconciliation( LedgerBook ledgerBook, DateTime reconciliationDate, IBudgetCurrencyContext budgetContext, StatementModel statement, bool ignoreWarnings, params BankBalance[] currentBankBalances) { if (ledgerBook == null) { throw new ArgumentNullException(nameof(ledgerBook)); } if (currentBankBalances == null) { throw new ArgumentNullException(nameof(currentBankBalances)); } if (budgetContext == null) { throw new ArgumentNullException(nameof(budgetContext)); } if (statement == null) { throw new ArgumentNullException(nameof(statement)); } if (!budgetContext.BudgetActive) { throw new ArgumentException("Reconciling against an inactive budget is invalid."); } var stopWatch = Stopwatch.StartNew(); this.logger.LogInfo(l => l.Format("Starting Ledger Book reconciliation {0}", DateTime.Now)); if (!ignoreWarnings) { this.validationMessages = new Collection <string>(); } try { PreReconciliationValidation(ledgerBook, reconciliationDate, statement); } catch (ValidationWarningException ex) { if (ShouldValidationExceptionBeRethrown(ignoreWarnings, ex)) { throw; } } ReconciliationResult recon; using (this.reconciliationConsistency.EnsureConsistency(ledgerBook)) { recon = ledgerBook.Reconcile(reconciliationDate, budgetContext.Model, statement, currentBankBalances); } // Create new single use matching rules - if needed to ensure transfers are assigned a bucket easily without user intervention. foreach (var task in recon.Tasks) { this.logger.LogInfo( l => l.Format("TASK: {0} SystemGenerated:{1}", task.Description, task.SystemGenerated)); var transferTask = task as TransferTask; if (transferTask != null && transferTask.SystemGenerated && transferTask.Reference.IsSomething()) { this.logger.LogInfo( l => l.Format( "TRANSFER-TASK detected- creating new single use rule. SystemGenerated:{1} Reference:{2}", task.Description, task.SystemGenerated, transferTask.Reference)); this.transactionRuleService.CreateNewSingleUseRule(transferTask.BucketCode, null, new[] { transferTask.Reference }, null, null, true); } } stopWatch.Stop(); this.logger.LogInfo(l => l.Format("Finished Ledger Book reconciliation {0}. It took {1:F0}ms", DateTime.Now, stopWatch.ElapsedMilliseconds)); this.validationMessages = null; return(recon); }
public LedgerEntryLine MonthEndReconciliation( LedgerBook ledgerBook, DateTime reconciliationDate, IBudgetCurrencyContext budgetContext, StatementModel statement, bool ignoreWarnings, params BankBalance[] balances) { var reconResult = this.reconciliationManager.MonthEndReconciliation(ledgerBook, reconciliationDate, budgetContext, statement, ignoreWarnings, balances); ReconciliationToDoList.Clear(); reconResult.Tasks.ToList().ForEach(ReconciliationToDoList.Add); return reconResult.Reconciliation; }
public ReconciliationResult MonthEndReconciliation( LedgerBook ledgerBook, DateTime reconciliationDate, IBudgetCurrencyContext budgetContext, StatementModel statement, bool ignoreWarnings, params BankBalance[] currentBankBalances) { if (ledgerBook == null) { throw new ArgumentNullException(nameof(ledgerBook)); } if (currentBankBalances == null) { throw new ArgumentNullException(nameof(currentBankBalances)); } if (budgetContext == null) { throw new ArgumentNullException(nameof(budgetContext)); } if (statement == null) { throw new ArgumentNullException(nameof(statement)); } if (!budgetContext.BudgetActive) { throw new ArgumentException("Reconciling against an inactive budget is invalid."); } var stopWatch = Stopwatch.StartNew(); this.logger.LogInfo(l => l.Format("Starting Ledger Book reconciliation {0}", DateTime.Now)); if (!ignoreWarnings) this.validationMessages = new Collection<string>(); try { PreReconciliationValidation(ledgerBook, reconciliationDate, statement); } catch (ValidationWarningException ex) { if (ShouldValidationExceptionBeRethrown(ignoreWarnings, ex)) throw; } ReconciliationResult recon; using (this.reconciliationConsistency.EnsureConsistency(ledgerBook)) { recon = ledgerBook.Reconcile(reconciliationDate, budgetContext.Model, statement, currentBankBalances); } // Create new single use matching rules - if needed to ensure transfers are assigned a bucket easily without user intervention. foreach (var task in recon.Tasks) { this.logger.LogInfo( l => l.Format("TASK: {0} SystemGenerated:{1}", task.Description, task.SystemGenerated)); var transferTask = task as TransferTask; if (transferTask != null && transferTask.SystemGenerated && transferTask.Reference.IsSomething()) { this.logger.LogInfo( l => l.Format( "TRANSFER-TASK detected- creating new single use rule. SystemGenerated:{1} Reference:{2}", task.Description, task.SystemGenerated, transferTask.Reference)); this.transactionRuleService.CreateNewSingleUseRule(transferTask.BucketCode, null, new[] { transferTask.Reference }, null, null, true); } } stopWatch.Stop(); this.logger.LogInfo(l => l.Format("Finished Ledger Book reconciliation {0}. It took {1:F0}ms", DateTime.Now, stopWatch.ElapsedMilliseconds)); this.validationMessages = null; return recon; }
private void ActOnTestData5(StatementModel statementModelTestData = null, bool ignoreWarnings = false) { this.testDataLedgerBook = LedgerBookTestData.TestData5(() => new LedgerBookTestHarness(new Mock<IReconciliationBuilder>().Object)); this.testDataBudgets = new BudgetCollection(new[] { BudgetModelTestData.CreateTestData5() }); this.testDataBudgetContext = new BudgetCurrencyContext(this.testDataBudgets, this.testDataBudgets.CurrentActiveBudget); this.testDataStatement = statementModelTestData ?? StatementModelTestData.TestData5(); Console.WriteLine("********************** BEFORE RUNNING RECONCILIATION *******************************"); this.testDataStatement.Output(ReconcileDate.AddMonths(-1)); this.testDataLedgerBook.Output(true); Act(bankBalances: new[] { new BankBalance(StatementModelTestData.ChequeAccount, 1850.5M), new BankBalance(StatementModelTestData.SavingsAccount, 1200M) }, ignoreWarnings: ignoreWarnings); Console.WriteLine(); Console.WriteLine("********************** AFTER RUNNING RECONCILIATION *******************************"); this.testDataLedgerBook.Output(true); }