public void WithdrawLimitScenario2NotEnoughBalanceTest_ChecksIfTheScenarioProceedsAsExpected_VerifiesThroughReturnedValue()
        {
            // Balance is less than the evaluated Maximum Withdrawal threshold
            IWithdrawLimitEvaluationService withdrawLimitEvaluationService = new WithdrawLimitEvaluationService();

            decimal dailyLimit   = 1000;
            decimal monthlyLimit = 5000;

            // Balance is less than the calculated maximum threshold
            decimal availableBalance = 1000 - 1.09m;
            decimal currentBalance   = 1000 - 1.09m;

            List <Withdraw> ledgers            = new List <Withdraw>();
            WithdrawLimit   withdrawLimit      = new WithdrawLimit("Tier0", dailyLimit, monthlyLimit);
            bool            evaluationResponse = withdrawLimitEvaluationService.EvaluateMaximumWithdrawLimit(999, ledgers,
                                                                                                             withdrawLimit, availableBalance, currentBalance);

            Assert.IsFalse(evaluationResponse);

            Assert.AreEqual(1000, withdrawLimitEvaluationService.DailyLimit);
            Assert.AreEqual(5000, withdrawLimitEvaluationService.MonthlyLimit);
            Assert.AreEqual(0, withdrawLimitEvaluationService.DailyLimitUsed);
            Assert.AreEqual(0, withdrawLimitEvaluationService.MonthlyLimitUsed);
            Assert.AreEqual(Math.Round(availableBalance, 5), withdrawLimitEvaluationService.MaximumWithdraw);
            Assert.AreEqual(0, withdrawLimitEvaluationService.WithheldAmount);
        }
        public void WithdrawLimitScenario3Test_ChecksIfTheScenarioProceedsAsExpected_VerifiesThroughReturnedValue()
        {
            // Scenario: DailyLimit = 0/1000, MonthlyLimit = 0/5000
            IWithdrawLimitEvaluationService withdrawLimitEvaluationService = new WithdrawLimitEvaluationService();
            Currency  currency     = new Currency("XBT");
            string    withdrawId   = "withdrawid123";
            AccountId accountId    = new AccountId(123);
            decimal   dailyLimit   = 1000;
            decimal   monthlyLimit = 5000;
            // Balance is less than the calculated maximum threshold
            decimal availableBalance = 1000 - 1.09m;
            decimal currentBalance   = 1000 - 1.09m;

            List <Withdraw> withdraws = new List <Withdraw>();
            Withdraw        withdraw  = new Withdraw(currency, "withdrawid123", DateTime.Now.AddDays(-40), WithdrawType.Bitcoin, 500,
                                                     0.001m, TransactionStatus.Pending, accountId,
                                                     new BitcoinAddress("bitcoin123"));

            withdraws.Add(withdraw);
            WithdrawLimit withdrawLimit      = new WithdrawLimit("Tier0", dailyLimit, monthlyLimit);
            bool          evaluationResponse = withdrawLimitEvaluationService.EvaluateMaximumWithdrawLimit(999, withdraws,
                                                                                                           withdrawLimit, availableBalance, currentBalance);

            Assert.IsFalse(evaluationResponse);

            Assert.AreEqual(1000, withdrawLimitEvaluationService.DailyLimit);
            Assert.AreEqual(5000, withdrawLimitEvaluationService.MonthlyLimit);
            Assert.AreEqual(0, withdrawLimitEvaluationService.DailyLimitUsed);
            Assert.AreEqual(0, withdrawLimitEvaluationService.MonthlyLimitUsed);
            Assert.AreEqual(Math.Round(availableBalance, 5), withdrawLimitEvaluationService.MaximumWithdraw);
            Assert.AreEqual(0, withdrawLimitEvaluationService.WithheldAmount);
        }
        public void WithdrawLimitScenario15Test_ChecksIfTheScenarioProceedsAsExpected_VerifiesThroughReturnedValue()
        {
            // Check to see the withheld amount
            IWithdrawLimitEvaluationService withdrawLimitEvaluationService = new WithdrawLimitEvaluationService();

            decimal dailyLimit   = 1000;
            decimal monthlyLimit = 5000;
            // We have suficient balance for this case
            decimal availableBalance = 1000 + 100;
            decimal currentBalance   = 1000 + 110;

            List <Withdraw> withdraws          = new List <Withdraw>();
            WithdrawLimit   withdrawLimit      = new WithdrawLimit("Tier0", dailyLimit, monthlyLimit);
            bool            evaluationResponse = withdrawLimitEvaluationService.EvaluateMaximumWithdrawLimit(900, withdraws,
                                                                                                             withdrawLimit, availableBalance, currentBalance);

            Assert.IsTrue(evaluationResponse);

            Assert.AreEqual(1000, withdrawLimitEvaluationService.DailyLimit);
            Assert.AreEqual(5000, withdrawLimitEvaluationService.MonthlyLimit);
            Assert.AreEqual(0, withdrawLimitEvaluationService.DailyLimitUsed);
            Assert.AreEqual(0, withdrawLimitEvaluationService.MonthlyLimitUsed);
            Assert.AreEqual(1000, withdrawLimitEvaluationService.MaximumWithdraw);
            Assert.AreEqual(currentBalance - availableBalance, withdrawLimitEvaluationService.WithheldAmount);
        }
        public void AssignWithdrawLimitsTest_TestsIfWithdrawLimitsGetAsignedProperlyWhenTier1IsNotVerified_VerifiesThroughReturnedValue()
        {
            IWithdrawApplicationService   withdrawApplicationService = (IWithdrawApplicationService)ContextRegistry.GetContext()["WithdrawApplicationService"];
            IWithdrawLimitRepository      withdrawLimitRepository    = (IWithdrawLimitRepository)ContextRegistry.GetContext()["WithdrawLimitRepository"];
            IWithdrawFeesRepository       withdrawFeesRepository     = (IWithdrawFeesRepository)ContextRegistry.GetContext()["WithdrawFeesRepository"];
            StubTierLevelRetrievalService tierLevelRetrievalService  = (ITierLevelRetrievalService)ContextRegistry.GetContext()["TierLevelRetrievalService"] as StubTierLevelRetrievalService;

            Assert.IsNotNull(tierLevelRetrievalService);
            tierLevelRetrievalService.SetTierLevel(TierConstants.TierLevel0);
            AccountId     accountId     = new AccountId(123);
            Currency      currency      = new Currency("BTC", true);
            WithdrawLimit withdrawLimit = withdrawLimitRepository.GetLimitByTierLevelAndCurrency("Tier 1", LimitsCurrency.Default.ToString());

            Assert.IsNotNull(withdrawLimit);

            WithdrawFees withdrawFees = withdrawFeesRepository.GetWithdrawFeesByCurrencyName(currency.Name);

            Assert.IsNotNull(withdrawFees);

            WithdrawLimitRepresentation withdrawLimitRepresentation = withdrawApplicationService.GetWithdrawLimitThresholds(accountId.Value, currency.Name);

            Assert.IsNotNull(withdrawLimitRepresentation);
            Assert.AreEqual(currency.Name, withdrawLimitRepresentation.Currency);
            Assert.AreEqual(accountId.Value, withdrawLimitRepresentation.AccountId);
            Assert.AreEqual(0, withdrawLimitRepresentation.DailyLimit);
            Assert.AreEqual(0, withdrawLimitRepresentation.MonthlyLimit);
            Assert.AreEqual(0, withdrawLimitRepresentation.DailyLimitUsed);
            Assert.AreEqual(0, withdrawLimitRepresentation.MonthlyLimitUsed);
            Assert.AreEqual(0, withdrawLimitRepresentation.CurrentBalance);
            Assert.AreEqual(withdrawFees.Fee, withdrawLimitRepresentation.Fee);
            Assert.AreEqual(withdrawFees.MinimumAmount, withdrawLimitRepresentation.MinimumAmount);
            Assert.AreEqual(0, withdrawLimitRepresentation.Withheld);
            Assert.AreEqual(0, withdrawLimitRepresentation.MaximumWithdraw);
        }
        public void WithdrawFailedTest_TestsIfWithdrawFailsBecauseOfNotEnoughBalance_VerifiesThroughDatabaseQueries()
        {
            IWithdrawApplicationService   withdrawApplicationService = (IWithdrawApplicationService)ContextRegistry.GetContext()["WithdrawApplicationService"];
            StubTierLevelRetrievalService tierLevelRetrievalService  = (ITierLevelRetrievalService)ContextRegistry.GetContext()["TierLevelRetrievalService"] as StubTierLevelRetrievalService;
            IWithdrawLimitRepository      withdrawLimitRepository    = (IWithdrawLimitRepository)ContextRegistry.GetContext()["WithdrawLimitRepository"];
            IFundsPersistenceRepository   fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"];

            Assert.IsNotNull(tierLevelRetrievalService);
            tierLevelRetrievalService.SetTierLevel(TierConstants.TierLevel1);
            AccountId      accountId      = new AccountId(123);
            Currency       currency       = new Currency("BTC", true);
            BitcoinAddress bitcoinAddress = new BitcoinAddress("bitcoinaddress1");
            WithdrawLimit  withdrawLimit  = withdrawLimitRepository.GetLimitByTierLevelAndCurrency(TierConstants.TierLevel1, LimitsCurrency.Default.ToString());

            Assert.IsNotNull(withdrawLimit);
            decimal amount = withdrawLimit.DailyLimit + 0.001M;

            Balance balance = new Balance(currency, accountId, amount - 1, amount - 1);

            fundsPersistenceRepository.SaveOrUpdate(balance);

            withdrawApplicationService.CommitWithdrawal(new CommitWithdrawCommand(accountId.Value, currency.Name,
                                                                                  currency.IsCryptoCurrency,
                                                                                  bitcoinAddress.Value, amount));
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="T:System.Object"/> class.
        /// </summary>
        public MockWithdrawLimitRepository()
        {
            WithdrawLimit withdrawLimit1 = new WithdrawLimit("Tier 0", 1000, 5000);
            WithdrawLimit withdrawLimit2 = new WithdrawLimit("Tier 1", 1000, 5000);

            _withdrawLimits.Add(withdrawLimit1);
            _withdrawLimits.Add(withdrawLimit2);
        }
Beispiel #7
0
        public void SaveWithdrawLimitAndRetreiveByTierLevelTest_SavesAnObjectToDatabaseAndManipulatesIt_ChecksIfItIsUpdatedAsExpected()
        {
            WithdrawLimit withdrawLimit = new WithdrawLimit("tierlevel1", 4000, 500);

            _persistanceRepository.SaveOrUpdate(withdrawLimit);

            WithdrawLimit retrievedWithdrawLimit = _withdrawLimitRepository.GetWithdrawLimitByTierLevel("tierlevel1");

            Assert.IsNotNull(retrievedWithdrawLimit);

            Assert.AreEqual(withdrawLimit.DailyLimit, retrievedWithdrawLimit.DailyLimit);
            Assert.AreEqual(withdrawLimit.MonthlyLimit, retrievedWithdrawLimit.MonthlyLimit);
        }
        public void WithdrawLimitScenario14Test_ChecksIfTheScenarioProceedsAsExpected_VerifiesThroughReturnedValue()
        {
            // Scenario: DailyLimit = 500/1000, MonthlyLimit = 4500/5000  with insufficient balance
            IWithdrawLimitEvaluationService withdrawLimitEvaluationService = new WithdrawLimitEvaluationService();
            Currency  currency     = new Currency("XBT");
            AccountId accountId    = new AccountId(123);
            decimal   dailyLimit   = 1000;
            decimal   monthlyLimit = 5000;
            // Balance is less than the calculated maximum threshold foor the remaining quantity from the daily limit used
            decimal availableBalance = 500 - 0.09m;
            decimal currentBalance   = 500 - 0.09m;
            // Amount that can be safely withdrawn
            decimal safeAmount = availableBalance;
            decimal fee        = 0.001m;

            List <Withdraw> withdraws = new List <Withdraw>();
            Withdraw        withdraw  = new Withdraw(currency, "withdrawid123", DateTime.Now.AddDays(-29), WithdrawType.Bitcoin,
                                                     4000, fee, TransactionStatus.Pending, accountId,
                                                     new BitcoinAddress("bitcoin123"));
            Withdraw withdraw2 = new Withdraw(currency, "withdrawid123", DateTime.Now.AddMinutes(-29), WithdrawType.Bitcoin,
                                              500, fee, TransactionStatus.Pending, accountId,
                                              new BitcoinAddress("bitcoin123"));

            withdraws.Add(withdraw);
            withdraws.Add(withdraw2);

            WithdrawLimit withdrawLimit      = new WithdrawLimit("Tier0", dailyLimit, monthlyLimit);
            bool          evaluationResponse = withdrawLimitEvaluationService.EvaluateMaximumWithdrawLimit(500, withdraws,
                                                                                                           withdrawLimit, availableBalance, currentBalance);

            Assert.IsFalse(evaluationResponse);

            Assert.AreEqual(1000, withdrawLimitEvaluationService.DailyLimit);
            Assert.AreEqual(5000, withdrawLimitEvaluationService.MonthlyLimit);
            Assert.AreEqual(500 + fee, withdrawLimitEvaluationService.DailyLimitUsed);
            Assert.AreEqual(4500 + fee * 2, withdrawLimitEvaluationService.MonthlyLimitUsed);
            Assert.AreEqual(Math.Round(availableBalance, 5), withdrawLimitEvaluationService.MaximumWithdraw);
            Assert.AreEqual(0, withdrawLimitEvaluationService.WithheldAmount);

            // Withdraw below the threshold limit
            evaluationResponse = withdrawLimitEvaluationService.EvaluateMaximumWithdrawLimit(safeAmount - 10, withdraws,
                                                                                             withdrawLimit, availableBalance, currentBalance);
            Assert.IsTrue(evaluationResponse);

            Assert.AreEqual(1000, withdrawLimitEvaluationService.DailyLimit);
            Assert.AreEqual(5000, withdrawLimitEvaluationService.MonthlyLimit);
            Assert.AreEqual(500 + fee, withdrawLimitEvaluationService.DailyLimitUsed);
            Assert.AreEqual(4500 + fee * 2, withdrawLimitEvaluationService.MonthlyLimitUsed);
            Assert.AreEqual(Math.Round(availableBalance, 5), withdrawLimitEvaluationService.MaximumWithdraw);
            Assert.AreEqual(0, withdrawLimitEvaluationService.WithheldAmount);
        }
        public void WithdrawLimitScenario7Test_ChecksIfTheScenarioProceedsAsExpected_VerifiesThroughReturnedValue()
        {
            // Scenario: DailyLimit = 500/1000, MonthlyLimit = 4000/5000
            IWithdrawLimitEvaluationService withdrawLimitEvaluationService = new WithdrawLimitEvaluationService();
            Currency  currency     = new Currency("XBT");
            AccountId accountId    = new AccountId(123);
            decimal   dailyLimit   = 1000;
            decimal   monthlyLimit = 5000;

            decimal availableBalance = 1000;
            decimal currentBalance   = 1000;
            decimal fee = 0.001m;

            List <Withdraw> withdraws = new List <Withdraw>();
            Withdraw        withdraw  = new Withdraw(currency, "withdrawid123", DateTime.Now.AddDays(-29), WithdrawType.Bitcoin,
                                                     3500, fee, TransactionStatus.Pending, accountId,
                                                     new BitcoinAddress("bitcoin123"));
            Withdraw withdraw2 = new Withdraw(currency, "withdrawid123", DateTime.Now.AddMinutes(-5), WithdrawType.Bitcoin,
                                              500, fee, TransactionStatus.Pending, accountId,
                                              new BitcoinAddress("bitcoin123"));

            withdraws.Add(withdraw);
            withdraws.Add(withdraw2);

            WithdrawLimit withdrawLimit      = new WithdrawLimit("Tier0", dailyLimit, monthlyLimit);
            bool          evaluationResponse = withdrawLimitEvaluationService.EvaluateMaximumWithdrawLimit(600 - fee * 2, withdraws,
                                                                                                           withdrawLimit, availableBalance, currentBalance);

            Assert.IsFalse(evaluationResponse);

            Assert.AreEqual(1000, withdrawLimitEvaluationService.DailyLimit);
            Assert.AreEqual(5000, withdrawLimitEvaluationService.MonthlyLimit);
            Assert.AreEqual(500 + fee, withdrawLimitEvaluationService.DailyLimitUsed);
            Assert.AreEqual(4000 + fee * 2, withdrawLimitEvaluationService.MonthlyLimitUsed);
            Assert.AreEqual(500 - fee, withdrawLimitEvaluationService.MaximumWithdraw);
            Assert.AreEqual(0, withdrawLimitEvaluationService.WithheldAmount);

            // Withdraw below the threshold limit
            evaluationResponse = withdrawLimitEvaluationService.EvaluateMaximumWithdrawLimit(500 - fee * 2, withdraws,
                                                                                             withdrawLimit, availableBalance, currentBalance);
            Assert.IsTrue(evaluationResponse);

            Assert.AreEqual(1000, withdrawLimitEvaluationService.DailyLimit);
            Assert.AreEqual(5000, withdrawLimitEvaluationService.MonthlyLimit);
            Assert.AreEqual(500 + fee, withdrawLimitEvaluationService.DailyLimitUsed);
            Assert.AreEqual(4000 + fee * 2, withdrawLimitEvaluationService.MonthlyLimitUsed);
            Assert.AreEqual(500 - fee, withdrawLimitEvaluationService.MaximumWithdraw);
            Assert.AreEqual(0, withdrawLimitEvaluationService.WithheldAmount);
        }
        /// <summary>
        /// Assign The Withdraw Limits
        /// </summary>
        /// <param name="baseCurrency"></param>
        /// <param name="tierLevel"></param>
        /// <param name="withdrawals"></param>
        /// <param name="availableBalance"></param>
        /// <param name="currentBalance"></param>
        public void AssignWithdrawLimits(string baseCurrency, string tierLevel,
                                         IList <Withdraw> withdrawals, decimal availableBalance, decimal currentBalance)
        {
            // If the admin has specified the limits to be calculated as the currency itself
            if (_adminDefinedLimitsCurrency == LimitsCurrency.Default.ToString())
            {
                Log.Debug(string.Format("Limits representation Currency = {0}", _adminDefinedLimitsCurrency));
                // Get the Current Withdraw limits for this user
                WithdrawLimit withdrawLimit = _withdrawLimitRepository.GetLimitByTierLevelAndCurrency(tierLevel,
                                                                                                      _adminDefinedLimitsCurrency);

                if (withdrawLimit != null)
                {
                    // Check if the current Withdraw transaction is within the Withdraw limits
                    _withdrawLimitEvaluationService.AssignWithdrawLimits(withdrawals, withdrawLimit,
                                                                         availableBalance, currentBalance);
                }
                else
                {
                    throw new InvalidOperationException(
                              string.Format("No Withdraw Limit found for Tier: Tier Level = {0} & " +
                                            "CurrencyType = {1}", tierLevel, _adminDefinedLimitsCurrency));
                }
            }
            // If the admin has specified that limits must be calculated in a FIAT currency
            else
            {
                Log.Debug(string.Format("Limits representation Currency = {0}", _adminDefinedLimitsCurrency));
                // Get the Current Withdraw limits for this user which will be in a FIAT currency
                WithdrawLimit withdrawLimit = _withdrawLimitRepository.GetLimitByTierLevelAndCurrency(tierLevel,
                                                                                                      _adminDefinedLimitsCurrency);

                if (withdrawLimit != null)
                {
                    // Get the best bid and best ask
                    Tuple <decimal, decimal> bestBidBestAsk = _bboCrossContextService.GetBestBidBestAsk(baseCurrency, _adminDefinedLimitsCurrency);
                    // Assign the withdraw limits in FIAT amounts
                    _withdrawLimitEvaluationService.AssignWithdrawLimits(withdrawals, withdrawLimit,
                                                                         availableBalance, currentBalance,
                                                                         bestBidBestAsk.Item1, bestBidBestAsk.Item2);
                }
                else
                {
                    throw new InvalidOperationException(
                              string.Format("No Withdraw Limit found for Tier: Tier Level = {0} & " +
                                            "CurrencyType = {1}", tierLevel, _adminDefinedLimitsCurrency));
                }
            }
        }
        public void WithdrawSuccessfulTest_TestsIfWithdrawIsSuccessfulWhenTierLevelIsHighEnough_VerifiesThroughDatabaseQueries()
        {
            IWithdrawApplicationService   withdrawApplicationService = (IWithdrawApplicationService)ContextRegistry.GetContext()["WithdrawApplicationService"];
            IWithdrawRepository           withdrawRepository         = (IWithdrawRepository)ContextRegistry.GetContext()["WithdrawRepository"];
            IFundsPersistenceRepository   fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"];
            IBalanceRepository            balanceRepository          = (IBalanceRepository)ContextRegistry.GetContext()["BalanceRepository"];
            IWithdrawFeesRepository       withdrawFeesRepository     = (IWithdrawFeesRepository)ContextRegistry.GetContext()["WithdrawFeesRepository"];
            StubTierLevelRetrievalService tierLevelRetrievalService  = (ITierLevelRetrievalService)ContextRegistry.GetContext()["TierLevelRetrievalService"] as StubTierLevelRetrievalService;
            IWithdrawLimitRepository      withdrawLimitRepository    = (IWithdrawLimitRepository)ContextRegistry.GetContext()["WithdrawLimitRepository"];

            Assert.IsNotNull(tierLevelRetrievalService);
            tierLevelRetrievalService.SetTierLevel(TierConstants.TierLevel1);
            AccountId      accountId      = new AccountId(123);
            Currency       currency       = new Currency("BTC", true);
            BitcoinAddress bitcoinAddress = new BitcoinAddress("bitcoinaddress1");
            WithdrawLimit  withdrawLimit  = withdrawLimitRepository.GetLimitByTierLevelAndCurrency(TierConstants.TierLevel1, LimitsCurrency.Default.ToString());

            Assert.IsNotNull(withdrawLimit);
            decimal amount = withdrawLimit.DailyLimit;

            Balance balance = new Balance(currency, accountId, amount + 1, amount + 1);

            fundsPersistenceRepository.SaveOrUpdate(balance);

            CommitWithdrawResponse commitWithdrawResponse = withdrawApplicationService.CommitWithdrawal(new CommitWithdrawCommand(accountId.Value, currency.Name, currency.IsCryptoCurrency, bitcoinAddress.Value, amount));

            Assert.IsNotNull(commitWithdrawResponse);
            Assert.IsTrue(commitWithdrawResponse.CommitSuccessful);

            Withdraw withdraw = withdrawRepository.GetWithdrawByWithdrawId(commitWithdrawResponse.WithdrawId);

            Assert.IsNotNull(withdraw);
            Assert.AreEqual(accountId.Value, withdraw.AccountId.Value);
            Assert.AreEqual(currency.Name, withdraw.Currency.Name);
            Assert.AreEqual(currency.IsCryptoCurrency, withdraw.Currency.IsCryptoCurrency);
            Assert.AreEqual(amount - withdraw.Fee, withdraw.Amount);
            Assert.AreEqual(TransactionStatus.Pending, withdraw.Status);

            WithdrawFees withdrawFees = withdrawFeesRepository.GetWithdrawFeesByCurrencyName(currency.Name);

            Assert.IsNotNull(withdrawFees);

            balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId);
            Assert.IsNotNull(balance);
            Assert.AreEqual((amount + 1) - (amount), balance.AvailableBalance);
            Assert.AreEqual(amount + 1, balance.CurrentBalance);
            Assert.AreEqual(amount, balance.PendingBalance);
        }
        /// <summary>
        /// Evaluate the threshold limits and limits used for withdraw
        /// </summary>
        /// <returns></returns>
        public bool EvaluateWithdrawLimits(string baseCurrency, string tierLevel, decimal amount,
                                           IList <Withdraw> withdrawals, decimal availableBalance, decimal currentBalance)
        {
            // If the admin has specified the limits to be calculated as the currency itself
            if (_adminDefinedLimitsCurrency == LimitsCurrency.Default.ToString())
            {
                // Get the Current Withdraw limits for this user
                WithdrawLimit withdrawLimit = _withdrawLimitRepository.GetLimitByTierLevelAndCurrency(tierLevel,
                                                                                                      _adminDefinedLimitsCurrency);

                if (withdrawLimit != null)
                {
                    // Check if the current Withdraw transaction is within the Withdraw limits
                    return(_withdrawLimitEvaluationService.EvaluateMaximumWithdrawLimit(amount, withdrawals,
                                                                                        withdrawLimit,
                                                                                        availableBalance, currentBalance));
                }
                throw new InvalidOperationException(string.Format("No Withdraw Limit found for Tier: Tier Level = {0} & " +
                                                                  "CurrencyType = {1}", tierLevel, _adminDefinedLimitsCurrency));
            }
            // If the admin has specified that limits must be calculated in a FIAT currency
            else
            {
                // Get the Current Withdraw limits for this user which will be in a FIAT currency
                WithdrawLimit withdrawLimit = _withdrawLimitRepository.GetLimitByTierLevelAndCurrency(tierLevel,
                                                                                                      _adminDefinedLimitsCurrency);

                if (withdrawLimit != null)
                {
                    // Convert the currency to FIAT
                    decimal amountInFiat = ConvertCurrencyToFiat(baseCurrency, amount);
                    // Check if the current Withdraw transaction is within the Withdraw limits
                    // NOTE: If there is no best bid and best ask, then the limits will be specified in the default crypto currency
                    // itself
                    return(_withdrawLimitEvaluationService.EvaluateMaximumWithdrawLimit(amountInFiat, withdrawals,
                                                                                        withdrawLimit,
                                                                                        availableBalance, currentBalance,
                                                                                        _bestBidBestAsk.Item1,
                                                                                        _bestBidBestAsk.Item2));
                }
                throw new InvalidOperationException(string.Format("No Withdraw Limit found for Tier: Tier Level = {0} & " +
                                                                  "CurrencyType = {1}", tierLevel, _adminDefinedLimitsCurrency));
            }
        }
 public bool AssignWithdrawLimits(IList <Withdraw> depositLedgers, WithdrawLimit withdrawLimit, decimal balance, decimal currentBalance, decimal bestBid = 0, decimal bestAsk = 0)
 {
     throw new NotImplementedException();
 }
 public bool EvaluateMaximumWithdrawLimit(decimal withdrawalAmount, IList <Withdraw> depositLedgers, WithdrawLimit withdrawLimit, decimal balance, decimal currentBalance, decimal bestBid = 0, decimal bestAsk = 0)
 {
     throw new NotImplementedException();
 }
        public void WithdrawExecutedEventTest_ChecksThatTheEventIsProperlyRaisedAndHandledWhenWithdrawIsSubmittedToTheNetwork_VerifiesThroughRaisedEvent()
        {
            // Withdraw is submitted and upon submission to network an event is raised confirming withdrawal execution which
            // is handled and balance is updated. This whole process of events firing and balance validation is checked by this
            // test case
            IWithdrawApplicationService   withdrawApplicationService = (IWithdrawApplicationService)ContextRegistry.GetContext()["WithdrawApplicationService"];
            IWithdrawRepository           withdrawRepository         = (IWithdrawRepository)ContextRegistry.GetContext()["WithdrawRepository"];
            IFundsPersistenceRepository   fundsPersistenceRepository = (IFundsPersistenceRepository)ContextRegistry.GetContext()["FundsPersistenceRepository"];
            IBalanceRepository            balanceRepository          = (IBalanceRepository)ContextRegistry.GetContext()["BalanceRepository"];
            IWithdrawFeesRepository       withdrawFeesRepository     = (IWithdrawFeesRepository)ContextRegistry.GetContext()["WithdrawFeesRepository"];
            IWithdrawLimitRepository      withdrawLimitRepository    = (IWithdrawLimitRepository)ContextRegistry.GetContext()["WithdrawLimitRepository"];
            IClientInteractionService     clientInteractionService   = (IClientInteractionService)ContextRegistry.GetContext()["ClientInteractionService"];
            StubTierLevelRetrievalService tierLevelRetrievalService  = (ITierLevelRetrievalService)ContextRegistry.GetContext()["TierLevelRetrievalService"] as StubTierLevelRetrievalService;

            Assert.IsNotNull(tierLevelRetrievalService);
            tierLevelRetrievalService.SetTierLevel(TierConstants.TierLevel1);
            AccountId      accountId      = new AccountId(123);
            Currency       currency       = new Currency(CurrencyConstants.Btc, true);
            BitcoinAddress bitcoinAddress = new BitcoinAddress("bitcoinaddress1");
            WithdrawLimit  withdrawLimit  = withdrawLimitRepository.GetLimitByTierLevelAndCurrency(TierConstants.TierLevel1, LimitsCurrency.Default.ToString());

            Assert.IsNotNull(withdrawLimit);
            decimal amount = withdrawLimit.DailyLimit;

            Balance balance = new Balance(currency, accountId, amount + 1, amount + 1);

            fundsPersistenceRepository.SaveOrUpdate(balance);
            bool             withdrawEventRaised = false;
            ManualResetEvent manualResetEvent    = new ManualResetEvent(false);
            Withdraw         receivedWithdraw    = null;

            clientInteractionService.WithdrawExecuted += delegate(Withdraw incomingWithdraw)
            {
                withdrawEventRaised = true;
                receivedWithdraw    = incomingWithdraw;
                manualResetEvent.Set();
            };

            CommitWithdrawResponse commitWithdrawResponse = withdrawApplicationService.CommitWithdrawal(new CommitWithdrawCommand(accountId.Value, currency.Name, currency.IsCryptoCurrency, bitcoinAddress.Value, amount));

            Assert.IsNotNull(commitWithdrawResponse);
            Assert.IsTrue(commitWithdrawResponse.CommitSuccessful);
            manualResetEvent.WaitOne();

            // Apply assertions after event has been handled
            Assert.IsTrue(withdrawEventRaised);
            Assert.IsNotNull(receivedWithdraw);
            Withdraw withdraw = withdrawRepository.GetWithdrawByWithdrawId(commitWithdrawResponse.WithdrawId);

            Assert.IsNotNull(withdraw);
            Assert.AreEqual(accountId.Value, withdraw.AccountId.Value);
            Assert.AreEqual(currency.Name, withdraw.Currency.Name);
            Assert.AreEqual(currency.IsCryptoCurrency, withdraw.Currency.IsCryptoCurrency);
            Assert.AreEqual(amount - withdraw.Fee, withdraw.Amount);
            Assert.AreEqual(TransactionStatus.Confirmed, withdraw.Status);

            Assert.AreEqual(receivedWithdraw.AccountId.Value, withdraw.AccountId.Value);
            Assert.AreEqual(receivedWithdraw.TransactionId.Value, withdraw.TransactionId.Value);
            Assert.AreEqual(receivedWithdraw.BitcoinAddress.Value, withdraw.BitcoinAddress.Value);
            Assert.AreEqual(receivedWithdraw.Currency.Name, withdraw.Currency.Name);
            Assert.AreEqual(TransactionStatus.Confirmed, withdraw.Status);
            Assert.AreEqual(receivedWithdraw.Amount, withdraw.Amount);
            Assert.AreEqual(receivedWithdraw.WithdrawId, withdraw.WithdrawId);

            WithdrawFees withdrawFees = withdrawFeesRepository.GetWithdrawFeesByCurrencyName(currency.Name);

            Assert.IsNotNull(withdrawFees);

            balance = balanceRepository.GetBalanceByCurrencyAndAccountId(currency, accountId);
            Assert.IsNotNull(balance);
            Assert.AreEqual((amount + 1) - (amount), balance.AvailableBalance);
            Assert.AreEqual((amount + 1) - (amount), balance.CurrentBalance);
            Assert.AreEqual(0, balance.PendingBalance);
        }