public async Task PerformRedundancyPaymentCalculationForAllAgeGroups(
            RedundancyPaymentCalculationRequestModel request, RedundancyPaymentResponseDto expectedResult)
        {
            //Act
            var actualResult = await _redundancyPaymentCalculationService.PerformRedundancyPayCalculationAsync(request, _options);

            //Assert
            Assert.IsType <RedundancyPaymentResponseDto>(actualResult);
            actualResult.AdjEmploymentStartDate.Should().Be(expectedResult.AdjEmploymentStartDate);
            actualResult.NoticeDateForRedundancyPay.Should().Be(expectedResult.NoticeDateForRedundancyPay);
            actualResult.NoticeEntitlementWeeks.Should().Be(expectedResult.NoticeEntitlementWeeks);
            actualResult.RedundancyPayWeeks.Should().Be(expectedResult.RedundancyPayWeeks);
            actualResult.YearsOfServiceUpto21.Should().Be(expectedResult.YearsOfServiceUpto21);
            actualResult.YearsOfServiceFrom22To41.Should().Be(expectedResult.YearsOfServiceFrom22To41);
            actualResult.YearsServiceOver41.Should().Be(expectedResult.YearsServiceOver41);
            actualResult.GrossEntitlement.Should().Be(expectedResult.NetEntitlement);
            actualResult.EmployerPartPayment.Should().Be(expectedResult.EmployerPartPayment);
            actualResult.NetEntitlement.Should().Be(expectedResult.NetEntitlement);
            actualResult.PreferentialClaim.Should().Be(0m);
            actualResult.NonPreferentialClaim.Should().Be(expectedResult.NetEntitlement);
            actualResult.StatutoryMax.Should().Be(expectedResult.StatutoryMax);
        }
        public async Task <RedundancyPaymentResponseDto> PerformRedundancyPayCalculationAsync(
            RedundancyPaymentCalculationRequestModel data, IOptions <ConfigLookupRoot> options)
        {
            var calculationResult = new RedundancyPaymentResponseDto();

            var adjStartDate = await data.EmploymentStartDate.GetAdjustedEmploymentStartDate(data.EmploymentBreaks);

            var relevantNoticeDate = await data.DateNoticeGiven.GetRelevantNoticeDate(data.DismissalDate);

            var noticeEntitlementWeeks = await adjStartDate.GetNoticeEntitlementWeeks(relevantNoticeDate);

            var projectedNoticeDate = await relevantNoticeDate.GetProjectedNoticeDate(noticeEntitlementWeeks);

            var relevantDismissalDate = await data.DismissalDate.GetRelevantDismissalDate(projectedNoticeDate);

            var statutoryMax = ConfigValueLookupHelper.GetStatutoryMax(options, relevantDismissalDate);

            var totalYearsOfService = await adjStartDate.GetServiceYearsAsync(relevantDismissalDate);

            //limit maximum service years to 20
            if (totalYearsOfService > 20)
            {
                totalYearsOfService = 20;
            }

            var appliedRateOfPay = Math.Min(statutoryMax, data.WeeklyWage);

            int yearsOfServiceUpto21 = 0, yearsOfService22To41 = 0;

            var yearsOfServiceOver41 = await data.DateOfBirth.GetYearsOfServiceOver41(adjStartDate, relevantDismissalDate);

            if (yearsOfServiceOver41 < totalYearsOfService)
            {
                yearsOfService22To41 = await data.DateOfBirth.GetYearsOfServiceFrom22To41(adjStartDate, relevantDismissalDate);

                if (yearsOfServiceOver41 + yearsOfService22To41 > totalYearsOfService)
                {
                    yearsOfService22To41 = totalYearsOfService - yearsOfServiceOver41;
                }
            }
            if (yearsOfServiceOver41 + yearsOfService22To41 < totalYearsOfService)
            {
                yearsOfServiceUpto21 = totalYearsOfService - (yearsOfService22To41 + yearsOfServiceOver41);
            }

            var redundancyPayWeeks = decimal.Multiply(yearsOfServiceUpto21, 0.5m) + yearsOfService22To41 + decimal.Multiply(yearsOfServiceOver41, 1.5m);
            var grossEntitlement   = redundancyPayWeeks * appliedRateOfPay;

            var grossEntitlementFinal    = Math.Max(0m, Math.Round(grossEntitlement, 2));
            var employerPartPaymentFinal = Math.Round(data.EmployerPartPayment, 2);
            var netEntitlementFinal      = Math.Max(0m, (grossEntitlementFinal - employerPartPaymentFinal));

            calculationResult.AdjEmploymentStartDate     = adjStartDate;
            calculationResult.NoticeDateForRedundancyPay = relevantDismissalDate;
            calculationResult.NoticeEntitlementWeeks     = noticeEntitlementWeeks;
            calculationResult.RedundancyPayWeeks         = Math.Round(redundancyPayWeeks, 4);
            calculationResult.YearsOfServiceUpto21       = yearsOfServiceUpto21;
            calculationResult.YearsOfServiceFrom22To41   = yearsOfService22To41;
            calculationResult.YearsServiceOver41         = yearsOfServiceOver41;
            //calculationResult.GrossEntitlement = grossEntitlementFinal;
            calculationResult.GrossEntitlement     = netEntitlementFinal; //TEMP CHANGE: Gross entitlement set to Net entitlement as quick fix for CMS message to BW
            calculationResult.EmployerPartPayment  = employerPartPaymentFinal;
            calculationResult.NetEntitlement       = netEntitlementFinal;
            calculationResult.PreferentialClaim    = 0m;
            calculationResult.NonPreferentialClaim = netEntitlementFinal;
            calculationResult.StatutoryMax         = statutoryMax;

            return(calculationResult);
        }