From 759512e592df55fdde5b50289d713e2d4e25e828 Mon Sep 17 00:00:00 2001 From: Dominic NEED Date: Mon, 11 Dec 2023 15:05:12 +0000 Subject: [PATCH 1/2] Spreadsheet download --- .../Dfe.PrepareConversions.Data.csproj | 1 + .../Features/ApiClient.cs | 5 ++- .../Features/IApiClient.cs | 1 + .../Features/PathFor.cs | 1 + .../AcademyConversionProjectRepository.cs | 31 +++++++++++++++++++ .../IAcademyConversionProjectRepository.cs | 10 ++++++ .../Services/SchoolOverviewService.cs | 1 + .../Pages/ProjectList/Index.cshtml.cs | 15 +++++++++ .../Pages/Shared/_ProjectListFilters.cshtml | 1 + ...emyConversionProjectItemsCacheDecorator.cs | 14 ++++++++- 10 files changed, 78 insertions(+), 2 deletions(-) diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Dfe.PrepareConversions.Data.csproj b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Dfe.PrepareConversions.Data.csproj index 5d96222ec..a5464137a 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Dfe.PrepareConversions.Data.csproj +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Dfe.PrepareConversions.Data.csproj @@ -14,6 +14,7 @@ + diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/ApiClient.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/ApiClient.cs index 7bd02a7a4..126af9dbb 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/ApiClient.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/ApiClient.cs @@ -28,7 +28,10 @@ public async Task GetAllProjectsAsync(AcademyConversionSear { return await AcademisationClient.PostAsync(PathFor.GetAllProjects, JsonContent.Create(searchModel)); } - + public async Task DownloadProjectExport(AcademyConversionSearchModel searchModel) + { + return await AcademisationClient.PostAsync(PathFor.DownloadProjectExport, JsonContent.Create(searchModel)); + } public async Task GetProjectByIdAsync(int id) { diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/IApiClient.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/IApiClient.cs index d3bd46693..deeb6a457 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/IApiClient.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/IApiClient.cs @@ -7,6 +7,7 @@ namespace Dfe.PrepareConversions.Data.Features; public interface IApiClient { Task GetAllProjectsAsync(AcademyConversionSearchModel searchModel); + Task DownloadProjectExport(AcademyConversionSearchModel searchModel); Task GetProjectByIdAsync(int id); Task UpdateProjectAsync(int id, UpdateAcademyConversionProject updateProject); Task GetFilterParametersAsync(); diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/PathFor.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/PathFor.cs index 57679fc85..44665cf8f 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/PathFor.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Features/PathFor.cs @@ -12,6 +12,7 @@ public PathFor(IFeatureManager features) } public string GetApplicationByReference => _useAcademisationApplication ? "/application/{0}/applicationReference" : "/v2/apply-to-become/application/{0}"; public static string GetAllProjects => "/legacy/projects"; + public static string DownloadProjectExport => "/export/export-projects"; public static string GetProjectById => "/legacy/project/{0}"; public static string UpdateProject => "/legacy/project/{0}"; public static string GetFilterParameters => "/legacy/projects/status"; diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/AcademyConversionProjectRepository.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/AcademyConversionProjectRepository.cs index 696da5d10..c153ab854 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/AcademyConversionProjectRepository.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/AcademyConversionProjectRepository.cs @@ -4,6 +4,7 @@ using Dfe.PrepareConversions.Data.Models; using Dfe.PrepareConversions.Data.Models.NewProject; using Dfe.PrepareConversions.Data.Services.Interfaces; +using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; using System.Linq; using System.Net.Http; @@ -132,6 +133,36 @@ public async Task> AddProjectNote(int id, AddProjectNot ? new ApiResponse(response.StatusCode, addProjectNote.ToProjectNote()) : new ApiResponse(response.StatusCode, null); } + public async Task> DownloadProjectExport( + int page, + int count, + string titleFilter = "", + IEnumerable statusFilters = default, + IEnumerable deliveryOfficerFilter = default, + IEnumerable regionsFilter = default, + IEnumerable applicationReferences = default) + { + AcademyConversionSearchModel searchModel = new() { TitleFilter = titleFilter, Page = page, Count = count }; + + ProcessFilters(statusFilters, deliveryOfficerFilter, searchModel, regionsFilter, applicationReferences); + + HttpResponseMessage response = await _apiClient.DownloadProjectExport(searchModel); + if (!response.IsSuccessStatusCode) + { + // handle error, for example: + return new ApiResponse(response.StatusCode, null); + } + + // Assuming response.Content is of type HttpContent, you need to read it as a stream. + var stream = await response.Content.ReadAsStreamAsync(); + + // Now create FileStreamResult from the stream. + FileStreamResult fileStreamResult = new FileStreamResult(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + + // Return ApiResponse with FileStreamResult. + return new ApiResponse(response.StatusCode, fileStreamResult); + } + private void ProcessFilters(IEnumerable statusFilters, IEnumerable deliveryOfficerFilter, diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/IAcademyConversionProjectRepository.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/IAcademyConversionProjectRepository.cs index 90edc53bc..bb13e3609 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/IAcademyConversionProjectRepository.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/IAcademyConversionProjectRepository.cs @@ -1,5 +1,6 @@ using Dfe.PrepareConversions.Data.Models; using Dfe.PrepareConversions.Data.Models.NewProject; +using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; using System.Threading.Tasks; @@ -16,6 +17,15 @@ Task>>> GetAllPro IEnumerable regionsFilter = default, IEnumerable applicationReferences = default ); + Task> DownloadProjectExport( + int page, + int count, + string titleFilter = "", + IEnumerable statusFilters = default, + IEnumerable deliveryOfficerFilter = default, + IEnumerable regionsFilter = default, + IEnumerable applicationReferences = default +); Task> GetProjectById(int id); Task> UpdateProject(int id, UpdateAcademyConversionProject updateProject); diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/SchoolOverviewService.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/SchoolOverviewService.cs index dad813df8..ae0690a26 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/SchoolOverviewService.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/SchoolOverviewService.cs @@ -16,6 +16,7 @@ public SchoolOverviewService(IGetEstablishment getEstablishment) public async Task GetSchoolOverviewByUrn(string urn) { + // TODO: Technical Debt - enrich EstablishmentDto establishment = await _getEstablishment.GetEstablishmentByUrn(urn); SchoolOverview schoolOverview = new() { diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/ProjectList/Index.cshtml.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/ProjectList/Index.cshtml.cs index aa22e465b..cc20b185f 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/ProjectList/Index.cshtml.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/ProjectList/Index.cshtml.cs @@ -51,4 +51,19 @@ public async Task OnGetAsync() Filters.AvailableRegions = filterParametersResponse.Body.Regions; } } + public async Task OnGetDownload() + { + Filters.PersistUsing(TempData).PopulateFrom(Request.Query); + ApiResponse response = await _repository.DownloadProjectExport(CurrentPage, PageSize, Filters.Title, Filters.SelectedStatuses, Filters.SelectedOfficers, Filters.SelectedRegions); + + if (response.Success) + { + return response.Body; + } + else + { + return null; + } + } + } diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/Shared/_ProjectListFilters.cshtml b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/Shared/_ProjectListFilters.cshtml index 057728afa..c4ec39056 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/Shared/_ProjectListFilters.cshtml +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Pages/Shared/_ProjectListFilters.cshtml @@ -6,6 +6,7 @@ Filter projects + Download as a spreadsheet
diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions/Services/AcademyConversionProjectItemsCacheDecorator.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions/Services/AcademyConversionProjectItemsCacheDecorator.cs index bd4d91ea3..9d262a695 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions/Services/AcademyConversionProjectItemsCacheDecorator.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions/Services/AcademyConversionProjectItemsCacheDecorator.cs @@ -3,6 +3,7 @@ using Dfe.PrepareConversions.Data.Models.NewProject; using Dfe.PrepareConversions.Data.Services; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; using System.Threading.Tasks; @@ -26,7 +27,18 @@ public async Task { return await _innerRepository.GetAllProjects(page, count, titleFilter, statusFilters, deliveryOfficerFilter, regionsFilter, applicationReferences); } - + public async Task> DownloadProjectExport( + int page, + int count, + string titleFilter = "", + IEnumerable statusFilters = default, + IEnumerable deliveryOfficerFilter = default, + IEnumerable regionsFilter = default, + IEnumerable applicationReferences = default +) + { + return await _innerRepository.DownloadProjectExport(page, count, titleFilter, statusFilters, deliveryOfficerFilter, regionsFilter, applicationReferences); + } public async Task> GetProjectById(int id) { if (_httpContext.Items.ContainsKey(id) && _httpContext.Items[id] is ApiResponse cached) From a82a79e929a1f20336ea99f4e4a36e3fbe2ab489 Mon Sep 17 00:00:00 2001 From: Dominic NEED Date: Mon, 11 Dec 2023 15:13:58 +0000 Subject: [PATCH 2/2] Updated to remove uneeded comments --- .../Services/AcademyConversionProjectRepository.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/AcademyConversionProjectRepository.cs b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/AcademyConversionProjectRepository.cs index c153ab854..ece4d9f56 100644 --- a/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/AcademyConversionProjectRepository.cs +++ b/Dfe.PrepareConversions/Dfe.PrepareConversions.Data/Services/AcademyConversionProjectRepository.cs @@ -149,17 +149,12 @@ public async Task> DownloadProjectExport( HttpResponseMessage response = await _apiClient.DownloadProjectExport(searchModel); if (!response.IsSuccessStatusCode) { - // handle error, for example: return new ApiResponse(response.StatusCode, null); } - // Assuming response.Content is of type HttpContent, you need to read it as a stream. var stream = await response.Content.ReadAsStreamAsync(); + FileStreamResult fileStreamResult = new(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); - // Now create FileStreamResult from the stream. - FileStreamResult fileStreamResult = new FileStreamResult(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); - - // Return ApiResponse with FileStreamResult. return new ApiResponse(response.StatusCode, fileStreamResult); }