public void DetermineBetRiskStatus(Bet bet, Customer customer)
        {
            // Identify unsettled bets that exhibit high risk characteristics
            if (bet.BetStatus == BetStatus.Settled)
            {
                return;
            }

            // TODO: Clarification required from product owner on relative severity of these business rules.

            // All upcoming (i.e. unsettled) bets from customers that win at an unusual rate should
            // be highlighted as risky (it is up to you how this is shown)
            if (customer.CustomerRiskStatus == CustomerRiskStatus.High)
            {
                bet.BetRiskStatus = BetRiskStatus.High;
                bet.RiskReason = "Customer has been identified as high risk.";
                return;
            }

            // TODO: Clarification required from product owner as to whether these business rules should be cumulative.

            // Bets where the amount to be won is $1000 or more.
            if (bet.Win > BetWinAmountRiskThreshold)
            {
                bet.BetRiskStatus = BetRiskStatus.High;
                bet.RiskReason =
                    string.Format("Potential win amount of {0:C} is higher than the risk threshold of {1:C}.", bet.Win,
                        BetWinAmountRiskThreshold);
                return;
            }

            decimal customerAverageBetStake = Convert.ToDecimal(customer.TotalSettledStake)/
                                              Convert.ToDecimal(customer.NumberOfSettledBets);

            // Bets where the stake is more than 30 times higher than that customer’s average bet in
            // their betting history should be highlighted as highly unusual
            if (bet.Stake > customerAverageBetStake * 30)
            {
                bet.BetRiskStatus = BetRiskStatus.High;
                bet.RiskReason = string.Format("Stake is more than 30 times higher than the customer's average or {0:C}.", customerAverageBetStake);
                return;
            }

            // Bets where the stake is more than 10 times higher than that customer’s average bet in
            // their betting history should be highlighted as unusual (again, it is up to you how
            // this is shown)
            if (bet.Stake > customerAverageBetStake*10)
            {
                bet.BetRiskStatus = BetRiskStatus.High;
                bet.RiskReason = string.Format("Stake is more than 10 times higher than the customer's average or {0:C}.", customerAverageBetStake);
                return;
            }
        }
        public void Given_A_Customer_With_No_Settled_Bets_When_Determining_CustomerRiskStatus_Then_Status_Should_Be_Normal()
        {
            // Arrange
            Customer customer = new Customer();
            customer.NumberOfSettledBets = 0;
            CustomerRiskCalculator calculator = new CustomerRiskCalculator();

            // Act
            calculator.DetermineCustomerRisk(customer);

            // Assert
            Assert.AreEqual(CustomerRiskStatus.Normal, customer.CustomerRiskStatus);
        }
        public void Given_A_Customer_With_More_Than_60_Percent_Winning_Bets_When_Determining_CustomerRiskStatus_Then_Status_Should_Be_High()
        {
            // Arrange
            Customer customer = new Customer();
            customer.NumberOfSettledBets = 10000;
            customer.NumberOfWinningBets = 6001;
            CustomerRiskCalculator calculator = new CustomerRiskCalculator();

            // Act
            calculator.DetermineCustomerRisk(customer);

            // Assert
            Assert.AreEqual(CustomerRiskStatus.High, customer.CustomerRiskStatus);
            Assert.AreEqual("Customer has won 60.01% of their settled bets, which is higher than the risk threshold of 60.00%.", customer.RiskReason);
        }
        private Customer BuildCustomer(IGrouping<int, Bet> bets)
        {
            Customer customer = new Customer();

            customer.Id = bets.Key;
            customer.TotalNumberOfBets = bets.Count();
            customer.NumberOfSettledBets = bets.Count(bet => bet.BetStatus == BetStatus.Settled);
            customer.NumberOfUnsettledBets = bets.Count(bet => bet.BetStatus == BetStatus.Unsettled);
            customer.NumberOfWinningBets = bets.Count(bet => bet.BetStatus == BetStatus.Settled && bet.Win > 0);
            customer.TotalSettledStake = bets.Where(bet => bet.BetStatus == BetStatus.Settled).Sum(bet => bet.Stake);
            customer.TotalSettledWin = bets.Where(bet => bet.BetStatus == BetStatus.Settled).Sum(bet => bet.Win);
            customer.TotalUnsettledStake = bets.Where(bet => bet.BetStatus == BetStatus.Unsettled).Sum(bet => bet.Stake);
            customer.TotalUnsettledWin = bets.Where(bet => bet.BetStatus == BetStatus.Unsettled).Sum(bet => bet.Win);

            _customerRiskCalculator.DetermineCustomerRisk(customer);

            return customer;
        }
        public void DetermineCustomerRisk(Customer customer)
        {
            if (customer.NumberOfSettledBets == 0)
            {
                return;
            }

            decimal winningBetPercentage = Convert.ToDecimal(customer.NumberOfWinningBets)/
                                           Convert.ToDecimal(customer.NumberOfSettledBets);

            if (winningBetPercentage > WinningBetPercentageRiskThreshold)
            {
                customer.CustomerRiskStatus = CustomerRiskStatus.High;
                customer.RiskReason =
                    string.Format(
                        "Customer has won {0:P} of their settled bets, which is higher than the risk threshold of {1:P}.",
                        winningBetPercentage, WinningBetPercentageRiskThreshold);
            }
        }