public void SaveFundingPeriod(FundingPeriod fundingPeriod)
        {
            Guard.ArgumentNotNull(fundingPeriod, nameof(fundingPeriod));
            Guard.IsNullOrWhiteSpace(fundingPeriod.Id, nameof(fundingPeriod.Id));

            _fundingPeriods[fundingPeriod.Id] = fundingPeriod;
        }
            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
                                                                              } });
            }
Exemple #3
0
        private void AddDurationAndFundingToStandards(ICollection <LarsStandard> standards, ICollection <ApprenticeshipFundingMetaData> metaData)
        {
            foreach (var std in standards)
            {
                var fundingBands =
                    metaData.Where(stdrd =>
                                   stdrd.ApprenticeshipType.ToLower() == "std" &&
                                   stdrd.ApprenticeshipCode == std.Id);

                if (!fundingBands.Any())
                {
                    continue;
                }

                std.Duration = fundingBands.First().ReservedValue1;

                std.FundingPeriods = new List <FundingPeriod>();
                foreach (var apprenticeshipFundingMetaData in fundingBands)
                {
                    var fundingPeriod = new FundingPeriod
                    {
                        FundingCap    = apprenticeshipFundingMetaData.MaxEmployerLevyCap,
                        EffectiveFrom = apprenticeshipFundingMetaData.EffectiveFrom,
                        EffectiveTo   = apprenticeshipFundingMetaData.EffectiveTo
                    };

                    std.FundingPeriods.Add(fundingPeriod);
                }

                std.FundingCap = fundingBands.Last(x => x.EffectiveFrom <= DateTime.Today).MaxEmployerLevyCap;
            }
        }
        public async Task GetFundingPeriodById__GivenFundingStreamnWasFound_ReturnsSuccess()
        {
            // Arrange
            const string fundingPeriodId = "fp-1";

            FundingPeriod fundingPeriod = new FundingPeriod
            {
                Id = fundingPeriodId
            };

            IPolicyRepository policyRepository = CreatePolicyRepository();

            policyRepository
            .GetFundingPeriodById(Arg.Is(fundingPeriodId))
            .Returns(fundingPeriod);

            FundingPeriodService fundingPeriodService = CreateFundingPeriodService(policyRepository: policyRepository);

            // Act
            IActionResult result = await fundingPeriodService.GetFundingPeriodById(fundingPeriodId);

            // Assert
            result
            .Should()
            .BeOfType <OkObjectResult>()
            .Which
            .Value
            .Should()
            .Be(fundingPeriod);
        }
        public void Then_The_Fields_Are_Correctly_Mapped(FundingPeriod fundingPeriod, string frameworkId)
        {
            var actual = new FrameworkFundingImport().Map(fundingPeriod, frameworkId);

            actual.Should().BeEquivalentTo(fundingPeriod);
            actual.FrameworkId.Should().Be(frameworkId);
        }
Exemple #6
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");
        }
Exemple #7
0
        /// <summary>
        /// Get the provider funding ids to return for a feed entry.
        /// </summary>
        /// <param name="orgGroup"></param>
        /// <param name="period"></param>
        /// <param name="stream"></param>
        /// <param name="fundingVersion"></param>
        /// <returns>A list of provider funding ids.</returns>
        private static List <string> GetProviderFundingIds(OrgGroup orgGroup, FundingPeriod period, Stream stream, string fundingVersion,
                                                           OrganisationType[] organisationTypes, VariationReason[] variationReasons, string[] ukprns)
        {
            var returnList = new List <string>();

            // We don't have variation reasons yet
            if (variationReasons?.Any() == true)
            {
                return(returnList);
            }

            // If we are asking for anything but local authorities, there won't be any results
            if (organisationTypes?.Any() == true && organisationTypes?.Contains(OrganisationType.LocalAuthority) == false)
            {
                return(returnList);
            }

            foreach (var provider in orgGroup.Providers)
            {
                var ukprn = $"MOCKUKPRN{provider.LaEstablishmentNo}";

                if (ukprns?.Any() == true && ukprns?.Contains(ukprn) == false)
                {
                    continue;
                }

                returnList.Add($"{stream.Code}_{period.Code}_{ukprn}_{fundingVersion}");
            }

            return(returnList);
        }
Exemple #8
0
        private void GivenTheFundingPeriod(Action <FundingPeriodBuilder> setUp = null)
        {
            FundingPeriodBuilder fundingPeriodBuilder = new FundingPeriodBuilder();

            setUp?.Invoke(fundingPeriodBuilder);

            _fundingPeriod = fundingPeriodBuilder.Build();
        }
Exemple #9
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);
        }
Exemple #10
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"));
        }
Exemple #11
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 ValidateFundingPeriod(FundingTemplateValidationResult fundingTemplateValidationResult)
        {
            if (!string.IsNullOrWhiteSpace(fundingTemplateValidationResult.FundingPeriodId))
            {
                FundingPeriod fundingPeriod = await _policyRepositoryPolicy.ExecuteAsync(() => _policyRepository.GetFundingPeriodById(fundingTemplateValidationResult.FundingPeriodId));

                if (fundingPeriod == null)
                {
                    fundingTemplateValidationResult.Errors
                    .Add(new ValidationFailure("", $"A funding period could not be found for funding period id '{fundingTemplateValidationResult.FundingPeriodId}'"));
                }
            }
        }
Exemple #13
0
        public async Task <string> GetFundingPeriodId(string fundingPeriodId)
        {
            ApiResponse <FundingPeriod> fundingPeriodResponse =
                await _policiesApiClientPolicy.ExecuteAsync(() => _policiesApiClient.GetFundingPeriodById(fundingPeriodId));

            if (fundingPeriodResponse?.Content == null)
            {
                return(null);
            }

            FundingPeriod fundingPeriod = fundingPeriodResponse.Content;

            return(string.Format(periodIdStringFormat, fundingPeriod.Type, fundingPeriod.Period));
        }
        public void ShouldReturnNoDetailsOfSingleInstanceIfItIsCurrent(DateTime?currentEffectiveFrom)
        {
            var numberOfMonths        = 3;
            var expectedFundingCap    = 1500;
            var expectedFundingPeriod = new FundingPeriod {
                EffectiveFrom = currentEffectiveFrom, FundingCap = expectedFundingCap
            };

            var fundingBands = new List <FundingPeriod>
            {
                expectedFundingPeriod
            };

            var res = _fundingBandService.GetNextFundingPeriodWithinTimePeriod(fundingBands, currentEffectiveFrom, numberOfMonths);

            res.Should().BeNull();
        }
        public void ShouldReturnNoDetailsOfSingleInstanceAt3MonthsAnd1Day(DateTime?currentEffectiveFrom)
        {
            var numberOfMonths        = 3;
            var expectedFundingCap    = 1500;
            var usedDateTime          = DateTime.Today.AddMonths(numberOfMonths).AddDays(1);
            var expectedFundingPeriod = new FundingPeriod {
                EffectiveFrom = usedDateTime, FundingCap = expectedFundingCap
            };

            var fundingBands = new List <FundingPeriod>
            {
                expectedFundingPeriod
            };

            var res = _fundingBandService.GetNextFundingPeriodWithinTimePeriod(fundingBands, currentEffectiveFrom, numberOfMonths);

            res.Should().BeNull();
        }
        public async Task <IActionResult> GetFundingPeriodById(string fundingPeriodId)
        {
            if (string.IsNullOrWhiteSpace(fundingPeriodId))
            {
                _logger.Error("No funding period id was provided to GetFundingPeriodById");

                return(new BadRequestObjectResult("Null or empty funding period id provided"));
            }

            FundingPeriod fundingPeriod = await _policyRepositoryPolicy.ExecuteAsync(() => _policyRepository.GetFundingPeriodById(fundingPeriodId));

            if (fundingPeriod == null)
            {
                _logger.Error($"No funding period was returned for funding period id: '{fundingPeriodId}'");

                return(new NotFoundResult());
            }

            return(new OkObjectResult(fundingPeriod));
        }
        public void ShouldReturnTheCorrectInstanceAt3MonthsForMixedListOf5(DateTime?currentEffectiveFrom)
        {
            var numberOfMonths     = 3;
            var earliestFundingCap = 1501;
            var earliestDateTime   = DateTime.Today.AddDays(1);
            var secondDateTime     = DateTime.Today.AddDays(7);
            var secondFundingCap   = 1507;
            var thirdDateTime      = DateTime.Today.AddDays(28);
            var thirdFundingCap    = 1528;
            var fourthDateTime     = DateTime.Today.AddDays(50);
            var fourthFundingCap   = 1550;

            var firstFundingPeriod = new FundingPeriod {
                EffectiveFrom = earliestDateTime, FundingCap = earliestFundingCap
            };
            var secondFundingPeriod = new FundingPeriod {
                EffectiveFrom = secondDateTime, FundingCap = secondFundingCap
            };
            var thirdFundingPeriod = new FundingPeriod {
                EffectiveFrom = thirdDateTime, FundingCap = thirdFundingCap
            };
            var fourthFundingPeriod = new FundingPeriod {
                EffectiveFrom = fourthDateTime, FundingCap = fourthFundingCap
            };
            var currentFundingPeriod = new FundingPeriod {
                EffectiveFrom = currentEffectiveFrom, FundingCap = 1200
            };

            var fundingBands = new List <FundingPeriod>
            {
                thirdFundingPeriod,
                currentFundingPeriod,
                secondFundingPeriod,
                fourthFundingPeriod,
                firstFundingPeriod
            };

            var res = _fundingBandService.GetNextFundingPeriodWithinTimePeriod(fundingBands, currentEffectiveFrom, numberOfMonths);

            res.Should().Be(firstFundingPeriod);
        }
        public void ShouldReturnTheCorrectInstanceAt3MonthsForListContainingCurrent(DateTime?currentEffectiveFrom)
        {
            var numberOfMonths        = 3;
            var expectedFundingCap    = 1500;
            var usedDateTime          = DateTime.Today.AddMonths(numberOfMonths);
            var expectedFundingPeriod = new FundingPeriod {
                EffectiveFrom = usedDateTime, FundingCap = expectedFundingCap
            };
            var currentFundingPeriod = new FundingPeriod {
                EffectiveFrom = currentEffectiveFrom, FundingCap = 1200
            };

            var fundingBands = new List <FundingPeriod>
            {
                currentFundingPeriod,
                expectedFundingPeriod
            };

            var res = _fundingBandService.GetNextFundingPeriodWithinTimePeriod(fundingBands, currentEffectiveFrom, numberOfMonths);

            res.Should().Be(expectedFundingPeriod);
        }
        public async Task <IEnumerable <FundingPeriod> > GetAllFundingPeriods()
        {
            IEnumerable <FundingPeriod> fundingPeriods = await _cacheProviderPolicy.ExecuteAsync(() => _cacheProvider.GetAsync <FundingPeriod[]>(CacheKeys.FundingPeriods));

            if (fundingPeriods.IsNullOrEmpty())
            {
                fundingPeriods = await _policyRepositoryPolicy.ExecuteAsync(() => _policyRepository.GetFundingPeriods());

                if (fundingPeriods.IsNullOrEmpty())
                {
                    _logger.Error("No funding periods were returned");

                    fundingPeriods = new FundingPeriod[0];
                }
                else
                {
                    await _cacheProviderPolicy.ExecuteAsync(() => _cacheProvider.SetAsync(CacheKeys.FundingPeriods, fundingPeriods.ToArraySafe()));
                }
            }

            return(fundingPeriods);
        }
Exemple #20
0
        private void ThenFundingPeriodResultMatches(IActionResult result)
        {
            result
            .Should()
            .BeOfType <OkObjectResult>()
            .Which
            .Value
            .Should()
            .BeOfType <List <FundingPeriod> >();

            IEnumerable <FundingPeriod> fundingPeriods = (result as OkObjectResult).Value as IEnumerable <FundingPeriod>;

            fundingPeriods
            .Count()
            .Should()
            .Be(1);

            fundingPeriods
            .FirstOrDefault()
            .Should()
            .NotBeNull();

            FundingPeriod fundingPeriod = fundingPeriods.FirstOrDefault();

            fundingPeriod
            .Id
            .Should()
            .Be(_fundingPeriodId);

            fundingPeriod
            .Name
            .Should()
            .Be(_fundingPeriodName);

            fundingPeriod
            .DefaultTemplateVersion
            .Should()
            .Be(_fundingPeriodDefaultTemplateVersion);
        }
Exemple #21
0
        private void AddDurationAndFundingToFrameworks(ICollection <FrameworkMetaData> frameworks, ICollection <ApprenticeshipFundingMetaData> metaData)
        {
            foreach (var framework in frameworks)
            {
                var fw =
                    metaData.Where(fwk =>
                                   fwk.ApprenticeshipType.ToLower() == "fwk" &&
                                   fwk.ApprenticeshipCode == framework.FworkCode &&
                                   fwk.ProgType == framework.ProgType &&
                                   fwk.PwayCode == framework.PwayCode &&
                                   fwk.EffectiveFrom.HasValue &&
                                   fwk.EffectiveFrom.Value.Date != DateTime.MinValue.Date)
                    .ToList();

                if (!fw.Any())
                {
                    continue;
                }

                framework.Duration = fw.OrderByDescending(x => x.EffectiveFrom).First().ReservedValue1;

                framework.FundingPeriods = new List <FundingPeriod>();
                foreach (var apprenticeshipFundingMetaData in fw)
                {
                    var fundingPeriod = new FundingPeriod
                    {
                        FundingCap    = apprenticeshipFundingMetaData.MaxEmployerLevyCap,
                        EffectiveFrom = apprenticeshipFundingMetaData.EffectiveFrom,
                        EffectiveTo   = apprenticeshipFundingMetaData.EffectiveTo
                    };

                    framework.FundingPeriods.Add(fundingPeriod);
                }

                framework.FundingCap = fw.Last(x => x.EffectiveFrom <= DateTime.Today).MaxEmployerLevyCap;
            }
        }
Exemple #22
0
        public SaveFundingConfigurationValidator(IPolicyRepository policyRepository,
                                                 IPolicyResiliencePolicies policyResiliencePolicies,
                                                 IFundingTemplateService fundingTemplateService)
        {
            Guard.ArgumentNotNull(policyRepository, nameof(policyRepository));
            Guard.ArgumentNotNull(fundingTemplateService, nameof(fundingTemplateService));
            Guard.ArgumentNotNull(policyResiliencePolicies?.PolicyRepository, nameof(policyResiliencePolicies.PolicyRepository));

            ResiliencePolicy policyRepositoryPolicy = policyResiliencePolicies.PolicyRepository;

            RuleFor(_ => _.ApprovalMode)
            .Must(_ => _ != ApprovalMode.Undefined)
            .WithMessage("No valid approval mode was selected");

            RuleFor(model => model.FundingStreamId)
            .NotEmpty()
            .WithMessage("No funding stream id was provided to SaveFundingConfiguration")
            .CustomAsync(async(name, context, cancellationToken) =>
            {
                FundingConfiguration model = context.ParentContext.InstanceToValidate as FundingConfiguration;
                if (!string.IsNullOrWhiteSpace(model.FundingStreamId))
                {
                    FundingStream fundingStream = await policyRepositoryPolicy.ExecuteAsync(() => policyRepository.GetFundingStreamById(model.FundingStreamId));
                    if (fundingStream == null)
                    {
                        context.AddFailure("Funding stream not found");
                    }
                }
            });

            RuleFor(model => model.FundingPeriodId)
            .NotEmpty()
            .WithMessage("No funding period id was provided to SaveFundingConfiguration")
            .CustomAsync(async(name, context, cancellationToken) =>
            {
                FundingConfiguration model = context.ParentContext.InstanceToValidate as FundingConfiguration;
                if (!string.IsNullOrWhiteSpace(model.FundingPeriodId))
                {
                    FundingPeriod fundingPeriod = await policyRepositoryPolicy.ExecuteAsync(() => policyRepository.GetFundingPeriodById(model.FundingPeriodId));
                    if (fundingPeriod == null)
                    {
                        context.AddFailure("Funding period not found");
                    }
                }
            });

            RuleFor(model => model.DefaultTemplateVersion)
            .CustomAsync(async(name, context, cancellationToken) =>
            {
                FundingConfiguration model = context.ParentContext.InstanceToValidate as FundingConfiguration;

                string fundingStreamId        = model.FundingStreamId;
                string defaultTemplateVersion = model.DefaultTemplateVersion;
                string fundingPeriodId        = model.FundingPeriodId;

                if (!string.IsNullOrWhiteSpace(fundingStreamId) && !string.IsNullOrWhiteSpace(fundingPeriodId) && !string.IsNullOrWhiteSpace(defaultTemplateVersion))
                {
                    if (!await fundingTemplateService.TemplateExists(fundingStreamId, fundingPeriodId, defaultTemplateVersion))
                    {
                        context.AddFailure("Default template not found");
                    }
                }
            });

            RuleFor(_ => _.UpdateCoreProviderVersion)
            .Must(v => v == UpdateCoreProviderVersion.Manual)
            .When(_ => _.ProviderSource != CalculateFunding.Models.Providers.ProviderSource.FDZ, ApplyConditionTo.CurrentValidator)
            .WithMessage(x => $"UpdateCoreProviderVersion - {x.UpdateCoreProviderVersion.ToString()} is not valid for provider source - {x.ProviderSource}");
        }
Exemple #23
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);
            }
        }
Exemple #24
0
        public SaveFundingDateValidator(
            IPolicyRepository policyRepository,
            IPolicyResiliencePolicies policyResiliencePolicies
            )
        {
            Guard.ArgumentNotNull(policyRepository, nameof(policyRepository));
            Guard.ArgumentNotNull(policyResiliencePolicies?.PolicyRepository, nameof(policyResiliencePolicies.PolicyRepository));

            ResiliencePolicy policyRepositoryPolicy = policyResiliencePolicies.PolicyRepository;

            RuleFor(model => model.FundingStreamId)
            .NotEmpty()
            .WithMessage("No funding stream id was provided to SaveFundingDate")
            .CustomAsync(async(name, context, cancellationToken) =>
            {
                FundingDate model = context.ParentContext.InstanceToValidate as FundingDate;
                if (!string.IsNullOrWhiteSpace(model.FundingStreamId))
                {
                    FundingStream fundingStream = await policyRepositoryPolicy.ExecuteAsync(() => policyRepository.GetFundingStreamById(model.FundingStreamId));
                    if (fundingStream == null)
                    {
                        context.AddFailure("Funding stream not found");
                    }
                }
            });

            RuleFor(model => model.FundingPeriodId)
            .NotEmpty()
            .WithMessage("No funding period id was provided to SaveFundingDate")
            .CustomAsync(async(name, context, cancellationToken) =>
            {
                FundingDate model = context.ParentContext.InstanceToValidate as FundingDate;
                if (!string.IsNullOrWhiteSpace(model.FundingPeriodId))
                {
                    FundingPeriod fundingPeriod = await policyRepositoryPolicy.ExecuteAsync(() => policyRepository.GetFundingPeriodById(model.FundingPeriodId));
                    if (fundingPeriod == null)
                    {
                        context.AddFailure("Funding period not found");
                    }
                }
            });

            RuleFor(model => model.Patterns)
            .NotEmpty()
            .WithMessage("No funding date pattern was provided to SaveFundingDate")
            .Custom((name, context) =>
            {
                FundingDate model = context.ParentContext.InstanceToValidate as FundingDate;

                if (model.Patterns == null)
                {
                    return;
                }

                foreach (FundingDatePattern fundingDatePattern in model.Patterns)
                {
                    if (fundingDatePattern.Occurrence == default ||
                        string.IsNullOrEmpty(fundingDatePattern.Period) ||
                        fundingDatePattern.PeriodYear == default ||
                        fundingDatePattern.PaymentDate == default)
                    {
                        context.AddFailure("FundingDatePattern information missing");
                    }
                }

                if (model.Patterns.GroupBy(x => new { x.Period, x.PeriodYear, x.Occurrence }).Any(_ => _.Count() > 1))
                {
                    context.AddFailure("Duplicate funding data pattern");
                }
            });
        }
Exemple #25
0
        /// <summary>
        /// Generate a feed from CSV files (from a spreadsheet).
        /// </summary>
        /// <param name="fundingPeriodStartYear">Optional - </param>
        /// <param name="fundingPeriodEndYear">Optional - </param>
        /// <param name="fundingPeriodCodes">Optional - The period codes to limit to (e.g. AY1920).</param>
        /// <param name="organisationGroupIdentifiers">Optional - The group identifiers to limit by (e.g. UKPRN 12345678).</param>
        /// <param name="organisationGroupTypes">Optional - The group types to limit to (e.g. Region, LocalAuthority).</param>
        /// <param name="organisationIdentifiers">Optional - The organisation identifiers to limit to (e.g. UKPRN 12345678).</param>
        /// <param name="organisationTypes">Optional - The organisation types to return.</param>
        /// <param name="variationReasons">Optional - Filter to only organisations with these variation reasons types</param>
        /// <param name="ukprns">Optional - Only get these UKPRNs back.</param>
        /// <param name="groupingReasons">Optional - The grouping reasons we want to get back (e.g. Information and/or Payment).</param>
        /// <param name="statuses">Optional - The status of the funding (e.g. Released).</param>
        /// <param name="minStatusChangeDate">Optional - Only get records back that were changed after this date.</param>
        /// <param name="fundingLineTypes">Optional - limit the types of lines we want to get back (e.g. Information and/or Payment).</param>
        /// <param name="templateLineIds">Optional - Filter the lines to these ids only.</param>
        /// <returns>An array of FeedResponseContentModel objects./returns>
        public static FeedResponseContentModel[] GenerateFeed(int?fundingPeriodStartYear, int?fundingPeriodEndYear,
                                                              string[] fundingPeriodCodes, OrganisationIdentifier[] organisationGroupIdentifiers, OrganisationType[] organisationGroupTypes,
                                                              OrganisationIdentifier[] organisationIdentifiers, OrganisationType[] organisationTypes, VariationReason[] variationReasons,
                                                              string[] ukprns, GroupingReason[] groupingReasons, FundingStatus[] statuses, DateTime?minStatusChangeDate,
                                                              FundingLineType[] fundingLineTypes, string[] templateLineIds)
        {
            var totalList = new List <FeedResponseContentModel>();

            // Check period dates
            if ((fundingPeriodStartYear != null && fundingPeriodStartYear != 2019) ||
                (fundingPeriodEndYear != null && fundingPeriodEndYear != 2020))
            {
                return(totalList.ToArray());
            }

            // Check period codes
            if (fundingPeriodCodes?.Any() == true && fundingPeriodCodes?.Contains("AY1920") == false)
            {
                return(totalList.ToArray());
            }

            // Check statuses
            if (statuses?.Any() == true && !statuses.Contains(FundingStatus.Released))
            {
                return(totalList.ToArray());
            }

            // Check feed cut off date
            if (minStatusChangeDate != null && minStatusChangeDate.Value > new DateTime(2019, 3, 1))
            {
                return(totalList.ToArray());
            }

            // If we only want information type, we are out of luck
            if (groupingReasons?.Any() == true && groupingReasons?.Contains(GroupingReason.Payment) == false)
            {
                return(totalList.ToArray());
            }

            var fundingVersion  = "1-0";
            var templateVersion = "1.0";
            var schemaVersion   = "1.0";

            var ukOffset = new TimeSpan(0, 0, 0);

            var period = new FundingPeriod
            {
                Code      = "AY1920",
                Name      = "Academic year 2019-20",
                Type      = PeriodType.AcademicYear,
                StartDate = new DateTimeOffset(2019, 9, 1, 0, 0, 0, ukOffset),
                EndDate   = new DateTimeOffset(2020, 8, 31, 0, 0, 0, ukOffset)
            };

            var stream = new StreamWithTemplateVersion
            {
                Code            = "PESports",
                Name            = "PE + Sport Premium",
                TemplateVersion = templateVersion,
            };

            var processFile = new ProcessPesportsCsv();

            var financialYearPeriod1920 = new FundingPeriod
            {
                Code      = "FY1920",
                Name      = "Financial Year 2019-20",
                Type      = PeriodType.FinancialYear,
                StartDate = new DateTimeOffset(2019, 4, 1, 0, 0, 0, ukOffset),
                EndDate   = new DateTimeOffset(2020, 3, 30, 0, 0, 0, ukOffset)
            };

            var financialYearPeriod2021 = new FundingPeriod
            {
                Code      = "FY2021",
                Name      = "Financial Year 2020-21",
                Type      = PeriodType.FinancialYear,
                StartDate = new DateTimeOffset(2020, 4, 1, 0, 0, 0, ukOffset),
                EndDate   = new DateTimeOffset(2021, 3, 30, 0, 0, 0, ukOffset)
            };

            var providerTypes = new List <string>
            {
                "MaintainedSchools",
                "Academies",
                "NonMaintainedSpecialSchools"
            };

            foreach (var providerType in providerTypes)
            {
                if ((providerType == "MaintainedSchools" || providerType == "NonMaintainedSpecialSchools") &&
                    organisationGroupTypes?.Any() == true && organisationGroupTypes?.Contains(OrganisationType.Provider) == false)
                {
                    continue;
                }
                else if (providerType == "Academies" &&
                         organisationGroupTypes?.Any() == true && organisationGroupTypes?.Contains(OrganisationType.AcademyTrust) == false)
                {
                    continue;
                }

                var groupByLa = false;

                switch (providerType)
                {
                case "MaintainedSchools":
                    groupByLa = true;

                    break;
                }

                var orgGroups = processFile.GetOrgsOrOrgGroups($"{providerType}.csv", groupByLa);

                totalList.AddRange(ProcessOrgGroups(orgGroups, providerType, financialYearPeriod1920, financialYearPeriod2021, period, stream, schemaVersion, fundingVersion,
                                                    organisationGroupIdentifiers, organisationIdentifiers, organisationTypes, variationReasons, ukprns, fundingLineTypes, templateLineIds)
                                   );
            }

            return(totalList.ToArray());
        }
Exemple #26
0
        /// <summary>
        /// Get provider funding from component parts.
        /// </summary>
        /// <param name="provider">A provider object.</param>
        /// <param name="financialYearPeriod1920">Period data for year1.</param>
        /// <param name="financialYearPeriod2021">Period data for year2.</param>
        /// <param name="period">Funding period.</param>
        /// <param name="stream">Data about a stream.</param>
        /// <param name="providerType">The type of provider (e.g. NonMaintainedSpecialSchools).</param>
        /// <param name="code">The code that identifies the provider (e.g. ukprn).</param>
        /// <returns>A provider funding object.</returns>
        private static ProviderFunding GetProviderFunding(Provider provider, FundingPeriod financialYearPeriod1920,
                                                          FundingPeriod financialYearPeriod2021, FundingPeriod period, Stream stream, string providerType, string code)
        {
            var ukprn = $"MOCKUKPRN{provider.LaEstablishmentNo}";

            var identifiers = new List <OrganisationIdentifier>
            {
                new OrganisationIdentifier
                {
                    Type  = OrganisationIdentifierType.UKPRN,
                    Value = ukprn
                }
            };

            if (providerType != "NonMaintainedSpecialSchools" && providerType != "Academies")
            {
                identifiers.Add(new OrganisationIdentifier
                {
                    Type  = OrganisationIdentifierType.LACode,
                    Value = provider.LaEstablishmentNo
                });
            }
            else
            {
                identifiers.Add(new OrganisationIdentifier
                {
                    Type  = OrganisationIdentifierType.URN,
                    Value = code
                });

                identifiers.Add(new OrganisationIdentifier
                {
                    Type  = OrganisationIdentifierType.DfeNumber,
                    Value = code
                });
            }

            var fundingVersion = "1-0";

            return(new ProviderFunding
            {
                Id = $"{stream.Code}_{period.Code}_{ukprn}_{fundingVersion}",
                FundingVersion = fundingVersion.Replace("-", "."),
                FundingPeriodCode = period.Code,
                FundingStreamCode = stream.Code,
                Organisation = new Organisation
                {
                    Name = provider.Name,
                    SearchableName = FundingController.SanitiseName(provider.Name),
                    OrganisationDetails = new OrganisationDetails()
                    {
                        DateClosed = null,
                        DateOpened = new DateTimeOffset(2012, 12, 2, 0, 0, 0, 0, TimeSpan.Zero),
                        PhaseOfEducation = "PhaseOfEducation",
                        Status = "Open",
                        OpenReason = ProviderOpenReason.NotRecorded,
                        CloseReason = null,
                        TrustName = null,
                        TrustStatus = TrustStatus.NotApplicable,
                        Address = new OrganisationAddress
                        {
                            Postcode = "MOCK POSTCODE",
                            Town = "MOCK TOWN"
                        }
                    },
                    ProviderType = providerType,
                    ProviderSubType = "Provider SubType",
                    ProviderVersionId = "1.0",
                    Identifiers = identifiers,
                },
                FundingValue = new FundingValue
                {
                    TotalValue = provider.TotalAllocation, // 16200, // "Maintained Schools" -> F3
                    FundingValueByDistributionPeriod = new List <FundingValueByDistributionPeriod>
                    {
                        new FundingValueByDistributionPeriod
                        {
                            DistributionPeriodCode = financialYearPeriod1920.Code,
                            Value = provider.OctoberPayment, //9450,  // "Maintained Schools" -> G3
                            FundingLines = new List <FundingLine>
                            {
                                new FundingLine
                                {
                                    Name = "Total Allocation", //
                                    TemplateLineId = 1,
                                    Type = FundingLineType.Payment,
                                    Value = provider.OctoberPayment, //9450, // "Maintained Schools"  -> G3
                                    ProfilePeriods = new List <FundingLinePeriod>
                                    {
                                        new FundingLinePeriod // ProfiorPeriods
                                        {
                                            Occurence = 1,
                                            Year = 2019,
                                            TypeValue = "October",
                                            ProfiledValue = provider.OctoberPayment, //9450, // "Maintained Schools"  -> G3
                                            Type = FundingLinePeriodType.CalendarMonth,
                                            PeriodCode = financialYearPeriod1920.Code
                                        }
                                    },
                                    Calculations = new List <Calculation>
                                    {
                                        new Calculation
                                        {
                                            Name = "Total Allocation",
                                            Type = CalculationType.Cash,
                                            TemplateCalculationId = 1,
                                            Value = provider.TotalAllocation, //"16200",  //  "Maintained Schools"
                                            ValueFormat = CalculationValueFormat.Currency,
                                            FormulaText = "School with pupils with less than 17 eligible pupils (X) = 1000 * X School with pupils with more than 16 eligible pupils (X) =((1 * 16000) + (10 * X))",
                                            ReferenceData = new List <ReferenceData>
                                            {
                                                new ReferenceData
                                                {
                                                    Name = "Eligible pupils",
                                                    Value = provider.EligiblePupilsCount.ToString(), // "20",   //  "Maintained Schools"
                                                    Format = ReferenceDataValueFormat.Number
                                                },
                                            }
                                        }
                                    }
                                }
                            }
                        },
                        new FundingValueByDistributionPeriod
                        {
                            DistributionPeriodCode = financialYearPeriod2021.Code,
                            Value = 6750, // "Maintained Schools" -> H3
                            FundingLines = new List <FundingLine>
                            {
                                new FundingLine
                                {
                                    Name = "April payment",// "Maintained Schools"
                                    TemplateLineId = 2,
                                    Type = FundingLineType.Payment,
                                    Value = provider.AprilPayment, //6750,  // "Maintained Schools" -> H3
                                    ProfilePeriods = new List <FundingLinePeriod>
                                    {
                                        new FundingLinePeriod
                                        {
                                            Occurence = 1,
                                            Year = 2020,
                                            TypeValue = "April",
                                            ProfiledValue = provider.AprilPayment,  //6750, // "Maintained Schools" -> H3
                                            Type = FundingLinePeriodType.CalendarMonth,
                                            PeriodCode = financialYearPeriod2021.Code
                                        }
                                    },
                                    Calculations = new List <Calculation>
                                    {
                                        new Calculation
                                        {
                                            Name = "Total Allocation",
                                            Type = CalculationType.Cash,
                                            TemplateCalculationId = 1,
                                            Value = provider.TotalAllocation, //"16200",  //  "Maintained Schools"
                                            ValueFormat = CalculationValueFormat.Currency,
                                            FormulaText = "School with pupils with less than 17 eligible pupils (X) = 1000 * X School with pupils with more than 16 eligible pupils (X) =((1 * 16000) + (10 * X))",
                                            ReferenceData = new List <ReferenceData>
                                            {
                                                new ReferenceData
                                                {
                                                    Name = "Eligible pupils",
                                                    Value = provider.EligiblePupilsCount.ToString(), // "20",   //  "Maintained Schools"
                                                    Format = ReferenceDataValueFormat.Number
                                                },
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            });
        }
Exemple #27
0
        public void GivenTheFundingPeriodExistsInThePoliciesService(Table table)
        {
            FundingPeriod fundingPeriod = table.CreateInstance <FundingPeriod>();

            _policiesStepContext.Repo.SaveFundingPeriod(fundingPeriod);
        }
Exemple #28
0
        public object GetExamples()
        {
            var ukOffset       = new TimeSpan(0, 0, 0);
            var fundingVersion = "1.0";

            var period = new FundingPeriod
            {
                Code      = "AY1920",
                Name      = "Academic year 2019-20",
                Type      = PeriodType.AcademicYear,
                StartDate = new DateTimeOffset(2019, 9, 1, 0, 0, 0, ukOffset),
                EndDate   = new DateTimeOffset(2020, 8, 31, 0, 0, 0, ukOffset)
            };

            var templateVersion = "2.1";

            var stream = new StreamWithTemplateVersion
            {
                Code            = "PESports",
                Name            = "PE + Sport Premium",
                TemplateVersion = templateVersion,
            };

            var schemaVersion = "1.0";

            var groupingOrg = new OrganisationGroup()
            {
                Type           = OrganisationType.LocalAuthority,
                Name           = "Camden",
                SearchableName = "Camden",
                Identifiers    = new List <OrganisationIdentifier>
                {
                    new OrganisationIdentifier
                    {
                        Type  = OrganisationIdentifierType.LACode,
                        Value = "203"
                    },
                    new OrganisationIdentifier
                    {
                        Type  = OrganisationIdentifierType.UKPRN,
                        Value = "12345678"
                    }
                }
            };

            var id = $"{stream.Code}_{period.Code}_{groupingOrg.Type}_{groupingOrg.Name}_{fundingVersion}";

            var financialYearPeriod1920 = new FundingPeriod
            {
                Code      = "FY1920",
                Name      = "Financial Year 2019-20",
                Type      = PeriodType.FinancialYear,
                StartDate = new DateTimeOffset(2019, 4, 1, 0, 0, 0, ukOffset),
                EndDate   = new DateTimeOffset(2020, 3, 30, 0, 0, 0, ukOffset)
            };

            var financialYearPeriod2021 = new FundingPeriod
            {
                Code      = "FY2021",
                Name      = "Financial Year 2020-21",
                Type      = PeriodType.FinancialYear,
                StartDate = new DateTimeOffset(2020, 4, 1, 0, 0, 0, ukOffset),
                EndDate   = new DateTimeOffset(2021, 3, 30, 0, 0, 0, ukOffset)
            };


            return(new LogicalBaseModel
            {
                SchemaUri = "http://example.org/#schema",
                SchemaVersion = schemaVersion,
                Funding = new FundingProvider
                {
                    FundingStream = stream,
                    FundingPeriod = period,
                    OrganisationGroup = groupingOrg,
                    Id = id,
                    FundingVersion = fundingVersion,

                    ExternalPublicationDate = new DateTimeOffset(2019, 9, 1, 0, 0, 0, new TimeSpan(1, 0, 0)),
                    PaymentDate = DateTimeOffset.Now,

                    Status = FundingStatus.Released,
                    StatusChangedDate = DateTimeOffset.Now,
                    GroupingReason = GroupingReason.Payment,
                    FundingValue = new FundingValue
                    {
                        FundingValueByDistributionPeriod = new List <FundingValueByDistributionPeriod>
                        {
                            new FundingValueByDistributionPeriod
                            {
                                DistributionPeriodCode = financialYearPeriod1920.Code,
                                Value = 1400,
                                FundingLines = new List <FundingLine>
                                {
                                    new FundingLine
                                    {
                                        Name = "Total funding line",
                                        FundingLineCode = "TotalFundingLine",
                                        TemplateLineId = 1,
                                        Type = FundingLineType.Payment,
                                        Value = 1400,
                                        ProfilePeriods = new List <FundingLinePeriod>
                                        {
                                            new FundingLinePeriod
                                            {
                                                Occurence = 1,
                                                Year = 2019,
                                                TypeValue = "October",
                                                ProfiledValue = 1400,
                                                Type = FundingLinePeriodType.CalendarMonth,
                                                PeriodCode = financialYearPeriod1920.Code
                                            }
                                        },
                                    }
                                }
                            },
                            new FundingValueByDistributionPeriod
                            {
                                DistributionPeriodCode = financialYearPeriod2021.Code,
                                Value = 1000,
                                FundingLines = new List <FundingLine>
                                {
                                    new FundingLine
                                    {
                                        Name = "Total funding line",
                                        FundingLineCode = "FundingLineCode2",
                                        TemplateLineId = 1,
                                        Type = FundingLineType.Payment,
                                        Value = 1000,
                                        ProfilePeriods = new List <FundingLinePeriod>
                                        {
                                            new FundingLinePeriod
                                            {
                                                Occurence = 1,
                                                Year = 2020,
                                                TypeValue = "April",
                                                ProfiledValue = 1000,
                                                Type = FundingLinePeriodType.CalendarMonth,
                                                PeriodCode = financialYearPeriod2021.Code
                                            }
                                        }
                                    }
                                }
                            }
                        },
                        TotalValue = 2400
                    },
                    ProviderFundings = new List <ProviderFunding>
                    {
                        new ProviderFunding
                        {
                            Id = $"{stream.Code}_{period.Code}_87654321_{fundingVersion}",
                            FundingVersion = fundingVersion,

                            FundingPeriodCode = period.Code,
                            FundingStreamCode = stream.Code,
                            Organisation = new Organisation
                            {
                                Name = "Example School 1",
                                SearchableName = "ExampleSchool1",
                                ProviderType = "School",
                                Identifiers = new List <OrganisationIdentifier>
                                {
                                    new OrganisationIdentifier
                                    {
                                        Type = OrganisationIdentifierType.URN,
                                        Value = "123453"
                                    },
                                    new OrganisationIdentifier
                                    {
                                        Type = OrganisationIdentifierType.UKPRN,
                                        Value = "87654321"
                                    }
                                }
                            },
                            FundingValue = new FundingValue
                            {
                                TotalValue = 1200,
                                FundingValueByDistributionPeriod = new List <FundingValueByDistributionPeriod>
                                {
                                    new FundingValueByDistributionPeriod
                                    {
                                        DistributionPeriodCode = financialYearPeriod1920.Code,
                                        Value = 700,
                                        FundingLines = new List <FundingLine>
                                        {
                                            new FundingLine
                                            {
                                                Name = "Total funding line",
                                                FundingLineCode = "TotalFundingLine",
                                                TemplateLineId = 1,
                                                Type = FundingLineType.Payment,
                                                Value = 700,
                                                ProfilePeriods = new List <FundingLinePeriod>
                                                {
                                                    new FundingLinePeriod
                                                    {
                                                        Occurence = 1,
                                                        Year = 2019,
                                                        TypeValue = "October",
                                                        ProfiledValue = 700,
                                                        Type = FundingLinePeriodType.CalendarMonth,
                                                        PeriodCode = financialYearPeriod1920.Code
                                                    }
                                                },
                                                Calculations = new List <Calculation>
                                                {
                                                    new Calculation
                                                    {
                                                        Name = "Number of pupils",
                                                        Type = CalculationType.PupilNumber,
                                                        TemplateCalculationId = 1,
                                                        Value = "456",
                                                        ValueFormat = CalculationValueFormat.Number,
                                                        FormulaText = "Something * something",
                                                        ReferenceData = new List <ReferenceData>
                                                        {
                                                            new ReferenceData
                                                            {
                                                                Name = "Academic year 2018 to 2019 pupil number on roll",
                                                                Value = "1",
                                                                Format = ReferenceDataValueFormat.Number,
                                                                TemplateReferenceId = 1,
                                                            }
                                                        }
                                                    },
                                                    new Calculation
                                                    {
                                                        Name = "Number of pupils",
                                                        Type = CalculationType.PupilNumber,
                                                        TemplateCalculationId = 1,
                                                        Value = "456",
                                                        ValueFormat = CalculationValueFormat.Number,
                                                        FormulaText = "Something * something",
                                                        ReferenceData = new List <ReferenceData>
                                                        {
                                                            new ReferenceData
                                                            {
                                                                Name = "Academic year 2018 to 2019 pupil number on roll",
                                                                Value = "1",
                                                                Format = ReferenceDataValueFormat.Number,
                                                                TemplateReferenceId = 2,
                                                            }
                                                        }
                                                    }
                                                },
                                            }
                                        }
                                    },
                                    new FundingValueByDistributionPeriod
                                    {
                                        DistributionPeriodCode = financialYearPeriod2021.Code,
                                        Value = 500,
                                        FundingLines = new List <FundingLine>
                                        {
                                            new FundingLine
                                            {
                                                Name = "Total funding line",
                                                FundingLineCode = "TotalFundingLine2",
                                                TemplateLineId = 1,
                                                Type = FundingLineType.Payment,
                                                Value = 500,
                                                ProfilePeriods = new List <FundingLinePeriod>
                                                {
                                                    new FundingLinePeriod
                                                    {
                                                        Occurence = 1,
                                                        Year = 2020,
                                                        TypeValue = "April",
                                                        ProfiledValue = 500,
                                                        Type = FundingLinePeriodType.CalendarMonth,
                                                        PeriodCode = financialYearPeriod2021.Code
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            },
                        },
                        new ProviderFunding
                        {
                            Id = $"{stream.Code}_{period.Code}_87654322_{fundingVersion}",
                            FundingVersion = fundingVersion,

                            FundingPeriodCode = period.Code,
                            FundingStreamCode = stream.Code,
                            Organisation = new Organisation
                            {
                                Name = "Example School 2",
                                SearchableName = "ExampleSchool2",
                                ProviderType = "School",
                                Identifiers = new List <OrganisationIdentifier>
                                {
                                    new OrganisationIdentifier
                                    {
                                        Type = OrganisationIdentifierType.URN,
                                        Value = "123453"
                                    },
                                    new OrganisationIdentifier
                                    {
                                        Type = OrganisationIdentifierType.UKPRN,
                                        Value = "87654322"
                                    }
                                }
                            },
                            FundingValue = new FundingValue
                            {
                                TotalValue = 1200,
                                FundingValueByDistributionPeriod = new List <FundingValueByDistributionPeriod>
                                {
                                    new FundingValueByDistributionPeriod
                                    {
                                        DistributionPeriodCode = financialYearPeriod1920.Code,
                                        Value = 700,
                                        FundingLines = new List <FundingLine>
                                        {
                                            new FundingLine
                                            {
                                                Name = "Total funding line",
                                                FundingLineCode = "TotalFundingLine",
                                                TemplateLineId = 1,
                                                Type = FundingLineType.Payment,
                                                Value = 700,
                                                ProfilePeriods = new List <FundingLinePeriod>
                                                {
                                                    new FundingLinePeriod
                                                    {
                                                        Occurence = 1,
                                                        Year = 2019,
                                                        TypeValue = "October",
                                                        ProfiledValue = 700,
                                                        Type = FundingLinePeriodType.CalendarMonth,
                                                        PeriodCode = financialYearPeriod1920.Code
                                                    }
                                                }
                                            }
                                        }
                                    },
                                    new FundingValueByDistributionPeriod
                                    {
                                        DistributionPeriodCode = financialYearPeriod2021.Code,
                                        Value = 500,
                                        FundingLines = new List <FundingLine>
                                        {
                                            new FundingLine
                                            {
                                                Name = "Total funding line",
                                                FundingLineCode = "TotalFundingLine2",
                                                TemplateLineId = 1,
                                                Type = FundingLineType.Payment,
                                                Value = 500,
                                                ProfilePeriods = new List <FundingLinePeriod>
                                                {
                                                    new FundingLinePeriod
                                                    {
                                                        Occurence = 1,
                                                        Year = 2020,
                                                        TypeValue = "April",
                                                        ProfiledValue = 500,
                                                        Type = FundingLinePeriodType.CalendarMonth,
                                                        PeriodCode = financialYearPeriod2021.Code
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            });
        }
Exemple #29
0
        /// <summary>
        /// Get the provider funding from the spreadsheet
        /// </summary>
        /// <param name="id">The id to lookup.</param>
        /// <returns>A provider funding object.</returns>
        public static ProviderFunding GenerateProviderFunding(string id)
        {
            var idParts = id.Split('_');
            var code    = idParts[2].Replace("MOCKUKPRN", string.Empty);

            var ukOffset = new TimeSpan(0, 0, 0);

            var period = new FundingPeriod
            {
                Code      = "AY1920",
                Name      = "Academic year 2019-20",
                Type      = PeriodType.AcademicYear,
                StartDate = new DateTimeOffset(2019, 9, 1, 0, 0, 0, ukOffset),
                EndDate   = new DateTimeOffset(2020, 8, 31, 0, 0, 0, ukOffset)
            };

            var templateVersion = "1.0";

            var stream = new StreamWithTemplateVersion
            {
                Code            = "PESports",
                Name            = "PE + Sport Premium",
                TemplateVersion = templateVersion,
            };

            var financialYearPeriod1920 = new FundingPeriod
            {
                Code      = "FY1920",
                Name      = "Financial Year 2019-20",
                Type      = PeriodType.FinancialYear,
                StartDate = new DateTimeOffset(2019, 4, 1, 0, 0, 0, ukOffset),
                EndDate   = new DateTimeOffset(2020, 3, 30, 0, 0, 0, ukOffset)
            };

            var financialYearPeriod2021 = new FundingPeriod
            {
                Code      = "FY2021",
                Name      = "Financial Year 2020-21",
                Type      = PeriodType.FinancialYear,
                StartDate = new DateTimeOffset(2020, 4, 1, 0, 0, 0, ukOffset),
                EndDate   = new DateTimeOffset(2021, 3, 30, 0, 0, 0, ukOffset)
            };

            var processFile = new ProcessPesportsCsv();

            var orgGroups = new List <OrgGroup>();

            orgGroups.AddRange(processFile.GetOrgsOrOrgGroups("MaintainedSchools.csv", true));
            orgGroups.AddRange(processFile.GetOrgsOrOrgGroups("Academies.csv", false));
            orgGroups.AddRange(processFile.GetOrgsOrOrgGroups("MaintainedSchools.csv", false));

            foreach (var orgGroup in orgGroups)
            {
                foreach (var provider in orgGroup.Providers)
                {
                    if (provider.LaEstablishmentNo == code)
                    {
                        return(GetProviderFunding(provider, financialYearPeriod1920, financialYearPeriod2021, period, stream, orgGroup.Type, orgGroup.Code));
                    }
                }
            }

            return(null);
        }
Exemple #30
0
        /// <summary>
        /// Process org groups into feed models.
        /// </summary>
        /// <param name="orgGroups">List of org groups.</param>
        /// <param name="providerType">The provider types we are looking at.</param>
        /// <param name="financialYearPeriod1920">Data about the first financial period.</param>
        /// <param name="financialYearPeriod2021">Data about the second financial period.</param>
        /// <param name="period">Period to use.</param>
        /// <param name="stream">Stream to use.</param>
        /// <param name="schemaVersion">Schema version number.</param>
        /// <param name="fundingVersion">Funding version number.</param>
        /// <param name="organisationGroupIdentifiers">Optional - The group identifiers to limit by (e.g. UKPRN 12345678).</param>
        /// <param name="organisationIdentifiers">Optional - The organisation identifiers to limit to (e.g. UKPRN 12345678).</param>
        /// <param name="organisationTypes">Optional - The organisation types to return.</param>
        /// <param name="variationReasons">Optional - Filter to only organisations with these variation reasons types</param>
        /// <param name="ukprns">Optional - Only get these UKPRNs back.</param>
        /// <param name="fundingLineTypes">Optional - limit the types of lines we want to get back (e.g. Information and/or Payment).</param>
        /// <param name="templateLineIds">Optional - Filter the lines to these ids only.</param>
        /// <returns>A list of feed response models.</returns>
        private static List <FeedResponseContentModel> ProcessOrgGroups(List <OrgGroup> orgGroups, string providerType, FundingPeriod financialYearPeriod1920,
                                                                        FundingPeriod financialYearPeriod2021, FundingPeriod period, StreamWithTemplateVersion stream, string schemaVersion, string fundingVersion,
                                                                        OrganisationIdentifier[] organisationGroupIdentifiers, OrganisationIdentifier[] organisationIdentifiers, OrganisationType[] organisationTypes,
                                                                        VariationReason[] variationReasons, string[] ukprns, FundingLineType[] fundingLineTypes, string[] templateLineIds)
        {
            var returnList = new List <FeedResponseContentModel>();

            // Limit by org group identifiers
            if (organisationGroupIdentifiers?.Any() == true)
            {
                foreach (var organisationGroupIdentifier in organisationGroupIdentifiers)
                {
                    orgGroups = orgGroups.Where(orgGroup => orgGroup.Type != organisationGroupIdentifier.Type.ToString() ||
                                                orgGroup.Code == organisationGroupIdentifier.Value).ToList();
                }
            }

            // Limit by org identifiers
            if (organisationIdentifiers?.Any() == true)
            {
                foreach (var orgGroup in orgGroups)
                {
                    orgGroup.Providers = orgGroup.Providers.Where(provider =>
                                                                  organisationIdentifiers.Any(oi => oi.Type != OrganisationIdentifierType.LACode || oi.Value == provider.LaEstablishmentNo)).ToList();
                }
            }

            foreach (var orgGroup in orgGroups)
            {
                var orgType = providerType == "NonMaintainedSpecialSchools" || providerType == "Academies" ?
                              (providerType == "NonMaintainedSpecialSchools" ? OrganisationType.Provider : OrganisationType.AcademyTrust) : OrganisationType.LocalAuthority;

                var ukprn = $"MOCKUKPRN{orgGroup.Code}";

                var groupingOrg = ConvertToOrganisationGroup(orgGroup, ukprn, orgType);
                var id          = $"{stream.Code}_{period.Code}_{groupingOrg.Type}_{ukprn}_{fundingVersion}";

                var data = new FeedBaseModel
                {
                    SchemaUri     = "http://example.org/#schema",
                    SchemaVersion = schemaVersion,
                    Funding       = new FundingFeed
                    {
                        Id = id,

                        FundingStream     = stream,
                        FundingPeriod     = period,
                        OrganisationGroup = groupingOrg,
                        FundingVersion    = fundingVersion.Replace("-", "."),

                        ExternalPublicationDate = new DateTimeOffset(2019, 9, 1, 0, 0, 0, new TimeSpan(1, 0, 0)),
                        PaymentDate             = DateTimeOffset.Now,

                        Status            = FundingStatus.Released,
                        StatusChangedDate = DateTimeOffset.Now,
                        GroupingReason    = GroupingReason.Payment,
                        ProviderFundings  = GetProviderFundingIds(orgGroup, period, stream, fundingVersion, organisationTypes, variationReasons, ukprns),
                        FundingValue      = new FundingValue
                        {
                            TotalValue = orgGroup.TotalAllocation,
                            FundingValueByDistributionPeriod = new List <FundingValueByDistributionPeriod>
                            {
                                new FundingValueByDistributionPeriod
                                {
                                    DistributionPeriodCode = financialYearPeriod1920.Code,
                                    Value        = orgGroup.OctoberTotal,
                                    FundingLines = new List <FundingLine>
                                    {
                                        new FundingLine
                                        {
                                            Name           = "Total funding line",
                                            TemplateLineId = 1,
                                            Type           = FundingLineType.Payment,
                                            Value          = orgGroup.OctoberTotal,
                                            ProfilePeriods = new List <FundingLinePeriod>
                                            {
                                                new FundingLinePeriod
                                                {
                                                    Occurence     = 1,
                                                    Year          = 2019,
                                                    TypeValue     = "October",
                                                    ProfiledValue = orgGroup.OctoberTotal,
                                                    Type          = FundingLinePeriodType.CalendarMonth,
                                                    PeriodCode    = financialYearPeriod1920.Code
                                                }
                                            },
                                        }
                                    }
                                },
                                new FundingValueByDistributionPeriod
                                {
                                    DistributionPeriodCode = financialYearPeriod2021.Code,
                                    Value        = orgGroup.AprilTotal,
                                    FundingLines = new List <FundingLine>
                                    {
                                        new FundingLine
                                        {
                                            Name           = "Total funding line",
                                            TemplateLineId = 2,
                                            Type           = FundingLineType.Payment,
                                            Value          = orgGroup.AprilTotal,
                                            ProfilePeriods = new List <FundingLinePeriod>
                                            {
                                                new FundingLinePeriod
                                                {
                                                    Occurence     = 1,
                                                    Year          = 2020,
                                                    TypeValue     = "April",
                                                    ProfiledValue = orgGroup.AprilTotal,
                                                    Type          = FundingLinePeriodType.CalendarMonth,
                                                    PeriodCode    = financialYearPeriod2021.Code
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                };

                if (fundingLineTypes?.Any() == true)
                {
                    foreach (var dperiod in data.Funding.FundingValue.FundingValueByDistributionPeriod)
                    {
                        dperiod.FundingLines = dperiod.FundingLines.Where(line => fundingLineTypes.Contains(line.Type)).ToList();

                        //TODO - filter at lower levels
                    }
                }

                if (templateLineIds?.Any() == true)
                {
                    foreach (var dperiod in data.Funding.FundingValue.FundingValueByDistributionPeriod)
                    {
                        dperiod.FundingLines = dperiod.FundingLines.Where(line => templateLineIds.Contains(line.TemplateLineId.ToString())).ToList();

                        //TODO - filter at lower levels
                    }
                }

                var host = "http://example.org";

                returnList.Add(new FeedResponseContentModel
                {
                    Content = data,
                    Id      = data.Funding.Id,
                    Author  = new FeedResponseAuthor
                    {
                        Email = "*****@*****.**",
                        Name  = "Calculate Funding Service"
                    },
                    Title   = data.Funding.Id,
                    Updated = DateTime.Now,
                    Link    = new FeedLink[]
                    {
                        new FeedLink
                        {
                            Href = $"{host}/api/funding/feed/byId/{data.Funding.Id}",
                            Rel  = "self"
                        }
                    }
                });
            }
            ;

            return(returnList);
        }