public async Task <IWriterResult> CreateTermDeposit(string userId, CreateTermDepositModel model)
        {
            using (var transactionScope = new TransactionScope(TransactionScopeOption.RequiresNew, new TransactionOptions {
                IsolationLevel = IsolationLevel.Snapshot
            }, TransactionScopeAsyncFlowOption.Enabled))
            {
                var currentUser = new Guid(userId);
                using (var context = ExchangeDataContextFactory.CreateContext())
                {
                    var user = await context.Users.FirstOrDefaultAsync(x => x.Id == currentUser).ConfigureAwait(false);

                    if (user == null)
                    {
                        return(new WriterResult <int>(false, "Unauthorized"));
                    }

                    var termDepositItem = await context.TermDepositItem.FirstOrDefaultAsync(x => x.Id == model.Id).ConfigureAwait(false);

                    if (termDepositItem == null)
                    {
                        return(new WriterResult <int>(false, "Invalid term deposit"));
                    }

                    var totalTermDeposit = termDepositItem.MinInvestment * model.Count;
                    var balance          = await context.Balance.FirstOrDefaultAsync(x => x.UserId == user.Id && x.CurrencyId == Constant.DOTCOIN_ID).ConfigureAwait(false);

                    if (balance == null || balance.Available < totalTermDeposit)
                    {
                        return(new WriterResult <int>(false, "Insufficient funds for term deposit."));
                    }

                    var withdrawal = new Entity.Withdraw
                    {
                        Address        = termDepositItem.Address,
                        Amount         = totalTermDeposit,
                        Confirmations  = 0,
                        CurrencyId     = Constant.DOTCOIN_ID,
                        Fee            = 0,
                        IsApi          = false,
                        Status         = WithdrawStatus.Pending,
                        TimeStamp      = DateTime.UtcNow,
                        TwoFactorToken = string.Empty,
                        Txid           = string.Empty,
                        Type           = WithdrawType.TermDeposit,
                        UserId         = user.Id
                    };

                    context.Withdraw.Add(withdrawal);
                    await context.SaveChangesAsync().ConfigureAwait(false);

                    await context.AuditUserBalance(user.Id, balance.CurrencyId).ConfigureAwait(false);

                    var termBegin   = DateTime.UtcNow;
                    var termEnd     = termBegin.AddDays(30 * termDepositItem.TermLength);
                    var nextPayment = termBegin.AddDays(30);
                    var termdeposit = new Entity.TermDeposit
                    {
                        UserId            = user.Id,
                        WithdrawId        = withdrawal.Id,
                        TermDepositItemId = termDepositItem.Id,
                        Status            = TermDepositStatus.Active,
                        TermBegin         = termBegin,
                        NextPayout        = nextPayment,
                        TermEnd           = termEnd,
                        Closed            = termEnd
                    };
                    context.TermDeposit.Add(termdeposit);
                    await context.SaveChangesAsync().ConfigureAwait(false);

                    transactionScope.Complete();
                    return(new WriterResult(true, $"Successfully created term deposit #{termdeposit.Id}"));
                }
            }
        }
Exemple #2
0
        private async Task <IWriterResult <int> > ProcessWithdraw(CreateWithdraw model)
        {
            using (var context = DataContextFactory.CreateContext())
            {
                var currency = await context.Currency.FirstOrDefaultAsync(x => x.Id == model.CurrencyId);

                if (currency == null || !currency.IsEnabled || currency.Status != CurrencyStatus.OK)
                {
                    return(WriterResult <int> .ErrorResult("Currency not found or is currently disabled."));
                }

                var user = await context.Users.FirstOrDefaultAsync(x => x.Id == model.UserId);

                if (user == null || !user.IsWithdrawEnabled)
                {
                    return(WriterResult <int> .ErrorResult("Your withdrawals are currently disabled."));
                }

                var auditResult = await AuditService.AuditUserCurrency(context, model.UserId, model.CurrencyId);

                if (!auditResult.Success || model.Amount > auditResult.Avaliable)
                {
                    return(WriterResult <int> .ErrorResult("Insufficient funds."));
                }

                if (model.Amount < currency.MinWithdraw || model.Amount > currency.MaxWithdraw)
                {
                    return(WriterResult <int> .ErrorResult("Withdrawal amount must be between {0} and {1} {2}", currency.MinWithdraw, currency.MaxWithdraw, currency.Symbol));
                }

                var isValidAddress = await WalletService.ValidateAddress(model.Address, currency.WalletHost, currency.WalletPort, currency.WalletUser, currency.WalletPass);

                if (!isValidAddress)
                {
                    return(WriterResult <int> .ErrorResult($"Invalid {currency.Symbol} address."));
                }

                var newWithdraw = new Entity.Withdraw
                {
                    IsApi          = model.IsApi,
                    TimeStamp      = DateTime.UtcNow,
                    TwoFactorToken = model.ConfirmationToken,
                    Address        = model.Address,
                    CurrencyId     = model.CurrencyId,
                    Amount         = Math.Max(0, model.Amount),
                    Fee            = currency.WithdrawFee,
                    WithdrawType   = WithdrawType.Normal,
                    WithdrawStatus = model.IsApi
                                         ? WithdrawStatus.Pending
                                         : WithdrawStatus.Unconfirmed,
                    UserId = model.UserId
                };

                context.Withdraw.Add(newWithdraw);
                await context.SaveChangesAsync();

                await AuditService.AuditUserCurrency(context, model.UserId, model.CurrencyId);

                return(WriterResult <int> .SuccessResult(newWithdraw.Id));
            }
        }