private List<LedgerTransaction> IncludeBudgetedAmount(BudgetModel currentBudget, LedgerBucket ledgerBucket, DateTime reconciliationDate) { var budgetedExpense = currentBudget.Expenses.FirstOrDefault(e => e.Bucket.Code == ledgerBucket.BudgetBucket.Code); var transactions = new List<LedgerTransaction>(); if (budgetedExpense != null) { BudgetCreditLedgerTransaction budgetedAmount; if (ledgerBucket.StoredInAccount.IsSalaryAccount) { budgetedAmount = new BudgetCreditLedgerTransaction { Amount = budgetedExpense.Bucket.Active ? budgetedExpense.Amount : 0, Narrative = budgetedExpense.Bucket.Active ? "Budgeted Amount" : "Warning! Bucket has been disabled." }; } else { budgetedAmount = new BudgetCreditLedgerTransaction { Amount = budgetedExpense.Bucket.Active ? budgetedExpense.Amount : 0, Narrative = budgetedExpense.Bucket.Active ? "Budget amount must be transferred into this account with a bank transfer, use the reference number for the transfer." : "Warning! Bucket has been disabled.", AutoMatchingReference = ReferenceNumberGenerator.IssueTransactionReferenceNumber() }; // TODO Maybe the budget should know which account the incomes go into, perhaps mapped against each income? var salaryAccount = this.newReconciliationLine.BankBalances.Single(b => b.Account.IsSalaryAccount).Account; this.toDoList.Add( new TransferTask( string.Format( CultureInfo.CurrentCulture, "Budgeted Amount for {0} transfer {1:C} from Salary Account to {2} with auto-matching reference: {3}", budgetedExpense.Bucket.Code, budgetedAmount.Amount, ledgerBucket.StoredInAccount, budgetedAmount.AutoMatchingReference), true) { Amount = budgetedAmount.Amount, SourceAccount = salaryAccount, DestinationAccount = ledgerBucket.StoredInAccount, BucketCode = budgetedExpense.Bucket.Code, Reference = budgetedAmount.AutoMatchingReference }); } budgetedAmount.Date = reconciliationDate; transactions.Add(budgetedAmount); } return transactions; }
public TransactionTestDataBuilder WithBudgetCredit(decimal amount, DateTime? date = null, string automatchingRef = null) { BudgetCreditLedgerTransaction budgetTxn = this.transactions.OfType<BudgetCreditLedgerTransaction>().FirstOrDefault(); if (budgetTxn == null) { budgetTxn = new BudgetCreditLedgerTransaction { AutoMatchingReference = automatchingRef, Date = date, Narrative = "Budgeted Amount" }; this.transactions.Add(budgetTxn); } budgetTxn.Amount = amount; return this; }
/// <summary> /// Called by <see cref="LedgerBook.Reconcile" />. It builds the contents of the new ledger line based on budget and /// statement input. /// </summary> /// <param name="previousEntries"> /// A collection of previous <see cref="LedgerEntry" />s to construct the running balance for /// the entries this line contains. /// </param> /// <param name="currentBudget">The current applicable budget</param> /// <param name="statement">The current period statement.</param> /// <param name="startDateIncl">The date for this ledger line.</param> internal void AddNew(IEnumerable<KeyValuePair<LedgerColumn, LedgerEntry>> previousEntries, BudgetModel currentBudget, StatementModel statement, DateTime startDateIncl) { if (!IsNew) { throw new InvalidOperationException("Cannot add a new entry to an existing Ledger Line, only new Ledger Lines can have new entries added."); } DateTime finishDateExcl = Date; List<Transaction> filteredStatementTransactions = statement == null ? new List<Transaction>() : statement.AllTransactions.Where(t => t.Date >= startDateIncl && t.Date < finishDateExcl).ToList(); foreach (var previousEntry in previousEntries) { LedgerColumn ledger = previousEntry.Key; decimal balance = previousEntry.Value == null ? 0 : previousEntry.Value.Balance; var newEntry = new LedgerEntry(true) { Balance = balance, LedgerColumn = ledger }; Expense expenseBudget = currentBudget.Expenses.FirstOrDefault(e => e.Bucket.Code == ledger.BudgetBucket.Code); var transactions = new List<LedgerTransaction>(); if (expenseBudget != null) { var budgetedAmount = new BudgetCreditLedgerTransaction { Credit = expenseBudget.Amount, Narrative = "Budgeted Amount" }; transactions.Add(budgetedAmount); } transactions.AddRange(IncludeStatementTransactions(newEntry, filteredStatementTransactions)); newEntry.SetTransactionsForReconciliation(transactions); this.entries.Add(newEntry); } }
/// <summary> /// Use this method to remove all funds from this ledger. This is commonly used periodically if overbudgeted and funds /// can be safely used elsewhere. /// By zeroing the balance the surplus will increase. /// </summary> public void ZeroTheBalance(string narrative = null) { if (!this.isNew) { throw new InvalidOperationException("This is not a new entry and therefore cannot be altered. Only newly created entries from creating a new reconciliation can use this operation."); } if (Balance <= 0) { return; } var zeroTxn = new BudgetCreditLedgerTransaction { Debit = Balance, Narrative = narrative ?? "Zeroing balance - excess funds in this account." }; this.transactions.Add(zeroTxn); Balance = 0; }