private async Task <ReProfileRequest> WhenTheReProfileRequestIsBuilt(string specificationId,
                                                                      string fundingStreamId,
                                                                      string fundingPeriodId,
                                                                      string providerId,
                                                                      string fundingLineCode,
                                                                      string profilePatternKey,
                                                                      ProfileConfigurationType configurationType,
                                                                      decimal?fundingLineTotal = null)
 => await _requestBuilder.BuildReProfileRequest(specificationId,
                                                fundingStreamId,
                                                fundingPeriodId,
                                                providerId,
                                                fundingLineCode,
                                                profilePatternKey,
                                                configurationType,
                                                fundingLineTotal);
        public async Task <ReProfileRequest> BuildReProfileRequest(string specificationId,
                                                                   string fundingStreamId,
                                                                   string fundingPeriodId,
                                                                   string providerId,
                                                                   string fundingLineCode,
                                                                   string profilePatternKey,
                                                                   ProfileConfigurationType configurationType,
                                                                   decimal?fundingLineTotal = null)
        {
            Guard.IsNullOrWhiteSpace(specificationId, nameof(specificationId));
            Guard.IsNullOrWhiteSpace(fundingStreamId, nameof(fundingStreamId));
            Guard.IsNullOrWhiteSpace(fundingPeriodId, nameof(fundingPeriodId));
            Guard.IsNullOrWhiteSpace(providerId, nameof(providerId));
            Guard.IsNullOrWhiteSpace(fundingLineCode, nameof(fundingLineCode));

            ProfileVariationPointer profileVariationPointer = await GetProfileVariationPointerForFundingLine(specificationId,
                                                                                                             fundingLineCode,
                                                                                                             fundingStreamId);

            ProfilePeriod[] orderedProfilePeriodsForFundingLine = await GetOrderedProfilePeriodsForFundingLine(fundingStreamId,
                                                                                                               fundingPeriodId,
                                                                                                               providerId,
                                                                                                               fundingLineCode);

            int paidUpToIndex = GetProfilePeriodIndexForVariationPointer(profileVariationPointer, orderedProfilePeriodsForFundingLine);

            IEnumerable <ExistingProfilePeriod> existingProfilePeriods = BuildExistingProfilePeriods(orderedProfilePeriodsForFundingLine, paidUpToIndex);

            decimal existingFundingLineTotal = orderedProfilePeriodsForFundingLine.Sum(_ => _.ProfiledValue);

            return(new ReProfileRequest
            {
                ProfilePatternKey = profilePatternKey,
                ConfigurationType = configurationType,
                FundingLineCode = fundingLineCode,
                FundingPeriodId = fundingPeriodId,
                FundingStreamId = fundingStreamId,
                FundingLineTotal = fundingLineTotal.GetValueOrDefault(existingFundingLineTotal),
                ExistingFundingLineTotal = existingFundingLineTotal,
                ExistingPeriods = existingProfilePeriods
            });
        }
 private void AndTheReProfileRequest(string specificationId,
                                     string fundingStreamId,
                                     string fundingPeriodId,
                                     string providerId,
                                     string fundingLineCode,
                                     string profilePatternKey,
                                     ProfileConfigurationType configurationType,
                                     decimal?fundingLineTotal,
                                     ReProfileRequest profileRequest)
 {
     _reProfilingRequestBuilder.Setup(_ => _.BuildReProfileRequest(specificationId,
                                                                   fundingStreamId,
                                                                   fundingPeriodId,
                                                                   providerId,
                                                                   fundingLineCode,
                                                                   profilePatternKey,
                                                                   configurationType,
                                                                   fundingLineTotal))
     .ReturnsAsync(profileRequest);
 }
        public async Task BuildsReProfileRequestsOutOfExistingFundingInformationUsingPublishedProvidersAndVariationPointers()
        {
            string  providerId       = NewRandomString();
            string  fundingStreamId  = NewRandomString();
            string  fundingPeriodId  = NewRandomString();
            string  fundingLineCode  = NewRandomString();
            string  specificationId  = NewRandomString();
            string  profilePattern   = NewRandomString();
            decimal fundingLineTotal = NewRandomAmount();
            ProfileConfigurationType profileConfigurationType = NewRandomProfileConfigurationType();

            GivenThePublishedProvider(fundingStreamId,
                                      fundingPeriodId,
                                      providerId,
                                      NewPublishedProvider(_ => _.WithCurrent(NewPublisherProviderVersion(pvp =>
                                                                                                          pvp.WithFundingLines(NewFundingLine(),
                                                                                                                               NewFundingLine(fl => fl.WithFundingLineCode(fundingLineCode)
                                                                                                                                              .WithDistributionPeriods(NewDistributionPeriod(dp =>
                                                                                                                                                                                             dp.WithProfilePeriods(NewProfilePeriod(pp => pp.WithDistributionPeriodId("dp1")
                                                                                                                                                                                                                                    .WithAmount(23)
                                                                                                                                                                                                                                    .WithOccurence(0)
                                                                                                                                                                                                                                    .WithYear(2021)
                                                                                                                                                                                                                                    .WithType(ProfilePeriodType.CalendarMonth)
                                                                                                                                                                                                                                    .WithTypeValue("January")),
                                                                                                                                                                                                                   NewProfilePeriod(pp => pp.WithDistributionPeriodId("dp1")
                                                                                                                                                                                                                                    .WithAmount(24)
                                                                                                                                                                                                                                    .WithOccurence(1)
                                                                                                                                                                                                                                    .WithYear(2021)
                                                                                                                                                                                                                                    .WithType(ProfilePeriodType.CalendarMonth)
                                                                                                                                                                                                                                    .WithTypeValue("January")),
                                                                                                                                                                                                                   NewProfilePeriod(pp => pp.WithDistributionPeriodId("dp1")
                                                                                                                                                                                                                                    .WithAmount(25)
                                                                                                                                                                                                                                    .WithOccurence(0)
                                                                                                                                                                                                                                    .WithYear(2021)
                                                                                                                                                                                                                                    .WithType(ProfilePeriodType.CalendarMonth)
                                                                                                                                                                                                                                    .WithTypeValue("March")),
                                                                                                                                                                                                                   NewProfilePeriod(pp => pp.WithDistributionPeriodId("dp1")
                                                                                                                                                                                                                                    .WithAmount(26)
                                                                                                                                                                                                                                    .WithOccurence(0)
                                                                                                                                                                                                                                    .WithYear(2021)
                                                                                                                                                                                                                                    .WithType(ProfilePeriodType.CalendarMonth)
                                                                                                                                                                                                                                    .WithTypeValue("April"))
                                                                                                                                                                                                                   )))))))));

            ReProfileRequest reProfileRequest = await WhenTheReProfileRequestIsBuilt(specificationId,
                                                                                     fundingStreamId,
                                                                                     fundingPeriodId,
                                                                                     providerId,
                                                                                     fundingLineCode,
                                                                                     profilePattern,
                                                                                     profileConfigurationType,
                                                                                     fundingLineTotal);

            reProfileRequest
            .Should()
            .BeEquivalentTo(new ReProfileRequest
            {
                ConfigurationType        = profileConfigurationType,
                FundingLineCode          = fundingLineCode,
                ExistingFundingLineTotal = 23 + 24 + 25 + 26,
                FundingLineTotal         = fundingLineTotal,
                FundingPeriodId          = fundingPeriodId,
                FundingStreamId          = fundingStreamId,
                ProfilePatternKey        = profilePattern,
                ExistingPeriods          = new []
                {
                    NewExististingProfilePeriod(_ => _.WithOccurrence(0)
                                                .WithDistributionPeriod("dp1")
                                                .WithValue(null)
                                                .WithPeriodType(PeriodType.CalendarMonth)
                                                .WithTypeValue("January")
                                                .WithYear(2021)),
                    NewExististingProfilePeriod(_ => _.WithOccurrence(1)
                                                .WithDistributionPeriod("dp1")
                                                .WithValue(null)
                                                .WithPeriodType(PeriodType.CalendarMonth)
                                                .WithTypeValue("January")
                                                .WithYear(2021)),
                    NewExististingProfilePeriod(_ => _.WithOccurrence(0)
                                                .WithDistributionPeriod("dp1")
                                                .WithValue(null)
                                                .WithPeriodType(PeriodType.CalendarMonth)
                                                .WithTypeValue("March")
                                                .WithYear(2021)),
                    NewExististingProfilePeriod(_ => _.WithOccurrence(0)
                                                .WithDistributionPeriod("dp1")
                                                .WithValue(null)
                                                .WithPeriodType(PeriodType.CalendarMonth)
                                                .WithTypeValue("April")
                                                .WithYear(2021))
                }
            });
        }