/// <summary>
 /// Calculates the premium that belongs to the passed policy.
 /// </summary>
 /// <param name="policy">The policy for which the premium should be calculated.</param>
 /// <returns>The calculated policy premium. Returns -1 if policy is declined.</returns>
 public decimal CalculatePremium(Policy policy)
 {
     if (DetermineIfPolicyShouldBeDeclined(policy).PolicyDeclined)
     {
         return -1;
     }
     var currentPremium = Basepremium;
     OccupationCalculation(ref currentPremium, policy.Drivers);
     var youngestDriver = policy.Drivers.OrderByDescending(o => o.DateOfBirth).First();
     AgeCalculation(ref currentPremium, youngestDriver.DateOfBirth, policy.StartDate);
     var allClaims = new List<Claim>();
     foreach (var driver in policy.Drivers)
     {
         if (driver.Claims != null)
         {
             allClaims.AddRange(driver.Claims);
         }
     }
     if (allClaims.Count > 0)
     {
         ClaimCalculation(ref currentPremium, allClaims, policy.StartDate);
     }
     return currentPremium;
 }
 /// <summary>
 /// Initializes a couple of policies, each with different details.
 /// </summary>
 public PremiumCalculationServiceTests()
 {
     _premiumCalculationService = new PremiumCalculationService();
     _policy1 = new Policy
     {
         StartDate = DateTime.Today.AddDays(-1),
         Drivers = new List<Driver>
         {
             new Driver
             {
                 Name = "Carlo",
                 DateOfBirth = new DateTime(1991, 1, 12),
                 Occupation = Occupation.Accountant
             }
         }
     };
     _policy2 = new Policy
     {
         StartDate = DateTime.Today.AddDays(1),
         Drivers = new List<Driver>
         {
             new Driver
             {
                 Name = "Carlo",
                 DateOfBirth = new DateTime(1998, 1, 12),
                 Occupation = Occupation.Accountant
             }
         }
     };
     _policy3 = new Policy
     {
         StartDate = DateTime.Today.AddDays(1),
         Drivers = new List<Driver>
         {
             new Driver
             {
                 Name = "Carlo",
                 DateOfBirth = new DateTime(1925, 1, 12),
                 Occupation = Occupation.Accountant
             }
         }
     };
     _policy4 = new Policy
     {
         StartDate = DateTime.Today.AddDays(1),
         Drivers = new List<Driver>
         {
             new Driver
             {
                 Name = "Carlo",
                 DateOfBirth = new DateTime(1991, 1, 12),
                 Occupation = Occupation.Accountant,
                 Claims = new List<Claim>()
                 {
                     new Claim
                     {
                         ClaimDate = new DateTime(2015, 7, 21)
                     },
                     new Claim
                     {
                         ClaimDate = new DateTime(2015, 8, 28)
                     }
                     ,
                     new Claim
                     {
                         ClaimDate = new DateTime(2014, 8, 28)
                     }
                 }
             }
         }
     };
     _policy5 = new Policy
     {
         StartDate = DateTime.Today.AddDays(1),
         Drivers = new List<Driver>
         {
             new Driver
             {
                 Name = "Carlo",
                 DateOfBirth = new DateTime(1991, 1, 12),
                 Occupation = Occupation.Accountant,
                 Claims = new List<Claim>()
                 {
                     new Claim
                     {
                         ClaimDate = new DateTime(2015, 7, 21)
                     },
                     new Claim
                     {
                         ClaimDate = new DateTime(2015, 8, 28)
                     }
                 }
             },
             new Driver
             {
                 Name = "Nicky",
                 DateOfBirth = new DateTime(1992, 2, 24),
                 Occupation =  Occupation.Chauffeur,
                 Claims = new List<Claim>
                 {
                     new Claim
                     {
                         ClaimDate = new DateTime(2015, 12, 12)
                     },
                     new Claim
                     {
                         ClaimDate = new DateTime(2015, 8, 28)
                     }
                 }
             }
         }
     };
     _policy6 = new Policy
     {
         StartDate = DateTime.Today.AddDays(1),
         Drivers = new List<Driver>
         {
             new Driver
             {
                 Name = "Carlo",
                 DateOfBirth = new DateTime(1991, 1, 12),
                 Occupation = Occupation.Accountant,
                 Claims = new List<Claim>()
                 {
                     new Claim
                     {
                         ClaimDate = DateTime.Today.AddYears(-1).AddMonths(-1)
                     },
                     new Claim
                     {
                         ClaimDate = DateTime.Today.AddYears(-1).AddMonths(1)
                     }
                 }
             },
             new Driver
             {
                 Name = "Nicky",
                 DateOfBirth = new DateTime(1992, 2, 24),
                 Occupation =  Occupation.Chauffeur,
                 Claims = new List<Claim>
                 {
                     new Claim
                     {
                         ClaimDate = DateTime.Today.AddYears(-1).AddMonths(6)
                     }
                 }
             },
             new Driver
             {
                 Name = "Roy",
                 DateOfBirth = new DateTime(1994, 5, 23),
                 Occupation =  Occupation.Chauffeur
             }
         }
     };
     _policy7 = new Policy
     {
         StartDate = DateTime.Today.AddDays(1),
         Drivers = new List<Driver>
         {
             new Driver
             {
                 Name = "Carlo",
                 DateOfBirth = new DateTime(1985, 1, 12),
                 Occupation = Occupation.Accountant,
                 Claims = new List<Claim>()
                 {
                     new Claim
                     {
                         ClaimDate = DateTime.Today.AddYears(-1).AddMonths(-1)
                     },
                     new Claim
                     {
                         ClaimDate = DateTime.Today.AddYears(-1).AddMonths(1)
                     }
                 }
             }
         }
     };
 }
 /// <summary>
 /// Determines if a policy should be declined.
 /// </summary>
 /// <param name="policy">The policy which should be accepted or declined.</param>
 /// <returns>A policy decline object containing whether it was declined or not including the reason.</returns>
 public PolicyDecline DetermineIfPolicyShouldBeDeclined(Policy policy)
 {
     if (policy.StartDate < DateTime.Today)
     {
         return new PolicyDecline
         {
             PolicyDeclined = true,
             PolicyDeclineReason = PolicyDeclineReason.StartDateBeforeCurrentDate
         };
     }
     var youngestDriver = policy.Drivers.OrderByDescending(o => o.DateOfBirth).First();
     if (AgeCalculationHelper.DetermineAgeOnDate(youngestDriver.DateOfBirth, policy.StartDate) < 21)
     {
         return new PolicyDecline
         {
             PolicyDeclined = true,
             PolicyDeclineReason = PolicyDeclineReason.YoungestDriverTooYoung
         };
     }
     var oldestDriver = policy.Drivers.OrderBy(o => o.DateOfBirth).First();
     if (AgeCalculationHelper.DetermineAgeOnDate(oldestDriver.DateOfBirth, policy.StartDate) > 75)
     {
         return new PolicyDecline
         {
             PolicyDeclined = true,
             PolicyDeclineReason = PolicyDeclineReason.OldestDriverTooOld
         };
     }
     var totalClaims = 0;
     foreach (var driver in policy.Drivers)
     {
         if (driver.Claims != null)
         {
             if (driver.Claims.Count > 2)
             {
                 return new PolicyDecline
                 {
                     PolicyDeclined = true,
                     PolicyDeclineReason = PolicyDeclineReason.SingleDriverMoreThanTwoClaims
                 };
             }
             totalClaims += driver.Claims.Count;
             if (totalClaims > 3)
             {
                 return new PolicyDecline
                 {
                     PolicyDeclined = true,
                     PolicyDeclineReason = PolicyDeclineReason.TotalMoreThanThreeClaims
                 };
             }
         }
     }
     return new PolicyDecline
     {
         PolicyDeclined = false
     };
 }