public async Task <IActionResult> GetByCustomerAsync()
        {
            var customerId = _requestContext.UserId;

            var walletResult = await _walletOperationsService.GetCustomerWalletAsync(customerId);

            switch (walletResult.Error)
            {
            case WalletsErrorCodes.None:

                var linkedWalletTask = _publicWalletLinkingService.GetLinkedWalletAddressAsync(customerId);

                var tokensStatisticsTask =
                    _operationsHistoryClient.StatisticsApi.GetTokensStatisticsForCustomerAsync(
                        new TokensStatisticsForCustomerRequest {
                    CustomerId = customerId
                });

                await Task.WhenAll(linkedWalletTask, tokensStatisticsTask);

                Money18?linkedWalletBalance = null;

                if (linkedWalletTask.Result.Status == PublicAddressStatus.Linked)
                {
                    var balance =
                        await _ethereumBridgeClient.Wallets.GetBalanceAsync(linkedWalletTask.Result.PublicAddress);

                    linkedWalletBalance = balance.Amount;
                }

                var response = new WalletResponseModel
                {
                    Balance                    = walletResult.Balance.ToDisplayString(),
                    ExternalBalance            = linkedWalletBalance?.ToDisplayString(),
                    AssetSymbol                = walletResult.AssetSymbol,
                    TotalEarned                = tokensStatisticsTask.Result.EarnedAmount.ToDisplayString(),
                    TotalSpent                 = tokensStatisticsTask.Result.BurnedAmount.ToDisplayString(),
                    IsWalletBlocked            = walletResult.IsWalletBlocked,
                    PrivateWalletAddress       = walletResult.Address,
                    PublicWalletAddress        = linkedWalletTask.Result.PublicAddress,
                    PublicAddressLinkingStatus = linkedWalletTask.Result.Status.ToLinkingStatus(),
                    StakedBalance              = walletResult.StakedBalance.ToDisplayString(),
                    TransitAccountAddress      = _settingsService.GetTransitAccountAddress(),
                };
                return(Ok(new List <WalletResponseModel> {
                    response
                }));

            case WalletsErrorCodes.InvalidCustomerId:
                throw LykkeApiErrorException.BadRequest(ApiErrorCodes.Service.InvalidCustomerId);

            case WalletsErrorCodes.CustomerWalletMissing:
                throw LykkeApiErrorException.BadRequest(ApiErrorCodes.Service.CustomerWalletMissing);

            default:
                throw new InvalidOperationException(
                          $"Unexpected error during Transfer for {_requestContext.UserId} - {walletResult.Error}");
            }
        }
        private async Task <string> GetCurrentRewardedAmountAsync(string earnRuleId)
        {
            Money18 reward = 0m;

            var rewardsForCampaign =
                await _operationsHistoryClient.OperationsHistoryApi.GetBonusCashInsAsync(_requestContext.UserId,
                                                                                         earnRuleId);

            foreach (var payment in rewardsForCampaign)
            {
                reward += payment.Amount;
            }

            return(reward.ToDisplayString());
        }
        private async Task SetRewardRatioGivenBonusAmountAsync(ConditionLocalizedResponse condition, string customerId, Dictionary <string, string> dictionary, RatioCompletion ratioCompletion)
        {
            var     amount      = dictionary["Amount"];
            Money18 givenReward = 0m;
            Money18 totalReward = 0m;

            //calculate bonus
            switch (condition.RewardType)
            {
            case RewardType.Fixed:
            {
                givenReward = CalculateReward(condition.RewardRatio.Ratios, condition.ImmediateReward, ratioCompletion.GivenThreshold);
                totalReward = condition.ImmediateReward;
            }
            break;

            case RewardType.Percentage:
                if (amount != null)
                {
                    var amountInCurrency = Money18.Parse(amount) * (condition.ImmediateReward / 100m);

                    var convertedAmount = await GetEligibilityEngineAmountByCondition(Guid.Parse(condition.Id),
                                                                                      Guid.Parse(customerId), amountInCurrency);

                    givenReward = CalculateReward(condition.RewardRatio.Ratios, convertedAmount, ratioCompletion.GivenThreshold);
                    totalReward = convertedAmount;
                }

                break;

            case RewardType.ConversionRate:
            {
                var convertedAmount = await GetEligibilityEngineAmountByCondition(Guid.Parse(condition.Id),
                                                                                  Guid.Parse(customerId), condition.ImmediateReward);

                givenReward = CalculateReward(condition.RewardRatio.Ratios, convertedAmount, ratioCompletion.GivenThreshold);
                totalReward = convertedAmount;
            }
            break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            ratioCompletion.GivenRatioRewardBonus = givenReward.ToDisplayString();
            ratioCompletion.TotalRatioRewardBonus = totalReward.ToDisplayString();
        }
        private async Task SetReferralAdditionalInformation(CampaignCompletionModel completions,
                                                            CustomerCommonReferralModel customerReferral,
                                                            EarnRuleLocalizedResponse earnRule,
                                                            IEnumerable <ReferralStakeResponseModel> stakes,
                                                            CommonReferralModel referral,
                                                            string customerId)
        {
            var customerCompletionCount = completions?.CampaignCompletionCount ?? 0;

            customerReferral.CurrentRewardedAmount =
                (customerCompletionCount * earnRule.Reward).ToDisplayString();

            if (customerReferral.Status != CommonReferralStatus.Ongoing && customerReferral.Status != CommonReferralStatus.AcceptedByLead)
            {
                var payments =
                    await _operationsHistoryClient.OperationsHistoryApi.GetBonusCashInsByReferralAsync(customerId, referral.Id);

                if (payments != null && payments.Any())
                {
                    Money18 paymentsSum = 0m;

                    foreach (var payment in payments)
                    {
                        paymentsSum += payment.Amount;
                    }

                    customerReferral.TotalReward = paymentsSum.ToDisplayString();
                }
            }
            else
            {
                customerReferral.TotalReward = earnRule.Reward.ToDisplayString();
            }

            customerReferral.IsApproximate = earnRule.IsApproximate || earnRule.Conditions.Any(c => c.IsApproximate);

            if (earnRule.Conditions.Any(c => c.HasStaking))
            {
                customerReferral.HasStaking = true;

                var staking = stakes.FirstOrDefault(s => s.ReferralId == referral.Id);

                if (staking != null)
                {
                    customerReferral.Staking = _mapper.Map <ReferralStakingModel>(staking);
                }
            }

            var ratioConditions = earnRule.Conditions
                                  .Where(c => c.RewardRatio != null && c.RewardRatio.Ratios.Any()).ToList();

            if (ratioConditions.Any())
            {
                customerReferral.RewardHasRatio = true;

                foreach (var condition in ratioConditions)
                {
                    customerReferral.RewardRatio =
                        await GetRatioRewardByReferral(condition, completions, referral.Id, customerId);
                }
            }
        }
        public async Task <IReadOnlyList <CustomerCommonReferralModel> > PrepareReferralCommonData(IEnumerable <CommonReferralModel> paged, string customerId, Guid?earnRuleId)
        {
            var result              = new List <CustomerCommonReferralModel>();
            var earnRule            = new EarnRuleLocalizedResponse();
            var campaignCompletions = new CampaignCompletionModel();

            var stakes = await _stakingClient.ReferralStakesApi.GetReferralStakesAsync(new GetReferralStakesRequest()
            {
                CustomerId = customerId
            });

            //when the referrals are filtered by earn rule
            if (earnRuleId.HasValue && earnRuleId != Guid.Empty)
            {
                earnRule = await _campaignClient.History.GetEarnRuleMobileAsync(earnRuleId.Value, Localization.En);

                if (earnRule != null)
                {
                    campaignCompletions = await _bonusEngineClient.Customers
                                          .GetCampaignCompletionsByCustomerIdAsync(customerId, earnRule.Id);
                }
            }

            foreach (var referral in paged)
            {
                var customerReferral = new CustomerCommonReferralModel()
                {
                    FirstName    = referral.FirstName,
                    LastName     = referral.LastName,
                    Email        = referral.Email,
                    ReferralType = referral.ReferralType,
                    Status       = _mapper.Map <CommonReferralStatus>(referral.Status),
                    TimeStamp    = referral.TimeStamp
                };

                if (earnRuleId.HasValue && earnRuleId != Guid.Empty)
                {
                    await SetReferralAdditionalInformation(campaignCompletions, customerReferral, earnRule, stakes, referral, customerId);
                }
                else if (referral.CampaignId.HasValue)
                {
                    earnRule = await _campaignClient.History.GetEarnRuleMobileAsync(referral.CampaignId.Value, Localization.En);

                    if (earnRule != null)
                    {
                        var completions = await _bonusEngineClient.Customers
                                          .GetCampaignCompletionsByCustomerIdAsync(customerId, earnRule.Id);

                        await SetReferralAdditionalInformation(completions, customerReferral, earnRule, stakes, referral, customerId);
                    }
                }
                else
                {
                    Money18 defaultValue = 0m;

                    customerReferral.CurrentRewardedAmount = defaultValue.ToDisplayString();
                    customerReferral.TotalReward           = defaultValue.ToDisplayString();
                }

                if (!string.IsNullOrWhiteSpace(referral.PartnerId))
                {
                    var request =
                        await _partnerManagementClient.Partners.GetByIdAsync(Guid.Parse(referral.PartnerId));

                    customerReferral.PartnerName = request.Name;
                }

                result.Add(customerReferral);
            }

            return(result);
        }