From e3639589b0de50c077ed233a5d8dee1808ce85ea Mon Sep 17 00:00:00 2001 From: Thomas Fransolet Date: Fri, 23 May 2025 15:32:30 +0200 Subject: [PATCH] Clean + reorder quiz + menu + working all --- .../Controllers/ConfigurationController.cs | 2 +- .../Controllers/SectionController.cs | 104 +++++++++--------- .../Controllers/SectionMenuController.cs | 12 +- .../Controllers/SectionQuizController.cs | 58 ++++++++-- ManagerService/DTOs/SectionDTO.cs | 2 +- ManagerService/DTOs/SubSection/QuizzDTO.cs | 4 +- ManagerService/Services/SectionFactory.cs | 22 ++-- 7 files changed, 118 insertions(+), 86 deletions(-) diff --git a/ManagerService/Controllers/ConfigurationController.cs b/ManagerService/Controllers/ConfigurationController.cs index 6d4e6d7..3d6731a 100644 --- a/ManagerService/Controllers/ConfigurationController.cs +++ b/ManagerService/Controllers/ConfigurationController.cs @@ -697,7 +697,7 @@ namespace ManagerService.Controllers newSection.IsSubSection = section.isSubSection; newSection.ParentId = section.parentId; //newSection.Data = section.data; - newSection.DateCreation = section.dateCreation; + newSection.DateCreation = section.dateCreation.Value; newSection.IsBeacon = section.isBeacon; newSection.BeaconId = section.beaconId; newSection.Latitude = section.latitude; diff --git a/ManagerService/Controllers/SectionController.cs b/ManagerService/Controllers/SectionController.cs index 3ffb6f1..f1067fb 100644 --- a/ManagerService/Controllers/SectionController.cs +++ b/ManagerService/Controllers/SectionController.cs @@ -8,6 +8,7 @@ using ManagerService.DTOs; using ManagerService.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Mqtt.Client.AspNetCore.Services; @@ -177,7 +178,15 @@ namespace ManagerService.Controllers List
sections = _myInfoMateDbContext.Sections.Where(s => s.ParentId == id && s.IsSubSection).ToList(); //List sections = _sectionService.GetAllSubSection(id); - return new OkObjectResult(sections.Select(r => r.ToDTO())); + List sectionsToReturn = new List(); + + foreach (var section in sections) + { + var dto = SectionFactory.ToDTO(section); + sectionsToReturn.Add(dto); + } + + return new OkObjectResult(sectionsToReturn); } catch (ArgumentNullException ex) { @@ -394,7 +403,7 @@ namespace ManagerService.Controllers section.ImageId = newSection.imageId; section.ImageSource = newSection.imageSource; section.ConfigurationId = newSection.configurationId; - section.DateCreation = DateTime.Now.ToUniversalTime(); + section.DateCreation = newSection.dateCreation == null ? DateTime.Now.ToUniversalTime() : newSection.dateCreation.Value; section.IsSubSection = newSection.isSubSection; section.ParentId = newSection.parentId; section.Type = newSection.type; @@ -406,7 +415,7 @@ namespace ManagerService.Controllers } else { - section.Order = _myInfoMateDbContext.Sections.Count(s => s.ConfigurationId == newSection.configurationId && !s.IsSubSection) + 1; + section.Order = 0; // _myInfoMateDbContext.Sections.Count(s => s.ConfigurationId == newSection.configurationId && !s.IsSubSection) + 1; } section.IsBeacon = newSection.isBeacon; @@ -414,7 +423,6 @@ namespace ManagerService.Controllers section.Latitude = newSection.latitude; section.Longitude = newSection.longitude; section.MeterZoneGPS = newSection.meterZoneGPS; - section.Title = LanguageInit.Init("Title", languages); section.Description = LanguageInit.Init("Description", languages); @@ -423,6 +431,22 @@ namespace ManagerService.Controllers _myInfoMateDbContext.Add(section); _myInfoMateDbContext.SaveChanges(); + // UPDATE OTHER ORDER + var sections = _myInfoMateDbContext.Sections.Where(s => s.ConfigurationId == newSection.configurationId && !s.IsSubSection).OrderBy(s => s.Order).ToList(); + + // Retirer la question déplacée + sections.RemoveAll(q => q.Id == section.Id); + + // Insérer à la première position (déjà en 0-based) + sections.Insert(0, section); + + // Réassigner les ordres en 0-based + for (int i = 0; i < sections.Count; i++) + { + sections[i].Order = i; + } + _myInfoMateDbContext.SaveChanges(); + return new OkObjectResult(section.ToDTO()); } catch (ArgumentNullException ex) @@ -495,7 +519,7 @@ namespace ManagerService.Controllers /// Update a section /// /// Section to update - [ProducesResponseType(typeof(SectionDTO), 200)] + [ProducesResponseType(typeof(object), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] @@ -529,57 +553,36 @@ namespace ManagerService.Controllers if (existingSection.Type != sectionDTO.type) return BadRequest("Type mismatch: cannot change section type"); - var updatedSectionDB = SectionFactory.Create(updatedSection, sectionDTO); - - // Todo add some verification ? - /*section.InstanceId = updatedSection.instanceId; - section.Label = updatedSection.label; - section.Title = updatedSection.title.Select(t => new Translation().FromDTO(t)).ToList(); // TODO CHECK - section.Description = updatedSection.description.Select(t => new Translation().FromDTO(t)).ToList();// TODO CHECK - section.Type = updatedSection.type; - section.ImageId = updatedSection.imageId; - section.ImageSource = updatedSection.imageSource; - section.ConfigurationId = updatedSection.configurationId; - section.IsSubSection = updatedSection.isSubSection; - section.ParentId = updatedSection.parentId; - //section.Data = updatedSection.data; - section.IsBeacon = updatedSection.isBeacon; - section.BeaconId = updatedSection.beaconId; - section.Latitude = updatedSection.latitude; - section.Longitude = updatedSection.longitude; - section.MeterZoneGPS = updatedSection.meterZoneGPS;*/ - - switch (updatedSectionDB) + if (existingSection.IsSubSection && sectionDTO.order != existingSection.Order) { - case SectionAgenda agenda: - // TODO in future events - break; + // If subsection, check if order changed + var subSections = _myInfoMateDbContext.Sections.Where(s => s.ParentId == existingSection.ParentId).OrderBy(s => s.Order).ToList(); - case SectionMap map: - // TODO Endpoint categories - // TODO Endpoint points + // Retirer la sous section déplacée + subSections.RemoveAll(q => q.Id == existingSection.Id); - map.MapCategories = updatedSectionDB.MapCategories; - //_myInfoMateDbContext.Entry(map).Property(p => p.MapCategories).IsModified = true; - break; + // Insérer à la nouvelle position (déjà en 0-based) + int newIndex = sectionDTO.order.Value; + newIndex = Math.Clamp(newIndex, 0, subSections.Count); + subSections.Insert(newIndex, existingSection); - case SectionMenu menu: - // TODO Endpoint Sections menu - //menu.Sections = new List
(); - break; - - case SectionQuiz quiz: - // TODO Endpoint QuizQuestions - quiz.QuizQuestions = []; - break; - - // Ajoute d'autres types ici + // Réassigner les ordres en 0-based + for (int i = 0; i < subSections.Count; i++) + { + subSections[i].Order = i; + } + _myInfoMateDbContext.SaveChanges(); } - _myInfoMateDbContext.Entry(existingSection).CurrentValues.SetValues(updatedSectionDB); - _myInfoMateDbContext.SaveChanges(); - //Section sectionModified = _sectionService.Update(updatedSection.id, section); + else + { + // classic update + var updatedSectionDB = SectionFactory.Create(updatedSection, sectionDTO); - MqttClientService.PublishMessage($"config/{existingSection.ConfigurationId}", JsonConvert.SerializeObject(new PlayerMessageDTO() { configChanged = true })); + _myInfoMateDbContext.Entry(existingSection).CurrentValues.SetValues(updatedSectionDB); + _myInfoMateDbContext.SaveChanges(); + + MqttClientService.PublishMessage($"config/{existingSection.ConfigurationId}", JsonConvert.SerializeObject(new PlayerMessageDTO() { configChanged = true })); + } return new OkObjectResult(SectionFactory.ToDTO(existingSection)); } @@ -717,7 +720,6 @@ namespace ManagerService.Controllers i++; } } - _myInfoMateDbContext.SaveChanges(); diff --git a/ManagerService/Controllers/SectionMenuController.cs b/ManagerService/Controllers/SectionMenuController.cs index 0575a5d..fd37e63 100644 --- a/ManagerService/Controllers/SectionMenuController.cs +++ b/ManagerService/Controllers/SectionMenuController.cs @@ -1,20 +1,10 @@ -using Manager.DTOs; -using Manager.Helpers; -using ManagerService.Data; -using ManagerService.Data.SubSection; -using ManagerService.DTOs; +using ManagerService.Data; using ManagerService.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; -using Mqtt.Client.AspNetCore.Services; -using Newtonsoft.Json; using NSwag.Annotations; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text.Json; namespace ManagerService.Controllers { diff --git a/ManagerService/Controllers/SectionQuizController.cs b/ManagerService/Controllers/SectionQuizController.cs index 3209472..e0d0228 100644 --- a/ManagerService/Controllers/SectionQuizController.cs +++ b/ManagerService/Controllers/SectionQuizController.cs @@ -16,6 +16,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Reflection.Emit; +using System.Security.Cryptography; using System.Text.Json; namespace ManagerService.Controllers @@ -62,8 +63,8 @@ namespace ManagerService.Controllers label = question.Label, responses = question.Responses, imageBackgroundResourceId = question.ResourceId, - imageBackgroundResourceType = question.Resource.Type, - imageBackgroundResourceUrl = question.Resource.Url, + imageBackgroundResourceType = question.Resource?.Type, + imageBackgroundResourceUrl = question.Resource?.Url, order = question.Order }); } @@ -85,7 +86,7 @@ namespace ManagerService.Controllers /// /// Section Id /// question - [ProducesResponseType(typeof(QuizQuestion), 200)] + [ProducesResponseType(typeof(QuestionDTO), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 409)] [ProducesResponseType(typeof(string), 500)] @@ -109,13 +110,24 @@ namespace ManagerService.Controllers quizQuestion.Label = questionDTO.label; quizQuestion.Responses = questionDTO.responses; quizQuestion.ResourceId = questionDTO.imageBackgroundResourceId; - quizQuestion.Order = questionDTO.order; + quizQuestion.Order = existingSection.QuizQuestions.Count(); existingSection.QuizQuestions.Add(quizQuestion); _myInfoMateDbContext.SaveChanges(); - return new OkObjectResult(quizQuestion); + var questionDTOToSend = new QuestionDTO() + { + id = quizQuestion.Id, + label = quizQuestion.Label, + responses = quizQuestion.Responses, + imageBackgroundResourceId = quizQuestion.ResourceId, + imageBackgroundResourceType = quizQuestion.Resource?.Type, + imageBackgroundResourceUrl = quizQuestion.Resource?.Url, + order = quizQuestion.Order + }; + + return new OkObjectResult(questionDTOToSend); } catch (ArgumentNullException ex) { @@ -151,10 +163,38 @@ namespace ManagerService.Controllers if (existingQuestion == null) throw new KeyNotFoundException("Question quiz does not exist"); - existingQuestion.Label = questionDTO.label; - existingQuestion.Responses = questionDTO.responses; - existingQuestion.Order = questionDTO.order; - existingQuestion.ResourceId = questionDTO.imageBackgroundResourceId; + if (questionDTO.order != existingQuestion.Order) + { + // Order update + var existingSection = _myInfoMateDbContext.Sections.OfType().Include(sq => sq.QuizQuestions.OrderBy(q => q.Order)).FirstOrDefault(sq => sq.Id == existingQuestion.SectionQuizId); + + if (existingSection == null) + throw new Exception("Section quiz not found"); + + var questions = existingSection.QuizQuestions.OrderBy(q => q.Order).ToList(); + + // Retirer la question déplacée + questions.RemoveAll(q => q.Id == existingQuestion.Id); + + // Insérer à la nouvelle position (déjà en 0-based) + int newIndex = questionDTO.order.Value; + newIndex = Math.Clamp(newIndex, 0, questions.Count); + questions.Insert(newIndex, existingQuestion); + + // Réassigner les ordres en 0-based + for (int i = 0; i < questions.Count; i++) + { + questions[i].Order = i; + } + + } + else { + // Simple update + existingQuestion.Label = questionDTO.label; + existingQuestion.Responses = questionDTO.responses; + existingQuestion.Order = questionDTO.order.Value; // TO TEST + existingQuestion.ResourceId = questionDTO.imageBackgroundResourceId; + } _myInfoMateDbContext.SaveChanges(); diff --git a/ManagerService/DTOs/SectionDTO.cs b/ManagerService/DTOs/SectionDTO.cs index 0475433..1d17149 100644 --- a/ManagerService/DTOs/SectionDTO.cs +++ b/ManagerService/DTOs/SectionDTO.cs @@ -15,7 +15,7 @@ namespace ManagerService.DTOs public bool isSubSection { get; set; } // true if part of menu type public string parentId { get; set; } // only if it's an subsection public SectionType type { get; set; } // !! If IsSubSection == true => Type can't not be menu ! - public DateTime dateCreation { get; set; } // == Include section type info + public DateTime? dateCreation { get; set; } // == Include section type info public int? order { get; set; } // Order to show public string instanceId { get; set; } public string latitude { get; set; } // MyVisit - Use to launch automatic content when current location is near diff --git a/ManagerService/DTOs/SubSection/QuizzDTO.cs b/ManagerService/DTOs/SubSection/QuizzDTO.cs index c49d0e4..5d29692 100644 --- a/ManagerService/DTOs/SubSection/QuizzDTO.cs +++ b/ManagerService/DTOs/SubSection/QuizzDTO.cs @@ -15,13 +15,13 @@ namespace Manager.DTOs public class QuestionDTO { - public int id { get; set; } + public int? id { get; set; } public List label { get; set; } public List responses { get; set; } public string imageBackgroundResourceId { get; set; } // question image background public ResourceType? imageBackgroundResourceType { get; set; } public string imageBackgroundResourceUrl { get; set; } // url to firebase storage or on internet - public int order { get; set; } // Order to show + public int? order { get; set; } // Order to show } public class ResponseDTO diff --git a/ManagerService/Services/SectionFactory.cs b/ManagerService/Services/SectionFactory.cs index 4d6b847..76835de 100644 --- a/ManagerService/Services/SectionFactory.cs +++ b/ManagerService/Services/SectionFactory.cs @@ -68,7 +68,7 @@ namespace ManagerService.Services SectionType.Agenda => new SectionAgenda { Id = dto.id, - DateCreation = dto.dateCreation, + DateCreation = dto.dateCreation.Value, ConfigurationId = dto.configurationId, InstanceId = dto.instanceId, Label = dto.label, @@ -91,7 +91,7 @@ namespace ManagerService.Services SectionType.Article => new SectionArticle { Id = dto.id, - DateCreation = dto.dateCreation, + DateCreation = dto.dateCreation.Value, ConfigurationId = dto.configurationId, InstanceId = dto.instanceId, Label = dto.label, @@ -117,7 +117,7 @@ namespace ManagerService.Services SectionType.Map => new SectionMap { Id = dto.id, - DateCreation = dto.dateCreation, + DateCreation = dto.dateCreation.Value, ConfigurationId = dto.configurationId, InstanceId = dto.instanceId, Label = dto.label, @@ -146,7 +146,7 @@ namespace ManagerService.Services SectionType.Menu => new SectionMenu { Id = dto.id, - DateCreation = dto.dateCreation, + DateCreation = dto.dateCreation.Value, ConfigurationId = dto.configurationId, InstanceId = dto.instanceId, Label = dto.label, @@ -168,7 +168,7 @@ namespace ManagerService.Services SectionType.PDF => new SectionPdf { Id = dto.id, - DateCreation = dto.dateCreation, + DateCreation = dto.dateCreation.Value, ConfigurationId = dto.configurationId, InstanceId = dto.instanceId, Label = dto.label, @@ -190,7 +190,7 @@ namespace ManagerService.Services SectionType.Puzzle => new SectionPuzzle { Id = dto.id, - DateCreation = dto.dateCreation, + DateCreation = dto.dateCreation.Value, ConfigurationId = dto.configurationId, InstanceId = dto.instanceId, Label = dto.label, @@ -216,7 +216,7 @@ namespace ManagerService.Services SectionType.Quiz => new SectionQuiz { Id = dto.id, - DateCreation = dto.dateCreation, + DateCreation = dto.dateCreation.Value, ConfigurationId = dto.configurationId, InstanceId = dto.instanceId, Label = dto.label, @@ -242,7 +242,7 @@ namespace ManagerService.Services SectionType.Slider => new SectionSlider { Id = dto.id, - DateCreation = dto.dateCreation, + DateCreation = dto.dateCreation.Value, ConfigurationId = dto.configurationId, InstanceId = dto.instanceId, Label = dto.label, @@ -264,7 +264,7 @@ namespace ManagerService.Services SectionType.Video => new SectionVideo { Id = dto.id, - DateCreation = dto.dateCreation, + DateCreation = dto.dateCreation.Value, ConfigurationId = dto.configurationId, InstanceId = dto.instanceId, Label = dto.label, @@ -287,7 +287,7 @@ namespace ManagerService.Services SectionType.Weather => new SectionWeather { Id = dto.id, - DateCreation = dto.dateCreation, + DateCreation = dto.dateCreation.Value, ConfigurationId = dto.configurationId, InstanceId = dto.instanceId, Label = dto.label, @@ -311,7 +311,7 @@ namespace ManagerService.Services SectionType.Web => new SectionWeb { Id = dto.id, - DateCreation = dto.dateCreation, + DateCreation = dto.dateCreation.Value, ConfigurationId = dto.configurationId, InstanceId = dto.instanceId, Label = dto.label,