public async Task <IActionResult> CreateOrUpdateDatasetDefinition(CreateDatasetDefinitionFromTemplateModel model, string correlationId, Reference user) { ValidationResult validationResult = await _createDatasetDefinitionFromTemplateValidator.ValidateAsync(model); if (!validationResult.IsValid) { string errorMessage = string.Join(";", validationResult.Errors.Select(x => x.ErrorMessage)); _logger.Error(errorMessage); return(new BadRequestObjectResult(errorMessage)); } ; FundingStream fundingStream = await _policyRepository.GetFundingStream(model.FundingStreamId); TemplateMetadataDistinctCalculationsContents templateContents = await _policyRepository.GetDistinctTemplateMetadataCalculationsContents(model.FundingStreamId, model.FundingPeriodId, model.TemplateVersion); if (templateContents == null) { return(new BadRequestObjectResult($"No funding template for given FundingStreamId " + $"- {model.FundingStreamId}, FundingPeriodId - {model.FundingPeriodId}, TemplateVersion - {model.TemplateVersion}")); } DatasetDefinition datasetDefinition = CreateDatasetDefinition(model, templateContents, fundingStream); return(await SaveDatasetDefinition(datasetDefinition, correlationId, user)); }
private void SetupMocks() { _validatorFactory = Substitute.For <IIoCValidatorFactory>(); _validatorFactory.Validate(Arg.Any <object>()).Returns(new ValidationResult()); _templateRepository = Substitute.For <ITemplateRepository>(); _templateRepository.CreateDraft(Arg.Any <Template>()).Returns(HttpStatusCode.OK); _versionRepository = Substitute.For <ITemplateVersionRepository>(); _versionRepository.SaveVersion(Arg.Any <TemplateVersion>()).Returns(HttpStatusCode.OK); _searchRepository = Substitute.For <ISearchRepository <TemplateIndex> >(); _searchRepository.Index(Arg.Any <IEnumerable <TemplateIndex> >()).Returns(Enumerable.Empty <IndexError>()); _fundingPeriod = new FundingPeriod { Id = _command.FundingPeriodId, Name = "Test Period", Type = FundingPeriodType.FY }; _fundingStream = new FundingStream { Id = _command.FundingStreamId, ShortName = "XX", Name = "FundingSteam" }; _policyRepository = Substitute.For <IPolicyRepository>(); _policyRepository.GetFundingPeriods().Returns(new [] { _fundingPeriod }); _policyRepository.GetFundingStreams().Returns(new [] { _fundingStream }); _policyRepository.GetFundingConfigurations().Returns(new [] { new FundingConfiguration { FundingStreamId = _fundingStream.Id, FundingPeriodId = _fundingPeriod.Id } }); }
public async Task GetFundingStreamById__GivenFundingStreamWasFound_ReturnsSuccess() { // Arrange const string fundingStreamId = "fs-1"; FundingStream fundingStream = new FundingStream { Id = fundingStreamId, Name = "Funding Stream Name", ShortName = "FSN", }; IPolicyRepository policyRepository = CreatePolicyRepository(); policyRepository .GetFundingStreamById(Arg.Is(fundingStreamId)) .Returns(fundingStream); FundingStreamService fundingStreamsService = CreateFundingStreamService(policyRepository: policyRepository); // Act IActionResult result = await fundingStreamsService.GetFundingStreamById(fundingStreamId); // Assert result .Should() .BeOfType <OkObjectResult>() .Which .Value .Should() .Be(fundingStream); }
public async Task GetFundingStreamById_StringParam_GivenFundingStreamnWasFound_ReturnsSuccess() { // Arrange ILogger logger = CreateLogger(); FundingStream fundingStream = new FundingStream { Id = FundingStreamId }; ISpecificationsRepository specificationsRepository = CreateSpecificationsRepository(); specificationsRepository .GetFundingStreamById(Arg.Is(FundingStreamId)) .Returns(fundingStream); IFundingService fundingService = CreateService(specificationsRepository: specificationsRepository, logger: logger); // Act IActionResult result = await fundingService.GetFundingStreamById(FundingStreamId); // Assert result .Should() .BeOfType <OkObjectResult>(); }
public void Summarise_CheckRounding(decimal value1, decimal value2, decimal result) { FundingStream fundingStream = GetFundingTypes() .SelectMany(ft => ft.FundingStreams) .Single(fs => fs.PeriodCode == "ESF1420" && fs.DeliverableLineCode == 1); int ukprn = GetProviders().First(); var allocation = GetContractAllocation(ukprn); var periods = new List <Period>() { new Period() { PeriodId = 1, CalendarMonth = 8, CalendarYear = 2018, Value = value1, }, new Period() { PeriodId = 1, CalendarMonth = 8, CalendarYear = 2018, Value = value2, }, }; List <PeriodisedData> periodisedDatas = new List <PeriodisedData>() { new PeriodisedData() { AttributeName = "StartEarnings", DeliverableCode = "ST01", Periods = periods, }, }; List <LearningDelivery> learningDeliveries = new List <LearningDelivery>() { new LearningDelivery() { ConRefNumber = "All10000001-1", PeriodisedData = periodisedDatas, }, }; LearningProvider testProvider = new LearningProvider() { UKPRN = ukprn, LearningDeliveries = learningDeliveries, }; var task = new SummarisationDeliverableProcess(); var results = task.Summarise(fundingStream, testProvider, allocation, GetCollectionPeriods()); results.Count.Should().Be(12); results.FirstOrDefault(w => w.ActualValue > 0).ActualValue.Should().Be(result); }
private void ThenFundingStreamResultMatches(IActionResult result) { result .Should() .BeOfType <OkObjectResult>() .Which .Value .Should() .BeOfType <List <FundingStream> >(); IEnumerable <FundingStream> fundingStreams = (result as OkObjectResult).Value as IEnumerable <FundingStream>; fundingStreams .Count() .Should() .Be(1); fundingStreams .FirstOrDefault() .Should() .NotBeNull(); FundingStream fundingStream = fundingStreams.FirstOrDefault(); fundingStream .Id .Should() .Be(_fundingStreamId); fundingStream .Name .Should() .Be(_fundingStreamName); }
public ICollection <SummarisedActual> Summarise(FundingStream fundingStream, LearningProvider provider, FcsContractAllocation allocation, ICollection <CollectionPeriod> collectionPeriods) { var summarisedActuals = new List <SummarisedActual>(); foreach (var fundLine in fundingStream.DeliverableLines) { var periodisedData = provider .LearningDeliveries .Where(ld => ld.ConRefNumber != null && ld.ConRefNumber.Trim().Equals(allocation.ContractAllocationNumber, StringComparison.OrdinalIgnoreCase)) .SelectMany(x => x.PeriodisedData.Where(w => w.DeliverableCode == fundLine.DeliverableCode)); var periods = GetPeriodsForFundLine(periodisedData, fundLine); summarisedActuals.AddRange(SummarisePeriods(periods, fundLine, collectionPeriods, allocation)); } return(summarisedActuals .GroupBy(grp => grp.Period) .Select(g => new SummarisedActual { OrganisationId = allocation.DeliveryOrganisation, DeliverableCode = fundingStream.DeliverableLineCode, FundingStreamPeriodCode = fundingStream.PeriodCode, Period = g.Key, ActualValue = Math.Round(g.Sum(x => x.ActualValue), 2), ActualVolume = g.Sum(x => x.ActualVolume), ContractAllocationNumber = allocation.ContractAllocationNumber, PeriodTypeCode = PeriodTypeCodeConstants.CalendarMonth }).ToList()); }
public void Summarise_FundingStream() { FundingStream fundingStream = GetFundingTypes() .SelectMany(ft => ft.FundingStreams) .Where(fs => fs.PeriodCode == "ESF1420" && fs.DeliverableLineCode == 5).FirstOrDefault(); int ukprn = GetProviders().First(); var allocation = GetContractAllocation(ukprn); var task = new SummarisationDeliverableProcess(); var result = task.Summarise(fundingStream, GetTestProvider(ukprn), allocation, GetCollectionPeriods()); result.Count.Should().Be(67); foreach (var item in result) { item.ActualValue.Should().Be(2 * periodValue); var fl = fundingStream.DeliverableLines.FirstOrDefault(); item.ActualVolume.Should().Be(fl?.CalculateVolume == true ? 2 : 0); } }
public TemplateCreateCommandValidator( IPolicyRepository policyRepository, IPolicyResiliencePolicies policyResiliencePolicies) { Guard.ArgumentNotNull(policyRepository, nameof(policyRepository)); Guard.ArgumentNotNull(policyResiliencePolicies?.PolicyRepository, nameof(policyResiliencePolicies.PolicyRepository)); AsyncPolicy policyRepositoryPolicy = policyResiliencePolicies.PolicyRepository; RuleFor(x => x.Description).Length(0, 1000); RuleFor(x => x.FundingStreamId) .NotEmpty() .WithMessage("Missing funding stream id") .MustAsync(async(command, propertyValue, context, cancellationToken) => { FundingStream fundingStream = await policyRepositoryPolicy.ExecuteAsync(() => policyRepository.GetFundingStreamById(command.FundingStreamId)); return(fundingStream != null); }) .WithMessage("Funding stream id does not exist"); RuleFor(x => x.FundingPeriodId) .NotEmpty() .WithMessage("Missing funding period id") .MustAsync(async(command, propertyValue, context, cancellationToken) => { FundingPeriod fundingPeriod = await policyRepositoryPolicy.ExecuteAsync(() => policyRepository.GetFundingPeriodById(command.FundingPeriodId)); return(fundingPeriod != null); }) .WithMessage("Funding period id does not exist"); }
public async Task <IActionResult> SaveFundingStream(HttpRequest request) { string yaml = await request.GetRawBodyStringAsync(); string yamlFilename = request.GetYamlFileNameFromRequest(); if (string.IsNullOrEmpty(yaml)) { _logger.Error($"Null or empty yaml provided for file: {yamlFilename}"); return(new BadRequestObjectResult($"Invalid yaml was provided for file: {yamlFilename}")); } IDeserializer deserializer = new DeserializerBuilder() .WithNamingConvention(new CamelCaseNamingConvention()) .Build(); FundingStream fundingStream = null; try { fundingStream = deserializer.Deserialize <FundingStream>(yaml); } catch (Exception exception) { _logger.Error(exception, $"Invalid yaml was provided for file: {yamlFilename}"); return(new BadRequestObjectResult($"Invalid yaml was provided for file: {yamlFilename}")); } try { HttpStatusCode result = await _specificationsRepository.SaveFundingStream(fundingStream); if (!result.IsSuccess()) { int statusCode = (int)result; _logger.Error($"Failed to save yaml file: {yamlFilename} to cosmos db with status {statusCode}"); return(new StatusCodeResult(statusCode)); } } catch (Exception exception) { _logger.Error(exception, $"Exception occurred writing to yaml file: {yamlFilename} to cosmos db"); return(new StatusCodeResult(500)); } _logger.Information($"Successfully saved file: {yamlFilename} to cosmos db"); bool keyExists = await _cacheProvider.KeyExists <FundingStream[]>(CacheKeys.AllFundingStreams); if (keyExists) { await _cacheProvider.KeyDeleteAsync <FundingStream[]>(CacheKeys.AllFundingStreams); } return(new OkResult()); }
private void GivenTheFundingStream(Action <FundingStreamBuilder> setUp = null) { FundingStreamBuilder fundingStreamBuilder = new FundingStreamBuilder(); setUp?.Invoke(fundingStreamBuilder); _fundingStream = fundingStreamBuilder.Build(); }
public async Task <ApiResponse <FundingStream> > SaveFundingStream(FundingStream fundingStream, string fileName) { Guard.ArgumentNotNull(fundingStream, nameof(fundingStream)); Guard.IsNullOrWhiteSpace(fileName, nameof(fileName)); string url = "fundingstreams"; return(await PostAsync <FundingStream, object>(url, fundingStream, CancellationToken.None, "json-file", fileName)); }
public async Task ValidateFundingTemplate_GivenTemplateWithValidFundingPeriodIdButNoFundingPeriodExists_ReturnsValidationResultWithErrors() { //Arrange const string schemaVersion = "1.0"; FundingStream fundingStream = new FundingStream(); JsonSchema schema = JsonSchema.FromType <TestTemplate_schema_1_0>(); TestTemplate_schema_1_0 testClassWithFunding = new TestTemplate_schema_1_0 { SchemaVersion = schemaVersion, Funding = new { templateVersion = "2.1", fundingStream = new { code = "PES" }, fundingPeriod = new { id = "AY-2020" } } }; string fundingTemplate = JsonConvert.SerializeObject(testClassWithFunding); string fundingSchema = schema.AsJson(); string blobName = $"{fundingSchemaFolder}/{schemaVersion}.json"; IFundingSchemaRepository fundingSchemaRepository = CreateFundingSchemaRepository(); fundingSchemaRepository .SchemaVersionExists(Arg.Is(blobName)) .Returns(true); fundingSchemaRepository .GetFundingSchemaVersion(Arg.Is(blobName)) .Returns(fundingSchema); IPolicyRepository policyRepository = CreatePolicyRepository(); policyRepository .GetFundingStreamById(Arg.Is("PES")) .Returns(fundingStream); FundingTemplateValidationService fundingTemplateValidationService = CreateFundingTemplateValidationService( fundingSchemaRepository: fundingSchemaRepository, policyRepository: policyRepository); //Act FundingTemplateValidationResult result = await fundingTemplateValidationService.ValidateFundingTemplate(fundingTemplate, "PES", "AY-2020", "2.1"); //Assert result .IsValid .Should() .BeFalse(); result .Errors[0] .ErrorMessage .Should() .Be("A funding period could not be found for funding period id 'AY-2020'"); }
public async Task GetFundingConfiguration__GivenFundingConfigurationWasFound_ReturnsSuccess(string fundingStreamId, string fundingPeriodId) { // Arrange FundingStream fundingStream = new FundingStream { Id = fundingStreamId }; FundingPeriod fundingPeriod = new FundingPeriod { Id = fundingPeriodId }; string configId = $"config-{fundingStreamId}-{fundingPeriodId}"; FundingConfiguration fundingConfiguration = new FundingConfiguration { Id = configId }; IPolicyRepository policyRepository = CreatePolicyRepository(); policyRepository .GetFundingStreamById(Arg.Is(fundingStreamId)) .Returns(fundingStream); policyRepository .GetFundingPeriodById(Arg.Is(fundingPeriodId)) .Returns(fundingPeriod); policyRepository .GetFundingConfiguration(Arg.Is(configId)) .Returns(fundingConfiguration); FundingConfigurationService fundingConfigurationsService = CreateFundingConfigurationService(policyRepository: policyRepository); // Act IActionResult result = await fundingConfigurationsService.GetFundingConfiguration(fundingStreamId, fundingPeriodId); // Assert result .Should() .BeOfType <OkObjectResult>() .Which .Value .Should() .Be(fundingConfiguration); FundingConfiguration fundingConfigurationResult = ((OkObjectResult)result).Value.As <FundingConfiguration>(); fundingConfigurationResult.ProviderSource.Should().Be(CalculateFunding.Models.Providers.ProviderSource.CFS); fundingConfigurationResult.PaymentOrganisationSource.Should().Be(PaymentOrganisationSource.PaymentOrganisationAsProvider); }
async public Task SaveFundingConfiguration_GivenValidConfigurationButFailedToSaveToDatabase_ReturnsStatusCode(string fundingStreamId, string fundingPeriodId) { //Arrange FundingStream fundingStream = new FundingStream { Id = fundingStreamId }; FundingPeriod fundingPeriod = new FundingPeriod { Id = fundingPeriodId }; ILogger logger = CreateLogger(); HttpStatusCode statusCode = HttpStatusCode.BadRequest; IPolicyRepository policyRepository = CreatePolicyRepository(); policyRepository .GetFundingStreamById(Arg.Is(fundingStreamId)) .Returns(fundingStream); policyRepository .GetFundingPeriodById(Arg.Is(fundingPeriodId)) .Returns(fundingPeriod); policyRepository .SaveFundingConfiguration(Arg.Is <FundingConfiguration>(x => x.FundingStreamId == fundingStreamId && x.FundingPeriodId == fundingPeriodId)) .Returns(statusCode); FundingConfigurationService fundingConfigurationsService = CreateFundingConfigurationService(logger: logger, policyRepository: policyRepository); FundingConfigurationViewModel fundingConfigurationViewModel = CreateConfigurationModel(); //Act IActionResult result = await fundingConfigurationsService.SaveFundingConfiguration("Action", "Controller", fundingConfigurationViewModel, fundingStreamId, fundingPeriodId); //Assert result .Should() .BeOfType <InternalServerErrorResult>(); InternalServerErrorResult statusCodeResult = (InternalServerErrorResult)result; statusCodeResult .StatusCode .Should() .Be(500); logger .Received(1) .Error(Arg.Is($"Failed to save configuration file for funding stream id: {fundingStreamId} and period id: {fundingPeriodId} to cosmos db with status 400")); }
private static FundingStream GetFundingStream(SpecificationCurrentVersion specification, ProviderChangeItem providerChangeItem) { FundingStream fundingStream = specification.FundingStreams.FirstOrDefault(s => s.AllocationLines.Any(a => a.ProviderLookups.Any(l => l.ProviderType == providerChangeItem.SuccessorProvider.ProviderType && l.ProviderSubType == providerChangeItem.SuccessorProvider.ProviderSubType))); if (fundingStream == null) { throw new NonRetriableException($"Could not find funding stream with matching provider type '{providerChangeItem.SuccessorProvider.ProviderType}' and subtype '{providerChangeItem.SuccessorProvider.ProviderSubType}' for specification '{specification.Id}'"); } return(fundingStream); }
private static DatasetDefinition CreateDatasetDefinition( CreateDatasetDefinitionFromTemplateModel model, TemplateMetadataDistinctCalculationsContents templateContent, FundingStream fundingStream) { int id = model.DatasetDefinitionId; string name = $"{fundingStream.Name}-{model.TemplateVersion}"; DatasetDefinition datasetDefinition = new DatasetDefinition() { Id = id.ToString(), Name = name, Description = name, FundingStreamId = fundingStream.Id }; id += 1; datasetDefinition.TableDefinitions = new List <TableDefinition>(); TableDefinition tableDefinition = new TableDefinition { Id = id.ToString(), Name = name, FieldDefinitions = new List <FieldDefinition>() }; id += 1; tableDefinition.FieldDefinitions.Add(new FieldDefinition() { Id = id.ToString(), Name = "UKPRN", IdentifierFieldType = IdentifierFieldType.UKPRN, Type = FieldType.String, Required = true }); foreach (TemplateMetadataCalculation calculation in templateContent.Calculations) { id += 1; FieldDefinition fieldDefinition = new FieldDefinition() { Id = id.ToString(), Name = calculation.Name, Required = false, Type = GetFieldType(calculation.Type), IsAggregable = calculation.AggregationType != AggregationType.None }; tableDefinition.FieldDefinitions.Add(fieldDefinition); } datasetDefinition.TableDefinitions.Add(tableDefinition); return(datasetDefinition); }
public async Task GetFundingConfiguration__GivenFundingConfigurationAlreadyInCache_ReturnsSuccessWithConfigurationFromCache(string fundingStreamId, string fundingPeriodId) { // Arrange FundingStream fundingStream = new FundingStream { Id = fundingStreamId }; FundingPeriod fundingPeriod = new FundingPeriod { Id = fundingPeriodId }; string configId = $"config-{fundingStreamId}-{fundingPeriodId}"; FundingConfiguration fundingConfiguration = new FundingConfiguration { Id = configId }; IPolicyRepository policyRepository = CreatePolicyRepository(); policyRepository .GetFundingStreamById(Arg.Is(fundingStreamId)) .Returns(fundingStream); policyRepository .GetFundingPeriodById(Arg.Is(fundingPeriodId)) .Returns(fundingPeriod); string cacheKey = $"{CacheKeys.FundingConfig}{fundingStreamId}-{fundingPeriodId}"; ICacheProvider cacheProvider = CreateCacheProvider(); cacheProvider .GetAsync <FundingConfiguration>(Arg.Is(cacheKey)) .Returns(fundingConfiguration); FundingConfigurationService fundingConfigurationsService = CreateFundingConfigurationService(policyRepository: policyRepository, cacheProvider: cacheProvider); // Act IActionResult result = await fundingConfigurationsService.GetFundingConfiguration(fundingStreamId, fundingPeriodId); // Assert result .Should() .BeOfType <OkObjectResult>() .Which .Value .Should() .Be(fundingConfiguration); }
private async Task ValidateFundingStream(FundingTemplateValidationResult fundingTemplateValidationResult) { if (!fundingTemplateValidationResult.FundingStreamId.IsNullOrEmpty()) { FundingStream fundingStream = await _policyRepositoryPolicy.ExecuteAsync(() => _policyRepository.GetFundingStreamById(fundingTemplateValidationResult.FundingStreamId)); if (fundingStream == null) { fundingTemplateValidationResult.Errors .Add(new ValidationFailure("", $"A funding stream could not be found for funding stream id '{fundingTemplateValidationResult.FundingStreamId}'")); } } }
public async Task GetFundingStream_WhenFundingStreamFound_ShouldReturnOkResult() { // Arrange string fundingStreamId = "PSG"; Models.Specs.FundingStream fundingStream = new Models.Specs.FundingStream { Id = fundingStreamId, Name = "PE and Sport Grant", RequireFinancialEnvelopes = true }; Mapper.Reset(); MapperConfigurationExpression mappings = new MapperConfigurationExpression(); mappings.AddProfile <ExternalApiMappingProfile>(); Mapper.Initialize(mappings); IMapper mapper = Mapper.Instance; IFundingService mockFundingService = Substitute.For <IFundingService>(); mockFundingService .GetFundingStreamById(Arg.Is(fundingStreamId)) .Returns(new OkObjectResult(fundingStream)); FundingStreamService fundingStreamService = new FundingStreamService(mockFundingService, mapper); // Act IActionResult result = await fundingStreamService.GetFundingStream(fundingStreamId); // Assert OkObjectResult okResult = result .Should() .BeOfType <OkObjectResult>() .Subject; FundingStream actualFundingStream = okResult.Value .Should() .BeOfType <FundingStream>() .Subject; actualFundingStream.Id.Should().Be(fundingStreamId); actualFundingStream.Name.Should().Be(fundingStream.Name); actualFundingStream.RequireFinancialEnvelopes.Should().Be(fundingStream.RequireFinancialEnvelopes); }
private PublishedProviderResult CreateSuccessorResult(SpecificationCurrentVersion specification, ProviderChangeItem providerChangeItem, Reference author, Period fundingPeriod) { FundingStream fundingStream = GetFundingStream(specification, providerChangeItem); PublishedFundingStreamDefinition fundingStreamDefinition = _mapper.Map <PublishedFundingStreamDefinition>(fundingStream); AllocationLine allocationLine = fundingStream.AllocationLines.FirstOrDefault(a => a.ProviderLookups.Any(l => l.ProviderType == providerChangeItem.SuccessorProvider.ProviderType && l.ProviderSubType == providerChangeItem.SuccessorProvider.ProviderSubType)); PublishedAllocationLineDefinition publishedAllocationLine = _mapper.Map <PublishedAllocationLineDefinition>(allocationLine); PublishedProviderResult successorResult = new PublishedProviderResult { FundingPeriod = fundingPeriod, FundingStreamResult = new PublishedFundingStreamResult { AllocationLineResult = new PublishedAllocationLineResult { AllocationLine = publishedAllocationLine, Current = new PublishedAllocationLineResultVersion { Author = author, Calculations = null, // don't set calcs as result hasn't been generated from calculation run Date = DateTimeOffset.Now, Provider = providerChangeItem.SuccessorProvider, ProviderId = providerChangeItem.SuccessorProviderId, SpecificationId = specification.Id, Status = AllocationLineStatus.Held, Value = 0, Version = 1 }, HasResultBeenVaried = true }, DistributionPeriod = $"{fundingStream.PeriodType.Id}{specification.FundingPeriod.Id}", FundingStream = fundingStreamDefinition, FundingStreamPeriod = $"{fundingStream.Id}{specification.FundingPeriod.Id}" }, ProviderId = providerChangeItem.SuccessorProviderId, SpecificationId = specification.Id, }; successorResult.FundingStreamResult.AllocationLineResult.Current.PublishedProviderResultId = successorResult.Id; EnsurePredecessors(successorResult, providerChangeItem.UpdatedProvider.Id); return(successorResult); }
public async Task <IActionResult> GetFundingStreamById(string fundingStreamId) { if (string.IsNullOrWhiteSpace(fundingStreamId)) { _logger.Error("No funding stream Id was provided to GetFundingStreamById"); return(new BadRequestObjectResult("Null or empty funding stream Id provided")); } FundingStream fundingStream = await _policyRepositoryPolicy.ExecuteAsync(() => _policyRepository.GetFundingStreamById(fundingStreamId)); if (fundingStream == null) { _logger.Error($"No funding stream was found for funding stream id : {fundingStreamId}"); return(new NotFoundResult()); } return(new OkObjectResult(fundingStream)); }
public async Task <IEnumerable <FundingStream> > GetAllFundingStreams() { IEnumerable <FundingStream> fundingStreams = await _cacheProviderPolicy.ExecuteAsync(() => _cacheProvider.GetAsync <FundingStream[]>(CacheKeys.AllFundingStreams)); if (fundingStreams.IsNullOrEmpty()) { fundingStreams = await _policyRepositoryPolicy.ExecuteAsync(() => _policyRepository.GetFundingStreams()); if (fundingStreams.IsNullOrEmpty()) { _logger.Error("No funding streams were returned"); fundingStreams = new FundingStream[0]; } await _cacheProviderPolicy.ExecuteAsync(() => _cacheProvider.SetAsync <FundingStream[]>(CacheKeys.AllFundingStreams, fundingStreams.ToArray())); } return(fundingStreams); }
public async Task <IActionResult> GetFundingStreams() { IEnumerable <FundingStream> fundingStreams = await _cacheProvider.GetAsync <FundingStream[]>(CacheKeys.AllFundingStreams); if (fundingStreams.IsNullOrEmpty()) { fundingStreams = await _specificationsRepository.GetFundingStreams(); if (fundingStreams.IsNullOrEmpty()) { _logger.Error("No funding streams were returned"); fundingStreams = new FundingStream[0]; } await _cacheProvider.SetAsync <FundingStream[]>(CacheKeys.AllFundingStreams, fundingStreams.ToArray()); } return(new OkObjectResult(fundingStreams)); }
public ICollection <SummarisedActual> Summarise( FundingStream fundingStream, TouchpointProviderFundingData providerFundingData, ICollection <FcsContractAllocation> allocations, ICollection <CollectionPeriod> collectionPeriods) { var summarisedActuals = new List <SummarisedActual>(); var fcsAllocation = allocations.FirstOrDefault(a => a.DeliveryUkprn == providerFundingData.Provider.UKPRN && a.UoPcode.Equals(providerFundingData.Provider.TouchpointId, StringComparison.OrdinalIgnoreCase) && a.FundingStreamPeriodCode.Equals(fundingStream.PeriodCode, StringComparison.OrdinalIgnoreCase)); if (fcsAllocation == null) { return(summarisedActuals); } foreach (var outcomeType in fundingStream.OutcomeTypes) { var fundingValues = providerFundingData .FundingValues .Where(ld => ld.OutcomeType == outcomeType).ToList(); summarisedActuals.AddRange(SummarisePeriods(fundingValues, collectionPeriods)); } return(summarisedActuals .GroupBy(grp => grp.Period) .Select(g => new SummarisedActual { OrganisationId = fcsAllocation.DeliveryOrganisation, UoPCode = fcsAllocation.UoPcode, DeliverableCode = fundingStream.DeliverableLineCode, FundingStreamPeriodCode = fundingStream.PeriodCode, Period = g.Key, ActualValue = Math.Round(g.Sum(x => x.ActualValue), 2), ContractAllocationNumber = fcsAllocation.ContractAllocationNumber, PeriodTypeCode = PeriodTypeCodeConstants.CalendarMonth }).ToList()); }
public void SummariseByFundingStream_R02(int apprenticeshipContractType, string fspCode, int dlc, string fundingSourceCSV, string transactionTypesCSV, string academicYearsCSV) { var fundingTypes = GetFundingTypes(); FundingStream fundingStream = fundingTypes.SelectMany(ft => ft.FundingStreams).Where(fs => fs.PeriodCode.Equals(fspCode, StringComparison.OrdinalIgnoreCase) && fs.DeliverableLineCode == dlc).First(); List <int> academicYears = academicYearsCSV.Split(',').Select(int.Parse).ToList(); int ilrFundlineCount = fundingStream.FundLines.Count(fl => fl.LineType.Equals("ILR", StringComparison.OrdinalIgnoreCase) && academicYears.Contains(fl.AcademicYear.HasValue ? fl.AcademicYear.Value : 0)); int easFundlineCount = fundingStream.FundLines.Count(fl => fl.LineType.Equals("EAS", StringComparison.OrdinalIgnoreCase) && academicYears.Contains(fl.AcademicYear.HasValue ? fl.AcademicYear.Value : 0)); List <int> fundingSources = fundingSourceCSV.Split(',').Select(int.Parse).ToList(); List <int> transactionTypes = transactionTypesCSV.Split(',').Select(int.Parse).ToList(); var summarisationMessageMock = new Mock <ISummarisationMessage>(); summarisationMessageMock.SetupGet(s => s.CollectionYear).Returns(1920); summarisationMessageMock.SetupGet(s => s.CollectionMonth).Returns(2); var task = new SummarisationPaymentsProcess(); var results = task.Summarise(fundingStream, GetTestProvider(apprenticeshipContractType, fundingSources, transactionTypes), GetContractAllocation(), GetCollectionPeriods(0), summarisationMessageMock.Object).OrderBy(x => x.Period).ToList(); results.Count.Should().Be(1); foreach (var item in results) { decimal ilrActualValue = learningDeliveryRecords * fundingSources.Count * ilrFundlineCount * transactionTypes.Count * periodsToGenerate * amount; decimal easActualValue = learningDeliveryRecords * easFundlineCount * periodsToGenerate * amount; decimal actualValue = ilrActualValue + easActualValue; item.ActualValue.Should().Be(actualValue); item.ContractAllocationNumber.Should().Be("AllocLEVY1799-2"); } }
public async Task CollectDetailsOfNotMappedTemplateCalculationsAsValidationErrors() { CalculationMetadata calculation2 = NewApiCalculation(_ => _.WithPublishStatus(PublishStatus.Approved)); CalculationMetadata calculation4 = NewApiCalculation(_ => _.WithPublishStatus(PublishStatus.Approved)); CalculationMetadata calculation5 = NewApiCalculation(_ => _.WithPublishStatus(PublishStatus.Approved)); string specificationId = NewRandomString(); string fundingStreamId = NewRandomString(); string templateMappingItemName1 = NewRandomString(); TemplateMappingEntityType templateMappingEntityType1 = NewRandomEnum <TemplateMappingEntityType>(); GivenTheCalculationsForTheSpecificationId(specificationId, calculation2, calculation4, calculation5); TemplateMapping templateMapping = NewTemplateMapping(_ => _.WithItems( NewTemplateMappingItem(mi => mi.WithCalculationId(string.Empty).WithEntityType(templateMappingEntityType1).WithName(templateMappingItemName1)), NewTemplateMappingItem(mi => mi.WithCalculationId(NewRandomString())))); GivenTheTemplateMappingForTheSpecificationIdAndFundingStreamId(specificationId, fundingStreamId, templateMapping); FundingStream[] fundingStreams = new FundingStream[] { new FundingStream { Id = fundingStreamId } }; await WhenThePreRequisitesAreChecked(specificationId, fundingStreams); _validationErrors .Should() .Contain(new[] { $"{templateMappingEntityType1} {templateMappingItemName1} is not mapped to a calculation in CFS" }); }
public async Task GetFundingStreamById_GivenFundingStreamnWasFound_ReturnsSuccess() { // Arrange IQueryCollection queryStringValues = new QueryCollection(new Dictionary <string, StringValues> { { "fundingStreamId", new StringValues(FundingStreamId) } }); HttpRequest request = Substitute.For <HttpRequest>(); request .Query .Returns(queryStringValues); ILogger logger = CreateLogger(); FundingStream fundingStream = new FundingStream { Id = FundingStreamId }; ISpecificationsRepository specificationsRepository = CreateSpecificationsRepository(); specificationsRepository .GetFundingStreamById(Arg.Is(FundingStreamId)) .Returns(fundingStream); IFundingService fundingService = CreateService(specificationsRepository: specificationsRepository, logger: logger); // Act IActionResult result = await fundingService.GetFundingStreamById(request); // Assert result .Should() .BeOfType <OkObjectResult>(); }
public ICollection <SummarisedActual> Summarise( FundingStream fundingStream, LearningProvider provider, ICollection <FcsContractAllocation> allocations, ICollection <CollectionPeriod> collectionPeriods) { var summarisedActuals = new List <SummarisedActual>(); foreach (var fundLine in fundingStream.FundLines) { var periodisedData = provider .LearningDeliveries .Where(ld => ld.Fundline.Equals(fundLine.Fundline, StringComparison.OrdinalIgnoreCase)) .SelectMany(x => x.PeriodisedData); var periods = GetPeriodsForFundLine(periodisedData, fundLine); summarisedActuals.AddRange(SummarisePeriods(periods)); } var fcsAllocations = allocations.ToDictionary(a => a.FundingStreamPeriodCode, StringComparer.OrdinalIgnoreCase); return(summarisedActuals .GroupBy(grp => grp.Period) .Select(g => new SummarisedActual { OrganisationId = fcsAllocations[fundingStream.PeriodCode].DeliveryOrganisation, DeliverableCode = fundingStream.DeliverableLineCode, FundingStreamPeriodCode = fundingStream.PeriodCode, Period = collectionPeriods.First(cp => cp.Period == g.Key).ActualsSchemaPeriod, ActualValue = Math.Round(g.Sum(x => x.ActualValue), 2), ContractAllocationNumber = fcsAllocations[fundingStream.PeriodCode].ContractAllocationNumber, PeriodTypeCode = PeriodTypeCodeConstants.CalendarMonth }).ToList()); }
public async Task <IActionResult> SaveFundingStream(FundingStreamSaveModel fundingStreamSaveModel) { if (fundingStreamSaveModel == null) { _logger.Error($"Null or empty json provided for file"); return(new BadRequestObjectResult($"Invalid json was provided for file")); } try { BadRequestObjectResult validationResult = (await _fundingStreamSaveModelValidator.ValidateAsync(fundingStreamSaveModel)).PopulateModelState(); if (validationResult != null) { return(validationResult); } } catch (Exception exception) { _logger.Error(exception, $"Invalid json was provided for file"); return(new BadRequestObjectResult($"Invalid json was provided for file")); } try { FundingStream fundingStream = new FundingStream() { Id = fundingStreamSaveModel.Id, Name = fundingStreamSaveModel.Name, ShortName = fundingStreamSaveModel.ShortName }; if (fundingStream != null) { HttpStatusCode result = await _policyRepositoryPolicy.ExecuteAsync(() => _policyRepository.SaveFundingStream(fundingStream)); if (!result.IsSuccess()) { int statusCode = (int)result; _logger.Error($"Failed to save to cosmos db with status {statusCode}"); return(new StatusCodeResult(statusCode)); } } } catch (Exception exception) { string errorMessage = $"Exception occurred writing to json file to cosmos db"; _logger.Error(exception, errorMessage); return(new InternalServerErrorResult(errorMessage)); } _logger.Information($"Successfully saved file to cosmos db"); bool keyExists = await _cacheProviderPolicy.ExecuteAsync(() => _cacheProvider.KeyExists <FundingStream[]>(CacheKeys.AllFundingStreams)); if (keyExists) { await _cacheProviderPolicy.ExecuteAsync(() => _cacheProvider.KeyDeleteAsync <FundingStream[]>(CacheKeys.AllFundingStreams)); } return(new OkResult()); }