From 6f10e9962736b9605c1030e1ee5ea0c861e41827 Mon Sep 17 00:00:00 2001 From: uppuv Date: Wed, 1 Nov 2023 12:42:30 -0400 Subject: [PATCH] added excel export and removed random number --- .../SurveyResponsesServiceTest.cs | 62 +++---- .../Controllers/SurveyResponsesController.cs | 32 +++- .../DamageAssesment.Api.Responses.csproj | 1 + .../Interfaces/IExcelExportService.cs | 7 + .../Interfaces/IQuestionServiceProvider.cs | 3 +- .../Interfaces/ISurveysResponse.cs | 3 +- .../Models/Attachment.cs | 1 + .../Models/Location.cs | 1 + .../Models/QuestionCategory.cs | 10 ++ .../Models/SurveyExport.cs | 24 +++ .../DamageAssesment.Api.Responses/Program.cs | 1 + .../Providers/ExcelExportService.cs | 56 ++++++ .../Providers/SurveyResponsesProvider.cs | 170 ++++++++++++++++-- .../Services/QuestionServiceProvider.cs | 27 ++- .../appsettings.json | 2 +- .../Providers/SurveysProvider.cs | 18 +- 16 files changed, 360 insertions(+), 58 deletions(-) create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IExcelExportService.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Responses/Models/QuestionCategory.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Responses/Models/SurveyExport.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Responses/Providers/ExcelExportService.cs diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses.Test/SurveyResponsesServiceTest.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses.Test/SurveyResponsesServiceTest.cs index 48cec58..05b3e02 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Responses.Test/SurveyResponsesServiceTest.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses.Test/SurveyResponsesServiceTest.cs @@ -12,9 +12,11 @@ namespace DamageAssesment.SurveyResponses.Test public class SurveyResponsesServiceTest { Mock mockSurveyResponseService; + Mock mockExcelExportService; public SurveyResponsesServiceTest() { mockSurveyResponseService = new Mock(); + mockExcelExportService = new Mock(); } [Fact(DisplayName = "Get Responses - Ok case")] @@ -23,7 +25,7 @@ namespace DamageAssesment.SurveyResponses.Test SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); var mockResponse = await MockData.getOkResponse(mockRequestObject); mockSurveyResponseService.Setup(service => service.GetSurveyResponsesAsync(1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); + var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesAsync(1); Assert.Equal(200, result.StatusCode); } @@ -33,7 +35,7 @@ namespace DamageAssesment.SurveyResponses.Test { var mockResponse = await MockData.getResponse(); mockSurveyResponseService.Setup(service => service.GetSurveyResponsesAsync(1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); + var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (BadRequestObjectResult)await surveyResponseProvider.GetSurveyResponsesAsync(1); Assert.Equal(400, result.StatusCode); } @@ -43,9 +45,9 @@ namespace DamageAssesment.SurveyResponses.Test { SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); var mockResponse = await MockData.getOkResponse(); - mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAsync(1,1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); - var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesAsync(1,1); + mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAsync(1, 1)).ReturnsAsync(mockResponse); + var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); + var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesAsync(1, 1); Assert.Equal(200, result.StatusCode); } @@ -53,9 +55,9 @@ namespace DamageAssesment.SurveyResponses.Test public async Task GetSurveyResponsesBySurveyAsync_ShouldReturnStatusCode204() { var mockResponse = await MockData.getResponse(); - mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAsync(1,1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); - var result = (NoContentResult)await surveyResponseProvider.GetSurveyResponsesAsync(1,1); + mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAsync(1, 1)).ReturnsAsync(mockResponse); + var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); + var result = (NoContentResult)await surveyResponseProvider.GetSurveyResponsesAsync(1, 1); Assert.Equal(204, result.StatusCode); } @@ -67,9 +69,9 @@ namespace DamageAssesment.SurveyResponses.Test { SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); var mockResponse = await MockData.getOkResponse(); - mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAndLocationAsync(1, 1,1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); - var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesBySurveyAndLocationAsync(1, 1,1); + mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAndLocationAsync(1, 1, 1)).ReturnsAsync(mockResponse); + var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); + var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesBySurveyAndLocationAsync(1, 1, 1); Assert.Equal(200, result.StatusCode); } @@ -78,7 +80,7 @@ namespace DamageAssesment.SurveyResponses.Test { var mockResponse = await MockData.getResponse(); mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAndLocationAsync(1, 1, 1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); + var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (NoContentResult)await surveyResponseProvider.GetSurveyResponsesBySurveyAndLocationAsync(1, 1, 1); Assert.Equal(204, result.StatusCode); } @@ -88,9 +90,9 @@ namespace DamageAssesment.SurveyResponses.Test { SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); var mockResponse = await MockData.getOkResponse(); - mockSurveyResponseService.Setup(service => service.GetResponsesByAnswerAsync(1, 1, "Yes",1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); - var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesByAnswerAsyncAsync(1, 1, "Yes",1); + mockSurveyResponseService.Setup(service => service.GetResponsesByAnswerAsync(1, 1, "Yes", 1)).ReturnsAsync(mockResponse); + var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); + var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesByAnswerAsyncAsync(1, 1, "Yes", 1); Assert.Equal(200, result.StatusCode); } @@ -99,8 +101,8 @@ namespace DamageAssesment.SurveyResponses.Test { var mockResponse = await MockData.getResponse(); mockSurveyResponseService.Setup(service => service.GetResponsesByAnswerAsync(1, 1, "Yes", 1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); - var result = (NoContentResult)await surveyResponseProvider.GetSurveyResponsesByAnswerAsyncAsync(1, 1, "Yes",1); + var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); + var result = (NoContentResult)await surveyResponseProvider.GetSurveyResponsesByAnswerAsyncAsync(1, 1, "Yes", 1); Assert.Equal(204, result.StatusCode); } @@ -110,8 +112,8 @@ namespace DamageAssesment.SurveyResponses.Test { SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); var mockResponse = await MockData.getOkResponse(); - mockSurveyResponseService.Setup(service => service.GetAnswersByRegionAsync(1,1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); + mockSurveyResponseService.Setup(service => service.GetAnswersByRegionAsync(1, 1)).ReturnsAsync(mockResponse); + var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (OkObjectResult)await surveyResponseProvider.GetAnswersByRegionAsync(1, 1); Assert.Equal(200, result.StatusCode); } @@ -121,7 +123,7 @@ namespace DamageAssesment.SurveyResponses.Test { var mockResponse = await MockData.getResponse(); mockSurveyResponseService.Setup(service => service.GetAnswersByRegionAsync(1, 1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); + var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (NoContentResult)await surveyResponseProvider.GetAnswersByRegionAsync(1, 1); Assert.Equal(204, result.StatusCode); } @@ -132,7 +134,7 @@ namespace DamageAssesment.SurveyResponses.Test SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); var mockResponse = await MockData.getOkResponse(); mockSurveyResponseService.Setup(service => service.GetSurveyResponsesByMaintenanceCenterAsync(1, 1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); + var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (OkObjectResult)await surveyResponseProvider.GetAnswersByMaintenaceCentersync(1, 1); Assert.Equal(200, result.StatusCode); } @@ -142,7 +144,7 @@ namespace DamageAssesment.SurveyResponses.Test { var mockResponse = await MockData.getResponse(); mockSurveyResponseService.Setup(service => service.GetSurveyResponsesByMaintenanceCenterAsync(1, 1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); + var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (NoContentResult)await surveyResponseProvider.GetAnswersByMaintenaceCentersync(1, 1); Assert.Equal(204, result.StatusCode); } @@ -153,7 +155,7 @@ namespace DamageAssesment.SurveyResponses.Test SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); var mockResponse = await MockData.getOkResponse(); mockSurveyResponseService.Setup(service => service.GetSurveyResponseByIdAsync(1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); + var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponseByIdAsync(1); Assert.Equal(200, result.StatusCode); } @@ -163,7 +165,7 @@ namespace DamageAssesment.SurveyResponses.Test { var mockResponse = await MockData.getResponse(); mockSurveyResponseService.Setup(service => service.GetSurveyResponseByIdAsync(1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object); + var surveyResponseProvider = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (NoContentResult)await surveyResponseProvider.GetSurveyResponseByIdAsync(1); Assert.Equal(204, result.StatusCode); } @@ -175,7 +177,7 @@ namespace DamageAssesment.SurveyResponses.Test SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); var mockResponse = await MockData.getOkResponse(mockRequestObject); mockSurveyResponseService.Setup(service => service.PostSurveyResponseAsync(mockRequestObject)).ReturnsAsync(mockResponse); - var surveyResponseController = new SurveyResponsesController(mockSurveyResponseService.Object); + var surveyResponseController = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (OkObjectResult)await surveyResponseController.PostSurveysAsync(mockRequestObject); Assert.Equal(200, result.StatusCode); } @@ -186,7 +188,7 @@ namespace DamageAssesment.SurveyResponses.Test SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); var mockResponse = await MockData.getResponse(); mockSurveyResponseService.Setup(service => service.PostSurveyResponseAsync(mockRequestObject)).ReturnsAsync(mockResponse); - var surveyResponseController = new SurveyResponsesController(mockSurveyResponseService.Object); + var surveyResponseController = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (BadRequestObjectResult)await surveyResponseController.PostSurveysAsync(mockRequestObject); Assert.Equal(400, result.StatusCode); } @@ -197,7 +199,7 @@ namespace DamageAssesment.SurveyResponses.Test SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); var mockResponse = await MockData.getOkResponse(mockRequestObject); mockSurveyResponseService.Setup(service => service.PutSurveyResponseAsync(1, mockRequestObject)).ReturnsAsync(mockResponse); - var surveyResponseController = new SurveyResponsesController(mockSurveyResponseService.Object); + var surveyResponseController = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (OkObjectResult)await surveyResponseController.PutSurveyResponseAsync(1, mockRequestObject); Assert.Equal(200, result.StatusCode); } @@ -208,7 +210,7 @@ namespace DamageAssesment.SurveyResponses.Test SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); var mockResponse = await MockData.getResponse(); mockSurveyResponseService.Setup(service => service.PutSurveyResponseAsync(1, mockRequestObject)).ReturnsAsync(mockResponse); ; - var surveyResponseController = new SurveyResponsesController(mockSurveyResponseService.Object); + var surveyResponseController = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (BadRequestObjectResult)await surveyResponseController.PutSurveyResponseAsync(1, mockRequestObject); Assert.Equal(400, result.StatusCode); } @@ -219,7 +221,7 @@ namespace DamageAssesment.SurveyResponses.Test SurveyResponse mockRequestObject = await MockData.getSurveyResponseObject(); var mockResponse = await MockData.getOkResponse(mockRequestObject); mockSurveyResponseService.Setup(service => service.DeleteSurveyResponseAsync(1)).ReturnsAsync(mockResponse); - var surveyResponseController = new SurveyResponsesController(mockSurveyResponseService.Object); + var surveyResponseController = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (OkObjectResult)await surveyResponseController.DeleteSurveyResponseAsync(1); Assert.Equal(200, result.StatusCode); } @@ -229,7 +231,7 @@ namespace DamageAssesment.SurveyResponses.Test { var mockResponse = await MockData.getResponse(); mockSurveyResponseService.Setup(service => service.DeleteSurveyResponseAsync(1)).ReturnsAsync(mockResponse); ; - var surveyResponseController = new SurveyResponsesController(mockSurveyResponseService.Object); + var surveyResponseController = new SurveyResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (NotFoundResult)await surveyResponseController.DeleteSurveyResponseAsync(1); Assert.Equal(404, result.StatusCode); } diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Controllers/SurveyResponsesController.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Controllers/SurveyResponsesController.cs index 36f40a5..a8f36f4 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Responses/Controllers/SurveyResponsesController.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Controllers/SurveyResponsesController.cs @@ -8,10 +8,12 @@ namespace DamageAssesment.Api.Responses.Controllers public class SurveyResponsesController : ControllerBase { private readonly ISurveysResponse surveyResponseProvider; + private readonly IExcelExportService excelExportService; - public SurveyResponsesController(ISurveysResponse surveyResponseProvider) + public SurveyResponsesController(ISurveysResponse surveyResponseProvider, IExcelExportService excelExportService) { this.surveyResponseProvider = surveyResponseProvider; + this.excelExportService = excelExportService; } /// /// GET request for retrieving survey responses. @@ -57,9 +59,9 @@ namespace DamageAssesment.Api.Responses.Controllers [Route("responses/{surveyid:int}/{locationid:int}/{employeeid:int}")] [Route("responses/{surveyid:int}/{locationid:int}")] [HttpGet] - public async Task GetSurveyResponsesBySurveyAndLocationAsync(int surveyid, int locationid,int? employeeid) + public async Task GetSurveyResponsesBySurveyAndLocationAsync(int surveyid, int locationid, int? employeeid) { - var result = await this.surveyResponseProvider.GetSurveyResponsesBySurveyAndLocationAsync(surveyid, locationid,employeeid ?? 0); + var result = await this.surveyResponseProvider.GetSurveyResponsesBySurveyAndLocationAsync(surveyid, locationid, employeeid ?? 0); if (result.IsSuccess) { return Ok(result.SurveyResponses); @@ -198,6 +200,9 @@ namespace DamageAssesment.Api.Responses.Controllers else return BadRequest(result.ErrorMessage); } + /// + /// Get All active surveys . + /// [Route("responses/surveys/active")] [Route("responses/surveys/active/{language:alpha}")] [Route("responses/surveys/active/{employeeid:int}")] @@ -212,6 +217,23 @@ namespace DamageAssesment.Api.Responses.Controllers } return NoContent(); } + /// + /// Export all survey response data based on survey id. + /// + [HttpGet] + [Route("responses/surveys/export/{surveyid}")] + public async Task GetExcelSurveysAsync(int surveyid,string language, bool IsAdmin = false) + { + var result = await this.surveyResponseProvider.ExportSurveyResponsesAsync(surveyid,language, IsAdmin); + if (result.IsSuccess&& result.surveyResponses.Count>0) + { + + byte[] fileContents = excelExportService.ExportToExcel(result.surveyResponses); + return File(fileContents, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "data.xlsx"); + //return Ok(result.Surveys); + } + return NoContent(); + } //[Route("responses/surveys/active")] //[Route("responses/surveys/active/{language:alpha}")] //[HttpGet] @@ -224,6 +246,10 @@ namespace DamageAssesment.Api.Responses.Controllers // } // return NoContent(); //} + + /// + /// Get all historical surveys . + /// [Route("responses/surveys/historic")] [Route("responses/surveys/historic/{language:alpha}")] [Route("responses/surveys/historic/{employeeid:int}")] diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/DamageAssesment.Api.Responses.csproj b/DamageAssesmentApi/DamageAssesment.Api.Responses/DamageAssesment.Api.Responses.csproj index 1ee7c58..99c5c0c 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Responses/DamageAssesment.Api.Responses.csproj +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/DamageAssesment.Api.Responses.csproj @@ -11,6 +11,7 @@ + diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IExcelExportService.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IExcelExportService.cs new file mode 100644 index 0000000..31b832f --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IExcelExportService.cs @@ -0,0 +1,7 @@ +namespace DamageAssesment.Api.Responses.Interfaces +{ + public interface IExcelExportService + { + public byte[] ExportToExcel(List responses); + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IQuestionServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IQuestionServiceProvider.cs index 5c54e57..bbcec8b 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IQuestionServiceProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/IQuestionServiceProvider.cs @@ -4,8 +4,9 @@ namespace DamageAssesment.Api.Responses.Interfaces { public interface IQuestionServiceProvider { - Task> getQuestionsAsync(); + Task> getQuestionsAsync(string language); Task> getSurveyQuestionsAsync(int surveyId); Task getQuestionsAsync(int questionId); + Task> GetQuestionCategoriesAsync(string? language); } } diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/ISurveysResponse.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/ISurveysResponse.cs index 19893c8..05a8eed 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/ISurveysResponse.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Interfaces/ISurveysResponse.cs @@ -7,8 +7,9 @@ namespace DamageAssesment.Api.Responses.Interfaces { Task<(bool IsSuccess, dynamic Answers, string ErrorMessage)> GetAnswersByRegionAsync(int surveyId, int employeeid); Task<(bool IsSuccess, Models.SurveyResponse SurveyResponse, string ErrorMessage)> PostSurveyResponseAsync(Models.SurveyResponse surveyResponse); - // Task<(bool IsSuccess,dynamic surveyResponses, string ErrorMessage)> GetSurveyResponseAsync(int responseId); + // Task<(bool IsSuccess,dynamic surveyResponses, string ErrorMessage)> GetSurveyResponseAsync(int responseId); Task<(bool IsSuccess, dynamic surveyResponses, string ErrorMessage)> GetSurveyResponsesAsync(int employeeid); + Task<(bool IsSuccess, List surveyResponses, string ErrorMessage)> ExportSurveyResponsesAsync(int surveyId, string language, bool IsAdmin); Task<(bool IsSuccess, dynamic Surveys, string ErrorMessage)> GetActiveSurveysAsync(int? employeeid, string language); Task<(bool IsSuccess, dynamic Surveys, string ErrorMessage)> GetHistoricSurveysAsync(int? employeeid, string language); Task<(bool IsSuccess, Models.SurveyResponse SurveyResponse, string ErrorMessage)> PutSurveyResponseAsync(int Id, Models.SurveyResponse surveyResponse); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Attachment.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Attachment.cs index 6194789..71a87d3 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Attachment.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Attachment.cs @@ -11,6 +11,7 @@ namespace DamageAssesment.Api.Responses.Models public int? AnswerId { get; set; } public bool IsDeleted { get; set; } + public string FileName { get; set; } public Attachment(int answerId, string uri) { diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Location.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Location.cs index d5996d2..e217a7b 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Location.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Location.cs @@ -4,6 +4,7 @@ { public int Id { get; set; } public int RegionId { get; set; } + public string LocationCode { get; set; } public string Name { get; set; } public string MaintenanceCenter { get; set; } public string SchoolType { get; set; } diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/QuestionCategory.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/QuestionCategory.cs new file mode 100644 index 0000000..c7c9379 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/QuestionCategory.cs @@ -0,0 +1,10 @@ +namespace DamageAssesment.Api.Responses.Models +{ + public class QuestionCategory + { + public int Id { get; set; } + public string IconName { get; set; } + public string IconLibrary { get; set; } + public object Titles { get; set; } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/SurveyExport.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/SurveyExport.cs new file mode 100644 index 0000000..e2f820b --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/SurveyExport.cs @@ -0,0 +1,24 @@ +namespace DamageAssesment.Api.Responses.Models +{ + public class SurveyExport + { + public int Id { get; set; } + public string SurveyQuestion { get; set; } + public string Answer { get; set; } + public string Category { get; set; } + + public string School { get; set; } + public string Location { get; set; } + public string Region { get; set; } + + public string MC { get; set; } + public string ResponseDate { get; set; } + public string Notes { get; set; } + + public string Attachment1 { get; set; } + public string Attachment2 { get; set; } + public string Attachment3 { get; set; } + public string Attachment4 { get; set; } + public string Attachment5 { get; set; } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Program.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Program.cs index f7b7216..91adc1c 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Responses/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Program.cs @@ -26,6 +26,7 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddHttpClient(). AddTransientHttpErrorPolicy(policy => policy.WaitAndRetryAsync(maxApiCallRetries, _ => TimeSpan.FromSeconds(intervalToRetry))). diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Providers/ExcelExportService.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Providers/ExcelExportService.cs new file mode 100644 index 0000000..0740cc6 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Providers/ExcelExportService.cs @@ -0,0 +1,56 @@ +using DamageAssesment.Api.Responses.Interfaces; +using DamageAssesment.Api.Responses.Models; +using OfficeOpenXml; +using System.Collections.Generic; + +namespace DamageAssesment.Api.Responses.Providers +{ + public class ExcelExportService : IExcelExportService + { + public byte[] ExportToExcel(List responses) + { + ExcelPackage.LicenseContext = LicenseContext.NonCommercial; + using (var package = new ExcelPackage()) + { + // Create the first worksheet and populate it with responses + var workSheet1 = package.Workbook.Worksheets.Add("responses"); + PopulateWorksheet(workSheet1, responses); + return package.GetAsByteArray(); + } + } + private void PopulateWorksheet(ExcelWorksheet worksheet, List data) + { + if (data.Count > 0) + { + var properties = data[0].GetType().GetProperties(); + List IsAttchments = new List(); + // Add column headers + for (int col = 1; col <= properties.Length; col++) + { + worksheet.Cells[1, col].Value = properties[col - 1].Name; + if (properties[col - 1].Name.ToLower().Contains("attachment")) + IsAttchments.Add(col); + } + + // Add data + for (int row = 2; row <= data.Count + 1; row++) + { + for (int col = 1; col <= properties.Length; col++) + { + string value = Convert.ToString(properties[col - 1].GetValue(data[row - 2])); + if (IsAttchments.Where(a => a == col).Count() > 0 && !string.IsNullOrEmpty(value)) + { + List attachments = value.Split("##").ToList(); + Uri linkUri = new Uri(attachments[1]); + worksheet.Cells[row, col].Hyperlink = linkUri; + worksheet.Cells[row, col].Value = attachments[0]; + worksheet.Cells[row, col].Style.Font.UnderLine = true; + } + else + worksheet.Cells[row, col].Value = value; + } + } + } + } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Providers/SurveyResponsesProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Providers/SurveyResponsesProvider.cs index af11925..2b5e3b0 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Responses/Providers/SurveyResponsesProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Providers/SurveyResponsesProvider.cs @@ -3,6 +3,9 @@ using DamageAssesment.Api.Responses.Db; using DamageAssesment.Api.Responses.Interfaces; using DamageAssesment.Api.Responses.Models; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Internal; +using System.Reflection; +using System.Text.Json; namespace DamageAssesment.Api.Responses.Providers { @@ -43,7 +46,6 @@ namespace DamageAssesment.Api.Responses.Providers // Create and save SurveyResponse records with references to existing Employee and Location records surveyResponseDbContext.SurveyResponses.Add(new Db.SurveyResponse { SurveyId = 1, EmployeeId = 1, LocationId = 1, ClientDevice = "Mobile", Latitude = 98.8767, Longitute = -129.9897, KeyAnswerResult = "true", CreatedDate = DateTime.Now }); surveyResponseDbContext.SurveyResponses.Add(new Db.SurveyResponse { SurveyId = 1, EmployeeId = 2, LocationId = 2, ClientDevice = "Mobile", Latitude = 98.8767, Longitute = -129.9897, KeyAnswerResult = "true", CreatedDate = DateTime.Now }); - surveyResponseDbContext.SaveChanges(); } } @@ -111,7 +113,7 @@ namespace DamageAssesment.Api.Responses.Providers return (false, null, ex.Message); } } - + public async Task<(bool IsSuccess, dynamic Surveys, string ErrorMessage)> GetActiveSurveysAsync(int? employeeid, string language) { try @@ -120,9 +122,9 @@ namespace DamageAssesment.Api.Responses.Providers //get all the survey that already taken by the employee var surveys = await surveyServiceProvider.getSurveysAsync(language); surveys = surveys.Where(s => s.IsEnabled == true && s.StartDate <= DateTime.Now && s.EndDate >= DateTime.Now).ToList(); - if (employeeid==null || employeeid==0) + if (employeeid == null || employeeid == 0) return (true, surveys, null); - List listOfsurveysId = await surveyResponseDbContext.SurveyResponses.Where(x => x.EmployeeId == employeeid.Value).Select(y => y.SurveyId).ToListAsync(); + List listOfsurveysId = await surveyResponseDbContext.SurveyResponses.Where(x => x.EmployeeId == employeeid.Value).Select(y => y.SurveyId).ToListAsync(); var activeSurveys = surveys.Where(s => !listOfsurveysId.Contains(s.Id)); return (true, activeSurveys, null); } @@ -142,10 +144,9 @@ namespace DamageAssesment.Api.Responses.Providers var surveys = await surveyServiceProvider.getSurveysAsync(language); // returning only historic data: end date is less than current date. surveys = surveys.Where(s => s.EndDate < DateTime.Now).ToList(); - if(employeeid==null|| employeeid==0) + if (employeeid == null || employeeid == 0) return (true, surveys, null); var surveyResponses = await surveyResponseDbContext.SurveyResponses.Where(x => x.EmployeeId == employeeid).ToListAsync(); - var historicSurveys = from s in surveys from r in surveyResponses where s.Id == r.SurveyId @@ -308,6 +309,26 @@ namespace DamageAssesment.Api.Responses.Providers return (false, null, ex.Message); } } + public async Task<(bool IsSuccess, List surveyResponses, string ErrorMessage)> ExportSurveyResponsesAsync(int surveyId, string language, bool isadmin) + { + try + { + var responses = await getAllSurveyResponsesExcelAsync(surveyId,language, isadmin); + + if (responses != null) + return (true, responses, "Request Successful."); + else + { + responses = null; + return (true, responses, "Empty object returned"); + } + } + catch (Exception ex) + { + logger?.LogError(ex.ToString()); + return (false, null, ex.Message); + } + } public async Task<(bool IsSuccess, Models.SurveyResponse SurveyResponse, string ErrorMessage)> PostSurveyResponseAsync(Models.SurveyResponse surveyResponse) { @@ -488,7 +509,7 @@ namespace DamageAssesment.Api.Responses.Providers { var employee = await employeeServiceProvider.getEmployeeAsync(surveyResponse.EmployeeId); var answers = await answerServiceProvider.GetAnswersByResponseIdAsync(surveyResponse.Id); - var allQuestions = await questionServiceProvider.getQuestionsAsync(); + var allQuestions = await questionServiceProvider.getQuestionsAsync(null); var questions = allQuestions.Where(s => s.SurveyId == surveyResponse.SurveyId); var attachments = await attachmentServiceProvider.getAttachmentsAsync(); @@ -544,7 +565,7 @@ namespace DamageAssesment.Api.Responses.Providers } var answers = await answerServiceProvider.getAnswersAsync(); - var questions = await questionServiceProvider.getQuestionsAsync(); + var questions = await questionServiceProvider.getQuestionsAsync(null); var surveyQuestions = from q in questions where q.SurveyId == surveyId select q; //var surveyQuestions = await questionServiceProvider.getSurveyQuestionsAsync(surveyId); @@ -650,7 +671,7 @@ namespace DamageAssesment.Api.Responses.Providers var answers = await answerServiceProvider.getAnswersAsync(); - var questions = await questionServiceProvider.getQuestionsAsync(); + var questions = await questionServiceProvider.getQuestionsAsync(null); var attachments = await attachmentServiceProvider.getAttachmentsAsync(); var result = from r in surveyResonses @@ -687,7 +708,136 @@ namespace DamageAssesment.Api.Responses.Providers return null; } } + //Method to get All Survey Responses for excel export + private async Task> getAllSurveyResponsesExcelAsync(int surveyId,string language, bool isadmin) + { + try + { + if (string.IsNullOrEmpty(language)) language = "en"; + List surveyResonses; + surveyResonses = await surveyResponseDbContext.SurveyResponses.Where(a=>a.SurveyId==surveyId).ToListAsync(); + var answers = await answerServiceProvider.getAnswersAsync(); + var Locations = await locationServiceProvider.getLocationsAsync(); + var regions = await regionServiceProvider.getRegionsAsync(); + var questions = await questionServiceProvider.getQuestionsAsync(language); + var categories = await questionServiceProvider.GetQuestionCategoriesAsync(language); + var attachments = await attachmentServiceProvider.getAttachmentsAsync(); + List questionLists = new List(); + var allques = from res in surveyResonses + join loc in Locations on res.LocationId equals loc.Id + join reg in regions on loc.RegionId equals reg.Id + join ans in answers on res.Id equals ans.SurveyResponseId + join q in questions on ans.QuestionId equals q.Id + join qc in categories on q.CategoryId equals qc.Id + select new + { + responseId = res.Id, + questionId = q.Id, + QuestionNumber = q.QuestionNumber, + Category = JsonSerializer.Deserialize>(qc.Titles.ToString())[language], + question = q.Text[language], + answerId = ans.Id, + AnswerText = ans.AnswerText, + Comment = ans.Comment, + Location = loc.LocationCode, + school = loc.Name, + Region = reg.Name, + MC = loc.MaintenanceCenter, + ResponseDate = res.CreatedDate, + EmployeeId = res.EmployeeId, + ClientDevice = res.ClientDevice, + Attachments = attachments.Where(a => a.AnswerId == ans.Id).Select(a => a.FileName + "##" + a.URI).ToList() + }; + List allresoponses = new List(); + foreach (var item in allques) + { + List ansattachments = item.Attachments.ToList(); + + //// Initialize the attachment dictionary + //var attachmentsobject = new Dictionary(); + //for (int i = 0; i < ansattachments.Count; i++) + //{ + // attachmentsobject["Attachment"+(i+1).ToString()] = ansattachments[i]; + //} + + + string[] variables = new string[5]; + for (int i = 0; i < 5; i++) // Assuming you want to assign 5 values + { + if (i < ansattachments.Count()) + { + variables[i] = ansattachments[i]; + } + else + { + variables[i] = string.Empty; // or null, or any other default value + } + } + + // Now, you can access the values using the variables + string att1 = variables[0], att2 = variables[1], att3 = variables[2], att4 = variables[3], att5 = variables[4]; + object response; + if (isadmin) + { + response = new + { + SurveyQuestion = item.question, + Answer = item.AnswerText, + Category = item.Category, + School = item.school, + Location = item.Location, + Region = item.Region, + MC = item.MC, + ResponseDate = item.ResponseDate.ToString(), + Notes = item.Comment, + Attachment1 = att1, + Attachment2 = att2, + Attachment3 = att3, + Attachment4 = att4, + Attachment5 = att5, + User = item.EmployeeId, + DeviceType = item.ClientDevice, + Reference = item.responseId + }; + // Add the attachment dictionary to the response object + // response = new { response, Attachments = attachments }; + } + else + { + response = new + { + SurveyQuestion = item.question, + Answer = item.AnswerText, + Category = item.Category, + School = item.school, + Location = item.Location, + Region = item.Region, + MC = item.MC, + ResponseDate = item.ResponseDate.ToString(), + Notes = item.Comment, + Attachment1 = att1, + Attachment2 = att2, + Attachment3 = att3, + Attachment4 = att4, + Attachment5 = att5 + }; + + // Add the attachment dictionary to the response object + // response = new { response, Attachments = attachments }; + } + allresoponses.Add(response); + } + return allresoponses; + + + } + catch (Exception ex) + { + logger?.LogError($"Exception Found : {ex.Message} - Ref: SurveyResponsesProvider.getSurveyResponseBySurveyIdAsync()"); + return null; + } + } //Method to get Answers By Maintenance Center by surveyId private async Task getResultsByMaintenanceCenterAsync(int surveyId, int employeeid) @@ -784,7 +934,7 @@ namespace DamageAssesment.Api.Responses.Providers } var answers = await answerServiceProvider.getAnswersAsync(); - var questions = await questionServiceProvider.getQuestionsAsync(); + var questions = await questionServiceProvider.getQuestionsAsync(null); var surveyQuestions = from q in questions where q.SurveyId == surveyId select q; var attachments = await attachmentServiceProvider.getAttachmentsAsync(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/QuestionServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/QuestionServiceProvider.cs index 95086b8..bc9c912 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/QuestionServiceProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/QuestionServiceProvider.cs @@ -10,10 +10,12 @@ namespace DamageAssesment.Api.Responses.Services { } - public async Task> getQuestionsAsync() + public async Task> getQuestionsAsync(string language) { try { + if (!string.IsNullOrEmpty(language)) + url = url + "/" + language; var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null); var questions = JsonConvert.DeserializeObject>(responseJsonString); @@ -27,6 +29,27 @@ namespace DamageAssesment.Api.Responses.Services return new List(); } } + public async Task> GetQuestionCategoriesAsync(string? language) + { + try + { + url = urlBase + configuration.GetValue("RessourceSettings:QuestionCategory"); + + if (!string.IsNullOrEmpty(language)) + url = url + "/" + language; + var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null); + var questions = JsonConvert.DeserializeObject>(responseJsonString); + + if (questions == null || !questions.Any()) + return new List(); + else return questions; + } + catch (Exception ex) + { + logger?.LogError($"Exception Found : {ex.Message} - Ref: QuestionServiceProvider.GetQuestionCategoriesAsync()"); + return new List(); + } + } public async Task> getSurveyQuestionsAsync(int surveyId) { @@ -37,7 +60,7 @@ namespace DamageAssesment.Api.Responses.Services var questions = JsonConvert.DeserializeObject>(responseJsonString); if (questions == null || !questions.Any()) - return new List() ; + return new List(); else return questions; } catch (Exception ex) diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/appsettings.json b/DamageAssesmentApi/DamageAssesment.Api.Responses/appsettings.json index f23b75a..f7df084 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Responses/appsettings.json +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/appsettings.json @@ -25,12 +25,12 @@ "AttachmentUrlBase": "http://damageassesment.api.attachments:80", "SurveyUrlBase": "http://damageassesment.api.surveys:80" }, - "RessourceSettings": { "Employee": "/employees", "EmployeeById": "/employees/{0}", "Question": "/questions", "QuestionById": "/questions/{0}", + "QuestionCategory": "/questions/categories", "SurveyQuestion": "/questions/bysurvey/{0}", "Survey": "/surveys", "SurveyById": "/surveys/{0}", diff --git a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Providers/SurveysProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Providers/SurveysProvider.cs index e48efc1..5a84843 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Providers/SurveysProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Providers/SurveysProvider.cs @@ -18,7 +18,7 @@ namespace DamageAssesment.Api.Surveys.Providers this.surveyDbContext = surveysDbContext; this.logger = logger; this.mapper = mapper; - // seedData(); + //seedData(); } // Method to seed initial data into the database @@ -44,10 +44,10 @@ namespace DamageAssesment.Api.Surveys.Providers surveyDbContext.SurveysTranslation.Add(new Db.SurveyTranslation { SurveyId = survey2.Id, Language = "en", Title = "Hurricane Andrew Aftermath Survey" }); surveyDbContext.SurveysTranslation.Add(new Db.SurveyTranslation { SurveyId = survey2.Id, Language = "es", Title = "Encuesta sobre las secuelas del huracán Andrew" }); surveyDbContext.SurveysTranslation.Add(new Db.SurveyTranslation { SurveyId = survey2.Id, Language = "fr", Title = "Enquête sur les conséquences de l'ouragan Andrew" }); - - surveyDbContext.SurveysTranslation.Add(new Db.SurveyTranslation { SurveyId = survey3.Id, Language = "en", Title = "Hurricane Idalia Aftermath Survey" }); - surveyDbContext.SurveysTranslation.Add(new Db.SurveyTranslation { SurveyId = survey3.Id, Language = "es", Title = "Encuesta sobre las secuelas del huracán Idalia" }); - surveyDbContext.SurveysTranslation.Add(new Db.SurveyTranslation { SurveyId = survey3.Id, Language = "fr", Title = "Enquête sur les conséquences de l'ouragan Idalia" }); + + surveyDbContext.SurveysTranslation.Add(new Db.SurveyTranslation { SurveyId = survey3.Id, Language = "en", Title = "Hurricane Irma" }); + surveyDbContext.SurveysTranslation.Add(new Db.SurveyTranslation { SurveyId = survey3.Id, Language = "es", Title = "Huracán Irma" }); + surveyDbContext.SurveysTranslation.Add(new Db.SurveyTranslation { SurveyId = survey3.Id, Language = "fr", Title = "Ouragan Irma" }); surveyDbContext.SaveChanges(); } @@ -85,7 +85,7 @@ namespace DamageAssesment.Api.Surveys.Providers MultiLanguage = dict; return MultiLanguage; } - public string GetStatus(DateTime StartDate,DateTime EndDate) + public string GetStatus(DateTime StartDate, DateTime EndDate) { if (StartDate > DateTime.Now) return SurveyStatus.PENDING.ToString(); @@ -114,7 +114,7 @@ namespace DamageAssesment.Api.Surveys.Providers EndDate = s.EndDate, IsEnabled = s.IsEnabled, CreatedDate = s.CreatedDate, - Status= GetStatus(s.StartDate,s.EndDate), + Status = GetStatus(s.StartDate, s.EndDate), Titles = CreateMultiLanguageObject(GetSurveyTranslations(s.Id, null, language)) }; @@ -217,12 +217,10 @@ namespace DamageAssesment.Api.Surveys.Providers _survey = mapper.Map(survey); surveyDbContext.Surveys.Update(_survey); await surveyDbContext.SaveChangesAsync(); - List listSurveyTranslation = new List(); - Random random = new Random(); foreach (var title in survey.Titles) { - listSurveyTranslation.Add(new Db.SurveyTranslation { Id = random.Next(), SurveyId = _survey.Id, Language = title.Language, Title = title.Title }); + listSurveyTranslation.Add(new Db.SurveyTranslation { SurveyId = _survey.Id, Language = title.Language, Title = title.Title }); } surveyDbContext.SurveysTranslation.AddRange(listSurveyTranslation); await surveyDbContext.SaveChangesAsync();