From 47b0c7b202264fba2c88bdc5bef7966d9fe54e6b Mon Sep 17 00:00:00 2001 From: Reginald Cherenfant Jasmin Date: Fri, 25 Aug 2023 08:55:11 -0400 Subject: [PATCH] Update Question and Survey to support multilingual functionnality and Make language optional in URL --- .../Controllers/QuestionsController.cs | 27 +-- .../Interfaces/IQuestionsProvider.cs | 4 +- .../Providers/QuestionsProvider.cs | 76 +++++--- .../QuestionsServiceTest.cs | 25 +-- .../Models/Survey.cs | 18 +- .../Models/SurveyTranslation.cs | 13 ++ .../MockData.cs | 4 +- .../SurveyServiceTest.cs | 16 +- .../Controllers/SurveysController.cs | 27 +-- .../DamageAssesment.Api.Surveys/Db/Survey.cs | 16 +- .../Db/SurveyTranslation.cs | 23 +++ .../Db/SurveysDbContext.cs | 2 +- .../Interfaces/ISurveyProvider.cs | 4 +- .../Models/Survey.cs | 18 +- .../Models/SurveyTranslation.cs | 13 ++ .../Providers/SurveysProvider.cs | 169 ++++++++++++++++-- 16 files changed, 321 insertions(+), 134 deletions(-) create mode 100644 DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/SurveyTranslation.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Surveys/Db/SurveyTranslation.cs create mode 100644 DamageAssesmentApi/DamageAssesment.Api.Surveys/Models/SurveyTranslation.cs diff --git a/DamageAssesmentApi/DamageAssesment.Api.Questions/Controllers/QuestionsController.cs b/DamageAssesmentApi/DamageAssesment.Api.Questions/Controllers/QuestionsController.cs index 0184d72..d376c20 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Questions/Controllers/QuestionsController.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Questions/Controllers/QuestionsController.cs @@ -1,8 +1,4 @@ -using DamageAssesment.Api.Questions.Db; -using DamageAssesment.Api.Questions.Interfaces; -using DamageAssesment.Api.Questions.Models; -using DamageAssesment.Api.Questions.Providers; -using Microsoft.AspNetCore.Http; +using DamageAssesment.Api.Questions.Interfaces; using Microsoft.AspNetCore.Mvc; namespace DamageAssesment.Api.Questions.Controllers @@ -20,10 +16,12 @@ namespace DamageAssesment.Api.Questions.Controllers } // get all questions - [HttpGet("Questions")] - public async Task GetQuestionsAsync() + [Route("{Language}/Questions")] + [Route("Questions")] + [HttpGet] + public async Task GetQuestionsAsync(string? Language) { - var result = await this.questionsProvider.GetQuestionsAsync(); + var result = await this.questionsProvider.GetQuestionsAsync(Language); if (result.IsSuccess) { return Ok(result.Questions); @@ -31,10 +29,12 @@ namespace DamageAssesment.Api.Questions.Controllers return NoContent(); } //Get questions based on question id - [HttpGet("Questions/{id}")] - public async Task GetQuestionAsync(int id) + [Route("{Language}/Questions/{id}")] + [Route("Questions/{id}")] + [HttpGet] + public async Task GetQuestionAsync(int id, string? Language) { - var result = await this.questionsProvider.GetQuestionAsync(id); + var result = await this.questionsProvider.GetQuestionAsync(id,Language); if (result.IsSuccess) { return Ok(result.Question); @@ -42,10 +42,11 @@ namespace DamageAssesment.Api.Questions.Controllers return NotFound(); } //get all questions based on survey id - [HttpGet("GetSurveyQuestions/{surveyId}")] + [Route("{Language}/GetSurveyQuestions/{surveyId}")] + [Route("GetSurveyQuestions/{surveyId}")] + [HttpGet] public async Task GetSurveyQuestions(int surveyId,string? Language) { - if (string.IsNullOrEmpty(Language)) Language = "en"; var result = await this.questionsProvider.GetSurveyQuestionAsync(surveyId, Language); if (result.IsSuccess) { diff --git a/DamageAssesmentApi/DamageAssesment.Api.Questions/Interfaces/IQuestionsProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Questions/Interfaces/IQuestionsProvider.cs index 0f62339..43aa2e3 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Questions/Interfaces/IQuestionsProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Questions/Interfaces/IQuestionsProvider.cs @@ -4,8 +4,8 @@ namespace DamageAssesment.Api.Questions.Interfaces { public interface IQuestionsProvider : IQuestionTypesProvider { - Task<(bool IsSuccess, Models.Question Question, string ErrorMessage)> GetQuestionAsync(int Id); - Task<(bool IsSuccess, IEnumerable Questions, string ErrorMessage)> GetQuestionsAsync(); + Task<(bool IsSuccess, Models.Question Question, string ErrorMessage)> GetQuestionAsync(int Id, string Language); + 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.Question Question, string ErrorMessage)> PostQuestionAsync(Models.Question Question); Task<(bool IsSuccess, Models.Question Question, string ErrorMessage)> UpdateQuestionAsync(Models.Question Question); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Questions/Providers/QuestionsProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Questions/Providers/QuestionsProvider.cs index 647f640..f684a9f 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Questions/Providers/QuestionsProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Questions/Providers/QuestionsProvider.cs @@ -31,7 +31,7 @@ namespace DamageAssesment.Api.Questions.Providers if (!questionDbContext.QuestionsTranslations.Any()) { - questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() {Id=1, QuestionId = 1, QuestionText = "Can You Open ?",Language="en" }); + questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { Id = 1, QuestionId = 1, QuestionText = "Can You Open ?", Language = "en" }); questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { Id = 2, QuestionId = 1, QuestionText = "Peux-tu ouvrir ?", Language = "fr" }); questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { Id = 3, QuestionId = 2, QuestionText = "Are the grounds flodded ?", Language = "en" }); questionDbContext.QuestionsTranslations.Add(new Db.QuestionsTranslation() { Id = 4, QuestionId = 2, QuestionText = "Les terrains sont-ils inondés ?", Language = "fr" }); @@ -44,9 +44,9 @@ namespace DamageAssesment.Api.Questions.Providers } if (!questionDbContext.Questions.Any()) { - questionDbContext.Questions.Add(new Db.Question() { Id = 1, QuestionTypeId = 2, SurveyId = 1, QuestionNumber = 1, IsRequired = true, Comment = false, Key = true, QuestionGroup = "group1",CategoryId=1 }); - questionDbContext.Questions.Add(new Db.Question() { Id = 2, QuestionTypeId = 1, SurveyId = 1, QuestionNumber = 2, IsRequired = false, Comment = true, Key = false, QuestionGroup = "group1", CategoryId = 1 }); - questionDbContext.Questions.Add(new Db.Question() { Id = 3, QuestionTypeId = 1, SurveyId = 1, QuestionNumber = 3, IsRequired = true, Comment = false, Key = true, QuestionGroup = "group1", CategoryId = 2 }); + questionDbContext.Questions.Add(new Db.Question() { Id = 1, QuestionTypeId = 2, SurveyId = 1, QuestionNumber = 1, IsRequired = true, Comment = false, Key = true, QuestionGroup = "group1", CategoryId = 1 }); + questionDbContext.Questions.Add(new Db.Question() { Id = 2, QuestionTypeId = 1, SurveyId = 1, QuestionNumber = 2, IsRequired = false, Comment = true, Key = false, QuestionGroup = "group1", CategoryId = 1 }); + questionDbContext.Questions.Add(new Db.Question() { Id = 3, QuestionTypeId = 1, SurveyId = 1, QuestionNumber = 3, IsRequired = true, Comment = false, Key = true, QuestionGroup = "group1", CategoryId = 2 }); questionDbContext.SaveChanges(); } if (!questionDbContext.QuestionTypes.Any()) @@ -61,17 +61,17 @@ namespace DamageAssesment.Api.Questions.Providers if (!questionDbContext.QuestionCategories.Any()) { - questionDbContext.QuestionCategories.Add(new Db.QuestionCategory() { Id = 1, CategoryName = "Category 1", CategoryImage="img1" }); + questionDbContext.QuestionCategories.Add(new Db.QuestionCategory() { Id = 1, CategoryName = "Category 1", CategoryImage = "img1" }); questionDbContext.QuestionCategories.Add(new Db.QuestionCategory() { Id = 2, CategoryName = "Category 2", CategoryImage = "img1" }); questionDbContext.QuestionCategories.Add(new Db.QuestionCategory() { Id = 3, CategoryName = "Category 3", CategoryImage = "img1" }); questionDbContext.QuestionCategories.Add(new Db.QuestionCategory() { Id = 4, CategoryName = "Category 4", CategoryImage = "img1" }); - questionDbContext.QuestionCategories.Add(new Db.QuestionCategory() { Id = 5, CategoryName = "Category 5", CategoryImage = "img1" }); + questionDbContext.QuestionCategories.Add(new Db.QuestionCategory() { Id = 5, CategoryName = "Category 5", CategoryImage = "img1" }); questionDbContext.SaveChanges(); } } - public async Task<(bool IsSuccess, IEnumerable Questions, string ErrorMessage)> GetQuestionsAsync() + public async Task<(bool IsSuccess, IEnumerable Questions, string ErrorMessage)> GetQuestionsAsync(string Language) { try { @@ -82,10 +82,20 @@ namespace DamageAssesment.Api.Questions.Providers //logger?.LogInformation($"{question} customer(s) found"); var result = mapper.Map, IEnumerable>(questions); + + foreach (var question in result) { - question.Questions=mapper.Map,List>( - questionDbContext.QuestionsTranslations.Where(a=>a.QuestionId==question.Id).ToList()); + if (string.IsNullOrEmpty(Language)) + { + question.Questions = mapper.Map, List>( + questionDbContext.QuestionsTranslations.Where(a => a.QuestionId == question.Id).ToList()); + } + else + { + question.Questions = mapper.Map, List>( + questionDbContext.QuestionsTranslations.Where(a => a.QuestionId == question.Id && a.Language == Language).ToList()); + } } return (true, result, null); } @@ -97,7 +107,7 @@ namespace DamageAssesment.Api.Questions.Providers return (false, null, ex.Message); } } - public async Task<(bool IsSuccess, Models.Question Question, string ErrorMessage)> GetQuestionAsync(int Id) + public async Task<(bool IsSuccess, Models.Question Question, string ErrorMessage)> GetQuestionAsync(int Id, string Language) { try { @@ -107,8 +117,17 @@ namespace DamageAssesment.Api.Questions.Providers { logger?.LogInformation($"{question} customer(s) found"); var result = mapper.Map(question); - result.Questions = mapper.Map, List>( - questionDbContext.QuestionsTranslations.Where(a => a.QuestionId == result.Id).ToList()); + + if (string.IsNullOrEmpty(Language)) + { + result.Questions = mapper.Map, List>( + questionDbContext.QuestionsTranslations.Where(a => a.QuestionId == result.Id).ToList()); + } + else + { + result.Questions = mapper.Map, List>( + questionDbContext.QuestionsTranslations.Where(a => a.QuestionId == result.Id && a.Language == Language).ToList()); + } return (true, result, null); } return (false, null, "Not found"); @@ -119,12 +138,23 @@ namespace DamageAssesment.Api.Questions.Providers return (false, null, ex.Message); } } - public List GetSurveyQuestion(List questions,string Language) + public List GetSurveyQuestion(List questions, string Language) { - foreach (var item in questions) + if (string.IsNullOrEmpty(Language)) { - item.Questions= mapper.Map, List>( - questionDbContext.QuestionsTranslations.Where(a => a.QuestionId == item.Id && a.Language== Language).ToList()); + foreach (var item in questions) + { + item.Questions = mapper.Map, List>( + questionDbContext.QuestionsTranslations.Where(a => a.QuestionId == item.Id).ToList()); + } + } + else + { + foreach (var item in questions) + { + item.Questions = mapper.Map, List>( + questionDbContext.QuestionsTranslations.Where(a => a.QuestionId == item.Id && a.Language == Language).ToList()); + } } return questions; } @@ -133,12 +163,12 @@ namespace DamageAssesment.Api.Questions.Providers try { logger?.LogInformation("Query Question"); - var questions = await questionDbContext.Questions.Include("QuestionType").Where(a=>a.SurveyId==SurveyId).AsNoTracking().ToListAsync(); + var questions = await questionDbContext.Questions.Include("QuestionType").Where(a => a.SurveyId == SurveyId).AsNoTracking().ToListAsync(); if (questions != null) { List surveyQuestionsList = new List(); - List CategoryIds=questions.Select(a=>a.CategoryId).Distinct().ToList(); - var questioncategories = await questionDbContext.QuestionCategories.Where(a =>CategoryIds.Contains(a.Id)).ToListAsync(); + List CategoryIds = questions.Select(a => a.CategoryId).Distinct().ToList(); + var questioncategories = await questionDbContext.QuestionCategories.Where(a => CategoryIds.Contains(a.Id)).ToListAsync(); //logger?.LogInformation($"{question} customer(s) found"); foreach (var item in questioncategories) { @@ -169,11 +199,11 @@ namespace DamageAssesment.Api.Questions.Providers 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(); + 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(); + questionDbContext.SaveChanges(); Question.Id = dbquestion.Id; return (true, Question, null); } @@ -192,7 +222,7 @@ namespace DamageAssesment.Api.Questions.Providers dbquestion.QuestionTypeId = questionDbContext.QuestionTypes.Where(a => a.TypeText == Question.TypeText).Select(a => a.Id).FirstOrDefault(); questionDbContext.Entry(dbquestion).State = EntityState.Modified; var oldquestions = questionDbContext.QuestionsTranslations.Where(a => a.QuestionId == dbquestion.Id).ToList(); - if(oldquestions!=null) + if (oldquestions != null) questionDbContext.QuestionsTranslations.RemoveRange(oldquestions); dbquestiontranslation.ForEach(i => i.QuestionId = dbquestion.Id); questionDbContext.QuestionsTranslations.AddRange(dbquestiontranslation); @@ -284,7 +314,7 @@ namespace DamageAssesment.Api.Questions.Providers // Question.QuestionType = GetQuestionType(Question.QuestionTypeId); questionDbContext.QuestionCategories.Add(dbQuestionCategory); questionDbContext.SaveChanges(); - QuestionCategory.Id=dbQuestionCategory.Id; + QuestionCategory.Id = dbQuestionCategory.Id; return (true, QuestionCategory, null); } catch (Exception ex) diff --git a/DamageAssesmentApi/DamageAssesment.Api.QuestionsTest/QuestionsServiceTest.cs b/DamageAssesmentApi/DamageAssesment.Api.QuestionsTest/QuestionsServiceTest.cs index b21fa9c..17797c6 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.QuestionsTest/QuestionsServiceTest.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.QuestionsTest/QuestionsServiceTest.cs @@ -1,16 +1,7 @@ - -using AutoMapper; using DamageAssesment.Api.Questions.Controllers; -using DamageAssesment.Api.Questions.Db; using DamageAssesment.Api.Questions.Interfaces; -using DamageAssesment.Api.Questions.Models; -using DamageAssesment.Api.Questions.Profiles; -using DamageAssesment.Api.Questions.Providers; using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata.Internal; using Moq; -using Newtonsoft.Json; using Xunit; namespace DamageAssesment.Api.Questions.Test @@ -22,10 +13,10 @@ namespace DamageAssesment.Api.Questions.Test { var mockQuestionService = new Mock(); var mockResponse = await MockData.getOkResponse(); - mockQuestionService.Setup(service => service.GetQuestionsAsync()).ReturnsAsync(mockResponse); + mockQuestionService.Setup(service => service.GetQuestionsAsync(null)).ReturnsAsync(mockResponse); var QuestionProvider = new QuestionsController(mockQuestionService.Object); - var result = (OkObjectResult)await QuestionProvider.GetQuestionsAsync(); + var result = (OkObjectResult)await QuestionProvider.GetQuestionsAsync(null); Assert.Equal(200, result.StatusCode); } @@ -35,10 +26,10 @@ namespace DamageAssesment.Api.Questions.Test { var mockQuestionService = new Mock(); var mockResponse = await MockData.getNoContentResponse(); - mockQuestionService.Setup(service => service.GetQuestionsAsync()).ReturnsAsync(mockResponse); + mockQuestionService.Setup(service => service.GetQuestionsAsync(null)).ReturnsAsync(mockResponse); var QuestionProvider = new QuestionsController(mockQuestionService.Object); - var result = (NoContentResult)await QuestionProvider.GetQuestionsAsync(); + var result = (NoContentResult)await QuestionProvider.GetQuestionsAsync(null); Assert.Equal(204, result.StatusCode); } @@ -48,10 +39,10 @@ namespace DamageAssesment.Api.Questions.Test { var mockQuestionService = new Mock(); var mockResponse = await MockData.getOkResponse(1); - mockQuestionService.Setup(service => service.GetQuestionAsync(1)).ReturnsAsync(mockResponse); + mockQuestionService.Setup(service => service.GetQuestionAsync(1,null)).ReturnsAsync(mockResponse); var QuestionProvider = new QuestionsController(mockQuestionService.Object); - var result = (OkObjectResult)await QuestionProvider.GetQuestionAsync(1); + var result = (OkObjectResult)await QuestionProvider.GetQuestionAsync(1,null); Assert.Equal(200, result.StatusCode); } @@ -61,10 +52,10 @@ namespace DamageAssesment.Api.Questions.Test { var mockQuestionService = new Mock(); var mockResponse = await MockData.getNotFoundResponse(); - mockQuestionService.Setup(service => service.GetQuestionAsync(99)).ReturnsAsync(mockResponse); + mockQuestionService.Setup(service => service.GetQuestionAsync(99,null)).ReturnsAsync(mockResponse); var QuestionProvider = new QuestionsController(mockQuestionService.Object); - var result = (NotFoundResult)await QuestionProvider.GetQuestionAsync(99); + var result = (NotFoundResult)await QuestionProvider.GetQuestionAsync(99,null); Assert.Equal(404, result.StatusCode); } diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Survey.cs b/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Survey.cs index 04b60e5..506a2f4 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Survey.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/Survey.cs @@ -4,25 +4,11 @@ namespace DamageAssesment.Api.SurveyResponses.Models { public class Survey { - [Key] public int Id { get; set; } - - [StringLength(100)] - public string Title { get; set; } - - //[StringLength(1000)] - //public string Description { get; set; } - public bool IsEnabled { get; set; } - public DateTime? StartDate { get; set; } - public DateTime? EndDate { get; set; } - - //public DateTime CreatedDate { get; set; } - - //[StringLength(6)] - //public string EmployeeID { get; set; } - + public DateTime CreatedDate { get; set; } + public IEnumerable Titles { get; set; } } } diff --git a/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/SurveyTranslation.cs b/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/SurveyTranslation.cs new file mode 100644 index 0000000..29a1b7c --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.SurveyResponses/Models/SurveyTranslation.cs @@ -0,0 +1,13 @@ +namespace DamageAssesment.Api.SurveyResponses.Models +{ + public class SurveyTranslation + { + public string Title { get; set; } + public string Language { get; set; } + } +} + + + + + diff --git a/DamageAssesmentApi/DamageAssesment.Api.Surveys.Test/MockData.cs b/DamageAssesmentApi/DamageAssesment.Api.Surveys.Test/MockData.cs index 6936c04..01972e3 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Surveys.Test/MockData.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Surveys.Test/MockData.cs @@ -15,7 +15,7 @@ namespace DamageAssesment.Api.Survey.Test for (int i = 0; i < 10; i++) { - list.Append(new Surveys.Models.Survey { Id = i, Title = "Survey Title - " + i }); + list.Append(new Surveys.Models.Survey { Id = i, /*Title = "Survey Title - " + i */}); } return (true, list, null); } @@ -45,7 +45,7 @@ namespace DamageAssesment.Api.Survey.Test public static async Task getInputSurveyData() { - return new Surveys.Models.Survey { Id = 100, Title = "Mock survey", IsEnabled= true, StartDate = DateTime.Now, EndDate = DateTime.Now.AddDays(90) }; + return new Surveys.Models.Survey { Id = 100, /*Title = "Mock survey",*/ IsEnabled= true, StartDate = DateTime.Now, EndDate = DateTime.Now.AddDays(90) }; } diff --git a/DamageAssesmentApi/DamageAssesment.Api.Surveys.Test/SurveyServiceTest.cs b/DamageAssesmentApi/DamageAssesment.Api.Surveys.Test/SurveyServiceTest.cs index 1aaf4a6..44f1f6e 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Surveys.Test/SurveyServiceTest.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Surveys.Test/SurveyServiceTest.cs @@ -14,10 +14,10 @@ namespace DamageAssesment.Api.Surveys.Test { var mockSurveyService = new Mock(); var mockResponse = await MockData.getOkResponse(); - mockSurveyService.Setup(service => service.GetSurveysAsync()).ReturnsAsync(mockResponse); + mockSurveyService.Setup(service => service.GetSurveysAsync(null)).ReturnsAsync(mockResponse); var surveyProvider = new SurveysController(mockSurveyService.Object); - var result = (OkObjectResult) await surveyProvider.GetSurveysAsync(); + var result = (OkObjectResult) await surveyProvider.GetSurveysAsync(null); Assert.Equal(200, result.StatusCode); } @@ -27,10 +27,10 @@ namespace DamageAssesment.Api.Surveys.Test { var mockSurveyService = new Mock(); var mockResponse = await MockData.getNoContentResponse(); - mockSurveyService.Setup(service => service.GetSurveysAsync()).ReturnsAsync(mockResponse); + mockSurveyService.Setup(service => service.GetSurveysAsync(null)).ReturnsAsync(mockResponse); var surveyProvider = new SurveysController(mockSurveyService.Object); - var result = (NoContentResult)await surveyProvider.GetSurveysAsync(); + var result = (NoContentResult)await surveyProvider.GetSurveysAsync(null); Assert.Equal(204, result.StatusCode); } @@ -40,10 +40,10 @@ namespace DamageAssesment.Api.Surveys.Test { var mockSurveyService = new Mock(); var mockResponse = await MockData.getOkResponse(1); - mockSurveyService.Setup(service => service.GetSurveysAsync(1)).ReturnsAsync(mockResponse); + mockSurveyService.Setup(service => service.GetSurveysAsync(1,null)).ReturnsAsync(mockResponse); var surveyProvider = new SurveysController(mockSurveyService.Object); - var result = (OkObjectResult)await surveyProvider.GetSurveysAsync(1); + var result = (OkObjectResult)await surveyProvider.GetSurveysAsync(1,null); Assert.Equal(200, result.StatusCode); } @@ -53,10 +53,10 @@ namespace DamageAssesment.Api.Surveys.Test { var mockSurveyService = new Mock(); var mockResponse = await MockData.getNotFoundResponse(); - mockSurveyService.Setup(service => service.GetSurveysAsync(99)).ReturnsAsync(mockResponse); + mockSurveyService.Setup(service => service.GetSurveysAsync(99,null)).ReturnsAsync(mockResponse); var surveyProvider = new SurveysController(mockSurveyService.Object); - var result = (NotFoundResult)await surveyProvider.GetSurveysAsync(99); + var result = (NotFoundResult)await surveyProvider.GetSurveysAsync(99,null); Assert.Equal(404, result.StatusCode); } diff --git a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Controllers/SurveysController.cs b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Controllers/SurveysController.cs index a68fd9f..3115228 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Controllers/SurveysController.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Controllers/SurveysController.cs @@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Mvc; namespace DamageAssesment.Api.Surveys.Controllers { - [Route("api/[controller]")] + [Route("api")] [ApiController] public class SurveysController : ControllerBase { @@ -16,10 +16,13 @@ namespace DamageAssesment.Api.Surveys.Controllers this.surveyProvider = surveyProvider; } + + [Route("Surveys")] + [Route("{Language}/Surveys")] [HttpGet] - public async Task GetSurveysAsync() + public async Task GetSurveysAsync(string? Language) { - var result = await this.surveyProvider.GetSurveysAsync(); + var result = await this.surveyProvider.GetSurveysAsync(Language); if (result.IsSuccess) { return Ok(result.Surveys); @@ -27,10 +30,12 @@ namespace DamageAssesment.Api.Surveys.Controllers return NoContent(); } - [HttpGet("{Id}")] - public async Task GetSurveysAsync(int Id) + [Route("Surveys/{Id}")] + [Route("{Language}/Surveys/{Id}")] + [HttpGet] + public async Task GetSurveysAsync(int Id, string? Language) { - var result = await this.surveyProvider.GetSurveysAsync(Id); + var result = await this.surveyProvider.GetSurveysAsync(Id, Language); if (result.IsSuccess) { return Ok(result.Surveys); @@ -38,7 +43,7 @@ namespace DamageAssesment.Api.Surveys.Controllers return NotFound(); } - [HttpPost] + [HttpPost("Surveys")] public async Task PostSurveysAsync(Models.Survey survey) { var result = await this.surveyProvider.PostSurveyAsync(survey); @@ -49,21 +54,21 @@ namespace DamageAssesment.Api.Surveys.Controllers return BadRequest(result.ErrorMessage); } - [HttpPut("{Id}")] + [HttpPut("Surveys/{Id}")] public async Task PutSurveysAsync(int Id, Models.Survey survey) { - var result = await this.surveyProvider.PutSurveyAsync(Id,survey); + var result = await this.surveyProvider.PutSurveyAsync(Id, survey); if (result.IsSuccess) { return Ok(result.Survey); } if (result.ErrorMessage == "Not Found") return NotFound(result.ErrorMessage); - + return BadRequest(result.ErrorMessage); } - [HttpDelete("{Id}")] + [HttpDelete("Surveys/{Id}")] public async Task DeleteSurveysAsync(int Id) { var result = await this.surveyProvider.DeleteSurveyAsync(Id); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Db/Survey.cs b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Db/Survey.cs index bff0339..36983bd 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Db/Survey.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Db/Survey.cs @@ -1,4 +1,5 @@ using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; namespace DamageAssesment.Api.Surveys.Db { @@ -6,11 +7,6 @@ namespace DamageAssesment.Api.Surveys.Db { [Key] public int Id { get; set; } - - [StringLength(100)] - [Required] - public string Title { get; set; } - //[StringLength(1000)] //public string Description { get; set; } @@ -20,9 +16,11 @@ namespace DamageAssesment.Api.Surveys.Db public DateTime? EndDate { get; set; } - //public DateTime CreatedDate { get; set; } - - //[StringLength(6)] - //public string EmployeeID { get; set; } + public DateTime CreatedDate { get; set; } = DateTime.Now; + /* + [StringLength(10)] + [ForeignKey("Employee")] + public string EmployeeId { get; set; } + */ } } diff --git a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Db/SurveyTranslation.cs b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Db/SurveyTranslation.cs new file mode 100644 index 0000000..340bf12 --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Db/SurveyTranslation.cs @@ -0,0 +1,23 @@ +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; + +namespace DamageAssesment.Api.Surveys.Db +{ + public class SurveyTranslation + { + [Key] + public int Id { get; set; } + [ForeignKey("Survey")] + public int SurveyId { get; set; } + + [StringLength(200)] + [Required] + public string Title { get; set; } + public string Language { get; set; } + } +} + + + + + diff --git a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Db/SurveysDbContext.cs b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Db/SurveysDbContext.cs index 9ff36cf..e912e96 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Db/SurveysDbContext.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Db/SurveysDbContext.cs @@ -9,6 +9,6 @@ namespace DamageAssesment.Api.Surveys.Db } public DbSet Surveys { get; set; } - + public DbSet SurveysTranslation { get; set; } } } diff --git a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Interfaces/ISurveyProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Interfaces/ISurveyProvider.cs index 42c488e..5cfded9 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Interfaces/ISurveyProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Interfaces/ISurveyProvider.cs @@ -2,8 +2,8 @@ { public interface ISurveyProvider { - Task<(bool IsSuccess, IEnumerable< Models.Survey> Surveys, string ErrorMessage)> GetSurveysAsync(); - Task<(bool IsSuccess, Models.Survey Surveys, string ErrorMessage)> GetSurveysAsync(int Id); + Task<(bool IsSuccess, IEnumerable< Models.Survey> Surveys, string ErrorMessage)> GetSurveysAsync(string Language); + Task<(bool IsSuccess, Models.Survey Surveys, string ErrorMessage)> GetSurveysAsync(int Id, string Language); Task<(bool IsSuccess, Models.Survey Survey, string ErrorMessage)> PostSurveyAsync(Models.Survey Survey); Task<(bool IsSuccess, Models.Survey Survey, string ErrorMessage)> PutSurveyAsync(int Id,Models.Survey Survey); Task<(bool IsSuccess, Models.Survey Survey, string ErrorMessage)> DeleteSurveyAsync(int Id); diff --git a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Models/Survey.cs b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Models/Survey.cs index cd5691b..ab741b5 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Models/Survey.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Models/Survey.cs @@ -4,25 +4,11 @@ namespace DamageAssesment.Api.Surveys.Models { public class Survey { - [Key] public int Id { get; set; } - - [StringLength(100)] - public string Title { get; set; } - - //[StringLength(1000)] - // public string? Description { get; set; } - public bool IsEnabled { get; set; } - public DateTime? StartDate { get; set; } - public DateTime? EndDate { get; set; } - - //public DateTime CreatedDate { get; set; } - - //[StringLength(6)] - //public string EmployeeID { get; set; } - + public DateTime CreatedDate { get; set; } + public IEnumerable Titles { get; set; } } } diff --git a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Models/SurveyTranslation.cs b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Models/SurveyTranslation.cs new file mode 100644 index 0000000..64671ee --- /dev/null +++ b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Models/SurveyTranslation.cs @@ -0,0 +1,13 @@ +namespace DamageAssesment.Api.Surveys.Models +{ + public class SurveyTranslation + { + public string Title { get; set; } + public string Language { get; set; } + } +} + + + + + diff --git a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Providers/SurveysProvider.cs b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Providers/SurveysProvider.cs index 3eb111c..abec85a 100644 --- a/DamageAssesmentApi/DamageAssesment.Api.Surveys/Providers/SurveysProvider.cs +++ b/DamageAssesmentApi/DamageAssesment.Api.Surveys/Providers/SurveysProvider.cs @@ -1,7 +1,9 @@ using AutoMapper; using DamageAssesment.Api.Surveys.Db; using DamageAssesment.Api.Surveys.Interfaces; +using DamageAssesment.Api.Surveys.Models; using Microsoft.EntityFrameworkCore; +using System.Collections.Generic; namespace DamageAssesment.Api.Surveys.Providers { @@ -23,24 +25,88 @@ namespace DamageAssesment.Api.Surveys.Providers { if (!surveyDbContext.Surveys.Any()) { - surveyDbContext.Surveys.Add(new Db.Survey { Id = 1, Title = "Sample Survey Title:Damage Assesment 2014", IsEnabled = true, StartDate = DateTime.Now, EndDate = DateTime.Now.AddDays(90) }); - surveyDbContext.Surveys.Add(new Db.Survey { Id = 2, Title = "Sample Survey Title: Damage Assesment 2016", IsEnabled = true, StartDate = DateTime.Now, EndDate = DateTime.Now.AddDays(90) }); - surveyDbContext.Surveys.Add(new Db.Survey { Id = 3, Title = "Sample Survey Title: Damage Assesment 2018", IsEnabled = true, StartDate = DateTime.Now, EndDate = DateTime.Now.AddDays(90) }); + surveyDbContext.Surveys.Add(new Db.Survey { Id = 1, IsEnabled = true, StartDate = DateTime.Now, EndDate = DateTime.Now.AddDays(90), CreatedDate = DateTime.Now }); + surveyDbContext.Surveys.Add(new Db.Survey { Id = 2, IsEnabled = true, StartDate = DateTime.Now, EndDate = DateTime.Now.AddDays(90), CreatedDate = DateTime.Now }); + surveyDbContext.Surveys.Add(new Db.Survey { Id = 3, IsEnabled = true, StartDate = DateTime.Now, EndDate = DateTime.Now.AddDays(90), CreatedDate = DateTime.Now }); + surveyDbContext.SaveChangesAsync(); + } + + if (!surveyDbContext.SurveysTranslation.Any()) + { + surveyDbContext.SurveysTranslation.Add(new Db.SurveyTranslation { Id = 1, SurveyId = 1, Language = "en", Title = "Impact of Tropical Storm Emily on Florida's Economy" }); + surveyDbContext.SurveysTranslation.Add(new Db.SurveyTranslation { Id = 2, SurveyId = 1, Language = "es", Title = "Impacto de la tormenta tropical Emily en la economía de Florida" }); + surveyDbContext.SurveysTranslation.Add(new Db.SurveyTranslation { Id = 3, SurveyId = 1, Language = "fr", Title = "Impact de la tempête tropicale Emily sur l'économie de la Floride" }); + + surveyDbContext.SurveysTranslation.Add(new Db.SurveyTranslation { Id = 4, SurveyId = 2, Language = "en", Title = "Hurricane Andrew Aftermath Survey" }); + surveyDbContext.SurveysTranslation.Add(new Db.SurveyTranslation { Id = 5, SurveyId = 2, Language = "es", Title = "Encuesta sobre las secuelas del huracán Andrew" }); + surveyDbContext.SurveysTranslation.Add(new Db.SurveyTranslation { Id = 6, SurveyId = 2, Language = "fr", Title = "Enquête sur les conséquences de l'ouragan Andrew" }); + + surveyDbContext.SurveysTranslation.Add(new Db.SurveyTranslation { Id = 7, SurveyId = 3, Language = "en", Title = "Public Perception of Hurricane Michael's Response" }); + surveyDbContext.SurveysTranslation.Add(new Db.SurveyTranslation { Id = 8, SurveyId = 3, Language = "es", Title = "Percepción pública de la respuesta del huracán Michael" }); + surveyDbContext.SurveysTranslation.Add(new Db.SurveyTranslation { Id = 9, SurveyId = 3, Language = "fr", Title = "Perception du public de la réponse de l'ouragan Michael" }); + surveyDbContext.SaveChangesAsync(); } } - public async Task<(bool IsSuccess, IEnumerable Surveys, string ErrorMessage)> GetSurveysAsync() + public async Task<(bool IsSuccess, IEnumerable Surveys, string ErrorMessage)> GetSurveysAsync(string Language) { + IEnumerable surveysList = null; try { logger?.LogInformation("Gell all Surveys from DB"); - var surveys = await surveyDbContext.Surveys.ToListAsync(); + var surveys = await surveyDbContext.Surveys.Where(s => s.IsEnabled == true).ToListAsync(); + var surveyTranslations = await surveyDbContext.SurveysTranslation.ToListAsync(); + if (surveys != null) { + + if (string.IsNullOrEmpty(Language)) + { + surveysList = from s in surveys + select new + Models.Survey + { + Id = s.Id, + StartDate = s.StartDate, + EndDate = s.EndDate, + IsEnabled = s.IsEnabled, + CreatedDate = s.CreatedDate, + Titles = from t in surveyTranslations + where t.SurveyId == s.Id + select new Models.SurveyTranslation + { + Title = t.Title, + Language = t.Language + } + + }; + } + else + { + surveysList = from s in surveys + select new + Models.Survey + { + Id = s.Id, + StartDate = s.StartDate, + EndDate = s.EndDate, + IsEnabled = s.IsEnabled, + CreatedDate = s.CreatedDate, + Titles = from t in surveyTranslations + where t.SurveyId == s.Id + && t.Language == Language + select new Models.SurveyTranslation + { + Title = t.Title, + Language = t.Language + } + + }; + } + logger?.LogInformation($"{surveys.Count} Items(s) found"); - var result = mapper.Map, IEnumerable>(surveys); - return (true, result, null); + return (true, surveysList, null); } return (false, null, "Not found"); } @@ -50,16 +116,55 @@ namespace DamageAssesment.Api.Surveys.Providers return (false, null, ex.Message); } } - public async Task<(bool IsSuccess, Models.Survey Surveys, string ErrorMessage)> GetSurveysAsync(int Id) + public async Task<(bool IsSuccess, Models.Survey Surveys, string ErrorMessage)> GetSurveysAsync(int Id, string Language) { try { logger?.LogInformation("Query Survey"); - var survey = await surveyDbContext.Surveys.SingleOrDefaultAsync(s => s.Id == Id); + var survey = await surveyDbContext.Surveys.SingleOrDefaultAsync(s => s.Id == Id && s.IsEnabled == true); if (survey != null) { + Models.Survey result = null; + var surveyTranslations = await surveyDbContext.SurveysTranslation.Where(s => s.SurveyId == survey.Id).ToListAsync(); + + if (string.IsNullOrEmpty(Language)) + { + result = new Models.Survey + { + Id = survey.Id, + StartDate = survey.StartDate, + EndDate = survey.EndDate, + IsEnabled = survey.IsEnabled, + CreatedDate = survey.CreatedDate, + Titles = from t in surveyTranslations + select new Models.SurveyTranslation + { + Title = t.Title, + Language = t.Language + } + + }; + } + else + { + result = new Models.Survey + { + Id = survey.Id, + StartDate = survey.StartDate, + EndDate = survey.EndDate, + IsEnabled = survey.IsEnabled, + CreatedDate = survey.CreatedDate, + Titles = from t in surveyTranslations + where t.Language == Language + select new Models.SurveyTranslation + { + Title = t.Title, + Language = t.Language + } + + }; + } logger?.LogInformation($"Survey Id: {Id} found"); - var result = mapper.Map(survey); return (true, result, null); } return (false, null, "Not found"); @@ -78,8 +183,16 @@ namespace DamageAssesment.Api.Surveys.Providers if (survey != null) { var surveys = await surveyDbContext.Surveys.ToListAsync(); - survey.Id = surveys.Count + 1; - surveyDbContext.Surveys.Add(mapper.Map(survey)); + + int Id = surveys.Count + 1; + surveyDbContext.Surveys.Add(new Db.Survey { Id = Id, IsEnabled = survey.IsEnabled, StartDate = survey.StartDate, EndDate = survey.EndDate, CreatedDate = DateTime.Now }); + var surveyTranslations = await surveyDbContext.SurveysTranslation.ToListAsync(); + int count = surveyTranslations.Count; + foreach (var title in survey.Titles) + { + count++; + surveyDbContext.SurveysTranslation.Add(new Db.SurveyTranslation { Id = count, SurveyId = Id, Language = title.Language, Title = title.Title }); + } await surveyDbContext.SaveChangesAsync(); return (true, survey, "Successful"); } @@ -106,12 +219,40 @@ namespace DamageAssesment.Api.Surveys.Providers if (_survey != null) { - _survey.Title = survey.Title; + var surveysTranslation = await surveyDbContext.SurveysTranslation.Where(s => s.SurveyId == Id).ToListAsync(); + surveyDbContext.SurveysTranslation.RemoveRange(surveysTranslation); + await surveyDbContext.SaveChangesAsync(); + _survey.IsEnabled = survey.IsEnabled; _survey.StartDate = survey.StartDate; _survey.EndDate = survey.EndDate; await surveyDbContext.SaveChangesAsync(); - return (true, mapper.Map(_survey), "Successful"); + + 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 }); + } + surveyDbContext.SurveysTranslation.AddRange(listSurveyTranslation); + await surveyDbContext.SaveChangesAsync(); + + var result = new Models.Survey + { + Id = Id, + StartDate = survey.StartDate, + EndDate = survey.EndDate, + IsEnabled = survey.IsEnabled, + CreatedDate = survey.CreatedDate, + Titles = from t in listSurveyTranslation + select new Models.SurveyTranslation + { + Title = t.Title, + Language = t.Language + } + + }; + return (true, result, "Successful"); } else {