private async Task <RewardRatioAttribute> GetRatioRewardByReferral(ConditionLocalizedResponse condition, CampaignCompletionModel completions, string referralId, string customerId)
        {
            if (!condition.RewardRatio.Ratios.Any())
            {
                return(null);
            }

            var ratio = new RewardRatioAttribute
            {
                Ratios = _mapper.Map <List <RatioAttributeModel> >(condition.RewardRatio.Ratios)
            };

            var completion = completions?.ConditionCompletions.FirstOrDefault(x => x.ConditionId == condition.Id);

            if (completion == null)
            {
                return(ratio);
            }

            var thresholds = condition.RewardRatio.Ratios.OrderBy(c => c.Order).Select(c => c.Threshold);

            //Data for given referral
            var dataDictionary = completion.Data.FirstOrDefault(c => c.ContainsKey(referralId));

            if (dataDictionary == null)
            {
                return(ratio);
            }

            foreach (var data in dataDictionary)
            {
                var dictionary = JsonConvert.DeserializeObject <Dictionary <string, string> >(data.Value);

                if (dictionary != null)
                {
                    var givenBonus   = dictionary["GivenRatioBonusPercent"];
                    var passedRatios = thresholds.Count(t => t <= Convert.ToDecimal(givenBonus));

                    var ratioCompletion = new RatioCompletion()
                    {
                        PaymentId      = referralId,
                        GivenThreshold = Convert.ToDecimal(givenBonus),
                        Checkpoint     = passedRatios
                    };

                    await SetRewardRatioGivenBonusAmountAsync(condition, customerId, dictionary, ratioCompletion);

                    ratio.RatioCompletion = new List <RatioCompletion>()
                    {
                        ratioCompletion
                    };
                }

                return(ratio);
            }

            return(null);
        }
        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();
        }