private static Entities.Budget BudgetFromElement( XElement element, Dictionary <string, Entities.Account> accountsByName) { string name = GetRequiredAttribute(element, "name").Value; string period = GetRequiredAttribute(element, "period").Value; var budget = new Entities.Budget { Name = name, Period = (BudgetPeriod)Enum.Parse(typeof(BudgetPeriod), period), Transactions = element .Elements(XName.Get("BudgetTransaction")) .Select(e => BudgetTransactionFromElement(e, accountsByName)).ToList() }; if (budget.Transactions.Count(t => t.IsInitial) != 1) { throw new ArgumentException("Budget element must have exactly one initial transaction", nameof(element)); } if (budget.Transactions.Count(t => t.IsSurplus) != 1) { throw new ArgumentException("Budget element must have exactly one surplus transaction", nameof(element)); } return(budget); }
public void Create(Budget budget) { if (budget == null) { throw new ArgumentNullException(nameof(budget)); } if (budget.InitialTransaction == null) { throw new ArgumentException("InitialTransaction cannot be null", nameof(budget)); } if (budget.SurplusTransaction == null) { throw new ArgumentException("SurplusTransaction cannot be null", nameof(budget)); } using (var transaction = m_dbContext.Database.BeginTransaction()) { var budgetEntity = new Entities.Budget { Name = budget.Name, Period = budget.Period }; m_dbContext.Budgets.Add(budgetEntity); m_dbContext.SaveChanges(); Entities.BudgetTransaction initialTransactionEntity = ToEntity(budgetEntity, budget.InitialTransaction); initialTransactionEntity.IsInitial = true; m_dbContext.BudgetTransactions.Add(initialTransactionEntity); List <Entities.BudgetTransaction> transactionEntities = budget.Transactions .Select(t => ToEntity(budgetEntity, t)) .ToList(); m_dbContext.BudgetTransactions.AddRange(transactionEntities); Entities.BudgetTransaction surplusTransactionEntity = ToEntity(budgetEntity, budget.SurplusTransaction); surplusTransactionEntity.IsSurplus = true; m_dbContext.BudgetTransactions.Add(surplusTransactionEntity); m_dbContext.SaveChanges(); transaction.Commit(); // Update IDs budget.BudgetId = budgetEntity.BudgetId; budget.InitialTransaction.BudgetTransactionId = initialTransactionEntity.BudgetTransactionId; for (int transactionIndex = 0; transactionIndex < budget.Transactions.Count(); ++transactionIndex) { budget.Transactions.ElementAt(transactionIndex).BudgetTransactionId = transactionEntities[transactionIndex].BudgetTransactionId; } budget.SurplusTransaction.BudgetTransactionId = surplusTransactionEntity.BudgetTransactionId; } }
private static XElement ElementFromBudget(Entities.Budget budget) { var element = new XElement(XName.Get("Budget"), new XAttribute(XName.Get("name"), budget.Name), new XAttribute(XName.Get("period"), budget.Period), budget.Transactions.Select(ElementFromBudgetTransaction) ); return(element); }
public void Delete(int budgetId) { Entities.Budget budgetEntity = m_dbContext.Budgets.SingleOrDefault(b => b.BudgetId == budgetId); if (budgetEntity == null) { throw new ArgumentException($"No Budget exists with BudgetId {budgetId}", nameof(budgetId)); } m_dbContext.Budgets.Remove(budgetEntity); m_dbContext.SaveChanges(); }
public void Update(Budget budget) { Entities.Budget budgetEntity = m_dbContext.Budgets .Include(b => b.Transactions) .Single(b => b.BudgetId == budget.BudgetId); budgetEntity.Name = budget.Name; budgetEntity.Period = (BudgetPeriod)budget.Period; Entities.BudgetTransaction initialTransactionEntity = budgetEntity.Transactions.Single(t => t.IsInitial); UpdateTransactionEntity(budget.InitialTransaction, initialTransactionEntity); List <Entities.BudgetTransaction> transactionEntities = budgetEntity.Transactions .Where(t => !t.IsInitial && !t.IsSurplus) .ToList(); var transactionIds = new HashSet <int>( budget.Transactions .Select(t => t.BudgetTransactionId) ); foreach (Entities.BudgetTransaction transactionEntity in transactionEntities) { if (transactionIds.Contains(transactionEntity.BudgetTransactionId)) { // update existing transaction BudgetTransaction transaction = budget.Transactions .Single(t => t.BudgetTransactionId == transactionEntity.BudgetTransactionId); UpdateTransactionEntity(transaction, transactionEntity); } else { // remove missing transaction budgetEntity.Transactions.Remove(transactionEntity); } } // add new transactions var transactionEntityIds = new HashSet <int>(transactionEntities.Select(t => t.BudgetTransactionId)); IEnumerable <BudgetTransaction> transactionsWithNoEntity = budget.Transactions.Where(t => !transactionEntityIds.ToList().Contains(t.BudgetTransactionId)); foreach (BudgetTransaction transactionWithNoEntity in transactionsWithNoEntity) { budgetEntity.Transactions.Add(ToEntity(budgetEntity, transactionWithNoEntity)); } Entities.BudgetTransaction surplusTransactionEntity = budgetEntity.Transactions.Single(t => t.IsSurplus); UpdateTransactionEntity(budget.SurplusTransaction, surplusTransactionEntity); m_dbContext.SaveChanges(); }
private static Entities.BudgetTransaction ToEntity(Entities.Budget budgetEntity, BudgetTransaction budgetTransaction) { var transactionEntity = new Entities.BudgetTransaction { Budget = budgetEntity, CreditAccountId = budgetTransaction.CreditAccount.AccountId, DebitAccountId = budgetTransaction.DebitAccount.AccountId, Amount = budgetTransaction.Amount, IsInitial = false, IsSurplus = false }; return(transactionEntity); }
public Budget Get(int budgetId) { Entities.Budget budgetEntity = m_dbContext.Budgets .Include(b => b.Transactions) .ThenInclude(t => t.CreditAccount) .Include(b => b.Transactions) .ThenInclude(t => t.DebitAccount) .SingleOrDefault(b => b.BudgetId == budgetId); if (budgetEntity == null) { throw new ArgumentException($"No Budget exists with BudgetId {budgetId}", nameof(budgetId)); } return(FromEntity(budgetEntity)); }
private static Budget FromEntity(Entities.Budget budgetEntity) { Entities.BudgetTransaction initialTransactionEntity = budgetEntity.Transactions.Single(t => t.IsInitial); IEnumerable <Entities.BudgetTransaction> transactionEntities = budgetEntity.Transactions.Where(t => !t.IsInitial && !t.IsSurplus); Entities.BudgetTransaction surplusTransactionEntity = budgetEntity.Transactions.Single(t => t.IsSurplus); var budget = new Budget { BudgetId = budgetEntity.BudgetId, Name = budgetEntity.Name, Period = (BudgetPeriod)budgetEntity.Period, InitialTransaction = FromEntity(initialTransactionEntity), Transactions = transactionEntities.Select(FromEntity).ToList(), SurplusTransaction = FromEntity(surplusTransactionEntity), }; return(budget); }
public void TestBudgetEditViewModelOK() { ILoggerFactory loggerFactory = new LoggerFactory(); using (var sqliteMemoryWrapper = new SqliteMemoryWrapper()) { var currencyFactory = new CurrencyFactory(); Entities.Currency usdCurrencyEntity = currencyFactory.Create(CurrencyPrefab.Usd, true); currencyFactory.Add(sqliteMemoryWrapper.DbContext, usdCurrencyEntity); var accountFactory = new AccountFactory(); Entities.Account incomeAccountEntity = accountFactory.Create(AccountPrefab.Income, usdCurrencyEntity); Entities.Account checkingAccountEntity = accountFactory.Create(AccountPrefab.Checking, usdCurrencyEntity); Entities.Account savingsAccountEntity = accountFactory.Create(AccountPrefab.Savings, usdCurrencyEntity); Entities.Account rentPrepaymentAccountEntity = accountFactory.Create(AccountPrefab.RentPrepayment, usdCurrencyEntity); Entities.Account rentExpenseAccountEntity = accountFactory.Create(AccountPrefab.RentExpense, usdCurrencyEntity); Entities.Account groceriesPrepaymentAccountEntity = accountFactory.Create(AccountPrefab.GroceriesPrepayment, usdCurrencyEntity); Entities.Account groceriesExpenseAccountEntity = accountFactory.Create(AccountPrefab.GroceriesExpense, usdCurrencyEntity); accountFactory.Add(sqliteMemoryWrapper.DbContext, incomeAccountEntity); accountFactory.Add(sqliteMemoryWrapper.DbContext, checkingAccountEntity); accountFactory.Add(sqliteMemoryWrapper.DbContext, savingsAccountEntity); accountFactory.Add(sqliteMemoryWrapper.DbContext, rentPrepaymentAccountEntity); accountFactory.Add(sqliteMemoryWrapper.DbContext, rentExpenseAccountEntity); accountFactory.Add(sqliteMemoryWrapper.DbContext, groceriesPrepaymentAccountEntity); accountFactory.Add(sqliteMemoryWrapper.DbContext, groceriesExpenseAccountEntity); var checkingToRentPrepaymentRelationship = new Entities.AccountRelationship { SourceAccount = checkingAccountEntity, DestinationAccount = rentPrepaymentAccountEntity, Type = AccountRelationshipType.PhysicalToLogical }; var checkingToGroceriesPrepaymentRelationship = new Entities.AccountRelationship { SourceAccount = checkingAccountEntity, DestinationAccount = groceriesPrepaymentAccountEntity, Type = AccountRelationshipType.PhysicalToLogical }; var rentPrepaymentToExpenseRelationship = new Entities.AccountRelationship { SourceAccount = rentPrepaymentAccountEntity, DestinationAccount = rentExpenseAccountEntity, Type = AccountRelationshipType.PrepaymentToExpense }; var groceriesPrepaymentToExpenseRelationship = new Entities.AccountRelationship { SourceAccount = groceriesPrepaymentAccountEntity, DestinationAccount = groceriesExpenseAccountEntity, Type = AccountRelationshipType.PrepaymentToExpense }; sqliteMemoryWrapper.DbContext.AccountRelationships.Add(checkingToRentPrepaymentRelationship); sqliteMemoryWrapper.DbContext.AccountRelationships.Add(checkingToGroceriesPrepaymentRelationship); sqliteMemoryWrapper.DbContext.AccountRelationships.Add(rentPrepaymentToExpenseRelationship); sqliteMemoryWrapper.DbContext.AccountRelationships.Add(groceriesPrepaymentToExpenseRelationship); sqliteMemoryWrapper.DbContext.SaveChanges(); var budget = new Entities.Budget { Name = "Budget", Period = BudgetPeriod.Fortnightly }; sqliteMemoryWrapper.DbContext.Budgets.Add(budget); sqliteMemoryWrapper.DbContext.SaveChanges(); var initialTransaction = new Entities.BudgetTransaction { CreditAccount = incomeAccountEntity, DebitAccount = checkingAccountEntity, Amount = 200m, IsInitial = true, Budget = budget }; var rentTransaction = new Entities.BudgetTransaction { CreditAccount = checkingAccountEntity, DebitAccount = rentPrepaymentAccountEntity, Amount = 100m, Budget = budget }; var groceriesTransaction = new Entities.BudgetTransaction { CreditAccount = checkingAccountEntity, DebitAccount = groceriesPrepaymentAccountEntity, Amount = 50m, Budget = budget }; var surplusTransaction = new Entities.BudgetTransaction { CreditAccount = checkingAccountEntity, DebitAccount = groceriesPrepaymentAccountEntity, IsSurplus = true, Budget = budget }; sqliteMemoryWrapper.DbContext.BudgetTransactions.Add(initialTransaction); sqliteMemoryWrapper.DbContext.BudgetTransactions.Add(rentTransaction); sqliteMemoryWrapper.DbContext.BudgetTransactions.Add(groceriesTransaction); sqliteMemoryWrapper.DbContext.BudgetTransactions.Add(surplusTransaction); sqliteMemoryWrapper.DbContext.SaveChanges(); var accountService = new AccountService( loggerFactory, sqliteMemoryWrapper.DbContext); var budgetService = new BudgetService( loggerFactory, sqliteMemoryWrapper.DbContext); var mockTransactionItemViewModelFactory = new Mock <IBudgetTransactionItemViewModelFactory>(); mockTransactionItemViewModelFactory .Setup(f => f.Create( It.IsAny <ObservableCollection <IAccountLinkViewModel> >(), It.IsAny <BudgetTransaction>(), It.IsAny <BudgetTransactionType>())) .Returns( (ObservableCollection <IAccountLinkViewModel> accountLinks, BudgetTransaction budgetTransaction, BudgetTransactionType type) => { return(new BudgetTransactionItemViewModel( loggerFactory, accountLinks, budgetTransaction, type)); }); var mockTransactionListViewModelFactory = new Mock <IBudgetTransactionListViewModelFactory>(); mockTransactionListViewModelFactory .Setup(f => f.Create(It.IsAny <int>())) .Returns((int budgetId) => { return(new BudgetTransactionListViewModel( loggerFactory, accountService, budgetService, new Concrete.StubAccountLinkViewModelFactory(), mockTransactionItemViewModelFactory.Object, new Mock <IDeleteConfirmationViewService>().Object, budgetId )); }); var viewModel = new BudgetEditViewModel( loggerFactory, budgetService, mockTransactionListViewModelFactory.Object, budget.BudgetId ); viewModel.Name = "My First Budget"; viewModel.SelectedPeriod = BudgetPeriod.Monthly; viewModel.OKCommand.Execute(this); List <Budget> budgets = budgetService.GetAll().ToList(); Assert.AreEqual(1, budgets.Count); Assert.AreEqual(viewModel.Name, budgets[0].Name); Assert.AreEqual(viewModel.SelectedPeriod, budgets[0].Period); Assert.AreEqual(initialTransaction.CreditAccountId, budgets[0].InitialTransaction.CreditAccount.AccountId); Assert.AreEqual(initialTransaction.DebitAccountId, budgets[0].InitialTransaction.DebitAccount.AccountId); Assert.AreEqual(initialTransaction.Amount, budgets[0].InitialTransaction.Amount); Assert.AreEqual(surplusTransaction.CreditAccountId, budgets[0].SurplusTransaction.CreditAccount.AccountId); Assert.AreEqual(surplusTransaction.DebitAccountId, budgets[0].SurplusTransaction.DebitAccount.AccountId); Assert.AreEqual(surplusTransaction.Amount, budgets[0].SurplusTransaction.Amount); Assert.AreEqual(2, budgets[0].Transactions.Count()); } }
public void TestReloadBudget() { const string path = "TestData/BudgetReload.xml"; ILoggerFactory loggerFactory = new LoggerFactory(); var currencyFactory = new CurrencyFactory(); Entities.Currency usdCurrencyEntity = currencyFactory.Create(CurrencyPrefab.Usd, true); var accountFactory = new AccountFactory(); Entities.Account incomeAccountEntity = accountFactory.Create(AccountPrefab.Income, usdCurrencyEntity); Entities.Account checkingAccountEntity = accountFactory.Create(AccountPrefab.Checking, usdCurrencyEntity); Entities.Account rentPrepaymentAccountEntity = accountFactory.Create(AccountPrefab.RentPrepayment, usdCurrencyEntity); Entities.Account savingsAccountEntity = accountFactory.Create(AccountPrefab.Savings, usdCurrencyEntity); var accountRelationship = new Entities.AccountRelationship { SourceAccount = checkingAccountEntity, DestinationAccount = rentPrepaymentAccountEntity, Type = AccountRelationshipType.PhysicalToLogical }; var budget = new Entities.Budget { Name = "The Budget", Period = BudgetPeriod.Fortnightly, Transactions = new List <Entities.BudgetTransaction> { new Entities.BudgetTransaction { CreditAccount = incomeAccountEntity, DebitAccount = checkingAccountEntity, Amount = 100m, IsInitial = true }, new Entities.BudgetTransaction { CreditAccount = checkingAccountEntity, DebitAccount = rentPrepaymentAccountEntity, Amount = 80m, }, new Entities.BudgetTransaction { CreditAccount = checkingAccountEntity, DebitAccount = savingsAccountEntity, Amount = 100m, IsSurplus = true } } }; using (var sqliteMemoryWrapper = new SqliteMemoryWrapper()) { currencyFactory.Add(sqliteMemoryWrapper.DbContext, usdCurrencyEntity); accountFactory.Add(sqliteMemoryWrapper.DbContext, incomeAccountEntity); accountFactory.Add(sqliteMemoryWrapper.DbContext, checkingAccountEntity); accountFactory.Add(sqliteMemoryWrapper.DbContext, rentPrepaymentAccountEntity); accountFactory.Add(sqliteMemoryWrapper.DbContext, savingsAccountEntity); sqliteMemoryWrapper.DbContext.AccountRelationships.Add(accountRelationship); sqliteMemoryWrapper.DbContext.SaveChanges(); sqliteMemoryWrapper.DbContext.Budgets.Add(budget); sqliteMemoryWrapper.DbContext.SaveChanges(); var service = new DatabaseSerializationXmlService(loggerFactory, sqliteMemoryWrapper.DbContext); service.Save(path); } using (var sqliteMemoryWrapper = new SqliteMemoryWrapper()) { var service = new DatabaseSerializationXmlService(loggerFactory, sqliteMemoryWrapper.DbContext); service.Load(path); List <Entities.Account> accounts = sqliteMemoryWrapper.DbContext.Accounts.ToList(); List <Entities.AccountRelationship> accountRelationships = sqliteMemoryWrapper.DbContext.AccountRelationships.ToList(); List <Entities.Budget> budgets = sqliteMemoryWrapper.DbContext.Budgets.ToList(); List <Entities.BudgetTransaction> budgetTransactions = sqliteMemoryWrapper.DbContext.BudgetTransactions.ToList(); List <Entities.Currency> currencies = sqliteMemoryWrapper.DbContext.Currencies.ToList(); List <Entities.Transaction> transactions = sqliteMemoryWrapper.DbContext.Transactions.ToList(); Assert.AreEqual(4, accounts.Count); Assert.AreEqual(1, accountRelationships.Count); Assert.AreEqual(1, budgets.Count); Assert.AreEqual(3, budgetTransactions.Count); Assert.AreEqual(1, currencies.Count); Assert.AreEqual(0, transactions.Count); Assert.AreEqual(budget.Name, budgets[0].Name); Assert.AreEqual(budget.Period, budgets[0].Period); Entities.BudgetTransaction initialTransaction = budgetTransactions.First(bt => bt.IsInitial && !bt.IsSurplus); Entities.BudgetTransaction regularTransaction = budgetTransactions.First(bt => !bt.IsInitial && !bt.IsSurplus); Entities.BudgetTransaction surplusTransaction = budgetTransactions.First(bt => !bt.IsInitial && bt.IsSurplus); Assert.AreEqual(budget.Transactions[0].DebitAccount.Name, initialTransaction.DebitAccount.Name); Assert.AreEqual(budget.Transactions[0].CreditAccount.Name, initialTransaction.CreditAccount.Name); Assert.AreEqual(budget.Transactions[0].Amount, initialTransaction.Amount); Assert.AreEqual(budget.Transactions[0].IsInitial, initialTransaction.IsInitial); Assert.AreEqual(budget.Transactions[0].IsSurplus, initialTransaction.IsSurplus); Assert.AreEqual(budget.Transactions[1].DebitAccount.Name, regularTransaction.DebitAccount.Name); Assert.AreEqual(budget.Transactions[1].CreditAccount.Name, regularTransaction.CreditAccount.Name); Assert.AreEqual(budget.Transactions[1].Amount, regularTransaction.Amount); Assert.AreEqual(budget.Transactions[1].IsInitial, regularTransaction.IsInitial); Assert.AreEqual(budget.Transactions[1].IsSurplus, regularTransaction.IsSurplus); Assert.AreEqual(budget.Transactions[2].DebitAccount.Name, surplusTransaction.DebitAccount.Name); Assert.AreEqual(budget.Transactions[2].CreditAccount.Name, surplusTransaction.CreditAccount.Name); Assert.AreEqual(budget.Transactions[2].Amount, surplusTransaction.Amount); Assert.AreEqual(budget.Transactions[2].IsInitial, surplusTransaction.IsInitial); Assert.AreEqual(budget.Transactions[2].IsSurplus, surplusTransaction.IsSurplus); } }