Inheritance: LedgerTransaction
        public void ConstructWithGuidShouldSetId()
        {
            Guid id = Guid.NewGuid();
            var subject = new CreditLedgerTransaction(id);

            Assert.AreEqual(id, subject.Id);
        }
        public void WithAmountMinus50ShouldCreateADebitOf50()
        {
            var subject = new CreditLedgerTransaction();

            LedgerTransaction result = subject.WithAmount(-50);

            Assert.AreEqual(-50M, result.Amount);
        }
        public void WithAmount50ShouldReturnSameObjectForChaining()
        {
            var subject = new CreditLedgerTransaction();

            LedgerTransaction result = subject.WithAmount(50);

            Assert.AreSame(subject, result);
        }
        public void WithReversal50ShouldCreateANegativeCreditOf50()
        {
            var subject = new CreditLedgerTransaction();

            LedgerTransaction result = subject.WithReversal(50);

            Assert.AreEqual(-50M, result.Credit);
        }
 public LedgerTransactionToDtoMapperTest()
 {
     TestData = new CreditLedgerTransaction(new Guid("7F921750-4467-4EA4-81E6-3EFD466341C6"))
     {
         Amount = 123.99M,
         Narrative = "Foo bar."
     };
 }
        public void WithReversal50ShouldAZeroDebitAmount()
        {
            var subject = new CreditLedgerTransaction();

            LedgerTransaction result = subject.WithReversal(50);

            Assert.AreEqual(0M, result.Debit);
        }
Exemplo n.º 7
0
        /// <summary>
        ///     Allows ledger bucket specific behaviour during reconciliation.
        /// </summary>
        /// <exception cref="System.ArgumentNullException"></exception>
        public override bool ApplyReconciliationBehaviour(IList <LedgerTransaction> transactions, DateTime reconciliationDate,
                                                          decimal openingBalance)
        {
            if (transactions == null)
            {
                throw new ArgumentNullException(nameof(transactions));
            }

            LedgerTransaction zeroingTransaction = null;
            var netAmount = transactions.Sum(t => t.Amount);

            // This ledger can accumulate a balance but cannot be negative.
            var closingBalance = openingBalance + netAmount;
            var budgetedAmount = transactions.FirstOrDefault(t => t is BudgetCreditLedgerTransaction);

            if (budgetedAmount != null && closingBalance < budgetedAmount.Amount)
            {
                // This ledger has a monthly budgeted amount and the balance has resulted in a balance less than the monthly budgeted amount, supplement from surplus to equal budgeted amount.
                // While there is a monthly amount the balance should not drop below this amount.
                zeroingTransaction = new CreditLedgerTransaction
                {
                    Date      = reconciliationDate,
                    Amount    = budgetedAmount.Amount - closingBalance,
                    Narrative = closingBalance < 0 ? SupplementOverdrawnText : SupplementLessThanBudgetText
                };
            }
            else if (closingBalance < 0)
            {
                zeroingTransaction = new CreditLedgerTransaction
                {
                    Date      = reconciliationDate,
                    Amount    = -closingBalance,
                    Narrative = SupplementOverdrawnText
                };
            }
            if (zeroingTransaction != null)
            {
                transactions.Add(zeroingTransaction);
                return(true);
            }

            return(false);
        }
Exemplo n.º 8
0
        /// <summary>
        ///     Allows ledger bucket specific behaviour during reconciliation.
        /// </summary>
        /// <exception cref="System.ArgumentNullException"></exception>
        public override void ApplyReconciliationBehaviour(IList<LedgerTransaction> transactions, DateTime reconciliationDate,
                                                          decimal openingBalance)
        {
            if (transactions == null)
            {
                throw new ArgumentNullException(nameof(transactions));
            }

            LedgerTransaction zeroingTransaction = null;
            var netAmount = transactions.Sum(t => t.Amount);

            // This ledger can accumulate a balance but cannot be negative.
            var closingBalance = openingBalance + netAmount;
            var budgetedAmount = transactions.FirstOrDefault(t => t is BudgetCreditLedgerTransaction);
            if (budgetedAmount != null && closingBalance < budgetedAmount.Amount)
            {
                // This ledger has a monthly budgeted amount and the balance has resulted in a balance less than the monthly budgeted amount, supplement from surplus to equal budgeted amount.
                // While there is a monthly amount the balance should not drop below this amount.
                zeroingTransaction = new CreditLedgerTransaction
                {
                    Date = reconciliationDate,
                    Amount = budgetedAmount.Amount - closingBalance,
                    Narrative = closingBalance < 0 ? SupplementOverdrawnText : SupplementLessThanBudgetText
                };
            }
            else if (closingBalance < 0)
            {
                zeroingTransaction = new CreditLedgerTransaction
                {
                    Date = reconciliationDate,
                    Amount = -closingBalance,
                    Narrative = SupplementOverdrawnText
                };
            }
            if (zeroingTransaction != null)
            {
                transactions.Add(zeroingTransaction);
            }
        }
        private void SaveNewEntryTransaction()
        {
            try
            {
                if (NewTransactionIsCredit || NewTransactionIsDebit)
                {
                    LedgerTransaction newTransaction;
                    if (NewTransactionIsCredit)
                    {
                        newTransaction = new CreditLedgerTransaction();
                    }
                    else
                    {
                        newTransaction = new DebitLedgerTransaction();
                    }

                    if (NewTransactionIsReversal)
                    {
                        newTransaction.WithReversal(NewTransactionAmount).WithNarrative(NewTransactionNarrative);
                    }
                    else
                    {
                        newTransaction.WithAmount(NewTransactionAmount).WithNarrative(NewTransactionNarrative);
                    }

                    if (NewTransactionAccountType != null)
                    {
                        newTransaction.WithAccountType(NewTransactionAccountType);
                    }

                    LedgerEntry.AddTransaction(newTransaction);
                    ShownTransactions.Add(newTransaction);
                }
            }
            catch (ArgumentException)
            {
                // Invalid transaction data
                return;
            }

            RaisePropertyChanged(() => TransactionsTotal);
            this.wasChanged = true;
        }
Exemplo n.º 10
0
        public LedgerTransaction BalanceAdjustment(decimal adjustment, string narrative)
        {
            if (!IsNew)
            {
                throw new InvalidOperationException("Cannot adjust existing ledger lines, only newly added lines can be adjusted.");
            }

            if (adjustment == 0)
            {
                throw new ArgumentException("The balance adjustment amount cannot be zero.", "adjustment");
            }

            LedgerTransaction newAdjustment;
            if (adjustment < 0)
            {
                newAdjustment = new DebitLedgerTransaction
                {
                    Debit = -adjustment,
                    Narrative = narrative,
                };
            }
            else
            {
                newAdjustment = new CreditLedgerTransaction
                {
                    Credit = adjustment,
                    Narrative = narrative,
                };
            }

            this.bankBalanceAdjustments.Add(newAdjustment);
            return newAdjustment;
        }
Exemplo n.º 11
0
        public LedgerTransaction CreateLedgerTransaction(LedgerEntryLine reconciliation, LedgerEntry ledgerEntry,
                                                         decimal amount, string narrative)
        {
            if (reconciliation == null)
            {
                throw new ArgumentNullException(nameof(reconciliation));
            }

            if (ledgerEntry == null)
            {
                throw new ArgumentNullException(nameof(ledgerEntry));
            }

            if (narrative == null)
            {
                throw new ArgumentNullException(nameof(narrative));
            }

            LedgerTransaction newTransaction = new CreditLedgerTransaction();
            newTransaction.WithAmount(amount).WithNarrative(narrative);
            newTransaction.Date = reconciliation.Date;
            ledgerEntry.AddTransaction(newTransaction);
            return newTransaction;
        }
Exemplo n.º 12
0
        private void PerformBankTransfer(TransferFundsCommand transferDetails, LedgerEntryLine ledgerEntryLine)
        {
            var sourceTransaction = new CreditLedgerTransaction
            {
                Amount = -transferDetails.TransferAmount,
                AutoMatchingReference = transferDetails.AutoMatchingReference,
                Date = ledgerEntryLine.Date,
                Narrative = transferDetails.Narrative
            };

            var destinationTransaction = new CreditLedgerTransaction
            {
                Amount = transferDetails.TransferAmount,
                AutoMatchingReference = transferDetails.AutoMatchingReference,
                Date = ledgerEntryLine.Date,
                Narrative = transferDetails.Narrative
            };

            if (transferDetails.BankTransferRequired)
            {
                ledgerEntryLine.BalanceAdjustment(-transferDetails.TransferAmount, transferDetails.Narrative,
                    transferDetails.FromLedger.StoredInAccount);
                ledgerEntryLine.BalanceAdjustment(transferDetails.TransferAmount, transferDetails.Narrative,
                    transferDetails.ToLedger.StoredInAccount);
                this.transactionRuleService.CreateNewSingleUseRule(
                    transferDetails.FromLedger.BudgetBucket.Code,
                    null,
                    new[] { transferDetails.AutoMatchingReference },
                    null,
                    -transferDetails.TransferAmount,
                    true);
                this.transactionRuleService.CreateNewSingleUseRule(
                    transferDetails.ToLedger.BudgetBucket.Code,
                    null,
                    new[] { transferDetails.AutoMatchingReference },
                    null,
                    transferDetails.TransferAmount,
                    true);
            }

            // No need for a source transaction for surplus ledger.
            if (!(transferDetails.FromLedger.BudgetBucket is SurplusBucket))
            {
                var ledgerEntry = ledgerEntryLine.Entries.Single(e => e.LedgerBucket == transferDetails.FromLedger);
                ledgerEntry.AddTransaction(sourceTransaction);
            }

            // No need for a destination transaction for surplus ledger.
            if (!(transferDetails.ToLedger.BudgetBucket is SurplusBucket))
            {
                var ledgerEntry = ledgerEntryLine.Entries.Single(e => e.LedgerBucket == transferDetails.ToLedger);
                ledgerEntry.AddTransaction(destinationTransaction);
            }
        }
Exemplo n.º 13
0
        /// <summary>
        ///     Called by <see cref="LedgerBook.Reconcile" />. Sets up this new Entry with transactions.
        /// </summary>
        /// <param name="newTransactions">The list of new transactions for this entry.</param>
        internal LedgerEntry SetTransactionsForReconciliation(List<LedgerTransaction> newTransactions)
        {
            this.transactions = newTransactions;
            if (LedgerColumn.BudgetBucket is SpentMonthlyExpenseBucket && NetAmount != 0)
            {
                // SpentMonthly ledgers automatically zero their balance. They dont accumulate nor can they be negative.
                LedgerTransaction zeroingTransaction = null;
                if (NetAmount < 0)
                {
                    if (newTransactions.OfType<BudgetCreditLedgerTransaction>().Any())
                    {
                        zeroingTransaction = new CreditLedgerTransaction
                        {
                            Credit = -NetAmount,
                            Narrative = "SpentMonthlyLedger: automatically supplementing shortfall from surplus",
                        };
                    }
                    else
                    {
                        if (Balance + NetAmount < 0)
                        {
                            zeroingTransaction = new CreditLedgerTransaction
                            {
                                Credit = -(Balance + NetAmount),
                                Narrative = "SpentMonthlyLedger: automatically supplementing shortfall from surplus",
                            };
                        }
                    }
                }
                else
                {
                    zeroingTransaction = new DebitLedgerTransaction
                    {
                        Debit = NetAmount,
                        Narrative = "SpentMonthlyLedger: automatically zeroing the credit remainder",
                    };
                }

                if (zeroingTransaction != null)
                {
                    this.transactions.Add(zeroingTransaction);
                }
            }
            else
            {
                // All other ledgers can accumulate a balance but cannot be negative.
                decimal newBalance = Balance + NetAmount;
                Balance = newBalance < 0 ? 0 : newBalance;
            }

            return this;
        }
Exemplo n.º 14
0
        public void UsingTestData1_AddTransactionShouldEffectEntryBalance()
        {
            ReconciliationResult entryLine = Act(this.subject, this.testDataBudget);
            var newTransaction = new CreditLedgerTransaction { Amount = -100 };
            LedgerEntry entry = entryLine.Reconciliation.Entries.First();
            entry.AddTransaction(newTransaction);

            this.subject.Output();
            Assert.AreEqual(20, entry.Balance);
        }