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));
        }
Пример #4
0
        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;
        }
Пример #6
0
        /// <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);
        }
Пример #8
0
        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));
        }
Пример #10
0
        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));
        }
Пример #12
0
        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);
        }
Пример #15
0
        /// <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);
            }
        }