示例#1
0
        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);
        }
示例#4
0
        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);
        }
示例#6
0
        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());
        }
示例#8
0
        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);
            }
        }
示例#9
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");
        }
示例#10
0
        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());
        }
示例#11
0
        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'");
        }
示例#14
0
        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);
        }
示例#15
0
        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"));
        }
示例#16
0
        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);
        }
示例#17
0
        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);
        }
示例#18
0
        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);
        }
示例#21
0
        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);
        }
示例#22
0
        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));
        }
示例#23
0
        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);
        }
示例#24
0
        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());
        }
示例#26
0
        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"
            });
        }
示例#28
0
        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());
        }
示例#30
0
        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());
        }