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 <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);
        }
        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);
        }