Exemple #1
0
        public void TestDeleteTransaction()
        {
            // Transaction to delete
            var transaction = new Transaction
            {
                Amount = 100,
                CategoryName = "TestCat",
                Description = "TestDesc",
                FiTransactionId = "TRN1"
            };

            // Mock for Entity() call on context
            var mockEntityEntry = new Mock<DbEntityEntry<Transaction>>();
            mockEntityEntry.SetupAllProperties();

            // Mock setup for DataService
            var mockTransactionSet = new Mock<DbSet<Transaction>>();
            var mockContext = new Mock<SoCashDbContext>();
            mockContext.Setup(m => m.Set<Transaction>()).Returns(mockTransactionSet.Object);

            // Delete the transaction
            using (var service = new DataService(mockContext.Object))
                service.DeleteTransaction(transaction);

            // Verify that the service removed the transaction on the mock db exactly once
            mockTransactionSet.Verify(m => m.Remove(transaction), Times.Once());

            // Verify that the transaction ended properly
            mockContext.Verify(m => m.SaveChanges(), Times.Once());
        }
Exemple #2
0
        public void TestUpdateTransaction()
        {
            // Transaction used for test
            var transaction = new Transaction
            {
                Amount = 100,
                CategoryName = "TestCat",
                Description = "TestDesc",
                FiTransactionId = "TRN1"
            };

            // Mock setup for DataService
            var mockTransactionSet = new Mock<DbSet<Transaction>>();
            var mockContext = new Mock<SoCashDbContext>();
            mockContext.Setup(m => m.Set<Transaction>()).Returns(mockTransactionSet.Object);

            // Update the transaction
            using (var service = new DataService(mockContext.Object))
                service.UpdateTransaction(transaction);

            // Verify that the service joined the transaction to the session in a modified state
            mockContext.Verify(m => m.SetModified(transaction), Times.Once());

            // Verify that the transaction ended properly
            mockContext.Verify(m => m.SaveChanges(), Times.Once());
        }
Exemple #3
0
        public void TestAddTransaction()
        {
            // Mock setup for DataService
            var mockAccountSet = new Mock<DbSet<Account>>();
            var mockTransactionSet = new Mock<ICollection<Transaction>>();
            var mockContext = new Mock<SoCashDbContext>();

            // Account containing mock transaction set
            var account = new Account {Transactions = mockTransactionSet.Object};

            // Place mock account into mock account list
            var data = new List<Account>
            {
                account
            };
            mockAccountSet.As<IQueryable<Account>>().Setup(m => m.Provider).Returns(data.AsQueryable().Provider);
            mockAccountSet.As<IQueryable<Account>>().Setup(m => m.Expression).Returns(data.AsQueryable().Expression);
            mockAccountSet.As<IQueryable<Account>>().Setup(m => m.ElementType).Returns(data.AsQueryable().ElementType);
            mockAccountSet.As<IQueryable<Account>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator());
            mockContext.Setup(m => m.Accounts).Returns(mockAccountSet.Object);

            // Transaction to add
            var newTransaction = new Transaction
            {
                Amount = 100,
                CategoryName = "TestCat",
                Description = "TestDesc",
                FiTransactionId = "TRN1"
            };

            // Add the transaction
            using (var service = new DataService(mockContext.Object))
            {

                service.AddTransaction(account, newTransaction);
            }

            // Verify that the service added the transaction on the mock db exactly once
            mockTransactionSet.Verify(m => m.Add(newTransaction), Times.Once());

            // Verify that the transaction ended properly
            mockContext.Verify(m => m.SaveChanges(), Times.Once());
        }
        /// <summary>
        /// Merge transactions from the provided statement into the specified account
        /// </summary>
        /// <param name="account">The account into which transactions will be merged</param>
        /// <param name="statement">The statement containing the transactions to merge. The statement owning account ID must match the ID of the passed account.</param>
        public static void MergeStatementTransactionsIntoAccount(Account account, OFX.Types.Statement statement)
        {
            using (BackgroundTaskTracker.BeginTask("Processing Transactions"))
            {
                using (var dataService = new DataService())
                {
                    // Retrieve matching account from DB - we need to get an entity in the current db session
                    var updateAccount = dataService.GetAccountById(account.AccountId);

                    // If the account has no account ID set, set it from the imported statement
                    if (updateAccount.FiAccountId == null)
                        updateAccount.FiAccountId = statement.OwningAccount.AccountId;
                    else if (updateAccount.FiAccountId != statement.OwningAccount.AccountId)
                    {
                        // TODO: Raise an error - this statement does not match the specified account.
                    }

                    // Add each transaction, and keep track of the earliest and latest dates
                    DateTimeOffset earliestTransaction = DateTimeOffset.MaxValue;
                    DateTimeOffset latestTransaction = DateTimeOffset.MinValue;
                    foreach (var transaction in statement.Transactions)
                    {
                        // Update date of earliest and latest transaction
                        if (earliestTransaction > transaction.PostDate)
                            earliestTransaction = transaction.PostDate;
                        if (latestTransaction < transaction.PostDate)
                            latestTransaction = transaction.PostDate;

                        // See if transaction is already in db
                        try
                        {
                            var existingTransaction =
                                updateAccount.Transactions.First(t => t.FiTransactionId == transaction.TransactionId);

                            // Ensure amount and date of transaction match
                            existingTransaction.Amount = transaction.Amount;
                            existingTransaction.Date = transaction.PostDate.Date;
                        }
                        catch (InvalidOperationException)
                        {
                            // No such transaction, add entity

                            // Create model transaction
                            var dbTransaction = new Transaction
                            {
                                Amount = transaction.Amount,
                                CategoryName = "",
                                Date = transaction.PostDate.Date,
                                Description = transaction.Name,
                                FiTransactionId = transaction.TransactionId,

                            };
                            updateAccount.Transactions.Add(dbTransaction);

                        }
                    }

                    // Sum all transactions in the data set and ensure the balance on the date of the end of the statement matches the reported balance
                    var dbBalance = updateAccount.Transactions.Where(t => t.Date <= latestTransaction)
                        .Sum(t => t.Amount);
                    if (dbBalance != statement.AccountBalance)
                    {
                        // Need to add or modify a filler transaction
                        try
                        {
                            // Look for a pre-existing filler transaction as the transaction prior to the start of this statement
                            var fillerTransaction =
                                updateAccount.Transactions.Where(t => t.Date < earliestTransaction)
                                    .OrderByDescending(t => t.Date)
                                    .First();
                            // If this is not a balance adjustment transaction, move to creating a new transaction to adjust
                            if (fillerTransaction.Description != "Balance Adjustment")
                                throw new InvalidOperationException();

                            // An existing balance adjustment is in place. Modify;
                            fillerTransaction.Amount += (statement.AccountBalance - dbBalance);
                        }
                        catch (InvalidOperationException)
                        {
                            // Determine date of filler - don't use a date in the future
                            var fillerDate = (earliestTransaction - new TimeSpan(1, 0, 0, 0)).DateTime;
                            if (fillerDate > DateTime.Now)
                                fillerDate = DateTime.Now;

                            // No existing balance adjustment transaction exists. Add one.
                            var fillerTransaction = new Transaction
                            {
                                Amount = (statement.AccountBalance - dbBalance),
                                CategoryName = "BALADJUST",
                                Description = "Balance Adjustment",
                                FiTransactionId = Guid.NewGuid().ToString(),
                                Date = fillerDate
                            };
                            updateAccount.Transactions.Add(fillerTransaction);
                        }
                    }
                }
            }
        }
Exemple #5
0
 /// <summary>
 /// Update values of an existing transaction
 /// Called from the UI for edits
 /// </summary>
 /// <param name="transaction">Modified transaction</param>
 public void UpdateTransaction(Transaction transaction)
 {
     // Attach to context and mark as modified
     DbContext.SetModified(transaction);
 }
Exemple #6
0
 /// <summary>
 /// Delete a transaction from the database
 /// Called from the UI for manual entry
 /// </summary>
 /// <param name="transaction">Transaction to delete</param>
 public void DeleteTransaction(Transaction transaction)
 {
     // Add the transaction to the context in unchanged state creating a current reference
     DbContext.SetUnchanged(transaction);
     // Delete from database
     DbContext.Set<Transaction>().Remove(transaction);
 }
Exemple #7
0
 /// <summary>
 /// Add a new transaction to an account.
 /// Called from the UI for manual entry
 /// </summary>
 /// <param name="account">Account to add transactions to</param>
 /// <param name="transaction">Transaction to add</param>
 public void AddTransaction(Account account, Transaction transaction)
 {
     // Retrieve matching account from DB - we need to get an entity in the current db session
     var updateAccount = DbContext.Accounts.First(dbAccount => dbAccount.AccountId == account.AccountId);
     updateAccount.Transactions.Add(transaction);
 }