private async Task <ProfilePeriod[]> GetOrderedProfilePeriodsForFundingLine(string fundingStreamId,
                                                                                    string fundingPeriodId,
                                                                                    string providerId,
                                                                                    string fundingLineCode)
        {
            PublishedProvider publishedProvider = await _publishedFundingResilience.ExecuteAsync(() => _publishedFunding.GetPublishedProvider(fundingStreamId,
                                                                                                                                              fundingPeriodId,
                                                                                                                                              providerId));

            if (publishedProvider == null)
            {
                throw new InvalidOperationException($"Did not locate a published provider for {fundingStreamId} {fundingPeriodId} {providerId}");
            }

            FundingLine fundingLine = publishedProvider.Current?.FundingLines?.SingleOrDefault(_ => _.FundingLineCode == fundingLineCode);

            if (fundingLine == null)
            {
                throw new InvalidOperationException(
                          $"Did not locate a funding line {fundingLineCode} on published provider for {fundingStreamId} {fundingPeriodId} {providerId}");
            }

            return(new YearMonthOrderedProfilePeriods(fundingLine)
                   .ToArray());
        }
Пример #2
0
        public void GivenThePublishedProviderHasTheFollowingFundingLines(string publishedProviderId,
                                                                         IEnumerable <FundingLine> fundingLines)
        {
            PublishedProvider publishedProvider = GetPublishedProvider(publishedProviderId);

            publishedProvider.Current.FundingLines = fundingLines.ToArray();
        }
        protected override Task <ErrorCheck> HasErrors(PublishedProvider publishedProvider, PublishedProvidersContext publishedProvidersContext)
        {
            ErrorCheck errorCheck = new ErrorCheck();

            PublishedProviderVersion publishedProviderVersion = publishedProvider.Current;

            foreach (FundingLine fundingLine in CustomPaymentFundingLinesFor(publishedProviderVersion))
            {
                decimal fundingLineValue = fundingLine.Value.GetValueOrDefault();
                decimal profiledValue    = GetProfiledSum(fundingLine, publishedProviderVersion);

                if (fundingLineValue != profiledValue)
                {
                    errorCheck.AddError(new PublishedProviderError
                    {
                        Identifier           = fundingLine.FundingLineCode,
                        Type                 = PublishedProviderErrorType.FundingLineValueProfileMismatch,
                        SummaryErrorMessage  = "A funding line profile doesn't match allocation value.",
                        DetailedErrorMessage = $"Funding line profile doesn't match allocation value. " +
                                               $"The allocation value is £{fundingLineValue}, but the profile value is set to £{profiledValue}",
                        FundingLineCode = fundingLine.FundingLineCode,
                        FundingStreamId = publishedProviderVersion.FundingStreamId
                    });
                }
            }

            return(Task.FromResult(errorCheck));
        }
 private void AndTheUpsertPublishedProviderResponse(HttpStatusCode httpStatusCode,
                                                    PublishedProvider expectedPublishedProvider)
 {
     _publishedFundingRepository.Setup(_ =>
                                       _.UpsertPublishedProvider(expectedPublishedProvider))
     .ReturnsAsync(httpStatusCode);
 }
        private bool PublishedProviderMatches(IEnumerable <PublishedProvider> publishedProviders,
                                              PublishedProvider expectedPublishedProvider)
        {
            PublishedProvider actualPublishedProvider = publishedProviders.FirstOrDefault();

            return(actualPublishedProvider == expectedPublishedProvider);
        }
Пример #6
0
        public async Task GivenPublishedProviderWhenRequestQueriedShouldReturnCurrentVersionAsTimedEtagHeaderValue()
        {
            string providerId                 = NewRandomString();
            string fundingPeriodId            = NewRandomString();
            string fundingStreamId            = NewRandomString();
            int    version                    = NewRandomNumber();
            string publishedProviderversionId = $"publishedprovider-{providerId}-{fundingPeriodId}-{fundingStreamId}-{version}";

            _routeValueDictionary.Add(nameof(publishedProviderversionId), publishedProviderversionId);

            PublishedProvider publishedProvider = new PublishedProvider()
            {
                Current = new PublishedProviderVersion()
                {
                    Version = NewRandomNumber()
                }
            };

            _publishedFundingRepository.GetPublishedProvider(fundingStreamId, fundingPeriodId, providerId)
            .Returns(publishedProvider);

            TimedEntityTagHeaderValue result = await WhenTheRequestIsQueried();

            result.ETag.Tag
            .Should()
            .Be($"\"{publishedProvider.Current.Version.ToString()}\"");
        }
Пример #7
0
        protected override void GivenTheOtherwiseValidVariationContext(Action <ProviderVariationContext> changes = null)
        {
            base.GivenTheOtherwiseValidVariationContext(changes);

            PublishedProvider publishedProvider =
                VariationContext.GetPublishedProviderOriginalSnapShot(VariationContext.ProviderId);

            if (publishedProvider == null)
            {
                return;
            }

            PublishedProviderVersion publishedProviderCurrent = publishedProvider.Current;

            publishedProviderCurrent.FundingLines = new[]
            {
                NewFundingLine(_ => _.WithFundingLineCode(FundingLineCode)
                               .WithFundingLineType(FundingLineType.Payment)
                               .WithValue(new RandomNumberBetween(1, int.MaxValue))
                               .WithDistributionPeriods(NewDistributionPeriod(dp =>
                                                                              dp.WithProfilePeriods(NewProfilePeriod()))))
            };
            publishedProviderCurrent.Provider = NewProvider();

            publishedProvider.Released = publishedProviderCurrent.DeepCopy();
        }
 private void AndTheNewCreatedPublishedProvider(PublishedProvider publishedProvider,
                                                PublishedProviderCreateVersionRequest expectedPublishedProviderCreateVersionRequest)
 {
     _publishedProviderVersioningService.Setup(_ =>
                                               _.CreateVersion(expectedPublishedProviderCreateVersionRequest))
     .ReturnsAsync(publishedProvider);
 }
Пример #9
0
        public void PerformPrerequisiteChecks_GivenASpecificationNotAbleToChooseAndPublishedProviders_ReturnsPreReqs()
        {
            // Arrange
            _publishedProvider = NewPublishedProvider(_ => _.WithCurrent(NewPublishedProviderVersion(version => version.WithFundingPeriodId(_publishedFundingPeriod.Id)
                                                                                                     .WithFundingStreamId("stream")
                                                                                                     .WithProviderId("provider"))));

            _specificationFundingStatusService.CheckChooseForFundingStatus(_specification)
            .Returns(SpecificationFundingStatus.CanChoose);

            _publishedProvider.Current.Status = PublishedProviderStatus.Approved;

            // Act
            Func <Task> invocation
                = () => _publishPrerequisiteChecker.PerformChecks(_specification, null, new List <PublishedProvider> {
                _publishedProvider
            });

            invocation
            .Should()
            .Throw <JobPrereqFailedException>()
            .Where(_ =>
                   _.Message == $"Specification with id: '{_specification.Id} has prerequisites which aren't complete.");

            // Assert
            _logger
            .Received(1)
            .Error($"Specification with id: '{_specification.Id}' is not chosen for funding");
        }
        public async Task AssignProfilePatternKeyReturnsNotModifiedIfMatchingProfilePatternKeyExists()
        {
            string fundingLineCode = NewRandomString();
            string key             = NewRandomString();

            GivenTheFundingConfiguration(true);
            ProfilePatternKey profilePatternKey = NewProfilePatternKey(_ => _.WithFundingLineCode(fundingLineCode).WithKey(key));

            PublishedProvider publishedProvider = NewPublishedProvider(_ => _.WithCurrent(
                                                                           NewPublishedProviderVersion(ppv => ppv.WithProfilePatternKeys(
                                                                                                           NewProfilePatternKey(ppk => ppk.WithFundingLineCode(fundingLineCode).WithKey(key))))));

            GivenThePublishedProvider(publishedProvider);

            StatusCodeResult result = await WhenProfilePatternKeyIsAssigned(_fundingStreamId, _fundingPeriodId, _providerId, profilePatternKey) as StatusCodeResult;

            result
            .Should()
            .NotBeNull();

            result
            .StatusCode
            .Should()
            .Be((int)HttpStatusCode.NotModified);
        }
Пример #11
0
        private void GivenThePublishedProvider(PublishedProvider publishedProvider)
        {
            string key = publishedProvider.Id;

            _publishedFunding.Setup(_ => _.GetPublishedProviderById(key, key))
            .ReturnsAsync(publishedProvider);
        }
        public void ThrowsExceptionWhenContentGeneratorReturnsNull()
        {
            // Arrange
            TemplateMetadataContents            templateMetadataContents           = Substitute.For <TemplateMetadataContents>();
            TemplateMapping                     templateMapping                    = Substitute.For <TemplateMapping>();
            IPublishedProviderContentsGenerator publishedProviderContentsGenerator = Substitute.For <IPublishedProviderContentsGenerator>();

            Dictionary <string, GeneratedProviderResult> generatedPublishedProviderData = new Dictionary <string, GeneratedProviderResult>();
            List <PublishedProvider> publishedProvidersToUpdate = new List <PublishedProvider>();

            GeneratedProviderResult generatedProviderResult = new GeneratedProviderResult();

            PublishedProviderVersion publishedProviderVersion = NewPublishedProviderVersion(providerVersion => providerVersion
                                                                                            .WithProviderId(ProviderVersionProviderId)
                                                                                            .WithFundingPeriodId(ProviderVersionFundingPeriodId)
                                                                                            .WithFundingStreamId(ProviderVersionFundingStreamId)
                                                                                            .WithVersion(ProviderVersionVersion));

            PublishedProvider publishedProvider = NewPublishedProvider(provider => provider.WithCurrent(publishedProviderVersion));

            generatedPublishedProviderData.Add(key, generatedProviderResult);
            publishedProvidersToUpdate.Add(publishedProvider);

            // Act
            Func <Task> invocation = async() => await _publishedProviderContentPersistanceService.SavePublishedProviderContents(
                templateMetadataContents, templateMapping, publishedProvidersToUpdate, publishedProviderContentsGenerator);

            // Assert
            ThenExceptionShouldBeThrown($"Generator failed to generate content for published provider version with id: '{publishedProviderVersion.Id}'", invocation);
        }
        public async Task TakesCarryOversIntoAccountWhenCheckingValueMismatchErrorForEachPaymentFundingLineWithValueMismatchesWhereWeHaveACustomProfile()
        {
            string fundingLineCode1 = NewRandomString();

            PublishedProvider publishedProvider = NewPublishedProvider(_ => _.WithCurrent(NewPublishedProviderVersion(ppv => ppv.WithProfilePatternKeys(
                                                                                                                          NewProfilePatternKey(pk => pk.WithFundingLineCode(fundingLineCode1)))
                                                                                                                      .WithCarryOvers(NewProfilingCarryOver(pco => pco.WithAmount(989)
                                                                                                                                                            .WithFundingLineCode(fundingLineCode1)
                                                                                                                                                            .WithType(ProfilingCarryOverType.CustomProfile)))
                                                                                                                      .WithFundingLines(
                                                                                                                          NewFundingLine(fl => fl.WithFundingLineType(FundingLineType.Payment)
                                                                                                                                         .WithFundingLineCode(fundingLineCode1)
                                                                                                                                         .WithValue(999)
                                                                                                                                         .WithDistributionPeriods(NewDistributionPeriod(dp =>
                                                                                                                                                                                        dp.WithProfilePeriods(
                                                                                                                                                                                            NewProfilePeriod(pp =>
                                                                                                                                                                                                             pp.WithAmount(10))))))))));

            await WhenErrorsAreDetectedOnThePublishedProvider(publishedProvider);

            publishedProvider.Current
            .Errors
            .Should()
            .BeNullOrEmpty();
        }
        public async Task AssignProfilePatternKeyReturnsBadRequestIfNewPublishedProviderVersionCreationFailed()
        {
            string fundingLineCode            = NewRandomString();
            string existingProfilePatternKey  = NewRandomString();
            string newProfilePatterFundingKey = NewRandomString();

            GivenTheFundingConfiguration(true);
            ProfilePatternKey profilePatternKey = NewProfilePatternKey(_ => _.WithFundingLineCode(fundingLineCode).WithKey(newProfilePatterFundingKey));

            FundingLine fundingLine = NewFundingLine(_ => _.WithFundingLineCode(fundingLineCode));
            PublishedProviderVersion existingPublishedProviderVersion =
                NewPublishedProviderVersion(ppv => ppv
                                            .WithFundingStreamId(_fundingStreamId)
                                            .WithFundingPeriodId(_fundingPeriodId)
                                            .WithProfilePatternKeys(
                                                NewProfilePatternKey(_ => _.WithFundingLineCode(fundingLineCode).WithKey(existingProfilePatternKey)))
                                            .WithFundingLines(fundingLine)
                                            );

            PublishedProvider publishedProvider = NewPublishedProvider(_ => _.WithCurrent(existingPublishedProviderVersion));

            GivenThePublishedProvider(publishedProvider);

            IActionResult result = await WhenProfilePatternKeyIsAssigned(_fundingStreamId, _fundingPeriodId, _providerId, profilePatternKey);

            ThenResultShouldBe(result, HttpStatusCode.BadRequest);
        }
 private void GivenThePublishedProvider(string fundingStreamId,
                                        string fundingPeriodId,
                                        string providerId,
                                        PublishedProvider publishedProvider)
 => _publishedFunding.Setup(_ => _.GetPublishedProvider(fundingStreamId,
                                                        fundingPeriodId,
                                                        providerId))
 .ReturnsAsync(publishedProvider);
        public Task <PublishedProvider> GetPublishedProvider(string fundingStreamId, string fundingPeriodId, string providerId)
        {
            PublishedProvider publishedProvider = _repo.PublishedProviders.SelectMany(c => c.Value).Where(p =>
                                                                                                          p.Current.FundingStreamId == fundingStreamId &&
                                                                                                          p.Current.FundingPeriodId == fundingPeriodId &&
                                                                                                          p.Current.ProviderId == providerId).FirstOrDefault();

            return(Task.FromResult(publishedProvider));
        }
        public Task <(string providerVersionId, string providerId)> GetPublishedProviderId(string publishedProviderVersion)
        {
            PublishedProvider publishedProvider = _repo.PublishedProviders.SelectMany(c => c.Value).Where(p =>
                                                                                                          p.Released.FundingId == publishedProviderVersion).FirstOrDefault();

            return(Task.FromResult((
                                       providerVersionId: publishedProvider?.Released?.Provider?.ProviderVersionId,
                                       providerId: publishedProvider?.Released?.Provider?.ProviderId)));
        }
        public async Task <IActionResult> ApplyCustomProfile(ApplyCustomProfileRequest request, Reference author)
        {
            Guard.ArgumentNotNull(request, nameof(request));
            Guard.ArgumentNotNull(author, nameof(author));

            ValidationResult validationResult = await _requestValidation.ValidateAsync(request);

            if (!validationResult.IsValid)
            {
                string validationErrors = validationResult.Errors.Select(_ => _.ErrorMessage).Join(", ");

                _logger.Information(
                    $"Unable to process apply custom profile request. Request was invalid. \n{validationErrors}");

                return(validationResult.AsBadRequest());
            }

            string publishedProviderId = request.PublishedProviderId;
            string fundingLineCode     = request.FundingLineCode;

            PublishedProvider publishedProvider = await _publishedFundingResilience.ExecuteAsync(() =>
                                                                                                 _publishedFundingRepository.GetPublishedProviderById(publishedProviderId, publishedProviderId));

            PublishedProviderVersion currentProviderVersion = publishedProvider.Current;

            foreach (IGrouping <string, ProfilePeriod> profilePeriods in request.ProfilePeriods.GroupBy(_ => _.DistributionPeriodId))
            {
                string distributionPeriodId = profilePeriods.Key;

                currentProviderVersion.UpdateDistributionPeriodForFundingLine(
                    fundingLineCode,
                    distributionPeriodId,
                    profilePeriods);

                currentProviderVersion.AddOrUpdateCustomProfile(fundingLineCode, request.CarryOver, distributionPeriodId);
            }

            if (request.HasCarryOver)
            {
                currentProviderVersion.AddCarryOver(fundingLineCode,
                                                    ProfilingCarryOverType.CustomProfile,
                                                    request.CarryOver.GetValueOrDefault());
            }
            else
            {
                currentProviderVersion.RemoveCarryOver(fundingLineCode);
            }

            currentProviderVersion.AddProfilingAudit(fundingLineCode, author);

            await _publishedProviderVersionCreation.UpdatePublishedProviderStatus(new[] { publishedProvider },
                                                                                  author,
                                                                                  currentProviderVersion.Status switch
            {
                PublishedProviderStatus.Draft => PublishedProviderStatus.Draft,
                _ => PublishedProviderStatus.Updated
            },
        public async Task ExecutesVariationStrategiesSpecifiedInSuppliedFundingVariationsAndReturnsVariationResult(
            FundingVariation[] fundingVariations)
        {
            IEnumerable <ProfileVariationPointer> variationPointers = ArraySegment <ProfileVariationPointer> .Empty;
            PublishedProvider existingPublishedProvider             = NewPublishedProvider();
            Provider          updatedProvider     = NewApiProvider();
            decimal           updatedTotalFunding = new RandomNumberBetween(0, 1000);
            IDictionary <string, PublishedProviderSnapShots> allPublishedProviderSnapShots     = new Dictionary <string, PublishedProviderSnapShots>();
            IDictionary <string, PublishedProvider>          allPublishedProviderRefreshStates = new Dictionary <string, PublishedProvider>();
            string providerVersionId = NewRandomString();

            ProviderVariationContext providerVariationContext = await _factory.CreateRequiredVariationChanges(existingPublishedProvider,
                                                                                                              updatedTotalFunding,
                                                                                                              updatedProvider,
                                                                                                              fundingVariations,
                                                                                                              allPublishedProviderSnapShots,
                                                                                                              allPublishedProviderRefreshStates,
                                                                                                              variationPointers,
                                                                                                              providerVersionId);

            providerVariationContext
            .UpdatedTotalFunding
            .Should()
            .Be(updatedTotalFunding);

            providerVariationContext
            .ReleasedState
            .Should()
            .BeSameAs(existingPublishedProvider.Released);

            providerVariationContext
            .UpdatedProvider
            .Should()
            .BeSameAs(updatedProvider);

            providerVariationContext
            .ProviderVersionId
            .Should()
            .BeSameAs(providerVersionId);

            Received.InOrder(() =>
            {
                foreach (FundingVariation fundingVariation in fundingVariations.OrderBy(_ => _.Order))
                {
                    _variationStrategyServiceLocator.GetService(fundingVariation.Name);
                    _variationStrategy.DetermineVariations(Arg.Is <ProviderVariationContext>(
                                                               ctx => ctx.UpdatedTotalFunding == updatedTotalFunding &&
                                                               ReferenceEquals(ctx.ReleasedState, existingPublishedProvider.Released) &&
                                                               ctx.ProviderId == existingPublishedProvider.Current.ProviderId &&
                                                               ReferenceEquals(ctx.UpdatedProvider, updatedProvider) &&
                                                               ReferenceEquals(ctx.AllPublishedProviderSnapShots, allPublishedProviderSnapShots) &&
                                                               ReferenceEquals(ctx.AllPublishedProvidersRefreshStates, allPublishedProviderRefreshStates) &&
                                                               ctx.ProviderVersionId == providerVersionId),
                                                           fundingVariation.FundingLineCodes);
                }
            });
        }
        public void GenerateOrganisationGroupsToSave_GivenOrganisationGroupsUnchanged_NoGroupResultsReturned()
        {
            IEnumerable <Common.ApiClient.Providers.Models.Provider> scopedProviders = GenerateScopedProviders();

            OrganisationGroupResult organisationGroupResult1 = NewOrganisationGroupResult(_ => _.WithGroupTypeClassification(OrganisationGroupTypeClassification.LegalEntity)
                                                                                          .WithGroupTypeCode(OrganisationGroupTypeCode.AcademyTrust).WithGroupTypeIdentifier(OrganisationGroupTypeIdentifier.AcademyTrustCode).WithIdentifierValue("101").WithProviders(scopedProviders.Where(p => p.TrustCode == "101")));
            OrganisationGroupResult organisationGroupResult2 = NewOrganisationGroupResult(_ => _.WithGroupTypeClassification(OrganisationGroupTypeClassification.LegalEntity)
                                                                                          .WithGroupTypeCode(OrganisationGroupTypeCode.AcademyTrust).WithGroupTypeIdentifier(OrganisationGroupTypeIdentifier.AcademyTrustCode).WithIdentifierValue("102").WithProviders(scopedProviders.Where(p => p.TrustCode == "102")));

            PublishedFundingPeriod publishedFundingPeriod = new PublishedFundingPeriod {
                Type = PublishedFundingPeriodType.AY, Period = "123"
            };

            PublishedFunding publishedFunding1 = NewPublishedFunding(_ => _.WithCurrent(NewPublishedFundingVersion(version => version.WithFundingId("funding1")
                                                                                                                   .WithProviderFundings(new string[] { "PSG-AY-123-provider1-1_0", "PSG-AY-123-provider2-1_0" })
                                                                                                                   .WithFundingPeriod(publishedFundingPeriod)
                                                                                                                   .WithFundingStreamId("PSG")
                                                                                                                   .WithOrganisationGroupTypeClassification(OrganisationGroupTypeClassification.LegalEntity)
                                                                                                                   .WithOrganisationGroupTypeIdentifier(OrganisationGroupTypeIdentifier.AcademyTrustCode)
                                                                                                                   .WithOrganisationGroupTypeCode(OrganisationGroupTypeCode.AcademyTrust)
                                                                                                                   .WithOrganisationGroupIdentifierValue("101"))));

            PublishedFunding publishedFunding2 = NewPublishedFunding(_ => _.WithCurrent(NewPublishedFundingVersion(version => version.WithFundingId("funding2")
                                                                                                                   .WithProviderFundings(new string[] { "DSG-AY-123-provider3-1_0" })
                                                                                                                   .WithFundingPeriod(publishedFundingPeriod)
                                                                                                                   .WithFundingStreamId("DSG")
                                                                                                                   .WithOrganisationGroupTypeClassification(OrganisationGroupTypeClassification.LegalEntity)
                                                                                                                   .WithOrganisationGroupTypeIdentifier(OrganisationGroupTypeIdentifier.AcademyTrustCode)
                                                                                                                   .WithOrganisationGroupTypeCode(OrganisationGroupTypeCode.AcademyTrust)
                                                                                                                   .WithOrganisationGroupIdentifierValue("102"))));

            PublishedProvider PublishedProvider1 = NewPublishedProvider(_ => _.WithCurrent(NewPublishedProviderVersion(version => version.WithFundingPeriodId(publishedFundingPeriod.Id)
                                                                                                                       .WithFundingStreamId("PSG")
                                                                                                                       .WithProviderId("provider1"))));

            PublishedProvider PublishedProvider2 = NewPublishedProvider(_ => _.WithCurrent(NewPublishedProviderVersion(version => version.WithFundingPeriodId(publishedFundingPeriod.Id)
                                                                                                                       .WithFundingStreamId("PSG")
                                                                                                                       .WithProviderId("provider2"))));

            PublishedProvider PublishedProvider3 = NewPublishedProvider(_ => _.WithCurrent(NewPublishedProviderVersion(version => version.WithFundingPeriodId(publishedFundingPeriod.Id)
                                                                                                                       .WithFundingStreamId("DSG")
                                                                                                                       .WithProviderId("provider3"))));

            IEnumerable <(PublishedFunding, OrganisationGroupResult)> results = _prerequisites.GenerateOrganisationGroupsToSave(new OrganisationGroupResult[] { organisationGroupResult1, organisationGroupResult2 },
                                                                                                                                new PublishedFunding[] { publishedFunding1, publishedFunding2 },
                                                                                                                                new Dictionary <string, PublishedProvider>(new KeyValuePair <string, PublishedProvider>[] {
                new KeyValuePair <string, PublishedProvider>(PublishedProvider1.Current.ProviderId, PublishedProvider1),
                new KeyValuePair <string, PublishedProvider>(PublishedProvider2.Current.ProviderId, PublishedProvider2),
                new KeyValuePair <string, PublishedProvider>(PublishedProvider3.Current.ProviderId, PublishedProvider3)
            })
                                                                                                                                );

            results.Count()
            .Should()
            .Be(0);
        }
 private void AndANewProviderVersionWasCreatedFor(PublishedProvider publishedProvider, PublishedProviderStatus newStatus, Reference author)
 {
     _publishedProviderVersionCreation.Verify(_ => _.UpdatePublishedProviderStatus(new [] { publishedProvider },
                                                                                   author,
                                                                                   newStatus,
                                                                                   null,
                                                                                   null,
                                                                                   true),
                                              Times.Once);
 }
Пример #22
0
        private async Task SavePublishedProvider(
            PublishedProvider publishedProvider,
            PublishedProviderVersion newPublishedProviderVersion)
        {
            HttpStatusCode saveVersionStatusCode = await _publishedProviderVersioningService.SaveVersion(newPublishedProviderVersion);

            ProcessStatusCode(saveVersionStatusCode, $"Failed to save published provider version for id: {newPublishedProviderVersion.Id} with status code {saveVersionStatusCode.ToString()}");

            HttpStatusCode upsertPublishedProviderStatusCode = await _publishingResiliencePolicy.ExecuteAsync(() => _publishedFundingRepository.UpsertPublishedProvider(publishedProvider));

            ProcessStatusCode(upsertPublishedProviderStatusCode, $"Failed to save published provider for id: {publishedProvider.Id} with status code {upsertPublishedProviderStatusCode.ToString()}");
        }
Пример #23
0
        public async Task DetectErrors(PublishedProvider publishedProvider, PublishedProvidersContext publishedProvidersContext)
        {
            Guard.ArgumentNotNull(publishedProvider, nameof(publishedProvider));

            ClearErrors(publishedProvider.Current);

            ErrorCheck errorCheck = await HasErrors(publishedProvider, publishedProvidersContext);

            if (errorCheck.HasErrors)
            {
                publishedProvider.Current.AddErrors(errorCheck.Errors);
            }
        }
Пример #24
0
        public async Task <IActionResult> AssignProfilePatternKey(
            string fundingStreamId,
            string fundingPeriodId,
            string providerId,
            ProfilePatternKey profilePatternKey,
            Reference author)
        {
            Guard.IsNullOrWhiteSpace(fundingStreamId, nameof(fundingStreamId));
            Guard.IsNullOrWhiteSpace(fundingPeriodId, nameof(fundingPeriodId));
            Guard.IsNullOrWhiteSpace(providerId, nameof(providerId));
            Guard.ArgumentNotNull(profilePatternKey, nameof(profilePatternKey));

            PublishedProvider publishedProvider = await _publishingResiliencePolicy.ExecuteAsync(async() =>
                                                                                                 await _publishedFundingRepository.GetPublishedProvider(fundingStreamId, fundingPeriodId, providerId));

            if (publishedProvider == null)
            {
                return(new StatusCodeResult((int)HttpStatusCode.NotFound));
            }

            FundingConfiguration fundingConfiguration = await _policiesService.GetFundingConfiguration(fundingStreamId, fundingPeriodId);

            if (fundingConfiguration == null || !fundingConfiguration.EnableUserEditableRuleBasedProfiles)
            {
                return(new BadRequestObjectResult($"User not allowed to edit rule based profiles for funding stream - '{fundingStreamId}' and funding period - '{fundingPeriodId}'"));
            }

            if (MatchingProfilePatternKeyExists(publishedProvider.Current, profilePatternKey))
            {
                return(new StatusCodeResult((int)HttpStatusCode.NotModified));
            }

            PublishedProvider modifiedPublishedProvider = await CreateVersion(publishedProvider, author);

            if (modifiedPublishedProvider == null)
            {
                return(new StatusCodeResult((int)HttpStatusCode.BadRequest));
            }

            PublishedProviderVersion newPublishedProviderVersion = publishedProvider.Current;

            newPublishedProviderVersion.SetProfilePatternKey(profilePatternKey, author);

            await ProfileFundingLineValues(newPublishedProviderVersion, profilePatternKey);

            await _publishedProviderErrorDetection.ProcessPublishedProvider(publishedProvider, _ => _ is FundingLineValueProfileMismatchErrorDetector);

            await SavePublishedProvider(publishedProvider, newPublishedProviderVersion);

            return(new StatusCodeResult((int)HttpStatusCode.OK));
        }
        public async Task DetermineVariations(ProviderVariationContext providerVariationContext, IEnumerable <string> fundingLineCodes)
        {
            Guard.ArgumentNotNull(providerVariationContext, nameof(providerVariationContext));

            Provider updatedProvider = providerVariationContext.UpdatedProvider;

            string successorId = updatedProvider.Successor;

            PublishedProviderVersion priorState = providerVariationContext.PriorState;

            if (priorState == null ||
                priorState.Provider.Status == Closed ||
                updatedProvider.Status != Closed ||
                successorId.IsNullOrWhitespace())
            {
                return;
            }

            if (providerVariationContext.UpdatedTotalFunding != priorState.TotalFunding)
            {
                providerVariationContext.RecordErrors("Unable to run Closure with Successor variation as TotalFunding has changed during the refresh funding");

                return;
            }

            PublishedProvider successorProvider = await GetOrCreateSuccessorProvider(providerVariationContext, successorId);

            if (successorProvider == null)
            {
                providerVariationContext.RecordErrors($"Unable to run Closure with Successor variation as could not locate or create a successor provider with id:{successorId}");

                return;
            }

            string providerId = providerVariationContext.ProviderId;

            if (successorProvider.HasPredecessor(providerId))
            {
                return;
            }

            providerVariationContext.SuccessorRefreshState = successorProvider.Current;

            successorProvider.AddPredecessor(providerId);

            providerVariationContext.QueueVariationChange(new TransferRemainingProfilesToSuccessorChange(providerVariationContext));
            providerVariationContext.QueueVariationChange(new ReAdjustSuccessorFundingValuesForProfileValueChange(providerVariationContext));
            providerVariationContext.QueueVariationChange(new ZeroRemainingProfilesChange(providerVariationContext));
            providerVariationContext.QueueVariationChange(new ReAdjustFundingValuesForProfileValuesChange(providerVariationContext));
        }
Пример #26
0
        public async Task ProcessPublishedProvider(PublishedProvider publishedProvider,
                                                   Func <IDetectPublishedProviderErrors, bool> predicate,
                                                   PublishedProvidersContext context)
        {
            IEnumerable <IDetectPublishedProviderErrors> errorDetectors = context.FundingConfiguration?.ErrorDetectors?.Select(_ => _errorDetectorLocator.GetDetector(_));

            if (errorDetectors.AnyWithNullCheck())
            {
                foreach (IDetectPublishedProviderErrors errorDetector in errorDetectors.Where(predicate))
                {
                    await errorDetector.DetectErrors(publishedProvider, context);
                }
            }
        }
        private async Task WhenErrorsAreDetectedOnThePublishedProvider(PublishedProvider publishedProvider, IEnumerable <Provider> providers, string specificationId, string providerVersionId, FundingConfiguration fundingConfiguration, IEnumerable <PublishedFunding> publishedFundings)
        {
            PublishedProvidersContext publishedProvidersContext = new PublishedProvidersContext
            {
                ScopedProviders              = providers,
                SpecificationId              = specificationId,
                ProviderVersionId            = providerVersionId,
                CurrentPublishedFunding      = publishedFundings,
                OrganisationGroupResultsData = new Dictionary <string, HashSet <string> >(),
                FundingConfiguration         = fundingConfiguration
            };

            await _errorDetector.DetectErrors(publishedProvider, publishedProvidersContext);
        }
 private void AndTheProfilingAuditWasUpdatedForTheFundingLine(PublishedProvider publishedProvider,
                                                              string fundingLineCode,
                                                              Reference author)
 {
     publishedProvider
     .Current
     .ProfilingAudits
     .Should()
     .Contain(a => a.FundingLineCode == fundingLineCode &&
              a.User != null &&
              a.User.Id == author.Id &&
              a.User.Name == author.Name &&
              a.Date.Date == DateTime.Today);
 }
        public Task <PublishedProvider> AddPublishedProvider(string specificationId, PublishedProvider publishedProvider)
        {
            Guard.IsNullOrWhiteSpace(specificationId, nameof(specificationId));
            Guard.ArgumentNotNull(publishedProvider, nameof(publishedProvider));

            if (!_repo.PublishedProviders.ContainsKey(specificationId))
            {
                _repo.PublishedProviders[specificationId] = new ConcurrentBag <PublishedProvider>();
            }

            _repo.PublishedProviders[specificationId].Add(publishedProvider);

            return(Task.FromResult(publishedProvider));
        }
 private void AndProfilingAuditUpdatedForFundingLines(PublishedProvider publishedProvider, string[] fundingLines, Reference author)
 {
     foreach (string fundingLineCode in fundingLines)
     {
         publishedProvider
         .Current
         .ProfilingAudits
         .Should()
         .Contain(a => a.FundingLineCode == fundingLineCode &&
                  a.User != null &&
                  a.User.Id == author.Id &&
                  a.User.Name == author.Name &&
                  a.Date.Date == DateTime.Today);
     }
 }