Exemple #1
0
            ) Transfer(string fromAccount, string toAccount, string currency, decimal money, string message)
        {
            if (money < 0)
            {
                throw new BusinessException("Money should be greater than 0.");
            }

            var nowUtc = DateTime.Now.ToUniversalTime();
            var sourceAccountEntity = BankAccountService.Get(fromAccount);
            var targetAccountEntity = BankAccountService.Get(toAccount);
            var currencyEntity      = CurrencyService.Get(currency);

            var exchangeRateFromSourceAccount = ExchangeRateHistoryService.GetExchangeRate(sourceAccountEntity.Currency, currencyEntity, nowUtc);
            var exchangeRateToTargetAccount   = ExchangeRateHistoryService.GetExchangeRate(currencyEntity, targetAccountEntity.Currency, nowUtc);
            var deltaFromSourceAccount        = money * exchangeRateFromSourceAccount;
            var deltaToTargetAccount          = money * exchangeRateToTargetAccount;

            if (deltaFromSourceAccount > sourceAccountEntity.Balance)
            {
                throw new BusinessException("Source account balance is not sufficient");
            }
            else if (deltaFromSourceAccount <= 0 || deltaToTargetAccount <= 0)
            {
                throw new BusinessException("Transfer delta is not valid.");
            }

            sourceAccountEntity.Balance -= deltaFromSourceAccount;
            targetAccountEntity.Balance += deltaToTargetAccount;

            var entity = new TransferMoneyTransaction
            {
                DateTimeUtc   = nowUtc,
                SourceAccount = sourceAccountEntity,
                Account       = targetAccountEntity,
                Currency      = currencyEntity,
                Money         = money,
                Message       = message
            };

            TransactionRepository.Create(entity);
            BankAccountRepository.Update(sourceAccountEntity);
            BankAccountRepository.Update(targetAccountEntity);

            UnitOfWork.SaveChanges();
            return(
                entity.Id,
                exchangeRateFromSourceAccount, deltaFromSourceAccount, sourceAccountEntity.Balance,
                exchangeRateToTargetAccount, deltaToTargetAccount, targetAccountEntity.Balance
                );
        }
Exemple #2
0
        public (int userId, int?bankAccountId) Create(string email, string password, string role, string firstName, string lastName, string bankAccount, string bankAccountCurrency)
        {
            password.EnsureNotNullOrWhiteSpace(nameof(password));
            email.EnsureNotNullOrWhiteSpace(nameof(email));
            firstName.EnsureNotNullOrWhiteSpace(nameof(firstName));
            lastName.EnsureNotNullOrWhiteSpace(nameof(lastName));

            var createBankAccount = !string.IsNullOrWhiteSpace(bankAccount) && !string.IsNullOrWhiteSpace(bankAccountCurrency);

            if (UserRepository.ByEmail(email) != null)
            {
                throw new BusinessException("Email is taken.");
            }

            if (createBankAccount && BankAccountService.Exists(bankAccount))
            {
                throw new BusinessException("Bank account name is taken.");
            }

            if (!Enum.TryParse(role, out UserRole userRole))
            {
                userRole = UserRole.Customer;
            }

            var(hash, salt) = CryptoHash.Pbkdf2Hash(password);

            var entity = new User
            {
                Email     = email,
                Role      = userRole,
                FirstName = firstName,
                LastName  = lastName,

                PasswordSalt = salt.GetBase64String(),
                PasswordHash = hash.GetBase64String()
            };

            UserRepository.Create(entity);
            UnitOfWork.SaveChanges();

            int?bankAccountId = !createBankAccount ? (int?)null : BankAccountService.Create(bankAccount, bankAccountCurrency, entity.Id);

            return(entity.Id, bankAccountId);
        }
Exemple #3
0
        public (DateTime from, DateTime to, IEnumerable <Transaction> transactions) QueryTransactions(string account, string fromDate, string toDate)
        {
            var from = fromDate.ParseToDateTime(DateTimeStyles.AssumeUniversal, null, DateTime.Now.Date.AddMonths(-3)).ToUniversalTime();
            var to   = toDate.ParseToDateTime(DateTimeStyles.AssumeUniversal, null, DateTime.Now.Date.AddDays(1).AddMilliseconds(-1)).ToUniversalTime();

            var accountEntity = BankAccountService.Get(account);

            var depositTransactions  = TransactionRepository.All.OfType <DepositMoneyTransaction>().Where(x => x.DateTimeUtc >= from && x.DateTimeUtc <= to && x.AccountId == accountEntity.Id).IncludeProperty(x => x.Currency);
            var withdrawTransactions = TransactionRepository.All.OfType <WithdrawMoneyTransaction>().Where(x => x.DateTimeUtc >= from && x.DateTimeUtc <= to && x.AccountId == accountEntity.Id).IncludeProperty(x => x.Currency);
            var transferTransactions = TransactionRepository.All.OfType <TransferMoneyTransaction>().Where(x => x.DateTimeUtc >= from && x.DateTimeUtc <= to && (x.AccountId == accountEntity.Id || x.SourceAccountId == accountEntity.Id)).IncludeProperty(x => x.Currency);

            //TODO: beware out of memory exception.
            var result = new List <Transaction>();

            result.AddRange(depositTransactions);
            result.AddRange(withdrawTransactions);
            result.AddRange(transferTransactions);

            return(from, to, result.OrderByDescending(x => x.DateTimeUtc));
        }
Exemple #4
0
        public (int transactionId, decimal exchangeRate, decimal delta, decimal newBalance) Withdraw(string accountName, string currency, decimal money, string message)
        {
            if (money < 0)
            {
                throw new BusinessException("Money should be greater than 0.");
            }

            var nowUtc         = DateTime.Now.ToUniversalTime();
            var accountEntity  = BankAccountService.Get(accountName);
            var currencyEntity = CurrencyService.Get(currency);

            var exchangeRate = ExchangeRateHistoryService.GetExchangeRate(currencyEntity, accountEntity.Currency, nowUtc);
            var delta        = money * exchangeRate;

            if (delta > accountEntity.Balance)
            {
                throw new BusinessException("Account balance is not sufficient");
            }
            else if (delta <= 0)
            {
                throw new BusinessException("Withdraw delta is not valid.");
            }

            accountEntity.Balance -= delta;

            var entity = new WithdrawMoneyTransaction
            {
                DateTimeUtc = nowUtc,
                Account     = accountEntity,
                Currency    = currencyEntity,
                Money       = money,
                Message     = message
            };

            TransactionRepository.Create(entity);
            BankAccountRepository.Update(accountEntity);

            UnitOfWork.SaveChanges();
            return(entity.Id, exchangeRate, delta, accountEntity.Balance);
        }
Exemple #5
0
        public (int transactionId, decimal exchangeRate, decimal delta, decimal newBalance) Deposit(User bankOfficer, string account, string currency, decimal money, string message)
        {
            if (money < 0)
            {
                throw new BusinessException("Money should be greater than 0.");
            }

            var nowUtc         = DateTime.Now.ToUniversalTime();
            var accountEntity  = BankAccountService.Get(account);
            var currencyEntity = CurrencyService.Get(currency);

            var exchangeRate = ExchangeRateHistoryService.GetExchangeRate(currencyEntity, accountEntity.Currency, nowUtc);
            var delta        = money * exchangeRate;

            if (delta <= 0)
            {
                throw new BusinessException("Deposit delta is not valid.");
            }

            accountEntity.Balance += delta;

            UnitOfWork.AttachEntity(bankOfficer).State = EntityState.Unchanged;

            var entity = new DepositMoneyTransaction
            {
                DateTimeUtc = nowUtc,
                Account     = accountEntity,
                Currency    = currencyEntity,
                Money       = money,
                Message     = message,
                BankOfficer = bankOfficer
            };

            TransactionRepository.Create(entity);
            BankAccountRepository.Update(accountEntity);

            UnitOfWork.SaveChanges();
            return(entity.Id, exchangeRate, delta, accountEntity.Balance);
        }
Exemple #6
0
 public IEnumerable <BankAccount> GetBankAccounts(string email)
 => BankAccountService.GetByUser(email);