public async Task PerformHolidayCalculationAsync_PerformsNoCalculationsWhenNoHtnpIsNull()
        {
            // Arrange
            var request = new HolidayCalculationRequestModel()
            {
                Hpa  = null,
                Htnp = null
            };

            // Act
            var results = await _service.PerformHolidayCalculationAsync(request, _options);

            // Assert
            results.Hpa.Should().BeNull();
            results.Htnp.Should().BeNull();

            _hpaService.Verify(m => m.PerformHolidayPayAccruedCalculationAsync(
                                   It.IsAny <HolidayPayAccruedCalculationRequestModel>(),
                                   It.IsAny <IOptions <ConfigLookupRoot> >()), Times.Never);
            _htnpService.Verify(m => m.PerformCalculationAsync(
                                    It.IsAny <List <HolidayTakenNotPaidCalculationRequestModel> >(),
                                    It.IsAny <string>(),
                                    It.IsAny <decimal>(),
                                    It.IsAny <decimal>(),
                                    It.IsAny <DateTime?>(),
                                    It.IsAny <IOptions <ConfigLookupRoot> >(), null), Times.Never);
        }
        public async Task PerformHolidayCalculationAsync_PerformsOnlyHpaCalculation()
        {
            // Arrange
            var hpaRequest  = HolidayPayAccruedTestsDataGenerator.GetValidRequestData();
            var hpaResponse = HolidayPayAccruedTestsDataGenerator.GetValidResponseData();

            _hpaService.Setup(m => m.PerformHolidayPayAccruedCalculationAsync(hpaRequest, _options)).ReturnsAsync(hpaResponse);

            var request = new HolidayCalculationRequestModel()
            {
                Hpa  = hpaRequest,
                Htnp = new List <HolidayTakenNotPaidCalculationRequestModel>()
            };

            // Act
            var results = await _service.PerformHolidayCalculationAsync(request, _options);

            // Assert
            results.Hpa.WeeklyResults.Count.Should().Be(hpaResponse.WeeklyResults.Count);
            results.Htnp.Should().BeNull();
            _htnpService.Verify(m => m.PerformCalculationAsync(
                                    It.IsAny <List <HolidayTakenNotPaidCalculationRequestModel> >(),
                                    It.IsAny <string>(),
                                    It.IsAny <decimal>(),
                                    It.IsAny <decimal>(),
                                    It.IsAny <DateTime?>(),
                                    It.IsAny <IOptions <ConfigLookupRoot> >(), null), Times.Never);
        }
        public async Task PostAsync_SucceedsWithOverlappingPeriodsInDifferentInputSources()
        {
            //Arrange
            var request = new HolidayCalculationRequestModel()
            {
                Hpa  = null,
                Htnp = new List <HolidayTakenNotPaidCalculationRequestModel>()
                {
                    new HolidayTakenNotPaidCalculationRequestModel(InputSource.Rp14a, new DateTime(2018, 10, 6), new DateTime(2018, 10, 6), new DateTime(2018, 9, 10), new DateTime(2018, 9, 18), 320m, new List <string> {
                        "1", "2", "3", "4", "5"
                    }, 6, true),
                    new HolidayTakenNotPaidCalculationRequestModel(InputSource.Rp1, new DateTime(2018, 10, 6), new DateTime(2018, 10, 6), new DateTime(2018, 9, 18), new DateTime(2018, 9, 20), 320m, new List <string> {
                        "1", "2", "3", "4", "5"
                    }, 6, true),
                }
            };
            var response = HolidayControllerTestsDataGenerator.GetValidResponseData();

            _service.Setup(m => m.PerformHolidayCalculationAsync(request, _confOptions)).ReturnsAsync(response);
            var controller = new HolidayController(_service.Object, _mockLogger.Object, _confOptions);

            //Act
            var result = await controller.PostAsync(request);

            //Assert
            var okObjectRequest = result.Should().BeOfType <OkObjectResult>().Subject;

            okObjectRequest.StatusCode.Should().Be((int)System.Net.HttpStatusCode.OK);
        }
        public async Task PostAsync_FailsWithBadRequest_WhenThereIsAHtnpValidationError(HolidayTakenNotPaidCalculationRequestModel htnpRequest, string expectedErrorMessage)
        {
            //Arrange
            var request = new HolidayCalculationRequestModel()
            {
                Htnp = new List <HolidayTakenNotPaidCalculationRequestModel>()
                {
                    htnpRequest
                }
            };

            var controller = new HolidayController(_service.Object, _mockLogger.Object, _confOptions);

            //Act
            var result = await controller.PostAsync(request);

            //Assert
            var badRequestObjectRequest = result.Should().BeOfType <BadRequestObjectResult>().Subject;

            badRequestObjectRequest.StatusCode.Should().Be((int)System.Net.HttpStatusCode.BadRequest);

            _mockLogger.Verify(x => x.Log(
                                   LogLevel.Error,
                                   It.IsAny <EventId>(),
                                   It.Is <object>(v => v.ToString().Contains(expectedErrorMessage)),
                                   null,
                                   It.IsAny <Func <object, Exception, string> >()
                                   ));
        }
        public async Task PostAsync_Succeeds_WithRP14aDataAndRP1NotRequiredOverride()
        {
            //Arrange
            var request = new HolidayCalculationRequestModel
            {
                Rp1NotRequired   = true,
                Rp14aNotRequired = true,
                Hpa = new HolidayPayAccruedCalculationRequestModel
                {
                    InsolvencyDate           = new DateTime(2017, 03, 22),
                    EmpStartDate             = new DateTime(2016, 12, 19),
                    DismissalDate            = new DateTime(2017, 03, 20),
                    ContractedHolEntitlement = 25,
                    HolidayYearStart         = new DateTime(2017, 01, 01),
                    IsTaxable    = true,
                    PayDay       = (int)DayOfWeek.Saturday,
                    ShiftPattern = new List <string> {
                        "1", "2", "3", "4", "5"
                    },
                    WeeklyWage      = 243.25m,
                    DaysCFwd        = 5.5m,
                    DaysTaken       = 3.5m,
                    IpConfirmedDays = 25
                },
                Htnp = new List <HolidayTakenNotPaidCalculationRequestModel>()
                {
                    new HolidayTakenNotPaidCalculationRequestModel()
                    {
                        InputSource      = InputSource.Rp14a,
                        InsolvencyDate   = new DateTime(2018, 01, 10),
                        DismissalDate    = new DateTime(2018, 01, 03),
                        UnpaidPeriodFrom = new DateTime(2017, 12, 12),
                        UnpaidPeriodTo   = new DateTime(2017, 12, 29),
                        WeeklyWage       = 306.85m,
                        ShiftPattern     = new List <string> {
                            "1", "2", "3", "4", "5"
                        },
                        PayDay    = 6,
                        IsTaxable = true
                    },
                }
            };
            var response = new HolidayCalculationResponseDTO();

            _service.Setup(m => m.PerformHolidayCalculationAsync(request, _confOptions)).ReturnsAsync(response);
            var controller = new HolidayController(_service.Object, _mockLogger.Object, _confOptions);

            //Act
            var result = await controller.PostAsync(request);

            //Assert
            var okObjectRequest = result.Should().BeOfType <OkObjectResult>().Subject;

            okObjectRequest.StatusCode.Should().Be((int)System.Net.HttpStatusCode.OK);
        }
        public async Task PerformHolidayCalculationAsync_PerformsOnlyHtnpCalculation()
        {
            // Arrange
            var htnpRequestRp1    = HolidayTakenNotPaidControllerTestsDataGenerator.GetValidRp1RequestData();
            var htnpRequestRp14a  = HolidayTakenNotPaidControllerTestsDataGenerator.GetValidRp14aRequestData();
            var htnpResponseRp1   = HolidayTakenNotPaidControllerTestsDataGenerator.GetValidRp1ResponseData();
            var htnpResponseRp14a = HolidayTakenNotPaidControllerTestsDataGenerator.GetValidRp14aResponseData();
            var htnpRequest       = new List <HolidayTakenNotPaidCalculationRequestModel>()
            {
                htnpRequestRp1,
                htnpRequestRp14a
            };

            _htnpService.Setup(m => m.PerformCalculationAsync(htnpRequest, InputSource.Rp1, It.IsAny <decimal>(), It.IsAny <decimal>(), It.IsAny <DateTime?>(), _options, It.IsAny <TraceInfo>())).ReturnsAsync(htnpResponseRp1);
            _htnpService.Setup(m => m.PerformCalculationAsync(htnpRequest, InputSource.Rp14a, It.IsAny <decimal>(), It.IsAny <decimal>(), It.IsAny <DateTime?>(), _options, It.IsAny <TraceInfo>())).ReturnsAsync(htnpResponseRp14a);

            var request = new HolidayCalculationRequestModel()
            {
                Hpa  = null,
                Htnp = htnpRequest
            };

            // Act
            var results = await _service.PerformHolidayCalculationAsync(request, _options);

            // Assert
            results.Hpa.Should().BeNull();
            _hpaService.Verify(m => m.PerformHolidayPayAccruedCalculationAsync(
                                   It.IsAny <HolidayPayAccruedCalculationRequestModel>(),
                                   It.IsAny <IOptions <ConfigLookupRoot> >()), Times.Never);
            _htnpService.Verify(m => m.PerformCalculationAsync(
                                    It.IsAny <List <HolidayTakenNotPaidCalculationRequestModel> >(),
                                    InputSource.Rp1,
                                    It.IsAny <decimal>(),
                                    It.IsAny <decimal>(),
                                    It.IsAny <DateTime?>(),
                                    It.IsAny <IOptions <ConfigLookupRoot> >(), It.IsAny <TraceInfo>()), Times.Once);
            _htnpService.Verify(m => m.PerformCalculationAsync(
                                    It.IsAny <List <HolidayTakenNotPaidCalculationRequestModel> >(),
                                    InputSource.Rp14a,
                                    It.IsAny <decimal>(),
                                    It.IsAny <decimal>(),
                                    It.IsAny <DateTime?>(),
                                    It.IsAny <IOptions <ConfigLookupRoot> >(), It.IsAny <TraceInfo>()), Times.Once);
        }
        public async Task <IActionResult> PostAsync([FromBody] HolidayCalculationRequestModel data)
        {
            try
            {
                if (data == null)
                {
                    ModelState.AddModelError("",
                                             "Bad payload provided; unable to parse the request , please review request data and try again");

                    _logger.LogError(400, $"Bad payload " +
                                     $"{ModelState}\n Request Data is null and could not be parsed");
                    return(BadRequest(ModelState));
                }

                var validator = new HolidayCalculationRequestValidator();
                if (!ModelState.IsValid || !validator.Validate(data).IsValid)
                {
                    _logger.LogError((int)System.Net.HttpStatusCode.BadRequest, $"Request model not valid " +
                                     $"{ModelState}\n Request Data {JsonConvert.SerializeObject(data)} \n Errors : " +
                                     $"{validator.Validate(data).Errors.GetErrorsAsString()} ");
                    return(BadRequest(ModelState));
                }

                var result = await _service.PerformHolidayCalculationAsync(data, _options);

                _logger.LogInformation((int)HttpStatusCode.OK,
                                       $"Calculation performed successfully for the request data provided \n Request Data: {JsonConvert.SerializeObject(data)}");
                return(Ok(result));
            }
            catch (MissingConfigurationException exp)
            {
                _logger.LogError((int)HttpStatusCode.BadRequest,
                                 $"Calculation was not performed for the request data provided \n Request Data: {JsonConvert.SerializeObject(data)} Bad payload provided; {exp.Message}, please review request data and try again");
                return(BadRequest($"Bad payload provided; {exp.Message}, please review request data and try again"));
            }
        }
        public async Task PerformHolidayCalculationAsync_PerformsHpaAndHtnpCalculationsWithRp14aSelected()
        {
            // Arrange
            var shiftPattern = new List <string> {
                "1", "2", "3", "4", "5"
            };

            var hpaRequest = new HolidayPayAccruedCalculationRequestModel
            {
                InsolvencyDate           = new DateTime(2018, 10, 1),
                EmpStartDate             = new DateTime(2016, 1, 1),
                DismissalDate            = new DateTime(2018, 10, 1),
                ContractedHolEntitlement = 25,
                HolidayYearStart         = new DateTime(2018, 1, 1),
                IsTaxable    = true,
                PayDay       = (int)DayOfWeek.Saturday,
                ShiftPattern = shiftPattern,
                WeeklyWage   = 320m,
                DaysCFwd     = 0m,
                DaysTaken    = 8m,
            };

            var hpaResponse = new HolidayPayAccruedResponseDTO()
            {
                StatutoryMax        = 508,
                HolidaysOwed        = 28,
                BusinessDaysInClaim = 261,
                WorkingDaysInClaim  = 196,
                ProRataAccruedDays  = 13.0268m,
                WeeklyResults       = new List <HolidayPayAccruedWeeklyResult>()
                {
                    new HolidayPayAccruedWeeklyResult(1, 508m, 320m, 320m, true, 64m, 18.96m, 237.04m, 320m, 0m),
                    new HolidayPayAccruedWeeklyResult(2, 508m, 320m, 320m, true, 64m, 18.96m, 237.04m, 320m, 0m),
                    new HolidayPayAccruedWeeklyResult(3, 292.23m, 193.72m, 193.72m, true, 38.74m, 3.81m, 151.17m, 193.72m, 0m),
                }
            };

            var htnpRequest = new List <HolidayTakenNotPaidCalculationRequestModel>()
            {
                new HolidayTakenNotPaidCalculationRequestModel(InputSource.Rp1, new DateTime(2018, 10, 1), new DateTime(2018, 10, 1), new DateTime(2018, 8, 1), new DateTime(2018, 8, 12), 320, shiftPattern, 6, true),
                new HolidayTakenNotPaidCalculationRequestModel(InputSource.Rp14a, new DateTime(2018, 10, 1), new DateTime(2018, 10, 1), new DateTime(2018, 8, 2), new DateTime(2018, 8, 14), 320, shiftPattern, 6, true)
            };

            var htnpResponseRp1 = new HolidayTakenNotPaidResponseDTO()
            {
                InputSource  = InputSource.Rp1,
                WeeklyResult = new List <HolidayTakenNotPaidWeeklyResult>()
                {
                    new HolidayTakenNotPaidWeeklyResult(1, new DateTime(2018, 8, 4), 508, 192, 192, true, 38.4m, 3.6m, 150m, 7, 3, 508, 192, 192, true),
                    new HolidayTakenNotPaidWeeklyResult(2, new DateTime(2018, 8, 11), 508, 320, 320, true, 64m, 18.96m, 237.04m, 7, 5, 508, 320, 320, true),
                }
            };

            var htnpResponseRp14a = new HolidayTakenNotPaidResponseDTO()
            {
                InputSource  = InputSource.Rp14a,
                WeeklyResult = new List <HolidayTakenNotPaidWeeklyResult>()
                {
                    new HolidayTakenNotPaidWeeklyResult(1, new DateTime(2018, 8, 4), 508, 128, 128, true, 25.6m, 0m, 102.4m, 7, 2, 508, 128, 128, false),
                    new HolidayTakenNotPaidWeeklyResult(2, new DateTime(2018, 8, 11), 508, 320, 320, true, 64m, 18.96m, 237.04m, 7, 5, 508, 320, 320, false),
                    new HolidayTakenNotPaidWeeklyResult(3, new DateTime(2018, 8, 18), 508, 128, 128, true, 25.6m, 0m, 102.4m, 7, 2, 508, 128, 128, false)
                }
            };

            _hpaService.Setup(x => x.PerformHolidayPayAccruedCalculationAsync(hpaRequest, _options)).ReturnsAsync(hpaResponse);
            _htnpService.Setup(x => x.PerformCalculationAsync(htnpRequest, InputSource.Rp1, It.IsAny <decimal>(), It.IsAny <decimal>(), It.IsAny <DateTime?>(), _options, It.IsAny <TraceInfo>())).ReturnsAsync(htnpResponseRp1);
            _htnpService.Setup(x => x.PerformCalculationAsync(htnpRequest, InputSource.Rp14a, It.IsAny <decimal>(), It.IsAny <decimal>(), It.IsAny <DateTime?>(), _options, It.IsAny <TraceInfo>())).ReturnsAsync(htnpResponseRp14a);

            var request = new HolidayCalculationRequestModel()
            {
                Hpa  = hpaRequest,
                Htnp = htnpRequest
            };

            // Act
            var results = await _service.PerformHolidayCalculationAsync(request, _options);

            // Assert
            results.Hpa.Should().NotBeNull();
            results.Htnp.Should().NotBeNull();
            results.Htnp.SelectedInputSource.Should().Be(InputSource.Rp1);

            _hpaService.Verify(m => m.PerformHolidayPayAccruedCalculationAsync(
                                   hpaRequest,
                                   It.IsAny <IOptions <ConfigLookupRoot> >()), Times.Once);
            _htnpService.Verify(m => m.PerformCalculationAsync(
                                    It.IsAny <List <HolidayTakenNotPaidCalculationRequestModel> >(),
                                    InputSource.Rp1,
                                    14.9732m,
                                    16.9732m,
                                    hpaRequest.HolidayYearStart,
                                    It.IsAny <IOptions <ConfigLookupRoot> >(), It.IsAny <TraceInfo>()), Times.Once);
            _htnpService.Verify(m => m.PerformCalculationAsync(
                                    htnpRequest,
                                    InputSource.Rp14a,
                                    0m,
                                    0m,
                                    hpaRequest.HolidayYearStart,
                                    It.IsAny <IOptions <ConfigLookupRoot> >(), It.IsAny <TraceInfo>()), Times.Once);
        }
        public async Task PerformHolidayCalculationAsync_PerformsHpaAndHtnpCalculationsWithNoHpaAndRp14aSelected()
        {
            // Arrange
            var shiftPattern = new List <string> {
                "1", "2", "3", "4", "5"
            };

            var htnpRequest = new List <HolidayTakenNotPaidCalculationRequestModel>()
            {
                new HolidayTakenNotPaidCalculationRequestModel(InputSource.Rp14a, new DateTime(2018, 10, 1), new DateTime(2018, 10, 1), new DateTime(2018, 8, 1), new DateTime(2018, 8, 12), 320, shiftPattern, 6, true),
                new HolidayTakenNotPaidCalculationRequestModel(InputSource.Rp1, new DateTime(2018, 10, 1), new DateTime(2018, 10, 1), new DateTime(2018, 8, 2), new DateTime(2018, 8, 14), 320, shiftPattern, 6, true)
            };

            var htnpResponseRp1 = new HolidayTakenNotPaidResponseDTO()
            {
                InputSource  = InputSource.Rp1,
                WeeklyResult = new List <HolidayTakenNotPaidWeeklyResult>()
                {
                    new HolidayTakenNotPaidWeeklyResult(1, new DateTime(2018, 8, 4), 508, 128, 128, true, 25.6m, 0m, 102.4m, 7, 2, 508, 128, 128, false),
                    new HolidayTakenNotPaidWeeklyResult(2, new DateTime(2018, 8, 11), 508, 320, 320, true, 64m, 18.96m, 237.04m, 7, 5, 508, 320, 320, false),
                    new HolidayTakenNotPaidWeeklyResult(3, new DateTime(2018, 8, 18), 508, 128, 128, true, 25.6m, 0m, 102.4m, 7, 2, 508, 128, 128, false)
                }
            };

            var htnpResponseRp14a = new HolidayTakenNotPaidResponseDTO()
            {
                InputSource  = InputSource.Rp14a,
                WeeklyResult = new List <HolidayTakenNotPaidWeeklyResult>()
                {
                    new HolidayTakenNotPaidWeeklyResult(1, new DateTime(2018, 8, 4), 508, 192, 192, true, 38.4m, 3.6m, 150m, 7, 3, 508, 192, 192, true),
                    new HolidayTakenNotPaidWeeklyResult(2, new DateTime(2018, 8, 11), 508, 320, 320, true, 64m, 18.96m, 237.04m, 7, 5, 508, 320, 320, true),
                }
            };

            _htnpService.Setup(x => x.PerformCalculationAsync(htnpRequest, InputSource.Rp1, It.IsAny <decimal>(), It.IsAny <decimal>(), It.IsAny <DateTime?>(), _options, null)).ReturnsAsync(htnpResponseRp1);
            _htnpService.Setup(x => x.PerformCalculationAsync(htnpRequest, InputSource.Rp14a, It.IsAny <decimal>(), It.IsAny <decimal>(), It.IsAny <DateTime?>(), _options, null)).ReturnsAsync(htnpResponseRp14a);

            var request = new HolidayCalculationRequestModel()
            {
                Hpa  = null,
                Htnp = htnpRequest
            };

            // Act
            var results = await _service.PerformHolidayCalculationAsync(request, _options);

            // Assert
            results.Hpa.Should().BeNull();
            results.Htnp.Should().NotBeNull();
            results.Htnp.SelectedInputSource.Should().Be(InputSource.Rp14a);

            _htnpService.Verify(m => m.PerformCalculationAsync(
                                    It.IsAny <List <HolidayTakenNotPaidCalculationRequestModel> >(),
                                    InputSource.Rp1,
                                    0m,
                                    0m,
                                    null,
                                    It.IsAny <IOptions <ConfigLookupRoot> >(), null), Times.Once);
            _htnpService.Verify(m => m.PerformCalculationAsync(
                                    htnpRequest,
                                    InputSource.Rp14a,
                                    0m,
                                    30m,
                                    null,
                                    It.IsAny <IOptions <ConfigLookupRoot> >(), It.IsAny <TraceInfo>()), Times.Once);
        }
        public async Task <HolidayCalculationResponseDTO> PerformHolidayCalculationWithHPAAsync(HolidayCalculationRequestModel data, IOptions <ConfigLookupRoot> options)
        {
            string selectedInputString = null;
            var    result    = new HolidayCalculationResponseDTO();
            var    traceinfo = new TraceInfo();

            // select the input source with lowest count in the currrent holiday year
            if (data.Htnp != null && data.Htnp.Any())
            {
                var firstHtnp = data.Htnp.First();

                var holidayYearStart = await data.Hpa.GetHolidayYearStart();

                var htnpEndDate = firstHtnp.DismissalDate.Date < firstHtnp.InsolvencyDate.Date ? firstHtnp.DismissalDate.Date : firstHtnp.InsolvencyDate.Date;

                var tweleveMonthsPrior = firstHtnp.InsolvencyDate.Date.AddMonths(-12).AddDays(1);
                var numRp1HtnpDays     = (await data.Htnp.GetHTNPDays(InputSource.Rp1, tweleveMonthsPrior, htnpEndDate)).Count;
                var numRp14aHtnpDays   = (await data.Htnp.GetHTNPDays(InputSource.Rp14a, tweleveMonthsPrior, htnpEndDate)).Count;

                if ((numRp1HtnpDays > 0 && numRp1HtnpDays < numRp14aHtnpDays) ||
                    (numRp14aHtnpDays == 0 && numRp1HtnpDays > 0))
                {
                    selectedInputString = InputSource.Rp1;
                }
                else
                {
                    selectedInputString = InputSource.Rp14a;
                }

                // align HPA day taken with htnp days
                int numHTNPDaysInCurrentHolYear = (await data.Htnp.GetHTNPDays(selectedInputString, holidayYearStart, htnpEndDate)).Count;
                data.Hpa.DaysTaken = Math.Max(data.Hpa.DaysTaken.Value, numHTNPDaysInCurrentHolYear);
            }

            result.Hpa = await _hpaService.PerformHolidayPayAccruedCalculationAsync(data.Hpa, options);

            if (data.Htnp != null && data.Htnp.Any())
            {
                result.Htnp = new HolidayTakenNotPaidAggregateOutput();
                result.Htnp.SelectedInputSource = selectedInputString;

                var firstHtnp = data.Htnp.First();
                var maximumHolidayEntitlement = 6m * firstHtnp.ShiftPattern.Count;

                var holidayYearStart = await data.Hpa.GetHolidayYearStart();

                decimal statHolEntitlement = 0.00m;
                statHolEntitlement = await statHolEntitlement.GetStatutoryHolidayEntitlement(data.Hpa.ShiftPattern);

                var holidayEntitlementForCurrentYear = (await statHolEntitlement.GetAdjustedHolidayEntitlement(data.Hpa.ContractedHolEntitlement.Value)) + data.Hpa.DaysCFwd.Value;

                var maximumHTNPDaysInHolidayYear = Math.Min(holidayEntitlementForCurrentYear, maximumHolidayEntitlement) - (result.Hpa?.ProRataAccruedDays ?? 0);
                var maximumHTNPDaysInTotal       = maximumHolidayEntitlement - (result.Hpa?.ProRataAccruedDays ?? 0);

                result.Htnp.RP1ResultsList = await _htnpService.PerformCalculationAsync(
                    data.Htnp,
                    InputSource.Rp1,
                    (selectedInputString == InputSource.Rp1)?maximumHTNPDaysInHolidayYear : 0,
                    (selectedInputString == InputSource.Rp1)?maximumHTNPDaysInTotal : 0,
                    holidayYearStart,
                    options,
                    (selectedInputString == InputSource.Rp1)?traceinfo : null);

                result.Htnp.RP14aResultsList = await _htnpService.PerformCalculationAsync(
                    data.Htnp,
                    InputSource.Rp14a,
                    (selectedInputString == InputSource.Rp14a)?maximumHTNPDaysInHolidayYear : 0,
                    (selectedInputString == InputSource.Rp14a)?maximumHTNPDaysInTotal : 0,
                    holidayYearStart,
                    options,
                    (selectedInputString == InputSource.Rp14a)?traceinfo : null);

                result.Htnp.TraceInfo = await traceinfo?.ConvertToJson();
            }
            return(result);
        }
 public async Task <HolidayCalculationResponseDTO> PerformHolidayCalculationAsync(HolidayCalculationRequestModel data, IOptions <ConfigLookupRoot> options)
 {
     if (data.Hpa != null)
     {
         return(await PerformHolidayCalculationWithHPAAsync(data, options));
     }
     else if (data.Htnp != null && data.Htnp.Any())
     {
         return(await PerformHolidayCalculationWithoutHPAAsync(data, options));
     }
     else
     {
         return(new HolidayCalculationResponseDTO());
     }
 }
        public async Task <HolidayCalculationResponseDTO> PerformHolidayCalculationWithoutHPAAsync(HolidayCalculationRequestModel data, IOptions <ConfigLookupRoot> options)
        {
            string selectedInputString = null;
            var    result    = new HolidayCalculationResponseDTO();
            var    traceinfo = new TraceInfo();

            var firstHtnp   = data.Htnp.First();
            var htnpEndDate = firstHtnp.DismissalDate.Date < firstHtnp.InsolvencyDate.Date ? firstHtnp.DismissalDate.Date : firstHtnp.InsolvencyDate.Date;
            var maximumHolidayEntitlement = 6m * firstHtnp.ShiftPattern.Count;

            var tweleveMonthsPrior = firstHtnp.InsolvencyDate.Date.AddMonths(-12).AddDays(1);
            var numRp1HtnpDays     = (await data.Htnp.GetHTNPDays(InputSource.Rp1, tweleveMonthsPrior, htnpEndDate)).Count;
            var numRp14aHtnpDays   = (await data.Htnp.GetHTNPDays(InputSource.Rp14a, tweleveMonthsPrior, htnpEndDate)).Count;

            if ((numRp1HtnpDays > 0 && numRp1HtnpDays < numRp14aHtnpDays) ||
                (numRp14aHtnpDays == 0 && numRp1HtnpDays > 0))
            {
                selectedInputString = InputSource.Rp1;
            }
            else
            {
                selectedInputString = InputSource.Rp14a;
            }

            result.Htnp = new HolidayTakenNotPaidAggregateOutput();
            result.Htnp.SelectedInputSource = selectedInputString;

            result.Htnp.RP1ResultsList = await _htnpService.PerformCalculationAsync(
                data.Htnp,
                InputSource.Rp1,
                0,
                (selectedInputString == InputSource.Rp1)?maximumHolidayEntitlement : 0,
                null,
                options,
                (selectedInputString == InputSource.Rp1)?traceinfo : null);

            result.Htnp.RP14aResultsList = await _htnpService.PerformCalculationAsync(
                data.Htnp,
                InputSource.Rp14a,
                0,
                (selectedInputString == InputSource.Rp14a)?maximumHolidayEntitlement : 0,
                null,
                options,
                (selectedInputString == InputSource.Rp14a)?traceinfo : null);

            result.Htnp.TraceInfo = await traceinfo?.ConvertToJson();

            return(result);
        }