Automated teller machine emulation.
using System;
using System.Collections.Generic;
using System.Linq;
using SergeyDrozdovATM.Data;
namespace SergeyDrozdovATM.BLL
{
public class ATMService : IATMService
{
public IEnumerable<Currency> GetCurrenciesList()
{
var currencies = new List<Currency>();
using (var dbContext = new SergeyDrozdovATMDbContext())
{
foreach (var dbCurrency in dbContext.Currencies)
{
currencies.Add(new Currency()
{
Id = dbCurrency.Id,
Name = dbCurrency.Name
});
}
}
return currencies;
}
public void CreateAccount(int userId, int currencyId)
{
using (var dbContext = new SergeyDrozdovATMDbContext())
{
var dbAccount = new Accounts
{
UserId = userId,
CurrencyId = currencyId,
CashAmount = 0
};
dbContext.Accounts.Add(dbAccount);
dbContext.SaveChanges();
}
}
public Account GetAccountById(int accountId)
{
var account = new Account();
using (var dbContext = new SergeyDrozdovATMDbContext())
{
var dbAccount = dbContext.Accounts.FirstOrDefault(x => x.Id == accountId);
if (dbAccount == null)
{
throw new Exception("Account not found.");
}
account.Id = dbAccount.Id;
account.UserId = dbAccount.UserId;
account.Currency = dbContext.Currencies.Where(x => x.Id == dbAccount.CurrencyId).Select(c => new Currency { Id = c.Id, Name = c.Name }).FirstOrDefault();
account.Balance = dbAccount.CashAmount;
}
return account;
}
public IEnumerable<Account> GetAccountsList(int userId)
{
var accounts = new List<Account>();
using (var dbContext = new SergeyDrozdovATMDbContext())
{
foreach (var dbAccount in dbContext.Accounts.Where(x => x.UserId == userId))
{
accounts.Add(new Account
{
Id = dbAccount.Id,
UserId = dbAccount.UserId,
Currency = dbContext.Currencies.Where(x => x.Id == dbAccount.CurrencyId).Select(c => new Currency { Id = c.Id, Name = c.Name }).FirstOrDefault(),
Balance = dbAccount.CashAmount
});
}
}
return accounts;
}
public CurrencyRate GetCurrencyRate(Account sourceAccount, Account destinationAccount)
{
CurrencyRate currencyRate = null;
using (var dbContext = new SergeyDrozdovATMDbContext())
{
var dbRate = dbContext.CurrencyRates.FirstOrDefault(x => x.SourceCurrencyId == sourceAccount.Currency.Id && x.DestinationCurrencyId == destinationAccount.Currency.Id);
if (dbRate == null)
{
throw new Exception("Currency rate not found.");
}
currencyRate = new CurrencyRate
{
Id = dbRate.Id,
SourceCurrency = sourceAccount.Currency,
DestinationCurrency = destinationAccount.Currency,
Rate = dbRate.Rate
};
}
return currencyRate;
}
public void Deposit(Account account, decimal cashAmount)
{
if (account == null)
{
throw new Exception("Account not found.");
}
if (cashAmount <= 0)
{
throw new Exception("Cash amount should be more than zero.");
}
using (var dbContext = new SergeyDrozdovATMDbContext())
{
var dbAccountInfo = dbContext.Accounts.FirstOrDefault(x => x.Id == account.Id);
if (dbAccountInfo == null)
{
throw new Exception("Account not found.");
}
dbAccountInfo.CashAmount += cashAmount;
dbContext.SaveChanges();
}
}
public void Withdraw(Account account, decimal cashAmount)
{
if (account == null)
{
throw new Exception("Account not found.");
}
if (cashAmount <= 0)
{
throw new Exception("Cash amount should be more than zero.");
}
using (var dbContext = new SergeyDrozdovATMDbContext())
{
var dbAccountInfo = dbContext.Accounts.FirstOrDefault(x => x.Id == account.Id);
if (dbAccountInfo == null)
{
throw new Exception("Account not found.");
}
if (ValidateAccountBalance(account, cashAmount))
{
dbAccountInfo.CashAmount -= cashAmount;
dbContext.SaveChanges();
}
}
}
public bool ValidateAccountBalance(Account account, decimal cashAmount)
{
if (account == null)
{
throw new Exception("Account not found.");
}
if (account.Balance < cashAmount)
{
throw new Exception("Not enough money.");
}
return true;
}
public void ConvertCurrency(Account sourceAccount, Account destinationAccount, decimal cashAmount)
{
if (sourceAccount == null)
{
throw new Exception("Source account not found.");
}
if (destinationAccount == null)
{
throw new Exception("Destination account not found.");
}
if (sourceAccount.Currency.Id == destinationAccount.Currency.Id)
{
throw new Exception("Currency accounts should be different.");
}
if (cashAmount <= 0)
{
throw new Exception("Cash amount should be more than zero.");
}
using (var dbContext = new SergeyDrozdovATMDbContext())
{
var dbSourceAccount = dbContext.Accounts.FirstOrDefault(x => x.Id == sourceAccount.Id);
var currencyRate = GetCurrencyRate(sourceAccount, destinationAccount);
var transferCashAmount = cashAmount * currencyRate.Rate;
var dbDestinationAccount = dbContext.Accounts.FirstOrDefault(x => x.Id == destinationAccount.Id);
dbSourceAccount.CashAmount -= cashAmount;
dbDestinationAccount.CashAmount += transferCashAmount;
dbContext.SaveChanges();
}
}
}
}