public async Task <IActionResult> PublishBatchProvidersFunding(string specificationId, PublishedProviderIdsRequest publishedProviderIdsRequest, Reference user, string correlationId) { ValidationResult specificationIdValidationResult = SpecificationIdValidator.Validate(specificationId); if (!specificationIdValidationResult.IsValid) { return(specificationIdValidationResult.AsBadRequest()); } ValidationResult publishedProviderIdsValidationResult = PublishedProviderIdsValidator.Validate(publishedProviderIdsRequest.PublishedProviderIds.ToArray()); if (!publishedProviderIdsValidationResult.IsValid) { return(publishedProviderIdsValidationResult.AsBadRequest()); } IActionResult actionResult = await IsSpecificationReadyForPublish(specificationId, ApprovalMode.Batches); if (!actionResult.IsOk()) { return(actionResult); } await FilterOutPublishedProvidersInError(publishedProviderIdsRequest); ApiJob job = await _createBatchPublishProviderFundingJobs.CreateJob(specificationId, user, correlationId, messageBody : JsonExtensions.AsJson(publishedProviderIdsRequest), compress : true); return(ProcessJobResponse(job, specificationId, JobConstants.DefinitionNames.PublishBatchProviderFundingJob)); }
public void SetUp() { _approveSpecificationFundingJobs = Substitute.For <ICreateApproveAllFundingJobs>(); _approveProviderFundingJobs = Substitute.For <ICreateApproveBatchFundingJobs>(); _cacheProvider = Substitute.For <ICacheProvider>(); _specificationFundingStatusService = Substitute.For <ISpecificationFundingStatusService>(); _prerequisiteCheckerLocator = Substitute.For <IPrerequisiteCheckerLocator>(); _prerequisiteChecker = Substitute.For <IPrerequisiteChecker>(); _providerService = Substitute.For <IProviderService>(); _publishedFunding = Substitute.For <IPublishedFundingRepository>(); _service = new SpecificationPublishingService( SpecificationIdValidator, ProviderIdsValidator, _providerService, Specifications, ResiliencePolicies, _cacheProvider, Jobs, _approveSpecificationFundingJobs, _approveProviderFundingJobs, _specificationFundingStatusService, FundingConfigurationService, _prerequisiteCheckerLocator, _publishedFunding); _approveProvidersRequest = BuildApproveProvidersRequest(_ => _.WithProviders(ProviderIds)); }
public async Task <IActionResult> GetProviderDataForBatchReleaseAsCsv(PublishedProviderIdsRequest providerIds, string specificationId) { return(await GetProviderDataAsCsv( providerIds, specificationId, $"ProvidersToRelease-{DateTime.UtcNow:yyyyMMdd-HHmmssffff}", PublishedProviderStatus.Approved)); }
public async Task <IActionResult> ApproveBatchProviderFunding( [FromRoute] string specificationId, [FromBody] PublishedProviderIdsRequest publishedProviderIdsRequest) { return(await _specificationPublishingService.ApproveBatchProviderFunding( specificationId, publishedProviderIdsRequest, Request.GetUser(), GetCorrelationId())); }
private async Task <IActionResult> GetProviderBatchCountForStatuses(PublishedProviderIdsRequest providerIds, string specificationId, params PublishedProviderStatus[] statuses) { PublishedProviderFundingCount fundingCount = await _fundingCountProcessor.GetFundingCount(providerIds.PublishedProviderIds, specificationId, statuses); return(new ObjectResult(fundingCount)); }
public async Task PublishFundingForBatchProviders() { string id = NewRandomString(); PublishedProviderIdsRequest publishProvidersRequest = new PublishedProviderIdsRequest(); await AssertPostRequest($"specifications/{id}/publish-providers", publishProvidersRequest, new JobCreationResponse(), () => _client.PublishFundingForBatchProviders(id, publishProvidersRequest)); }
public async Task GetProviderBatchForApprovalCount_Returns_BadRequestObjectResult_Given_InvalidInputs() { string specificationId = "spec1"; PublishedProviderIdsRequest publishedProviderIds = new PublishedProviderIdsRequest(); _publishingApiClient.GetProviderBatchForApprovalCount(publishedProviderIds, specificationId) .Returns(new ApiResponse <PublishedProviderFundingCount>(HttpStatusCode.BadRequest, null)); IActionResult actual = await _publishController.GetProviderBatchForApprovalCount(publishedProviderIds, specificationId); actual.Should().BeOfType <BadRequestObjectResult>(); }
public async Task GenerateCsvForBatchPublishedProvidersForApproval() { PublishedProviderIdsRequest publishedProviderIdsRequest = new PublishedProviderIdsRequest(); string specificationId = NewRandomString(); await AssertPostRequest( $"specifications/{specificationId}/publishedproviders/generate-csv-for-approval/batch", publishedProviderIdsRequest, new PublishedProviderDataDownload { Url = NewRandomString() }, () => _client.GenerateCsvForBatchPublishedProvidersForApproval(publishedProviderIdsRequest, specificationId)); }
public async Task GetProviderBatchForReleaseCount() { string specificationId = NewRandomString(); PublishedProviderIdsRequest publishProvidersRequest = new PublishedProviderIdsRequest(); await AssertPostRequest($"specifications/{specificationId}/publishedproviders/publishingstatus-for-release", publishProvidersRequest, new PublishedProviderFundingCount { Count = NewRandomInt(), TotalFunding = NewRandomInt() }, () => _client.GetProviderBatchForReleaseCount(publishProvidersRequest, specificationId)); }
public async Task GetProviderBatchForApprovalCount_Returns_OkObjectResult_Given_ValidSpecificationIdAndPublishProviderIds() { string specificationId = "Specification-Id"; PublishedProviderIdsRequest publishedProviderIds = new PublishedProviderIdsRequest() { PublishedProviderIds = new[] { "p1" } }; _publishingApiClient.GetProviderBatchForApprovalCount(publishedProviderIds, specificationId) .Returns(new ApiResponse <PublishedProviderFundingCount>(HttpStatusCode.OK, new PublishedProviderFundingCount())); IActionResult actual = await _publishController.GetProviderBatchForApprovalCount(publishedProviderIds, specificationId); actual.Should().BeOfType <OkObjectResult>(); }
public async Task <IActionResult> GetProviderDataForAllReleaseAsCsv(string specificationId) { IEnumerable <string> publishedProviderIds = await _publishedFundingRepositoryResilience.ExecuteAsync(() => _publishedFundingRepository.GetPublishedProviderPublishedProviderIds(specificationId)); PublishedProviderIdsRequest publishedProviderIdsRequest = new PublishedProviderIdsRequest { PublishedProviderIds = publishedProviderIds }; return(await GetProviderDataAsCsv( publishedProviderIdsRequest, specificationId, $"ProvidersToRelease-{DateTime.UtcNow:yyyyMMdd-HHmmssffff}", PublishedProviderStatus.Approved)); }
public async Task PublishProviderFundingResults(Message message, bool batched = false) { Guard.ArgumentNotNull(message, nameof(message)); string logMessage = batched ? "Batch" : "All"; _logger.Information($"Starting Publish{logMessage}ProviderFundingResults job"); Reference author = message.GetUserDetails(); string specificationId = message.UserProperties["specification-id"] as string; SpecificationSummary specification = await _specificationService.GetSpecificationSummaryById(specificationId); if (specification == null) { throw new NonRetriableException($"Could not find specification with id '{specificationId}'"); } string correlationId = message.GetUserProperty <string>(SfaCorrelationId); PublishedProviderIdsRequest publishedProviderIdsRequest = null; if (batched) { publishedProviderIdsRequest = message.GetPayloadAsInstanceOf <PublishedProviderIdsRequest>(); } foreach (Reference fundingStream in specification.FundingStreams) { await PublishFundingStream(fundingStream, specification, Job.Id, author, correlationId, batched?PrerequisiteCheckerType.ReleaseBatchProviders : PrerequisiteCheckerType.ReleaseAllProviders, publishedProviderIdsRequest?.PublishedProviderIds?.ToArray()); } _logger.Information($"Running search reindexer for published funding"); await _publishedIndexSearchResiliencePolicy.ExecuteAsync(() => _publishedFundingSearchRepository.RunIndexer()); await GenerateCsvJobs(specificationId, correlationId, specification, author); }
public void SetUp() { _publishedFundingRepository = Substitute.For <IPublishedFundingRepository>(); _createBatchPublishProviderFundingJobs = Substitute.For <ICreateBatchPublishProviderFundingJobs>(); _createPublishIntegrityJob = Substitute.For <ICreatePublishIntegrityJob>(); _service = new ProviderFundingPublishingService( SpecificationIdValidator, ProviderIdsValidator, Specifications, ResiliencePolicies, Jobs, _createBatchPublishProviderFundingJobs, _publishedFundingRepository, FundingConfigurationService, _createPublishIntegrityJob); _publishProvidersRequest = BuildPublishProvidersRequest(_ => _.WithProviders(ProviderIds)); }
public async Task WhenPartialFundingIsApproved(Table table) { Message message = new Message(); string[] providerIds = table.AsStrings(); PublishedProviderIdsRequest approveProvidersRequest = new PublishedProviderIdsRequest { PublishedProviderIds = providerIds }; string approveProvidersRequestJson = JsonExtensions.AsJson(approveProvidersRequest); message.UserProperties.Add("user-id", _currentUserStepContext.UserId); message.UserProperties.Add("user-name", _currentUserStepContext.UserName); message.UserProperties.Add("specification-id", _currentSpecificationStepContext.SpecificationId); message.UserProperties.Add("jobId", _currentJobStepContext.JobId); message.Body = Encoding.UTF8.GetBytes(approveProvidersRequestJson); await _approveService.Run(message, async() => { await _approveService.ApproveResults(message, batched: true); }); }
public async Task ApproveResults(Message message, bool batched = false) { Guard.ArgumentNotNull(message, nameof(message)); _logger.Information("Starting approve provider funding job"); string specificationId = message.GetUserProperty <string>("specification-id"); PublishedProviderIdsRequest publishedProviderIdsRequest = null; string logApproveProcessingMessage = $"Processing approve specification funding job. JobId='{Job.Id}'. SpecificationId='{specificationId}'."; if (batched) { publishedProviderIdsRequest = message.GetPayloadAsInstanceOf <PublishedProviderIdsRequest>(); logApproveProcessingMessage += $" Request = {JsonExtensions.AsJson(publishedProviderIdsRequest)}."; } await PerformPrerequisiteChecks(specificationId, Job.Id, batched == true?PrerequisiteCheckerType.ApproveBatchProviders : PrerequisiteCheckerType.ApproveAllProviders); _logger.Information(logApproveProcessingMessage); _logger.Information("Fetching published providers for specification funding approval"); IEnumerable <PublishedProvider> publishedProviders = await GetPublishedProvidersForApproval(specificationId, publishedProviderIdsRequest?.PublishedProviderIds?.ToArray()); CheckPublishedProviderForErrors(specificationId, publishedProviders); Reference author = message.GetUserDetails(); string correlationId = message.GetUserProperty <string>(SfaCorrelationId); await ApproveProviders(publishedProviders, specificationId, Job.Id, author, correlationId); }
public async Task GenerateCsvForBatchPublishedProvidersForReleaseDelegatesToPublishingEndPoint() { string specificationId = NewRandomString(); PublishedProviderIdsRequest request = new PublishedProviderIdsRequest { PublishedProviderIds = new List <string> { NewRandomString() } }; PublishedProviderDataDownload expectedResponse = new PublishedProviderDataDownload(); _publishingApiClient.GenerateCsvForBatchPublishedProvidersForRelease(Arg.Is(request), Arg.Is(specificationId)) .Returns(new ApiResponse <PublishedProviderDataDownload>(HttpStatusCode.OK, expectedResponse)); OkObjectResult result = await _publishController.GenerateCsvForBatchPublishedProvidersForRelease(request, specificationId) as OkObjectResult; result? .Value .Should() .BeSameAs(expectedResponse); }
public async Task <IActionResult> GenerateCsvForBatchPublishedProvidersForRelease( [FromBody] PublishedProviderIdsRequest providerIds, [FromRoute] string specificationId) { return(await _publishedProviderStatusService.GetProviderDataForBatchReleaseAsCsv(providerIds, specificationId)); }
private async Task <IActionResult> GetProviderDataAsCsv(PublishedProviderIdsRequest providerIds, string specificationId, string csvFileSuffix, params PublishedProviderStatus[] statuses) { ValidationResult validationResults = _validator.Validate(specificationId); if (!validationResults.IsValid) { return(validationResults.AsBadRequest()); } if (providerIds.PublishedProviderIds.IsNullOrEmpty()) { return(new BadRequestObjectResult("Provider ids must be provided")); } IEnumerable <PublishedProviderFundingCsvData> publishedProviderFundingData = await _fundingCsvDataProcessor.GetFundingData( providerIds.PublishedProviderIds, specificationId, statuses); if (publishedProviderFundingData.IsNullOrEmpty()) { return(new NotFoundObjectResult("No data found for given specification and published provider ids.")); } IEnumerable <dynamic> csvRows = publishedProviderFundingData.Select(x => new { UKPRN = x.Ukprn, URN = x.Urn, UPIN = x.Upin, ProviderName = x.ProviderName, FundingAmount = x.TotalFunding }); string csvFileData = _csvUtils.AsCsv(csvRows, true); string fundingStreamId = publishedProviderFundingData.First().FundingStreamId; string fundingPeriodId = publishedProviderFundingData.First().FundingPeriodId; string csvFileName = $"{fundingStreamId}-{fundingPeriodId}-{csvFileSuffix}.csv"; string blobName = $"{csvFileName}"; string blobUrl = string.Empty; await _blobClientPolicy.ExecuteAsync(async() => { ICloudBlob blob = _blobClient.GetBlockBlobReference(blobName, BlobContainerName); blob.Properties.ContentDisposition = $"attachment; filename={csvFileName}"; using (MemoryStream stream = new MemoryStream(csvFileData.AsUTF8Bytes())) { await blob.UploadFromStreamAsync(stream); } blob.Metadata["fundingStreamId"] = fundingStreamId; blob.Metadata["fundingPeriodId"] = fundingPeriodId; blob.Metadata["specificationId"] = specificationId; blob.Metadata["fileName"] = Path.GetFileNameWithoutExtension(csvFileName); blob.SetMetadata(); blobUrl = _blobClient.GetBlobSasUrl(blobName, DateTimeOffset.Now.AddDays(1), SharedAccessBlobPermissions.Read, BlobContainerName); }); return(new OkObjectResult(new PublishedProviderDataDownload() { Url = blobUrl })); }
public async Task <IActionResult> GetProviderBatchCountForApproval(PublishedProviderIdsRequest providerIds, string specificationId) => await GetProviderBatchCountForStatuses(providerIds, specificationId, PublishedProviderStatus.Draft, PublishedProviderStatus.Updated);
private async Task WhenPublishBatchProvidersMessageReceivedWithJobIdAndCorrelationId(PublishedProviderIdsRequest publishProvidersRequest) { Message message = NewMessage(_ => _ .WithUserProperty("specification-id", SpecificationId) .WithUserProperty("jobId", JobId) .WithUserProperty("sfa-correlationId", CorrelationId) .WithMessageBody(Encoding.UTF8.GetBytes(publishProvidersRequest.AsJson()))); await _publishService.Run(message, async() => { await _publishService.PublishProviderFundingResults(message, batched: true); }); }
private async Task FilterOutPublishedProvidersInError(PublishedProviderIdsRequest providerIdsRequest) { providerIdsRequest.PublishedProviderIds = await ResiliencePolicy.ExecuteAsync(() => _publishedFundingRepository.RemoveIdsInError(providerIdsRequest.PublishedProviderIds)); }
public async Task <IActionResult> GetProviderBatchCountForRelease(PublishedProviderIdsRequest providerIds, string specificationId) => await GetProviderBatchCountForStatuses(providerIds, specificationId, PublishedProviderStatus.Approved);
private async Task WhenPublishIntegrityCheckMessageReceivedWithJobIdAndBatchedProviders(PublishedProviderIdsRequest publishProvidersRequest) { Message message = NewMessage(_ => _ .WithUserProperty("specification-id", SpecificationId) .WithUserProperty("jobId", JobId) .WithUserProperty("sfa-correlationId", CorrelationId) .WithUserProperty("providers-batch", publishProvidersRequest.PublishedProviderIds.AsJson())); await _publishIntegrityService.Run(message); }
private void GivenTheMessageHasTheApproveProvidersRequest(PublishedProviderIdsRequest approveProvidersRequest) { _message.Body = Encoding.UTF8.GetBytes(JsonExtensions.AsJson(approveProvidersRequest)); }
public async Task <IActionResult> GetProviderBatchForApprovalCount( [FromBody] PublishedProviderIdsRequest providerIds, [FromRoute] string specificationId) => await _publishedProviderStatusService.GetProviderBatchCountForApproval(providerIds, specificationId);