public Task <HttpStatusCode> UpsertPublishedFunding(PublishedFunding publishedFunding) { Guard.ArgumentNotNull(publishedFunding, nameof(publishedFunding)); Guard.ArgumentNotNull(publishedFunding.Current, nameof(publishedFunding.Current)); Guard.IsNullOrWhiteSpace(publishedFunding.Current.SpecificationId, nameof(publishedFunding.Current.SpecificationId)); Guard.IsNullOrWhiteSpace(publishedFunding.Id, nameof(publishedFunding.Id)); string specificationId = publishedFunding.Current.SpecificationId; if (!_repo.PublishedFunding.ContainsKey(specificationId)) { _repo.PublishedFunding.TryAdd(specificationId, new ConcurrentBag <PublishedFunding>()); } List <PublishedFunding> itemsToRemove = new List <PublishedFunding>(); PublishedFunding existingFunding = _repo.PublishedFunding[specificationId].Where(p => p.Id == publishedFunding.Id).FirstOrDefault(); if (existingFunding != null) { existingFunding = publishedFunding; } else { _repo.PublishedFunding[specificationId].Add(publishedFunding); } return(Task.FromResult(HttpStatusCode.OK)); }
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 GivenPublishedFunding() { _publishedFundingVersion = NewPublishedFundingVersion(_ => _.WithFundingId("funding1") .WithProviderFundings(new List <string> { "providerfunding1", "providerfunding2" }) .WithFundingPeriod(_publishedFundingPeriod) .WithFundingStreamId("stream1") .WithOrganisationGroupTypeClassification(OrganisationGroupTypeClassification.LegalEntity) .WithOrganisationGroupTypeIdentifier(OrganisationGroupTypeIdentifier.AcademyTrustCode) .WithOrganisationGroupTypeCode(OrganisationGroupTypeCode.AcademyTrust) .WithOrganisationGroupIdentifierValue("101")); _publishedFunding = NewPublishedFunding(_ => _.WithCurrent(_publishedFundingVersion)); }
public void FlattensTemplateCalculationsAndProviderMetaDataIntoRows( CalculateFunding.Models.Publishing.GroupingReason expectedGroupingReason) { PublishedFunding publishedFunding = NewPublishedFunding(_ => _.WithCurrent( NewPublishedFundingVersion(pfv => pfv.WithOrganisationGroupTypeCode(OrganisationGroupTypeCode.LocalAuthority) .WithOrganisationGroupName("Enfield") .WithGroupReason(expectedGroupingReason) .WithProviderFundings(new [] { "one", "two" }) .WithPublishedProviderStatus(PublishedFundingStatus.Released) .WithMajor(1) .WithAuthor(NewReference(rf => rf.WithName("system"))) .WithDate("2020-02-05T20:03:55") .WithFundingLines( NewFundingLines(fl => fl.WithName("fundingLine1") .WithValue(123M), fl => fl.WithName("fundingLine2") .WithValue(456M)))))); dynamic[] expectedCsvRows = { new Dictionary <string, object> { { "Grouping Reason",expectedGroupingReason.ToString() }, { "Grouping Code", "LocalAuthority" }, { "Grouping Name", "Enfield" }, { "Allocation Status","Released" }, { "Allocation Major Version","1" }, { "Allocation Author","system" }, { "Allocation DateTime","2020-02-05T20:03:55" }, { "Provider Count", 2 }, { "fundingLine1", 123M.ToString(CultureInfo.InvariantCulture) }, //funding lines to be alpha numerically ordered on name { "fundingLine2", 456M.ToString(CultureInfo.InvariantCulture) } } }; ExpandoObject[] transformProviderResultsIntoCsvRows = _transformation.Transform(new [] { publishedFunding }).ToArray(); transformProviderResultsIntoCsvRows .Should() .BeEquivalentTo(expectedCsvRows); }
public async Task ThenTheFollowingPublishedFundingIsProduced(Table table) { PublishedFundingLookupModel lookupModel = table.CreateInstance <PublishedFundingLookupModel>(); _publishedFundingRepositoryStepContext.Repo.Should().NotBeNull(); _publishedFundingResultStepContext.Should().NotBeNull(); string fundingId = $"funding-{lookupModel.FundingStreamId}-{lookupModel.FundingPeriodId}-{lookupModel.GroupingReason}-{lookupModel.OrganisationGroupTypeCode}-{lookupModel.OrganisationGroupIdentifierValue}"; PublishedFunding publishedFunding = await _publishedFundingRepositoryStepContext.Repo .GetPublishedFundingById(fundingId, "partitionNotUesd"); publishedFunding .Should() .NotBeNull("Published funding not found for ID '{0}'", fundingId); _publishedFundingResultStepContext.CurrentPublishedFunding = publishedFunding; }
/// <summary> /// Generates the organisation group results which do not currently exist, or whose providers have updated since the last save /// </summary> /// <param name="organisationGroups"></param> /// <param name="existingPublishedFunding"></param> /// <param name="currentPublishedProviders"></param> /// <returns></returns> public IEnumerable <(PublishedFunding PublishedFunding, OrganisationGroupResult OrganisationGroupResult)> GenerateOrganisationGroupsToSave(IEnumerable <OrganisationGroupResult> organisationGroups, IEnumerable <PublishedFunding> existingPublishedFunding, IDictionary <string, PublishedProvider> currentPublishedProviders) { ConcurrentBag <(PublishedFunding, OrganisationGroupResult)> results = new ConcurrentBag <(PublishedFunding, OrganisationGroupResult)>(); Parallel.ForEach(organisationGroups, (organisationGroup) => { // get all funding where the organisation group matches the published funding PublishedFunding publishedFunding = existingPublishedFunding?.Where(_ => organisationGroup.IdentifierValue == _.Current.OrganisationGroupIdentifierValue && organisationGroup.GroupTypeCode == Enum.Parse <OrganisationGroupTypeCode>(_.Current.OrganisationGroupTypeCode) && organisationGroup.GroupTypeClassification == Enum.Parse <OrganisationGroupTypeClassification>(_.Current.OrganisationGroupTypeClassification) && organisationGroup.GroupTypeIdentifier == Enum.Parse <OrganisationGroupTypeIdentifier>(_.Current.OrganisationGroupTypeIdentifier) ).OrderBy(_ => _.Current.Version).LastOrDefault(); // no existing published funding so need to yield the organisation group if (publishedFunding == null || publishedFunding.Current == null) { results.Add((null, organisationGroup)); return; }
public void ThenThePublishedFundingContainsTheFollowingPublishedProviderIds(Table table) { PublishedFunding publishedFunding = _publishedFundingResultStepContext.CurrentPublishedFunding; publishedFunding.Should() .NotBeNull(); List <string> expectedPublishedProviderIds = new List <string>(); for (int i = 0; i < table.Rows.Count; i++) { expectedPublishedProviderIds.Add(table.Rows[i][0]); } publishedFunding .Current .ProviderFundings .Should() .BeEquivalentTo(expectedPublishedProviderIds); }
public Task <IEnumerable <PublishedFunding> > GetPublishedFundings( IEnumerable <KeyValuePair <string, string> > publishedFundingIds) { List <PublishedFunding> publishedFundings = new List <PublishedFunding>(); foreach (KeyValuePair <string, string> publishedFundingId in publishedFundingIds) { PublishedFunding publishedFunding = _repo .PublishedFunding .SelectMany(c => c.Value) .FirstOrDefault(p => p.Id == publishedFundingId.Key); if (publishedFunding != null) { publishedFundings.Add(publishedFunding); } } return(Task.FromResult(publishedFundings.AsEnumerable())); }
public async Task SetsCurrentToLatestPreviousVersionAndDeletesIfInitialVersion() { PublishedFunding publishedFundingOne = NewPublishedFunding(); PublishedFunding publishedFundingTwo = NewPublishedFunding(); PublishedFunding publishedFundingThree = NewPublishedFunding(); PublishedFunding publishedFundingFour = NewPublishedFunding(); PublishedFunding publishedFundingFive = NewPublishedFunding(); PublishedFundingVersion previousVersionTwo = NewPublishedFundingVersion(); PublishedFundingVersion previousVersionThree = NewPublishedFundingVersion(); PublishedFundingVersion previousVersionFive = NewPublishedFundingVersion(); GivenThePublishedFundingFeed(NewFeedIterator(WithPages(Page(publishedFundingOne, publishedFundingTwo), Page(publishedFundingThree, publishedFundingFour), Page(publishedFundingFive)))); AndThePreviousLatestVersion(publishedFundingTwo.Current, previousVersionTwo); AndThePreviousLatestVersion(publishedFundingThree.Current, previousVersionThree); AndThePreviousLatestVersion(publishedFundingFive.Current, previousVersionFive); await WhenTheTaskIsRun(); ThenTheDocumentsWereDeleted(new[] { publishedFundingOne }, new[] { publishedFundingOne.ParitionKey }, _isHardDelete); ThenTheDocumentsWereDeleted(new[] { publishedFundingFour }, new[] { publishedFundingFour.ParitionKey }, _isHardDelete); AndTheDocumentsWereUpdated(new[] { publishedFundingTwo }, new[] { publishedFundingTwo.ParitionKey }); AndTheDocumentsWereUpdated(new[] { publishedFundingThree }, new[] { publishedFundingThree.ParitionKey }); AndTheDocumentsWereUpdated(new[] { publishedFundingFive }, new[] { publishedFundingFive.ParitionKey }); AndThePublishedFundingHasCurrent((publishedFundingFive, previousVersionFive), (publishedFundingTwo, previousVersionTwo), (publishedFundingThree, previousVersionThree)); }
public async Task TransformsPublishedGroupsForSpecificationInBatchesAndCreatesCsvWithResults( FundingLineCsvGeneratorJobType jobType) { string specificationId = NewRandomString(); string fundingPeriodId = NewRandomString(); string fundingLineCode = NewRandomString(); string fundingStreamId = NewRandomString(); string expectedInterimFilePath = NewRandomString(); IEnumerable <PublishedFunding> publishedFundingOne = new List <PublishedFunding> { NewPublishedFunding(_ => _.WithCurrent( NewPublishedFundingVersion(ppv => ppv.WithFundingId("f-id") .WithProviderFundings(new List <string>())))), }; IEnumerable <PublishedFunding> publishedFundingWithProviderTwo = new[] { NewPublishedFunding(_ => _.WithCurrent( NewPublishedFundingVersion(ppv => ppv.WithFundingId("f-id1")))), NewPublishedFunding(_ => _.WithCurrent( NewPublishedFundingVersion(ppv => ppv.WithFundingId("f-id2")))), NewPublishedFunding(_ => _.WithCurrent( NewPublishedFundingVersion(ppv => ppv.WithFundingId("f-id3")))) }; ExpandoObject[] transformedRowsOne = { new ExpandoObject(), new ExpandoObject(), new ExpandoObject(), new ExpandoObject(), }; ExpandoObject[] transformedRowsTwo = { new ExpandoObject(), new ExpandoObject(), new ExpandoObject(), new ExpandoObject(), }; string expectedCsvOne = NewRandomString(); string expectedCsvTwo = NewRandomString(); string predicate = NewRandomString(); string joinPredicate = NewRandomString(); GivenTheCsvRowTransformation(publishedFundingOne, transformedRowsOne, expectedCsvOne, true); AndTheCsvRowTransformation(publishedFundingWithProviderTwo, transformedRowsTwo, expectedCsvTwo, false); AndThePredicate(jobType, predicate); AndTheJoinPredicate(jobType, joinPredicate); PublishedFunding.Setup(_ => _.PublishedGroupBatchProcessing(specificationId, It.IsAny <Func <List <PublishedFunding>, Task> >(), 100)) .Callback <string, Func <List <PublishedFunding>, Task>, int>((spec, batchProcessor, batchSize) => { batchProcessor(publishedFundingOne.ToList()) .GetAwaiter() .GetResult(); }) .Returns(Task.CompletedTask); bool processedResults = await WhenTheCsvIsGenerated(jobType, specificationId, fundingPeriodId, expectedInterimFilePath, fundingLineCode, fundingStreamId); processedResults .Should() .BeTrue(); }
public Task <PublishedFunding> GetPublishedFundingById(string cosmosId, string partitionKey) { PublishedFunding publishedFunding = _repo.PublishedFunding.SelectMany(c => c.Value).FirstOrDefault(p => p.Id == cosmosId); return(Task.FromResult(publishedFunding)); }
public async Task TransformsPublishedFundingForSpecificationInBatchesAndCreatesCsvWithResults() { string specificationId = NewRandomString(); string fundingPeriodId = NewRandomString(); string fundingLineCode = NewRandomString(); string fundingStreamId = NewRandomString(); string expectedInterimFilePath = NewRandomString(); IEnumerable <PublishedFundingVersion> publishedFundingVersionsOne = new[] { NewPublishedFundingVersion() }; IEnumerable <PublishedFundingVersion> publishedFundingVersionsTwo = new[] { NewPublishedFundingVersion(), NewPublishedFundingVersion(), NewPublishedFundingVersion() }; ExpandoObject[] transformedRowsOne = { new ExpandoObject(), new ExpandoObject(), new ExpandoObject(), new ExpandoObject() }; ExpandoObject[] transformedRowsTwo = { new ExpandoObject(), new ExpandoObject(), new ExpandoObject(), new ExpandoObject() }; string expectedCsvOne = NewRandomString(); string expectedCsvTwo = NewRandomString(); GivenTheCsvRowTransformation(publishedFundingVersionsOne, transformedRowsOne, expectedCsvOne, true); AndTheCsvRowTransformation(publishedFundingVersionsTwo, transformedRowsTwo, expectedCsvTwo, false); PublishedFunding.Setup(_ => _.PublishedFundingVersionBatchProcessing(specificationId, fundingStreamId, fundingPeriodId, It.IsAny <Func <List <PublishedFundingVersion>, Task> >(), 100)) .Callback <string, string, string, Func <List <PublishedFundingVersion>, Task>, int>((spec, stream, period, batchProcessor, batchSize) => { batchProcessor(publishedFundingVersionsOne.ToList()) .GetAwaiter() .GetResult(); batchProcessor(publishedFundingVersionsTwo.ToList()) .GetAwaiter() .GetResult(); }) .Returns(Task.CompletedTask); bool processedResults = await WhenTheCsvIsGenerated(FundingLineCsvGeneratorJobType.HistoryOrganisationGroupValues, specificationId, fundingPeriodId, expectedInterimFilePath, fundingLineCode, fundingStreamId); processedResults .Should() .BeTrue(); FileSystemAccess .Verify(_ => _.Append(expectedInterimFilePath, expectedCsvOne, default), Times.Once); FileSystemAccess .Verify(_ => _.Append(expectedInterimFilePath, expectedCsvTwo, default), Times.Once); }
public void FlattensTemplateCalculationsAndProviderMetaDataIntoRows() { PublishedFunding publishedFunding = NewPublishedFunding(_ => _.WithCurrent( NewPublishedFundingVersion(ppv => ppv.WithFundingId("f-id1") .WithMajor(1) .WithGroupReason(CalculateFunding.Models.Publishing.GroupingReason.Contracting) .WithOrganisationGroupTypeCode(Generators.OrganisationGroup.Enums.OrganisationGroupTypeCode.AcademyTrust) .WithOrganisationGroupName("g-name1") .WithOrganisationGroupTypeIdentifier(Generators.OrganisationGroup.Enums.OrganisationGroupTypeIdentifier.AcademyTrustCode) .WithOrganisationGroupIdentifierValue("groupValue1") .WithOrganisationGroupTypeClassification(Generators.OrganisationGroup.Enums.OrganisationGroupTypeClassification.GeographicalBoundary) .WithTotalFunding(100) .WithAuthor(new Common.Models.Reference("aid", "aname")) .WithStatusChangedDate(new System.DateTime(2020, 07, 10)) ))); IEnumerable <PublishedProvider> publishedProviders = NewPublishedProviders(_ => _.WithReleased( NewPublishedProviderVersion(ppv => ppv.WithProvider( NewProvider(pr => pr.WithEstablishmentNumber("en1") .WithName("prname1") .WithLACode("lacode1") .WithAuthority("laname1") .WithURN("urn1") .WithUKPRN("ukprn1") .WithProviderType("pt1") .WithProviderSubType("pst1") .WithStatus("Open") .WithSuccessor("Successor1"))) .WithFundingStreamId("fs1") .WithFundingPeriodId("fp1") .WithFundingLines(NewFundingLine(fl => fl.WithName("bfl1") .WithValue(999M)), NewFundingLine(fl => fl.WithName("afl2") .WithValue(666M))) .WithProviderId("pid1") .WithPredecessors(new[] { "Pre1", "Pre2" }) .WithVariationReasons(new[] { VariationReason.AuthorityFieldUpdated, VariationReason.CensusWardCodeFieldUpdated }) .WithAuthor(NewReference(auth => auth.WithName("author1"))) .WithMajorVersion(1) .WithMinorVersion(11) .WithTotalFunding(1) .WithPublishedProviderStatus(PublishedProviderStatus.Updated) .WithDate("2020-01-05T20:05:44") .WithVariationReasons(new[] { VariationReason.AuthorityFieldUpdated, VariationReason.CensusWardCodeFieldUpdated })))); IEnumerable <PublishedFundingWithProvider> publishedFundingsWithProviders = new List <PublishedFundingWithProvider> { new PublishedFundingWithProvider() { PublishedFunding = publishedFunding, PublishedProviders = publishedProviders } }; dynamic[] expectedCsvRows = { new Dictionary <string, object> { { "Funding ID", "f-id1" }, { "Funding Major Version", 1 }, { "Grouping Reason","Contracting" }, { "Grouping Code", "AcademyTrust" }, { "Grouping Name", "g-name1" }, { "Grouping Type Identifier","AcademyTrustCode" }, { "Grouping Identifier Value","groupValue1" }, { "Grouping Type Classification","GeographicalBoundary" }, { "Grouping Total Funding", 100m }, { "Author", "aname" }, { "Release Date", new DateTime(2020, 07, 10).ToString("s") }, { "Provider Count", 0 }, { "Provider Funding ID","fs1-fp1-pid1-1_11" }, { "Provider Id", "pid1" }, { "Provider Name", "prname1" }, { "Provider Major Version", 1 }, { "Provider Total Funding", 1m }, { "Provider UKPRN", "ukprn1" }, { "Provider URN", "urn1" }, { "Provider UPIN", null }, { "Provider LACode","lacode1" }, { "Provider Status","Open" }, { "Provider Successor","Successor1" }, { "Provider Predecessors","Pre1;Pre2" }, { "Provider Variation Reasons","AuthorityFieldUpdated;CensusWardCodeFieldUpdated" } } }; ExpandoObject[] transformProviderResultsIntoCsvRows = _transformation.Transform(publishedFundingsWithProviders).ToArray(); transformProviderResultsIntoCsvRows .Should() .BeEquivalentTo(expectedCsvRows, cfg => cfg.WithStrictOrdering()); }
public async Task TransformsPublishedProvidersForSpecificationInBatchesAndCreatesCsvWithResults( FundingLineCsvGeneratorJobType jobType) { string specificationId = NewRandomString(); string fundingPeriodId = NewRandomString(); string fundingLineCode = NewRandomString(); string fundingStreamId = NewRandomString(); string expectedInterimFilePath = NewRandomString(); IEnumerable <PublishedProvider> publishProvidersOne = new [] { NewPublishedProvider(), }; IEnumerable <PublishedProvider> publishedProvidersTwo = new [] { NewPublishedProvider(), NewPublishedProvider(), NewPublishedProvider() }; ExpandoObject[] transformedRowsOne = { new ExpandoObject(), new ExpandoObject(), new ExpandoObject(), new ExpandoObject(), }; ExpandoObject[] transformedRowsTwo = { new ExpandoObject(), new ExpandoObject(), new ExpandoObject(), new ExpandoObject(), }; string expectedCsvOne = NewRandomString(); string expectedCsvTwo = NewRandomString(); string predicate = NewRandomString(); string joinPredicate = NewRandomString(); GivenTheCsvRowTransformation(publishProvidersOne, transformedRowsOne, expectedCsvOne, true); AndTheCsvRowTransformation(publishedProvidersTwo, transformedRowsTwo, expectedCsvTwo, false); AndThePredicate(jobType, predicate); AndTheJoinPredicate(jobType, joinPredicate); PublishedFunding.Setup(_ => _.PublishedProviderBatchProcessing(predicate, specificationId, It.IsAny <Func <List <PublishedProvider>, Task> >(), 100, joinPredicate, fundingLineCode)) .Callback <string, string, Func <List <PublishedProvider>, Task>, int, string, string>((pred, spec, batchProcessor, batchSize, joinPred, flc) => { batchProcessor(publishProvidersOne.ToList()) .GetAwaiter() .GetResult(); batchProcessor(publishedProvidersTwo.ToList()) .GetAwaiter() .GetResult(); }) .Returns(Task.CompletedTask); bool processedResults = await WhenTheCsvIsGenerated(jobType, specificationId, fundingPeriodId, expectedInterimFilePath, fundingLineCode, fundingStreamId); processedResults .Should() .BeTrue(); FileSystemAccess .Verify(_ => _.Append(expectedInterimFilePath, expectedCsvOne, default), Times.Once); FileSystemAccess .Verify(_ => _.Append(expectedInterimFilePath, expectedCsvTwo, default), Times.Once); }
/// <summary> /// Generate instances of the PublishedFundingVersion to save into cosmos for the Organisation Group Results /// </summary> /// <param name="publishedFundingInput"></param> /// <param name="publishedProviders"></param> /// <returns></returns> public IEnumerable <(PublishedFunding, PublishedFundingVersion)> GeneratePublishedFunding(PublishedFundingInput publishedFundingInput, IEnumerable <PublishedProvider> publishedProviders) { Guard.ArgumentNotNull(publishedFundingInput, nameof(publishedFundingInput)); Guard.ArgumentNotNull(publishedFundingInput.FundingPeriod, nameof(publishedFundingInput.FundingPeriod)); Guard.ArgumentNotNull(publishedFundingInput.FundingStream, nameof(publishedFundingInput.FundingStream)); Guard.ArgumentNotNull(publishedFundingInput.OrganisationGroupsToSave, nameof(publishedFundingInput.OrganisationGroupsToSave)); Guard.ArgumentNotNull(publishedProviders, nameof(publishedProviders)); Guard.ArgumentNotNull(publishedFundingInput.PublishingDates, nameof(publishedFundingInput.PublishingDates)); Guard.ArgumentNotNull(publishedFundingInput.TemplateMetadataContents, nameof(publishedFundingInput.TemplateMetadataContents)); Guard.IsNullOrWhiteSpace(publishedFundingInput.TemplateVersion, nameof(publishedFundingInput.TemplateVersion)); Guard.IsNullOrWhiteSpace(publishedFundingInput.SpecificationId, nameof(publishedFundingInput.SpecificationId)); IEnumerable <(PublishedFunding PublishedFunding, OrganisationGroupResult OrganisationGroupResult)> organisationGroupsToSave = publishedFundingInput.OrganisationGroupsToSave; TemplateMetadataContents templateMetadataContents = publishedFundingInput.TemplateMetadataContents; string templateVersion = publishedFundingInput.TemplateVersion; FundingPeriod fundingPeriod = publishedFundingInput.FundingPeriod; FundingValueAggregator fundingValueAggregator = new FundingValueAggregator(); foreach ((PublishedFunding PublishedFunding, OrganisationGroupResult OrganisationGroupResult)organisationGroup in organisationGroupsToSave) { // TODO: extract interface IEnumerable <string> providerIds = organisationGroup.OrganisationGroupResult.Providers.Select(p => p.ProviderId); IEnumerable <string> publishedProvidersIds = publishedProviders.Select(p => p.Current.ProviderId); List <PublishedProvider> publishedProvidersForOrganisationGroup = new List <PublishedProvider>(publishedProviders.Where(p => providerIds.Contains(p.Current.ProviderId))); List <PublishedProviderVersion> publishedProviderVersionsForOrganisationGroup = new List <PublishedProviderVersion>( publishedProvidersForOrganisationGroup.Select(p => p.Current)); IEnumerable <string> missingProviders = providerIds.Except(publishedProvidersIds); if (missingProviders.AnyWithNullCheck()) { string providerIdsString = string.Join(", ", missingProviders); throw new Exception($"Missing PublishedProvider result for organisation group '{organisationGroup.OrganisationGroupResult.GroupReason}' '{organisationGroup.OrganisationGroupResult.GroupTypeCode}' '{organisationGroup.OrganisationGroupResult.GroupTypeIdentifier}' '{organisationGroup.OrganisationGroupResult.IdentifierValue}'. Provider IDs={providerIdsString}"); } List <AggregateFundingLine> fundingLineAggregates = new List <AggregateFundingLine>( fundingValueAggregator.GetTotals(templateMetadataContents, publishedProviderVersionsForOrganisationGroup)); IEnumerable <Common.TemplateMetadata.Models.FundingLine> fundingLineDefinitions = templateMetadataContents.RootFundingLines.Flatten(_ => _.FundingLines) ?? Enumerable.Empty <Common.TemplateMetadata.Models.FundingLine>(); // Add in calculations in numerator/demoninator and percentagechange targets List <PublishingModels.FundingLine> fundingLines = GenerateFundingLines(fundingLineAggregates, fundingLineDefinitions); List <FundingCalculation> calculations = GenerateCalculations(fundingLineAggregates.Flatten(_ => _.FundingLines) .SelectMany(c => c.Calculations ?? Enumerable.Empty <AggregateFundingCalculation>())); decimal?totalFunding = publishedProviderVersionsForOrganisationGroup.Sum(_ => _.TotalFunding); PublishedFundingVersion publishedFundingVersion = new PublishedFundingVersion { FundingStreamId = publishedFundingInput.FundingStream.Id, FundingStreamName = publishedFundingInput.FundingStream.Name, TotalFunding = totalFunding, FundingPeriod = new PublishedFundingPeriod { Type = Enum.Parse <PublishedFundingPeriodType>(fundingPeriod.Type.GetValueOrDefault().ToString()), Period = fundingPeriod.Period, EndDate = fundingPeriod.EndDate, StartDate = fundingPeriod.StartDate, Name = fundingPeriod.Name, }, SpecificationId = publishedFundingInput.SpecificationId, OrganisationGroupTypeCode = organisationGroup.OrganisationGroupResult.GroupTypeCode.ToString(), OrganisationGroupTypeIdentifier = organisationGroup.OrganisationGroupResult.GroupTypeIdentifier.ToString(), OrganisationGroupIdentifierValue = organisationGroup.OrganisationGroupResult.IdentifierValue, OrganisationGroupTypeClassification = organisationGroup.OrganisationGroupResult.GroupTypeClassification.ToString(), OrganisationGroupName = organisationGroup.OrganisationGroupResult.Name, OrganisationGroupSearchableName = organisationGroup.OrganisationGroupResult.SearchableName, OrganisationGroupIdentifiers = _mapper.Map <IEnumerable <PublishedOrganisationGroupTypeIdentifier> >(organisationGroup.OrganisationGroupResult.Identifiers), FundingLines = fundingLines, Calculations = calculations, SchemaVersion = templateMetadataContents.SchemaVersion, Status = PublishedFundingStatus.Approved, GroupingReason = organisationGroup.OrganisationGroupResult.GroupReason.AsMatchingEnum <PublishingModels.GroupingReason>(), ProviderFundings = publishedProviderVersionsForOrganisationGroup.Select(_ => _.FundingId), TemplateVersion = templateVersion, StatusChangedDate = publishedFundingInput.PublishingDates.StatusChangedDate.TrimToTheSecond(), EarliestPaymentAvailableDate = publishedFundingInput.PublishingDates.EarliestPaymentAvailableDate.TrimToTheMinute(), ExternalPublicationDate = publishedFundingInput.PublishingDates.ExternalPublicationDate.TrimToTheMinute(), }; publishedFundingVersion.FundingId = _publishedFundingIdGeneratorResolver.GetService(templateMetadataContents.SchemaVersion).GetFundingId(publishedFundingVersion); PublishedFunding publishedFundingResult = organisationGroup.PublishedFunding; if (publishedFundingResult == null) { publishedFundingResult = new PublishedFunding() { Current = publishedFundingVersion, }; } yield return(publishedFundingResult, publishedFundingVersion); } }