diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks.Test/DoculinkServiceTest.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks.Test/DoculinkServiceTest.cs index 299a162..2ea6ffb 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks.Test/DoculinkServiceTest.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks.Test/DoculinkServiceTest.cs @@ -16,7 +16,7 @@ namespace DamageAssesment.Api.DocuLinks.Test { var mockDocumentService = new Mock(); var mockUploadService = new Mock(); - var mockResponse = await MockData.getNoContentResponses(); + var mockResponse = await MockData.getNoContentResponse(); mockDocumentService.Setup(service => service.GetdocumentsByLinkAsync("forms", "en", null)).ReturnsAsync(mockResponse); var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object); @@ -30,7 +30,7 @@ namespace DamageAssesment.Api.DocuLinks.Test { var mockDocumentService = new Mock(); var mockUploadService = new Mock(); - var mockResponse = await MockData.getNoContentResponses(); + var mockResponse = await MockData.getNoContentResponse(); mockDocumentService.Setup(service => service.GetdocumentsByLinkAsync("forms", "en", true)).ReturnsAsync(mockResponse); var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object); @@ -83,7 +83,7 @@ namespace DamageAssesment.Api.DocuLinks.Test { var mockDocumentService = new Mock(); var mockUploadService = new Mock(); - var mockResponse = await MockData.getNoContentResponses(); + var mockResponse = await MockData.getNoContentResponse(); mockDocumentService.Setup(service => service.GetdocumentsByLinkTypeIdAsync(null, "en", true)).ReturnsAsync(mockResponse); var DocumentProvider = new DoculinkController(mockDocumentService.Object, mockUploadService.Object); diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks.Test/MockData.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks.Test/MockData.cs index e5e2d67..92c10b1 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks.Test/MockData.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks.Test/MockData.cs @@ -11,7 +11,7 @@ namespace DamageAssesment.Api.DocuLinks.Test public class MockData { - public static async Task<(bool, List, string)> getOkResponses() + public static async Task<(bool, List, string)> getOkResponses() { List list = new List(); @@ -48,8 +48,8 @@ namespace DamageAssesment.Api.DocuLinks.Test doclinksAttachments = doclinksAttachments }); } - List doculinks = list.GroupBy(a => a.linkTypeId).Select(a => new ResDoculinks() { linkTypeId = a.Key, doculinks = a.ToList() }).ToList(); - return (true, doculinks, null); + // List doculinks = list.GroupBy(a => a.linkTypeId).Select(a => new ResDoculinks() { linkTypeId = a.Key, doculinks = a.ToList() }).ToList(); + return (true, list, null); } diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IDoculinkProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IDoculinkProvider.cs index 6d271fd..e9717ee 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IDoculinkProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Interfaces/IDoculinkProvider.cs @@ -6,11 +6,11 @@ namespace DamageAssesment.Api.DocuLinks.Interfaces { Task<(bool IsSuccess, Models.ResDoculink Document, string ErrorMessage)> GetDocumentAsync(int id, string? linktype, string? language); Task<(bool IsSuccess, Models.Doculink Document, string ErrorMessage)> GetDocumentByidAsync(int id); - // Task<(bool IsSuccess, IEnumerable documents, string ErrorMessage)> GetDocumnetsAsync(string? language); - Task<(bool IsSuccess, IEnumerable documents, string ErrorMessage)> GetdocumentsByLinkAsync(string? linkType, string? language, bool? isactive); - Task<(bool IsSuccess, IEnumerable documents, string ErrorMessage)> GetdocumentsByLinkTypeIdAsync(int? linkTypeId, string? language, bool? isactive); + // Task<(bool IsSuccess, IEnumerable documents, string ErrorMessage)> GetDocumnetsAsync(string? language); + Task<(bool IsSuccess, IEnumerable documents, string ErrorMessage)> GetdocumentsByLinkAsync(string? linkType, string? language, bool? isactive); + Task<(bool IsSuccess, IEnumerable documents, string ErrorMessage)> GetdocumentsByLinkTypeIdAsync(int? linkTypeId, string? language, bool? isactive); Task<(bool IsSuccess, Models.ResDoculink Document, string ErrorMessage)> PostDocumentAsync(Models.Doculink Document); - Task<(bool IsSuccess, Models.ResDoculink Document, string ErrorMessage)> UpdateDocumentAsync(int id,Models.Doculink Document); + Task<(bool IsSuccess, Models.ResDoculink Document, string ErrorMessage)> UpdateDocumentAsync(int id, Models.Doculink Document); Task<(bool IsSuccess, Models.ResDoculink Document, string ErrorMessage)> DeleteDocumentAsync(int id); Task<(bool IsSuccess, int counter, string message)> GetDocumentCounter(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/DoculinkProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/DoculinkProvider.cs index 15eefa6..7fce286 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/DoculinkProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.DocuLinks/Providers/DoculinkProvider.cs @@ -173,7 +173,7 @@ namespace DamageAssesment.Api.DocuLinks.Providers return MultiLanguage; } - public async Task<(bool IsSuccess, IEnumerable documents, string ErrorMessage)> GetdocumentsByLinkTypeIdAsync(int? linkTypeId, string? language, bool? isactive) + public async Task<(bool IsSuccess, IEnumerable documents, string ErrorMessage)> GetdocumentsByLinkTypeIdAsync(int? linkTypeId, string? language, bool? isactive) { try @@ -197,8 +197,8 @@ namespace DamageAssesment.Api.DocuLinks.Providers item.doclinksAttachments = mapper.Map, List>( DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.DocumentId == item.Id).ToList()); } - List doculinks = result.GroupBy(a => a.linkTypeId).Select(a => new ResDoculinks() { linkTypeId = a.Key, doculinks = a.ToList() }).ToList(); - return (true, doculinks, null); + // List doculinks = result.GroupBy(a => a.linkTypeId).Select(a => new ResDoculinks() { linkTypeId = a.Key, doculinks = a.ToList() }).ToList(); + return (true, result, null); } return (false, null, "Not found"); } @@ -209,7 +209,7 @@ namespace DamageAssesment.Api.DocuLinks.Providers } } - public async Task<(bool IsSuccess, IEnumerable documents, string ErrorMessage)> GetdocumentsByLinkAsync(string? linkType, string? language, bool? isactive) + public async Task<(bool IsSuccess, IEnumerable documents, string ErrorMessage)> GetdocumentsByLinkAsync(string? linkType, string? language, bool? isactive) { try @@ -233,8 +233,8 @@ namespace DamageAssesment.Api.DocuLinks.Providers item.doclinksAttachments = mapper.Map, List>( DocumentDbContext.DoclinksAttachments.AsNoTracking().Where(a => a.DocumentId == item.Id).ToList()); } - List doculinks = result.GroupBy(a => a.linkTypeId).Select(a => new ResDoculinks() { linkTypeId = a.Key, doculinks = a.ToList() }).ToList(); - return (true, doculinks, null); + //List doculinks = result.GroupBy(a => a.linkTypeId).Select(a => new ResDoculinks() { linkTypeId = a.Key, doculinks = a.ToList() }).ToList(); + return (true, result, null); } return (false, null, "Not found"); } diff --git a/DamageAssesmentApi/DamageAssesment.Api.Questions/Controllers/QuestionsController.cs b/DamageAssesmentApi/DamageAssesment.Api.Questions/Controllers/QuestionsController.cs index 1171b0d..14df48f 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Questions/Controllers/QuestionsController.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Questions/Controllers/QuestionsController.cs @@ -90,6 +90,27 @@ namespace DamageAssesment.Api.Questions.Controllers return CreatedAtRoute("DefaultApi", new { id = question.Id }, question); } /// + /// POST request for creating a multiple question (multilingual). + /// + [Authorize(Roles = "admin")] + [HttpPost("questions/multiple")] + public async Task CreateQuestions(List questions) + { + if (questions != null) + { + var result = await this.questionsProvider.PostQuestionsAsync(questions); + if (result.IsSuccess) + { + return Ok(result.Question); + } + if (result.ErrorMessage == "Not Found") + return NotFound(result.ErrorMessage); + + return BadRequest(result.ErrorMessage); + } + return CreatedAtRoute("DefaultApi", questions); + } + /// /// POST request for creating a new question (multilingual). /// diff --git a/DamageAssesmentApi/DamageAssesment.Api.Questions/Interfaces/IQuestionsProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Questions/Interfaces/IQuestionsProvider.cs index f8e13c8..4fcea32 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Questions/Interfaces/IQuestionsProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Questions/Interfaces/IQuestionsProvider.cs @@ -8,6 +8,7 @@ namespace DamageAssesment.Api.Questions.Interfaces Task<(bool IsSuccess, IEnumerable Questions, string ErrorMessage)> GetQuestionsAsync(string language); Task<(bool IsSuccess, List SurveyQuestions, string ErrorMessage)> GetSurveyQuestionAsync(int surveyId,string language); Task<(bool IsSuccess, Models.MultiLanguage Question, string ErrorMessage)> PostQuestionAsync(Models.Question Question); + Task<(bool IsSuccess, IEnumerable Question, string ErrorMessage)> PostQuestionsAsync(List Questions); Task<(bool IsSuccess, Models.MultiLanguage Question, string ErrorMessage)> UpdateQuestionAsync(Models.Question Question); Task<(bool IsSuccess, Models.MultiLanguage Question, string ErrorMessage)> DeleteQuestionAsync(int id); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Questions/Providers/QuestionsProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Questions/Providers/QuestionsProvider.cs index 0122af7..de179ba 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Questions/Providers/QuestionsProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Questions/Providers/QuestionsProvider.cs @@ -334,16 +334,7 @@ namespace DamageAssesment.Api.Questions.Providers try { logger?.LogInformation("Query Question"); - var dbquestion = mapper.Map(Question); - var dbquestiontranslation = mapper.Map, List>(Question.Questions); - dbquestion.QuestionTypeId = questionDbContext.QuestionTypes.Where(a => a.TypeText == Question.TypeText).Select(a => a.Id).FirstOrDefault(); - questionDbContext.Questions.Add(dbquestion); - dbquestiontranslation.ForEach(i => i.QuestionId = dbquestion.Id); - questionDbContext.QuestionsTranslations.AddRange(dbquestiontranslation); - questionDbContext.SaveChanges(); - Question.Id = dbquestion.Id; - var result = mapper.Map(dbquestion); - result.Text = CreateMultiLanguageObject(GetQuestionsTranslations(result.Id,"")); + var result = InsertQuestion(Question); return (true, result, null); } catch (Exception ex) @@ -352,6 +343,39 @@ namespace DamageAssesment.Api.Questions.Providers return (false, null, ex.Message); } } + private Models.MultiLanguage InsertQuestion(Models.Question Question) + { + var dbquestion = mapper.Map(Question); + var dbquestiontranslation = mapper.Map, List>(Question.Questions); + dbquestion.QuestionTypeId = questionDbContext.QuestionTypes.Where(a => a.TypeText == Question.TypeText).Select(a => a.Id).FirstOrDefault(); + questionDbContext.Questions.Add(dbquestion); + questionDbContext.SaveChanges(); + dbquestiontranslation.ForEach(i => i.QuestionId = dbquestion.Id); + questionDbContext.QuestionsTranslations.AddRange(dbquestiontranslation); + questionDbContext.SaveChanges(); + Question.Id = dbquestion.Id; + var result = mapper.Map(dbquestion); + result.Text = CreateMultiLanguageObject(GetQuestionsTranslations(result.Id, "")); + return result; + } + public async Task<(bool IsSuccess, IEnumerable Question, string ErrorMessage)> PostQuestionsAsync(List Questions) + { + try + { + List results = new List(); + logger?.LogInformation("Query Question"); + foreach (Models.Question Question in Questions) + { + results.Add(InsertQuestion(Question)); + } + return (true, results, null); + } + catch (Exception ex) + { + logger?.LogError(ex.ToString()); + return (false, null, ex.Message); + } + } public async Task<(bool IsSuccess, Models.MultiLanguage Question, string ErrorMessage)> UpdateQuestionAsync(Models.Question Question) { try diff --git a/DamageAssesmentApi/DamageAssesment.Api.QuestionsTest/MockData.cs b/DamageAssesmentApi/DamageAssesment.Api.QuestionsTest/MockData.cs index 8b13b70..94eb466 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.QuestionsTest/MockData.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.QuestionsTest/MockData.cs @@ -75,8 +75,20 @@ namespace DamageAssesment.Api.Questions.Test return new Questions.Models.Question { Id = 1, Questions=QuestionsTranslations, TypeText = "Text 1", SurveyId = 1, QuestionNumber = 1, IsRequired = true, Comment = false, Key = true, CategoryId=1}; } - - + public static async Task> getInputQuestionsData() + { + Models.QuestionsTranslation QuestionsTranslation = new Models.QuestionsTranslation() + { + Language = "en", + QuestionText = "Sample question" + }; + List QuestionsTranslations = new List(); + List Questions = new List(); + QuestionsTranslations.Add(QuestionsTranslation); + Questions.Models.Question question = new Questions.Models.Question() { Id = 1, Questions = QuestionsTranslations, TypeText = "Text 1", SurveyId = 1, QuestionNumber = 1, IsRequired = true, Comment = false, Key = true, CategoryId = 1 }; + Questions.Add(question); + return Questions; + } } } diff --git a/DamageAssesmentApi/DamageAssesment.Api.QuestionsTest/QuestionsServiceTest.cs b/DamageAssesmentApi/DamageAssesment.Api.QuestionsTest/QuestionsServiceTest.cs index bda9db2..dff4dfa 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.QuestionsTest/QuestionsServiceTest.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.QuestionsTest/QuestionsServiceTest.cs @@ -110,6 +110,33 @@ namespace DamageAssesment.Api.Questions.Test Assert.Equal(400, result.StatusCode); } + [Fact(DisplayName = "Post Questions - Ok case")] + public async Task PostQuestionsAsync_ShouldReturnStatusCode200() + { + var mockQuestionService = new Mock(); + var mockResponse = await MockData.getOkResponse(); + var mockInputQuestion = await MockData.getInputQuestionsData(); + mockQuestionService.Setup(service => service.PostQuestionsAsync(mockInputQuestion)).ReturnsAsync(mockResponse); + + var QuestionProvider = new QuestionsController(mockQuestionService.Object); + var result = (OkObjectResult)await QuestionProvider.CreateQuestions(mockInputQuestion); + + Assert.Equal(200, result.StatusCode); + } + + [Fact(DisplayName = "Post Questions - BadRequest case")] + public async Task PostQuestionsAsync_ShouldReturnStatusCode400() + { + var mockQuestionService = new Mock(); + var mockInputQuestion = await MockData.getInputQuestionData(); + var mockResponse = await MockData.getBadRequestResponse(); + mockQuestionService.Setup(service => service.UpdateQuestionAsync(mockInputQuestion)).ReturnsAsync(mockResponse); + + var QuestionProvider = new QuestionsController(mockQuestionService.Object); + var result = (BadRequestObjectResult)await QuestionProvider.UpdateQuestion(mockInputQuestion); + + Assert.Equal(400, result.StatusCode); + } [Fact(DisplayName = "Put Question - Ok case")] public async Task PutQuestionAsync_ShouldReturnStatusCode200() @@ -329,6 +356,5 @@ namespace DamageAssesment.Api.Questions.Test Assert.Equal(404, result.StatusCode); } - } } \ No newline at end of file diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses.Test/SurveyResponsesServiceTest.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses.Test/SurveyResponsesServiceTest.cs index 59c764d..90a9a73 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 ResponsesController(mockSurveyResponseService.Object); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesAsync(1); Assert.Equal(200, result.StatusCode); } @@ -32,7 +34,7 @@ namespace DamageAssesment.SurveyResponses.Test { var mockResponse = await MockData.getResponse(); mockSurveyResponseService.Setup(service => service.GetSurveyResponsesAsync(1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (BadRequestObjectResult)await surveyResponseProvider.GetSurveyResponsesAsync(1); Assert.Equal(400, result.StatusCode); } @@ -43,7 +45,7 @@ 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 ResponsesController(mockSurveyResponseService.Object); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesAsync(1, 1); Assert.Equal(200, result.StatusCode); } @@ -53,7 +55,7 @@ namespace DamageAssesment.SurveyResponses.Test { var mockResponse = await MockData.getResponse(); mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAsync(1, 1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (NoContentResult)await surveyResponseProvider.GetSurveyResponsesAsync(1, 1); Assert.Equal(204, result.StatusCode); } @@ -67,7 +69,7 @@ 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 ResponsesController(mockSurveyResponseService.Object); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesBySurveyAndLocationAsync(1, 1, 1); Assert.Equal(200, result.StatusCode); } @@ -77,7 +79,7 @@ namespace DamageAssesment.SurveyResponses.Test { var mockResponse = await MockData.getResponse(); mockSurveyResponseService.Setup(service => service.GetSurveyResponsesBySurveyAndLocationAsync(1, 1, 1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (NoContentResult)await surveyResponseProvider.GetSurveyResponsesBySurveyAndLocationAsync(1, 1, 1); Assert.Equal(204, result.StatusCode); } @@ -88,7 +90,7 @@ 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 ResponsesController(mockSurveyResponseService.Object); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponsesByAnswerAsyncAsync(1, 1, "Yes", 1); Assert.Equal(200, result.StatusCode); } @@ -98,7 +100,7 @@ namespace DamageAssesment.SurveyResponses.Test { var mockResponse = await MockData.getResponse(); mockSurveyResponseService.Setup(service => service.GetResponsesByAnswerAsync(1, 1, "Yes", 1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (NoContentResult)await surveyResponseProvider.GetSurveyResponsesByAnswerAsyncAsync(1, 1, "Yes", 1); Assert.Equal(204, result.StatusCode); } @@ -110,7 +112,7 @@ 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 ResponsesController(mockSurveyResponseService.Object); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (OkObjectResult)await surveyResponseProvider.GetAnswersByRegionAsync(1, 1); Assert.Equal(200, result.StatusCode); } @@ -120,7 +122,7 @@ namespace DamageAssesment.SurveyResponses.Test { var mockResponse = await MockData.getResponse(); mockSurveyResponseService.Setup(service => service.GetAnswersByRegionAsync(1, 1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (NoContentResult)await surveyResponseProvider.GetAnswersByRegionAsync(1, 1); Assert.Equal(204, result.StatusCode); } @@ -131,7 +133,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 ResponsesController(mockSurveyResponseService.Object); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (OkObjectResult)await surveyResponseProvider.GetAnswersByMaintenaceCentersync(1, 1); Assert.Equal(200, result.StatusCode); } @@ -141,7 +143,7 @@ namespace DamageAssesment.SurveyResponses.Test { var mockResponse = await MockData.getResponse(); mockSurveyResponseService.Setup(service => service.GetSurveyResponsesByMaintenanceCenterAsync(1, 1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (NoContentResult)await surveyResponseProvider.GetAnswersByMaintenaceCentersync(1, 1); Assert.Equal(204, result.StatusCode); } @@ -152,7 +154,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 ResponsesController(mockSurveyResponseService.Object); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (OkObjectResult)await surveyResponseProvider.GetSurveyResponseByIdAsync(1); Assert.Equal(200, result.StatusCode); } @@ -162,7 +164,7 @@ namespace DamageAssesment.SurveyResponses.Test { var mockResponse = await MockData.getResponse(); mockSurveyResponseService.Setup(service => service.GetSurveyResponseByIdAsync(1)).ReturnsAsync(mockResponse); - var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object); + var surveyResponseProvider = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (NoContentResult)await surveyResponseProvider.GetSurveyResponseByIdAsync(1); Assert.Equal(204, result.StatusCode); } @@ -174,7 +176,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 ResponsesController(mockSurveyResponseService.Object); + var surveyResponseController = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (OkObjectResult)await surveyResponseController.PostSurveysAsync(mockRequestObject); Assert.Equal(200, result.StatusCode); } @@ -185,7 +187,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 ResponsesController(mockSurveyResponseService.Object); + var surveyResponseController = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (BadRequestObjectResult)await surveyResponseController.PostSurveysAsync(mockRequestObject); Assert.Equal(400, result.StatusCode); } @@ -196,7 +198,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 ResponsesController(mockSurveyResponseService.Object); + var surveyResponseController = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (OkObjectResult)await surveyResponseController.PutSurveyResponseAsync(1, mockRequestObject); Assert.Equal(200, result.StatusCode); } @@ -207,7 +209,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 ResponsesController(mockSurveyResponseService.Object); + var surveyResponseController = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (BadRequestObjectResult)await surveyResponseController.PutSurveyResponseAsync(1, mockRequestObject); Assert.Equal(400, result.StatusCode); } @@ -218,7 +220,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 ResponsesController(mockSurveyResponseService.Object); + var surveyResponseController = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (OkObjectResult)await surveyResponseController.DeleteSurveyResponseAsync(1); Assert.Equal(200, result.StatusCode); } @@ -228,7 +230,7 @@ namespace DamageAssesment.SurveyResponses.Test { var mockResponse = await MockData.getResponse(); mockSurveyResponseService.Setup(service => service.DeleteSurveyResponseAsync(1)).ReturnsAsync(mockResponse); ; - var surveyResponseController = new ResponsesController(mockSurveyResponseService.Object); + var surveyResponseController = new ResponsesController(mockSurveyResponseService.Object, mockExcelExportService.Object); var result = (NotFoundResult)await surveyResponseController.DeleteSurveyResponseAsync(1); Assert.Equal(404, result.StatusCode); } diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Controllers/ResponsesController.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Controllers/ResponsesController.cs index 4cdeab6..85c38ea 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Responses/Controllers/ResponsesController.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Controllers/ResponsesController.cs @@ -9,10 +9,12 @@ namespace DamageAssesment.Api.Responses.Controllers public class ResponsesController : ControllerBase { private readonly ISurveysResponse surveyResponseProvider; + private readonly IExcelExportService excelExportService; - public ResponsesController(ISurveysResponse surveyResponseProvider) + public ResponsesController(ISurveysResponse surveyResponseProvider, IExcelExportService excelExportService) { this.surveyResponseProvider = surveyResponseProvider; + this.excelExportService = excelExportService; } /// /// GET request for retrieving survey responses. @@ -210,6 +212,9 @@ namespace DamageAssesment.Api.Responses.Controllers else return BadRequest(result.ErrorMessage); } + /// + /// Get All active surveys . + /// [Authorize(Roles = "admin,survey,user,report")] [Route("responses/surveys/active")] @@ -226,7 +231,40 @@ namespace DamageAssesment.Api.Responses.Controllers } return NoContent(); } + /// + /// Export all survey response data based on survey id. + /// + [Authorize(Roles = "admin,survey,user,report")] + [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] + //public async Task GetActiveSurveysAsync( string? language) + //{ + // var result = await this.surveyResponseProvider.GetActiveSurveysAsync(null, language); + // if (result.IsSuccess) + // { + // return Ok(result.Surveys); + // } + // return NoContent(); + //} + + /// + /// Get all historical surveys . + /// [Authorize(Roles = "admin,survey,user,report")] [Route("responses/surveys/historic")] [Route("responses/surveys/historic/{language:alpha}")] diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/DamageAssesment.Api.Responses.csproj b/DamageAssesmentApi/DamageAssesment.Api.Responses/DamageAssesment.Api.Responses.csproj index c704179..c9d3645 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Responses/DamageAssesment.Api.Responses.csproj +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/DamageAssesment.Api.Responses.csproj @@ -11,6 +11,8 @@ + + all 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 b37a171..37a5159 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(string token); + Task> getQuestionsAsync(string language, string token); Task> getSurveyQuestionsAsync(int surveyId, string token); Task getQuestionsAsync(int questionId, string token); + Task> GetQuestionCategoriesAsync(string? language, string token); } } 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/Survey.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Survey.cs index 8265046..5419251 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Survey.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Models/Survey.cs @@ -2,13 +2,20 @@ namespace DamageAssesment.Api.Responses.Models { + public enum SurveyStatus + { + PENDING, + ACTIVE, + INACTIVE + } public class Survey { public int Id { get; set; } public bool IsEnabled { get; set; } - public DateTime StartDate { get; set; } - public DateTime EndDate { get; set; } + public DateTime? StartDate { get; set; } + public DateTime? EndDate { get; set; } public DateTime CreatedDate { get; set; } + public string Status { get; set; } public Dictionary 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..be527f7 --- /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 379caab..4a96c9b 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Responses/Program.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Program.cs @@ -48,6 +48,7 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddHttpContextAccessor(); builder.Services.AddHttpClient(). diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Providers/ExcelExportService.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Providers/ExcelExportService.cs new file mode 100644 index 0000000..2fadd9d --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Providers/ExcelExportService.cs @@ -0,0 +1,62 @@ +using ClosedXML.Excel; +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(); + try + { + Uri linkUri = new Uri(attachments[1]); + worksheet.Cells[row, col].Value = attachments[0]; + worksheet.Cells[row, col].Style.Font.UnderLine = true; + } + catch { worksheet.Cells[row, col].Value = attachments[1]; } + } + 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 00f030e..a2e8208 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Responses/Providers/SurveyResponsesProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Providers/SurveyResponsesProvider.cs @@ -2,7 +2,11 @@ using DamageAssesment.Api.Responses.Db; using DamageAssesment.Api.Responses.Interfaces; using DamageAssesment.Api.Responses.Models; +using DamageAssesment.Api.Responses.Services; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Internal; +using System.Reflection; +using System.Text.Json; namespace DamageAssesment.Api.Responses.Providers { @@ -57,7 +61,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(); } } @@ -125,6 +128,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 @@ -132,7 +136,7 @@ namespace DamageAssesment.Api.Responses.Providers logger?.LogInformation("Querying to get SurveyResponse object from DB"); //get all the survey that already taken by the employee var surveys = await surveyServiceProvider.getSurveysAsync(language, token); - surveys = surveys.Where(s => s.IsEnabled == true && s.StartDate <= DateTime.Now && s.EndDate >= DateTime.Now).ToList(); + surveys = surveys.Where(s => s.IsEnabled == true && s.Status == SurveyStatus.ACTIVE.ToString()).ToList(); 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(); @@ -152,9 +156,9 @@ namespace DamageAssesment.Api.Responses.Providers { logger?.LogInformation("Querying to get SurveyResponse object from DB"); - var surveys = await surveyServiceProvider.getSurveysAsync(language,token); + var surveys = await surveyServiceProvider.getSurveysAsync(language, token); // returning only historic data: end date is less than current date. - surveys = surveys.Where(s => s.EndDate < DateTime.Now).ToList(); + surveys = surveys.Where(s => s.Status == SurveyStatus.INACTIVE.ToString()).ToList(); if (employeeid == null || employeeid == 0) return (true, surveys, null); var surveyResponses = await surveyResponseDbContext.SurveyResponses.Where(x => x.EmployeeId == employeeid).ToListAsync(); @@ -177,7 +181,7 @@ namespace DamageAssesment.Api.Responses.Providers try { logger?.LogInformation("Querying to get Survey object from microservice"); - var survey = await surveyServiceProvider.getSurveyAsync(surveyId,token); + var survey = await surveyServiceProvider.getSurveyAsync(surveyId, token); if (survey != null) { @@ -271,7 +275,7 @@ namespace DamageAssesment.Api.Responses.Providers { logger?.LogInformation("Querying to get Survey object from microservice"); var survey = await surveyServiceProvider.getSurveyAsync(surveyId, token); - var question = await questionServiceProvider.getQuestionsAsync(questionId,token); + var question = await questionServiceProvider.getQuestionsAsync(questionId, token); bool IsCorrectAnswer = answer.ToLower().Equals("yes") || answer.ToLower().Equals("no") ? true : false; @@ -320,6 +324,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) { @@ -500,7 +524,7 @@ namespace DamageAssesment.Api.Responses.Providers { var employee = await employeeServiceProvider.getEmployeeAsync(surveyResponse.EmployeeId, token); var answers = await answerServiceProvider.GetAnswersByResponseIdAsync(surveyResponse.Id, token); - var allQuestions = await questionServiceProvider.getQuestionsAsync(token); + var allQuestions = await questionServiceProvider.getQuestionsAsync(null, token); var questions = allQuestions.Where(s => s.SurveyId == surveyResponse.SurveyId); var attachments = await attachmentServiceProvider.getAttachmentsAsync(token); @@ -541,10 +565,22 @@ namespace DamageAssesment.Api.Responses.Providers { try { - var surveyResonses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == surveyId).ToListAsync(); - var employees = await employeeServiceProvider.getEmployeesAsync(token); + List surveyResonses = null; + Employee employee = null; + List employees = null; + if (employeeid == 0) + { + surveyResonses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == surveyId).ToListAsync(); + employees = await employeeServiceProvider.getEmployeesAsync(token); + } + else + { + surveyResonses = await surveyResponseDbContext.SurveyResponses.Where(x => x.SurveyId == surveyId && x.EmployeeId == employeeid).ToListAsync(); + employee = await employeeServiceProvider.getEmployeeAsync(employeeid, token); + } + var answers = await answerServiceProvider.getAnswersAsync(token); - var questions = await questionServiceProvider.getQuestionsAsync(token); + var questions = await questionServiceProvider.getQuestionsAsync(null, token); var surveyQuestions = from q in questions where q.SurveyId == surveyId select q; //var surveyQuestions = await questionServiceProvider.getSurveyQuestionsAsync(surveyId); @@ -612,7 +648,7 @@ namespace DamageAssesment.Api.Responses.Providers var answers = await answerServiceProvider.getAnswersAsync(token); - var questions = await questionServiceProvider.getQuestionsAsync(token); + var questions = await questionServiceProvider.getQuestionsAsync(null, token); var attachments = await attachmentServiceProvider.getAttachmentsAsync(token); var result = from r in surveyResonses @@ -647,7 +683,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(token); + var Locations = await locationServiceProvider.getLocationsAsync(token); + var regions = await regionServiceProvider.getRegionsAsync(token); + var questions = await questionServiceProvider.getQuestionsAsync(language, token); + var categories = await questionServiceProvider.GetQuestionCategoriesAsync(language, token); + var attachments = await attachmentServiceProvider.getAttachmentsAsync(token); + 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) @@ -744,7 +909,7 @@ namespace DamageAssesment.Api.Responses.Providers } var answers = await answerServiceProvider.getAnswersAsync(token); - var questions = await questionServiceProvider.getQuestionsAsync(token); + var questions = await questionServiceProvider.getQuestionsAsync(null, token); var surveyQuestions = from q in questions where q.SurveyId == surveyId select q; var attachments = await attachmentServiceProvider.getAttachmentsAsync(token); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/QuestionServiceProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/QuestionServiceProvider.cs index 4f2e75f..70e33f6 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/QuestionServiceProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/Services/QuestionServiceProvider.cs @@ -10,11 +10,13 @@ namespace DamageAssesment.Api.Responses.Services { } - public async Task> getQuestionsAsync(string token) + public async Task> getQuestionsAsync(string language, string token) { try { - var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null,token); + if (!string.IsNullOrEmpty(language)) + url = url + "/" + language; + var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null, token); var questions = JsonConvert.DeserializeObject>(responseJsonString); if (questions == null || !questions.Any()) @@ -27,7 +29,27 @@ namespace DamageAssesment.Api.Responses.Services return new List(); } } + public async Task> GetQuestionCategoriesAsync(string? language, string token) + { + try + { + url = urlBase + configuration.GetValue("RessourceSettings:QuestionCategory"); + if (!string.IsNullOrEmpty(language)) + url = url + "/" + language; + var responseJsonString = await httpUtil.SendAsync(HttpMethod.Get, url, null, token); + 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, string token) { try @@ -37,7 +59,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 e76acbb..3118bbf 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Responses/appsettings.json +++ b/DamageAssesmentApi/DamageAssesment.Api.Responses/appsettings.json @@ -14,6 +14,15 @@ "ResponsesConnection": "Server=tcp:da-dev.database.windows.net,1433;Initial Catalog=da-dev-db;Encrypt=True;User ID=admin-dev;Password=b3tgRABw8LGE75k;TrustServerCertificate=False;Connection Timeout=30;" }, + //"EndPointSettings": { + // "AnswerUrlBase": "http://localhost:5200", + // "LocationUrlBase": "http://localhost:5213", + // "RegionUrlBase": "http://localhost:5211", + // "QuestionUrlBase": "http://localhost:5133", + // "EmployeeUrlBase": "http://localhost:5135", + // "AttachmentUrlBase": "http://localhost:5243", + // "SurveyUrlBase": "http://localhost:5009" + //}, "EndPointSettings": { "AnswerUrlBase": "http://damageassesment.api.answers:80", "LocationUrlBase": "http://damageassesment.api.locations:80", @@ -28,6 +37,7 @@ "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/Db/Survey.cs b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Db/Survey.cs index aa49acc..2f19281 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Db/Survey.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Db/Survey.cs @@ -13,9 +13,9 @@ namespace DamageAssesment.Api.Surveys.Db public bool IsEnabled { get; set; } - public DateTime StartDate { get; set; } + public DateTime? StartDate { get; set; } - public DateTime EndDate { get; set; } + public DateTime? EndDate { get; set; } public DateTime CreatedDate { get; set; } = DateTime.Now; /* diff --git a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Models/Survey.cs b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Models/Survey.cs index 25f5405..746047c 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Models/Survey.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Models/Survey.cs @@ -2,9 +2,16 @@ namespace DamageAssesment.Api.Surveys.Models { + public enum SurveyStatus + { + PENDING, + ACTIVE, + INACTIVE + } public class MultiLanSurvey : BaseSurvey { public object Titles { get; set; } + public string Status { get; set; } } public class Survey : BaseSurvey { @@ -14,8 +21,8 @@ namespace DamageAssesment.Api.Surveys.Models { public int Id { get; set; } public bool IsEnabled { get; set; } - public DateTime StartDate { get; set; } - public DateTime EndDate { get; set; } - public DateTime CreatedDate { get; set; } + public DateTime? StartDate { get; set; } + public DateTime? EndDate { get; set; } + public DateTime? CreatedDate { get; set; } } } diff --git a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Providers/SurveysProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Providers/SurveysProvider.cs index 5acb580..359238b 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Providers/SurveysProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Providers/SurveysProvider.cs @@ -26,9 +26,9 @@ namespace DamageAssesment.Api.Surveys.Providers { if (!surveyDbContext.Surveys.Any()) { - var survey1 = new Db.Survey { IsEnabled = true, StartDate = DateTime.Now, EndDate = DateTime.Now.AddDays(90), CreatedDate = DateTime.Now }; - var survey2 = new Db.Survey { IsEnabled = true, StartDate = DateTime.Now, EndDate = DateTime.Now.AddDays(90), CreatedDate = DateTime.Now }; - var survey3 = new Db.Survey { IsEnabled = true, StartDate = DateTime.Now, EndDate = DateTime.Now.AddDays(90), CreatedDate = DateTime.Now }; + var survey1 = new Db.Survey { IsEnabled = true, StartDate = DateTime.Now.AddDays(10), EndDate = DateTime.Now.AddDays(90), CreatedDate = DateTime.Now }; + var survey2 = new Db.Survey { IsEnabled = true, StartDate = DateTime.Now.AddDays(-10), EndDate = DateTime.Now.AddDays(90), CreatedDate = DateTime.Now.AddDays(-10) }; + var survey3 = new Db.Survey { IsEnabled = true, StartDate = DateTime.Now.AddDays(-100), EndDate = DateTime.Now.AddDays(-10), CreatedDate = DateTime.Now.AddDays(-100) }; surveyDbContext.Surveys.Add(survey1); surveyDbContext.Surveys.Add(survey2); @@ -85,7 +85,22 @@ namespace DamageAssesment.Api.Surveys.Providers MultiLanguage = dict; return MultiLanguage; } - + public string GetStatus(DateTime? StartDate,DateTime? EndDate) + { + try + { + if (StartDate > DateTime.Now) + return SurveyStatus.PENDING.ToString(); + else if (StartDate <= DateTime.Now && EndDate > DateTime.Now) + return SurveyStatus.ACTIVE.ToString(); + else + return SurveyStatus.INACTIVE.ToString(); + } + catch + { + return SurveyStatus.INACTIVE.ToString(); + } + } // Method to get surveys asynchronously with multi-language support public async Task<(bool IsSuccess, IEnumerable Surveys, string ErrorMessage)> GetSurveysAsync(string language) { @@ -105,6 +120,7 @@ namespace DamageAssesment.Api.Surveys.Providers EndDate = s.EndDate, IsEnabled = s.IsEnabled, CreatedDate = s.CreatedDate, + Status= GetStatus(s.StartDate,s.EndDate), Titles = CreateMultiLanguageObject(GetSurveyTranslations(s.Id, null, language)) }; @@ -126,7 +142,8 @@ namespace DamageAssesment.Api.Surveys.Providers try { logger?.LogInformation("Query Survey"); - var survey = await surveyDbContext.Surveys.SingleOrDefaultAsync(s => s.Id == id && s.IsEnabled == true); + // removed is enabled becuase we are using it in responses to get response + var survey = await surveyDbContext.Surveys.SingleOrDefaultAsync(s => s.Id == id); if (survey != null) { @@ -139,6 +156,7 @@ namespace DamageAssesment.Api.Surveys.Providers EndDate = survey.EndDate, IsEnabled = survey.IsEnabled, CreatedDate = survey.CreatedDate, + Status = GetStatus(survey.StartDate, survey.EndDate), Titles = CreateMultiLanguageObject(GetSurveyTranslations(survey.Id, null, language)) }; logger?.LogInformation($"Survey Id: {id} found"); @@ -172,6 +190,7 @@ namespace DamageAssesment.Api.Surveys.Providers } await surveyDbContext.SaveChangesAsync(); var result = mapper.Map(_survey); + result.Status = GetStatus(_survey.StartDate, _survey.EndDate); result.Titles = CreateMultiLanguageObject(GetSurveyTranslations(_survey.Id, survey.Titles, "")); return (true, result, "Successful"); } @@ -205,17 +224,16 @@ 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(); var result = mapper.Map(_survey); + result.Status = GetStatus(_survey.StartDate, _survey.EndDate); result.Titles = CreateMultiLanguageObject(GetSurveyTranslations(_survey.Id, survey.Titles, "")); return (true, result, "Successful"); } @@ -248,6 +266,7 @@ namespace DamageAssesment.Api.Surveys.Providers if (survey != null) { var result = mapper.Map(survey); + result.Status = GetStatus(survey.StartDate, survey.EndDate); result.Titles = CreateMultiLanguageObject(GetSurveyTranslations(survey.Id, null, "")); surveyDbContext.Surveys.Remove(survey); await surveyDbContext.SaveChangesAsync(); diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Controllers/UsersAccessController.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Controllers/UsersAccessController.cs index e0aae67..755b21e 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Controllers/UsersAccessController.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Controllers/UsersAccessController.cs @@ -14,6 +14,16 @@ namespace DamageAssesment.Api.UsersAccess.Controllers { this.userAccessProvider = userAccessProvider; } + [HttpPost("dadeschooltoken")] + public async Task DadeSchoolAuthenticateAsync(string username, string password) + { + var result = await userAccessProvider.DadeSchoolAuthenticateAsync(username, password); + if (result.IsSuccess) + { + return Ok(result.TokenResponse); + } + return Unauthorized(result.ErrorMessage); + } [Authorize(Policy = "Dadeschools")] [HttpPost("token/{employecode}")] public async Task AuthenticateAsync(string employecode) diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/DamageAssesment.Api.UsersAccess.csproj b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/DamageAssesment.Api.UsersAccess.csproj index 6c6eb21..264aea4 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/DamageAssesment.Api.UsersAccess.csproj +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/DamageAssesment.Api.UsersAccess.csproj @@ -4,6 +4,8 @@ net6.0 enable enable + Linux + ..\docker-compose.dcproj @@ -22,6 +24,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Dockerfile b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Dockerfile new file mode 100644 index 0000000..35ca369 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Dockerfile @@ -0,0 +1,21 @@ +#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base +WORKDIR /app +EXPOSE 80 + +FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +WORKDIR /src +COPY ["DamageAssesment.Api.UsersAccess/DamageAssesment.Api.UsersAccess.csproj", "DamageAssesment.Api.UsersAccess/"] +RUN dotnet restore "DamageAssesment.Api.UsersAccess/DamageAssesment.Api.UsersAccess.csproj" +COPY . . +WORKDIR "/src/DamageAssesment.Api.UsersAccess" +RUN dotnet build "DamageAssesment.Api.UsersAccess.csproj" -c Release -o /app/build + +FROM build AS publish +RUN dotnet publish "DamageAssesment.Api.UsersAccess.csproj" -c Release -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "DamageAssesment.Api.UsersAccess.dll"] \ No newline at end of file diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Interfaces/IUsersAccessProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Interfaces/IUsersAccessProvider.cs index ea64376..6a70a5b 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Interfaces/IUsersAccessProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Interfaces/IUsersAccessProvider.cs @@ -11,6 +11,7 @@ namespace DamageAssesment.Api.UsersAccess.Interfaces public Task<(bool IsSuccess, Models.User User, string ErrorMessage)> DeleteUserAsync(int Id); public Task<(bool IsSuccess, IEnumerable Roles, string ErrorMessage)> GetRolesAsync(); public Task<(bool IsSuccess, Models.TokenResponse TokenResponse, string ErrorMessage)> AuthenticateAsync(string employeCode); + public Task<(bool IsSuccess, Models.DadeSchoolToken TokenResponse, string ErrorMessage)> DadeSchoolAuthenticateAsync(string username, string password); public Task<(bool IsSuccess, Models.TokenResponse TokenResponse, string ErrorMessage)>RefreshTokenAsync(TokenResponse tokenResponse); public void seedData(); } diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Models/DadeSchoolToken.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Models/DadeSchoolToken.cs new file mode 100644 index 0000000..6b88ea5 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Models/DadeSchoolToken.cs @@ -0,0 +1,10 @@ +namespace DamageAssesment.Api.UsersAccess.Models +{ + public class DadeSchoolToken + { + public string access_token { get; set; } + public int expires_in { get; set; } + public string token_type { get; set; } + public string scope { get; set; } + } +} diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Properties/launchSettings.json b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Properties/launchSettings.json index 859e680..91b8925 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Properties/launchSettings.json +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Properties/launchSettings.json @@ -17,7 +17,9 @@ "applicationUrl": "http://localhost:5027", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - } + }, + "dotnetRunMessages": true, + "applicationUrl": "http://localhost:5027" }, "IIS Express": { "commandName": "IISExpress", @@ -26,6 +28,21 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } + }, + "Docker": { + "commandName": "Docker", + "launchBrowser": true, + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", + "publishAllPorts": true + } + }, + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:28382", + "sslPort": 0 } } -} +} \ No newline at end of file diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Providers/UserAccessProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Providers/UserAccessProvider.cs index 63a9772..939ca4e 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Providers/UserAccessProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/Providers/UserAccessProvider.cs @@ -6,6 +6,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; using System.Data; +using Newtonsoft.Json; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; @@ -19,9 +20,10 @@ namespace DamageAssesment.Api.UsersAccess.Providers private readonly IMapper mapper; //private readonly IEmployeeServiceProvider employeeServiceProvider; private readonly JwtSettings jwtSettings; - private readonly ITokenServiceProvider tokenServiceProvider; + private readonly ITokenServiceProvider tokenServiceProvider; + private readonly IConfiguration configuration; - public UsersAccessProvider(IOptions options, ITokenServiceProvider tokenServiceProvider, UsersAccessDbContext userAccessDbContext, IEmployeeServiceProvider employeeServiceProvider, ILogger logger, IMapper mapper) + public UsersAccessProvider(IConfiguration configuration,IOptions options, ITokenServiceProvider tokenServiceProvider, UsersAccessDbContext userAccessDbContext, IEmployeeServiceProvider employeeServiceProvider, ILogger logger, IMapper mapper) { this.userAccessDbContext = userAccessDbContext; //this.employeeServiceProvider = employeeServiceProvider; @@ -29,26 +31,27 @@ namespace DamageAssesment.Api.UsersAccess.Providers this.mapper = mapper; jwtSettings = options.Value; this.tokenServiceProvider = tokenServiceProvider; - // seedData(); + this.configuration = configuration; + // seedData(); } public void seedData() { if (!userAccessDbContext.Users.Any()) { - userAccessDbContext.Users.Add(new Db.User { Id = 1, EmployeeId = 1, EmployeeCode = "Emp1", RoleId = 1, IsActive = true, CreateDate = DateTime.Now }); - userAccessDbContext.Users.Add(new Db.User { Id = 2, EmployeeId = 2, EmployeeCode = "Emp2", RoleId = 2, IsActive = true, CreateDate = DateTime.Now }); - userAccessDbContext.Users.Add(new Db.User { Id = 3, EmployeeId = 3, EmployeeCode = "Emp3", RoleId = 3, IsActive = true, CreateDate = DateTime.Now }); + userAccessDbContext.Users.Add(new Db.User { EmployeeId = 1, EmployeeCode = "Emp1", RoleId = 1, IsActive = true, CreateDate = DateTime.Now }); + userAccessDbContext.Users.Add(new Db.User { EmployeeId = 2, EmployeeCode = "Emp2", RoleId = 2, IsActive = true, CreateDate = DateTime.Now }); + //userAccessDbContext.Users.Add(new Db.User { EmployeeId = 3, EmployeeCode = "Emp3", RoleId = 3, IsActive = true, CreateDate = DateTime.Now }); userAccessDbContext.SaveChanges(); } if (!userAccessDbContext.Roles.Any()) { - userAccessDbContext.Roles.Add(new Db.Role { Id = 1, Name = "admin", Description ="Administrator role have full access" }); - userAccessDbContext.Roles.Add(new Db.Role { Id = 2, Name = "user", Description =" User role"}); - userAccessDbContext.Roles.Add(new Db.Role { Id = 3, Name = "survey", Description ="Survey role" }); - userAccessDbContext.Roles.Add(new Db.Role { Id = 4, Name = "report", Description ="Report role"}); - userAccessDbContext.Roles.Add(new Db.Role { Id = 5, Name = "document", Description ="Document role" }); + userAccessDbContext.Roles.Add(new Db.Role { Name = "admin", Description ="Administrator role have full access" }); + userAccessDbContext.Roles.Add(new Db.Role { Name = "user", Description =" User role"}); + userAccessDbContext.Roles.Add(new Db.Role { Name = "survey", Description ="Survey role" }); + userAccessDbContext.Roles.Add(new Db.Role { Name = "report", Description ="Report role"}); + userAccessDbContext.Roles.Add(new Db.Role { Name = "document", Description ="Document role" }); userAccessDbContext.SaveChanges(); } } @@ -187,7 +190,35 @@ namespace DamageAssesment.Api.UsersAccess.Providers return (false, null, ex.Message); } } + public async Task<(bool IsSuccess, DadeSchoolToken TokenResponse, string ErrorMessage)> DadeSchoolAuthenticateAsync(string username, string password) + { + try + { + var client = new HttpClient(); + var request = new HttpRequestMessage(HttpMethod.Post, configuration.GetValue("Dadeschools:TokenUrl")); + var collection = new List>(); + collection.Add(new("client_id", configuration.GetValue("Dadeschools:TokenClientId"))); + collection.Add(new("client_secret", configuration.GetValue("Dadeschools:TokenClientSecret"))); + collection.Add(new("scope", configuration.GetValue("Dadeschools:scope"))); + collection.Add(new("grant_type", configuration.GetValue("Dadeschools:grant_type"))); + collection.Add(new("username", username)); + collection.Add(new("password", password)); + var content = new FormUrlEncodedContent(collection); + request.Content = content; + var response = await client.SendAsync(request); + var responseString = await response.Content.ReadAsStringAsync(); + if (response.IsSuccessStatusCode) + { + return (true, JsonConvert.DeserializeObject(responseString), ""); + } + return (false, null, responseString); + } + catch (Exception ex) + { + return (false, null, ex.Message); + } + } public async Task<(bool IsSuccess, TokenResponse TokenResponse, string ErrorMessage)> AuthenticateAsync(string employecode) { diff --git a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/appsettings.json b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/appsettings.json index b86718e..d4e399a 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/appsettings.json +++ b/DamageAssesmentApi/DamageAssesment.Api.UsersAccess/appsettings.json @@ -21,6 +21,10 @@ "TokenUrl": "https://dev-graph.dadeschools.net/connect/token", "ClientId": "dmapi", "ClientSecret": "bfce2c8d-2064-4a02-b19d-7f1d42b16eae", + "TokenClientId": "damage_assessment_postman", + "TokenClientSecret": "e4774164-f018-44c9-b9d2-3a29fc21db3c", + "scope": "openid profile", + "grant_type": "password", "Name": "Dadeschools Identity Server" }, "Scopes": [ diff --git a/DamageAssesmentApi/DamageAssesment.sln b/DamageAssesmentApi/DamageAssesment.sln index a6c9a8f..fce9c66 100644 --- a/DamageAssesmentApi/DamageAssesment.sln +++ b/DamageAssesmentApi/DamageAssesment.sln @@ -11,7 +11,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DamageAssesment.Api.Attachm EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4CB40DC2-D9D2-4384-A7A6-9968F5C777A2}" ProjectSection(SolutionItems) = preProject - ..\..\..\..\Sample\Migrations.ps1 = ..\..\..\..\Sample\Migrations.ps1 + ..\db\migrate-sqldb_v1.ps1 = ..\db\migrate-sqldb_v1.ps1 + ..\..\Sample\Migrations.ps1 = ..\..\Sample\Migrations.ps1 ReadMe.txt = ReadMe.txt ReadMe4Dev.txt = ReadMe4Dev.txt EndProjectSection diff --git a/DamageAssesmentApi/docker-compose.acr.yml b/DamageAssesmentApi/docker-compose.acr.yml new file mode 100644 index 0000000..b275839 --- /dev/null +++ b/DamageAssesmentApi/docker-compose.acr.yml @@ -0,0 +1,75 @@ +version: '3.4' + +services: + damageassesment.api.answers: + image: dadeschoolscontainerregistry.azurecr.io/damageassesmentapianswers + build: + context: . + dockerfile: DamageAssesment.Api.Answers/Dockerfile + ports: + - "6001:80" + command: bash -c "docker push dadeschoolscontainerregistry.azurecr.io/damageassesmentapianswers" + + damageassesment.api.attachments: + image: dadeschoolscontainerregistry.azurecr.io/damageassesmentapiattachments + build: + context: . + dockerfile: DamageAssesment.Api.Attachments/Dockerfile + ports: + - "6001:80" + command: bash -c "docker push dadeschoolscontainerregistry.azurecr.io/damageassesmentapiattachments" + + damageassesment.api.employees: + image: dadeschoolscontainerregistry.azurecr.io/damageassesmentapiemployees + build: + context: . + dockerfile: DamageAssesment.Api.Employees/Dockerfile + ports: + - "6003:80" + command: bash -c "docker push dadeschoolscontainerregistry.azurecr.io/damageassesmentapiemployees" + + damageassesment.api.locations: + image: dadeschoolscontainerregistry.azurecr.io/damageassesmentapilocations + build: + context: . + dockerfile: DamageAssesment.Api.Locations/Dockerfile + ports: + - "6004:80" + command: bash -c "docker push dadeschoolscontainerregistry.azurecr.io/damageassesmentapilocations" + + damageassesment.api.questions: + image: dadeschoolscontainerregistry.azurecr.io/damageassesmentapiquestions + build: + context: . + dockerfile: DamageAssesment.Api.Questions/Dockerfile + ports: + - "6005:80" + command: bash -c "docker push dadeschoolscontainerregistry.azurecr.io/damageassesmentapiquestions" + + damageassesment.api.surveys: + image: dadeschoolscontainerregistry.azurecr.io/damageassesmentapisurveys + build: + context: . + dockerfile: DamageAssesment.Api.Surveys/Dockerfile + ports: + - "6006:80" + command: bash -c "docker push dadeschoolscontainerregistry.azurecr.io/damageassesmentapisurveys" + + damageassesment.api.doculinks: + image: dadeschoolscontainerregistry.azurecr.io/damageassesmentapidoculinks + build: + context: . + dockerfile: DamageAssesment.Api.DocuLinks/Dockerfile + ports: + - "6008:80" + command: bash -c "docker push dadeschoolscontainerregistry.azurecr.io/damageassesmentapidoculinks" + + damageassesment.api.responses: + image: dadeschoolscontainerregistry.azurecr.io/damageassesmentapiresponses + build: + context: . + dockerfile: DamageAssesment.Api.Responses/Dockerfile + ports: + - "6007:80" + command: bash -c "docker push dadeschoolscontainerregistry.azurecr.io/damageassesmentapiresponses" + diff --git a/DamageAssesmentApi/docker-compose.dcproj b/DamageAssesmentApi/docker-compose.dcproj index 178f3d6..185e0e4 100644 --- a/DamageAssesmentApi/docker-compose.dcproj +++ b/DamageAssesmentApi/docker-compose.dcproj @@ -9,6 +9,7 @@ damageassesment.api.answers + diff --git a/DamageAssesmentApi/docker-compose.override.yml b/DamageAssesmentApi/docker-compose.override.yml index c05d349..c45f8e0 100644 --- a/DamageAssesmentApi/docker-compose.override.yml +++ b/DamageAssesmentApi/docker-compose.override.yml @@ -55,6 +55,12 @@ services: ports: - "6007:80" + + damageassesment.api.usersaccess: + environment: + - ASPNETCORE_ENVIRONMENT=Development + ports: + - "6008:80" damageassesment.api.doculinks: environment: @@ -64,3 +70,5 @@ services: + + diff --git a/DamageAssesmentApi/docker-compose.yml b/DamageAssesmentApi/docker-compose.yml index 0e6f487..b7b8c90 100644 --- a/DamageAssesmentApi/docker-compose.yml +++ b/DamageAssesmentApi/docker-compose.yml @@ -55,3 +55,10 @@ services: context: . dockerfile: DamageAssesment.Api.Responses/Dockerfile + + damageassesment.api.usersaccess: + image: ${DOCKER_REGISTRY-}damageassesmentapiusersaccess + build: + context: . + dockerfile: DamageAssesment.Api.UsersAccess/Dockerfile + diff --git a/DamageAssesmentApi/launchSettings.json b/DamageAssesmentApi/launchSettings.json index eebfc00..ca7ee86 100644 --- a/DamageAssesmentApi/launchSettings.json +++ b/DamageAssesmentApi/launchSettings.json @@ -12,7 +12,8 @@ "damageassesment.api.surveyresponses": "StartDebugging", "damageassesment.api.surveys": "StartDebugging", "damageassesment.api.doculinks": "StartDebugging", - "damageassesment.api.responses": "StartDebugging" + "damageassesment.api.responses": "StartDebugging", + "damageassesment.api.usersaccess": "StartDebugging" } } } diff --git a/db/migrate-sqldb_v1.ps1 b/db/migrate-sqldb_v1.ps1 index 699f0e6..9701f9c 100644 --- a/db/migrate-sqldb_v1.ps1 +++ b/db/migrate-sqldb_v1.ps1 @@ -10,7 +10,8 @@ $microservices = @( "DamageAssesment.Api.Locations", "DamageAssesment.Api.Questions", "DamageAssesment.Api.Responses", - "DamageAssesment.Api.Surveys" + "DamageAssesment.Api.Surveys", + "DamageAssesment.Api.UsersAccess" )