1153 lines
50 KiB
C#
1153 lines
50 KiB
C#
using Manager.DTOs;
|
||
using Manager.Helpers;
|
||
using Manager.Interfaces.Models;
|
||
using Manager.Services;
|
||
using ManagerService.Data;
|
||
using ManagerService.Data.SubSection;
|
||
using ManagerService.DTOs;
|
||
using ManagerService.Helpers;
|
||
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;
|
||
using Newtonsoft.Json;
|
||
using NSwag.Annotations;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Net.Http;
|
||
using System.Security.Cryptography;
|
||
using System.Text.Json;
|
||
using System.Threading.Tasks;
|
||
using static ManagerService.Data.SubSection.SectionEvent;
|
||
|
||
namespace ManagerService.Controllers
|
||
{
|
||
[Authorize(Policy = ManagerService.Service.Security.Policies.ContentEditor)]
|
||
[ApiController, Route("api/[controller]")]
|
||
[OpenApiTag("Section", Description = "Section management")]
|
||
public class SectionController : ControllerBase
|
||
{
|
||
private readonly MyInfoMateDbContext _myInfoMateDbContext;
|
||
|
||
private SectionDatabaseService _sectionService;
|
||
private ConfigurationDatabaseService _configurationService;
|
||
private readonly ILogger<SectionController> _logger;
|
||
private readonly IConfiguration _configuration;
|
||
IHexIdGeneratorService idService = new HexIdGeneratorService();
|
||
|
||
public SectionController(IConfiguration configuration, ILogger<SectionController> logger, SectionDatabaseService sectionService, ConfigurationDatabaseService configurationService, MyInfoMateDbContext myInfoMateDbContext)
|
||
{
|
||
_logger = logger;
|
||
_configuration = configuration;
|
||
_sectionService = sectionService;
|
||
_configurationService = configurationService;
|
||
_myInfoMateDbContext = myInfoMateDbContext;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Get a list of all section (summary)
|
||
/// </summary>
|
||
/// <param name="id">id instance</param>
|
||
[ProducesResponseType(typeof(List<SectionDTO>), 200)]
|
||
[ProducesResponseType(typeof(string), 500)]
|
||
[ProducesResponseType(typeof(string), 400)]
|
||
[HttpGet]
|
||
public ObjectResult Get([FromQuery] string instanceId)
|
||
{
|
||
try
|
||
{
|
||
if (instanceId == null)
|
||
throw new ArgumentNullException("Param is null");
|
||
|
||
//List<OldSection> sections = _sectionService.GetAll(instanceId);
|
||
List<Section> sections = _myInfoMateDbContext.Sections.Where(s => s.InstanceId == instanceId).ToList();
|
||
|
||
|
||
/* CLEAN ARTICLE AUDIO - Init new field AudioIds */
|
||
|
||
/*foreach (var article in sections.Where(s => s.Type == SectionType.Article))
|
||
{
|
||
try
|
||
{
|
||
ArticleDTO articleDTO = JsonConvert.DeserializeObject<ArticleDTO>(article.Data);
|
||
List<string> languages = _configuration.GetSection("SupportedLanguages").Get<List<string>>();
|
||
articleDTO.audioIds = LanguageInit.Init("Audio", languages, true);
|
||
article.Data = JsonConvert.SerializeObject(articleDTO); // Include all info from specific section as JSON
|
||
|
||
Section sectionModified = _sectionService.Update(article.Id, article);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
|
||
}
|
||
}*/
|
||
|
||
return new OkObjectResult(sections.Select(s => s.ToDTO()));
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return new ObjectResult(ex.Message) { StatusCode = 500 };
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Get a list of all section (summary)
|
||
/// </summary>
|
||
/// <param name="id">id instance</param>
|
||
[ProducesResponseType(typeof(List<SectionDTO>), 200)]
|
||
[ProducesResponseType(typeof(string), 500)]
|
||
[ProducesResponseType(typeof(string), 400)]
|
||
[HttpGet("detail")]
|
||
public ObjectResult GetAllFromType([FromQuery] string instanceId, [FromQuery] SectionType sectionType)
|
||
{
|
||
try
|
||
{
|
||
if (instanceId == null)
|
||
throw new ArgumentNullException("Param is null");
|
||
|
||
List<Section> sections = _myInfoMateDbContext.Sections.Where(s => s.InstanceId == instanceId && s.Type == sectionType).OrderBy(s => s.Order).ToList();
|
||
//List<OldSection> sections = _sectionService.GetAllSubSection(id);
|
||
|
||
List<object> sectionsToReturn = new List<object>();
|
||
|
||
foreach (var section in sections)
|
||
{
|
||
var dto = SectionFactory.ToDTO(section);
|
||
sectionsToReturn.Add(dto);
|
||
}
|
||
|
||
return new OkObjectResult(sectionsToReturn);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return new ObjectResult(ex.Message) { StatusCode = 500 };
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Get a list of all section from a specific configuration
|
||
/// </summary>
|
||
/// <param name="id">configuration id</param>
|
||
[AllowAnonymous]
|
||
[ProducesResponseType(typeof(List<SectionDTO>), 200)]
|
||
[ProducesResponseType(typeof(string), 500)]
|
||
[ProducesResponseType(typeof(string), 400)]
|
||
[HttpGet("configuration/{id}")]
|
||
public ObjectResult GetFromConfiguration(string id)
|
||
{
|
||
try
|
||
{
|
||
if (id == null)
|
||
throw new ArgumentNullException("Param is null");
|
||
|
||
Configuration configuration = _myInfoMateDbContext.Configurations.FirstOrDefault(c => c.Id == id);
|
||
|
||
if (configuration != null)
|
||
{
|
||
List<Section> sections = _myInfoMateDbContext.Sections.Where(s => s.ConfigurationId == id && !s.IsSubSection).ToList();
|
||
//List<OldSection> sections = _sectionService.GetAllFromConfiguration(id);
|
||
|
||
return new OkObjectResult(sections.Select(r => r.ToDTO()));
|
||
}
|
||
else
|
||
return new NotFoundObjectResult("Configuration not found");
|
||
}
|
||
catch (ArgumentNullException ex)
|
||
{
|
||
return new BadRequestObjectResult(ex.Message) { };
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return new ObjectResult(ex.Message) { StatusCode = 500 };
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Get a list of all section from a specific configuration (mobile format)
|
||
/// </summary>
|
||
/// <param name="id">configuration id</param>
|
||
[AllowAnonymous]
|
||
[ProducesResponseType(typeof(List<object>), 200)]
|
||
[ProducesResponseType(typeof(string), 500)]
|
||
[ProducesResponseType(typeof(string), 400)]
|
||
[HttpGet("configuration/{id}/detail")]
|
||
public async Task<ObjectResult> GetFromConfigurationDetail(string id)
|
||
{
|
||
try
|
||
{
|
||
if (id == null)
|
||
throw new ArgumentNullException("Param is null");
|
||
|
||
Configuration configuration = _myInfoMateDbContext.Configurations.FirstOrDefault(c => c.Id == id);
|
||
|
||
if (configuration != null)
|
||
{
|
||
List<Section> sections = _myInfoMateDbContext.Sections.Where(s => s.ConfigurationId == id && !s.IsSubSection).OrderBy(s => s.Order).ToList();
|
||
List<object> sectionsToReturn = new List<object>();
|
||
|
||
foreach (var section in sections)
|
||
{
|
||
var dto = SectionFactory.ToDTO(section);
|
||
|
||
switch (section.Type)
|
||
{
|
||
case SectionType.Agenda:
|
||
var eventAgendas = _myInfoMateDbContext.EventAgendas.Where(ea => ea.SectionAgendaId == section.Id)/*.OrderBy(gp => gp.or)*/.ToList();
|
||
List<EventAgendaDTO> eventAgendaDTOs = new List<EventAgendaDTO>();
|
||
foreach (var eventAgenda in eventAgendas)
|
||
{
|
||
eventAgendaDTOs.Add(eventAgenda.ToDTO());
|
||
}
|
||
(dto as AgendaDTO).events = eventAgendaDTOs;
|
||
break;
|
||
case SectionType.Event:
|
||
var sectionEvent = _myInfoMateDbContext.Sections.OfType<SectionEvent>().Include(se => se.Programme).ThenInclude(se => se.MapAnnotations).FirstOrDefault(s => s.Id == id);
|
||
(dto as SectionEventDTO).Programme = sectionEvent.Programme; // TODO test ! Need dto ?
|
||
break;
|
||
case SectionType.Game:
|
||
Resource resource = _myInfoMateDbContext.Resources.FirstOrDefault(r => r.Id == (dto as GameDTO).puzzleImageId);
|
||
(dto as GameDTO).puzzleImage = resource.ToDTO();
|
||
break;
|
||
case SectionType.Map:
|
||
var geoPoints = _myInfoMateDbContext.GeoPoints.Where(gp => gp.SectionMapId == section.Id)/*.OrderBy(gp => gp.or)*/.ToList();
|
||
List<GeoPointDTO> geoPointDTOs = new List<GeoPointDTO>();
|
||
foreach (var geoPoint in geoPoints)
|
||
{
|
||
geoPointDTOs.Add(new GeoPointDTO() {
|
||
id = geoPoint.Id,
|
||
title = geoPoint.Title,
|
||
description = geoPoint.Description,
|
||
contents = geoPoint.Contents,
|
||
categorieId = geoPoint.CategorieId,
|
||
imageResourceId = geoPoint.ImageResourceId,
|
||
imageUrl = geoPoint.ImageUrl,
|
||
schedules = geoPoint.Schedules,
|
||
prices = geoPoint.Prices,
|
||
phone = geoPoint.Phone,
|
||
email = geoPoint.Email,
|
||
site = geoPoint.Site,
|
||
polyColor = geoPoint.PolyColor,
|
||
geometry = geoPoint.Geometry?.ToDto()
|
||
});
|
||
}
|
||
(dto as MapDTO).points = geoPointDTOs;
|
||
break;
|
||
case SectionType.Quiz:
|
||
var quizQuestions = _myInfoMateDbContext.QuizQuestions.Where(qq => qq.SectionQuizId == section.Id).OrderBy(q => q.Order).ToList();
|
||
List<QuestionDTO> questionDTOs = new List<QuestionDTO>();
|
||
foreach (var quizQuestion in quizQuestions)
|
||
{
|
||
questionDTOs.Add(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,
|
||
});
|
||
}
|
||
(dto as QuizDTO).questions = questionDTOs;
|
||
break;
|
||
case SectionType.Menu:
|
||
var subSections = _myInfoMateDbContext.Sections.Where(s => s.IsSubSection && s.ParentId == section.Id).OrderBy(s => s.Order).ToList();
|
||
List<object> subSectionToReturn = new List<object>();
|
||
foreach (var subSection in subSections)
|
||
{
|
||
var subDTO = SectionFactory.ToDTO(subSection);
|
||
switch (subSection.Type)
|
||
{
|
||
case SectionType.Game:
|
||
Resource resourceSub = _myInfoMateDbContext.Resources.FirstOrDefault(r => r.Id == (subDTO as GameDTO).puzzleImageId);
|
||
(subDTO as GameDTO).puzzleImage = resourceSub?.ToDTO();
|
||
break;
|
||
case SectionType.Map:
|
||
var geoPointsSub = _myInfoMateDbContext.GeoPoints.Where(gp => gp.SectionMapId == subSection.Id).ToList();
|
||
List<GeoPointDTO> geoPointDTOsSub = new List<GeoPointDTO>();
|
||
foreach (var geoPointSub in geoPointsSub)
|
||
{
|
||
geoPointDTOsSub.Add(new GeoPointDTO()
|
||
{
|
||
id = geoPointSub.Id,
|
||
title = geoPointSub.Title,
|
||
description = geoPointSub.Description,
|
||
contents = geoPointSub.Contents,
|
||
categorieId = geoPointSub.CategorieId,
|
||
imageResourceId = geoPointSub.ImageResourceId,
|
||
imageUrl = geoPointSub.ImageUrl,
|
||
schedules = geoPointSub.Schedules,
|
||
prices = geoPointSub.Prices,
|
||
phone = geoPointSub.Phone,
|
||
email = geoPointSub.Email,
|
||
site = geoPointSub.Site,
|
||
polyColor = geoPointSub.PolyColor,
|
||
geometry = geoPointSub.Geometry?.ToDto()
|
||
});
|
||
}
|
||
(subDTO as MapDTO).points = geoPointDTOsSub;
|
||
break;
|
||
case SectionType.Quiz:
|
||
var quizQuestionsSub = _myInfoMateDbContext.QuizQuestions.Where(qq => qq.SectionQuizId == subSection.Id).OrderBy(q => q.Order).ToList();
|
||
List<QuestionDTO> questionDTOsSub = new List<QuestionDTO>();
|
||
foreach (var quizQuestionSub in quizQuestionsSub)
|
||
{
|
||
questionDTOsSub.Add(new QuestionDTO()
|
||
{
|
||
id = quizQuestionSub.Id,
|
||
label = quizQuestionSub.Label,
|
||
responses = quizQuestionSub.Responses,
|
||
imageBackgroundResourceId = quizQuestionSub.ResourceId,
|
||
imageBackgroundResourceType = quizQuestionSub.Resource?.Type,
|
||
imageBackgroundResourceUrl = quizQuestionSub.Resource?.Url,
|
||
order = quizQuestionSub.Order,
|
||
});
|
||
}
|
||
(subDTO as QuizDTO).questions = questionDTOsSub;
|
||
break;
|
||
}
|
||
|
||
subSectionToReturn.Add(subDTO);
|
||
}
|
||
(dto as MenuDTO).sections = subSectionToReturn;
|
||
break;
|
||
}
|
||
|
||
sectionsToReturn.Add(dto);
|
||
}
|
||
|
||
try
|
||
{
|
||
var weatherSections = _myInfoMateDbContext.Sections.OfType<SectionWeather>()
|
||
.Where(s => s.ConfigurationId == id && !s.IsSubSection)
|
||
.ToList();
|
||
|
||
foreach (var weatherSection in weatherSections)
|
||
{
|
||
if (weatherSection.WeatherCity != null && weatherSection.WeatherCity.Length >= 2 &&
|
||
(weatherSection.WeatherUpdatedDate == null || weatherSection.WeatherUpdatedDate.Value.AddHours(3) < DateTimeOffset.Now)) // Update all 4 hours
|
||
{
|
||
// Call Openweather api with token from appSettings and update result with json
|
||
var apiKey = _configuration.GetSection("OpenWeatherApiKey").Get<string>();
|
||
|
||
if (apiKey != null && apiKey.Length > 0)
|
||
{
|
||
string url = $"http://api.openweathermap.org/geo/1.0/direct?q={weatherSection.WeatherCity}&limit=1&appid={apiKey}";
|
||
|
||
using (HttpClient client = new HttpClient())
|
||
{
|
||
try
|
||
{
|
||
HttpResponseMessage response = await client.GetAsync(url);
|
||
response.EnsureSuccessStatusCode();
|
||
string responseBody = await response.Content.ReadAsStringAsync();
|
||
|
||
List<CityData> cities = JsonConvert.DeserializeObject<List<CityData>>(responseBody);
|
||
|
||
if (cities.Count > 0)
|
||
{
|
||
double lat = cities[0].Lat;
|
||
double lon = cities[0].Lon;
|
||
|
||
//string onecallUrl = $"https://api.openweathermap.org/data/3.0/onecall?lat={lat}&lon={lon}&appid={apiKey}";
|
||
string callUrl = $"https://api.openweathermap.org/data/2.5/forecast?lat={lat}&lon={lon}&units=metric&appid={apiKey}";
|
||
|
||
HttpResponseMessage callResponse = await client.GetAsync(callUrl);
|
||
callResponse.EnsureSuccessStatusCode();
|
||
string callResponseBody = await callResponse.Content.ReadAsStringAsync();
|
||
|
||
|
||
weatherSection.WeatherUpdatedDate = DateTimeOffset.Now.ToUniversalTime(); ;
|
||
weatherSection.WeatherResult = callResponseBody;
|
||
_myInfoMateDbContext.SaveChanges();
|
||
}
|
||
else
|
||
{
|
||
Console.WriteLine("Aucune ville trouv<75>e.");
|
||
}
|
||
}
|
||
catch (HttpRequestException e)
|
||
{
|
||
Console.WriteLine($"Une erreur s'est produite lors de la requ<71>te HTTP : {e.Message}");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Console.WriteLine($"Une erreur s'est produite lors de la mise <20> jour des sections de type m<>t<EFBFBD>o : {e.Message}");
|
||
}
|
||
|
||
return new OkObjectResult(sectionsToReturn);
|
||
}
|
||
else
|
||
return new NotFoundObjectResult("Configuration not found");
|
||
}
|
||
catch (ArgumentNullException ex)
|
||
{
|
||
return new BadRequestObjectResult(ex.Message) { };
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return new ObjectResult(ex.Message) { StatusCode = 500 };
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Delete all section from a specific configuration
|
||
/// </summary>
|
||
/// <param name="id">configuration id</param>
|
||
[ProducesResponseType(typeof(string), 202)]
|
||
[ProducesResponseType(typeof(string), 500)]
|
||
[ProducesResponseType(typeof(string), 400)]
|
||
[HttpDelete("configuration/{id}")]
|
||
public ObjectResult DeleteAllForConfiguration(string id)
|
||
{
|
||
try
|
||
{
|
||
if (id == null)
|
||
throw new ArgumentNullException("Param is null");
|
||
|
||
//_sectionService.DeleteAllFromConfiguration(id);
|
||
List<Section> sections = _myInfoMateDbContext.Sections.Where(s => s.ConfigurationId == id).ToList();
|
||
// TODO test
|
||
_myInfoMateDbContext.RemoveRange(sections);
|
||
|
||
return new ObjectResult("All section from the specified configuration has been deleted") { StatusCode = 202 };
|
||
}
|
||
catch (ArgumentNullException ex)
|
||
{
|
||
return new BadRequestObjectResult(ex.Message) { };
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return new ObjectResult(ex.Message) { StatusCode = 500 };
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Get a list of all subsection (summary) of a specific section
|
||
/// </summary>
|
||
/// <param name="id">section id</param>
|
||
[ProducesResponseType(typeof(List<object>), 200)]
|
||
[ProducesResponseType(typeof(string), 500)]
|
||
[ProducesResponseType(typeof(string), 400)]
|
||
[HttpGet("{id}/subsections")]
|
||
public ObjectResult GetAllSectionSubSections(string id)
|
||
{
|
||
try
|
||
{
|
||
if (id == null)
|
||
throw new ArgumentNullException("Param is null");
|
||
|
||
List<Section> sections = _myInfoMateDbContext.Sections.Where(s => s.ParentId == id && s.IsSubSection).OrderBy(s=> s.Order).ToList();
|
||
//List<OldSection> sections = _sectionService.GetAllSubSection(id);
|
||
|
||
List<object> sectionsToReturn = new List<object>();
|
||
|
||
foreach (var section in sections)
|
||
{
|
||
var dto = SectionFactory.ToDTO(section);
|
||
sectionsToReturn.Add(dto);
|
||
}
|
||
|
||
return new OkObjectResult(sectionsToReturn);
|
||
}
|
||
catch (ArgumentNullException ex)
|
||
{
|
||
return new BadRequestObjectResult(ex.Message) { };
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return new ObjectResult(ex.Message) { StatusCode = 500 };
|
||
}
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// Get a specific section
|
||
/// </summary>
|
||
/// <param name="id">section id</param>
|
||
[AllowAnonymous]
|
||
[ProducesResponseType(typeof(object), 200)]
|
||
[ProducesResponseType(typeof(string), 404)]
|
||
[ProducesResponseType(typeof(string), 500)]
|
||
[HttpGet("{id}")]
|
||
public ObjectResult GetDetail(string id)
|
||
{
|
||
try
|
||
{
|
||
Section section = _myInfoMateDbContext.Sections.FirstOrDefault(s => s.Id == id);
|
||
|
||
if (section == null)
|
||
throw new KeyNotFoundException("This section was not found");
|
||
|
||
var dto = SectionFactory.ToDTO(section);
|
||
|
||
return new OkObjectResult(dto);
|
||
}
|
||
catch (KeyNotFoundException ex)
|
||
{
|
||
return new NotFoundObjectResult(ex.Message) {};
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return new ObjectResult(ex.Message) { StatusCode = 500 };
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Get all section with beacon
|
||
/// </summary>
|
||
/// <param name="instanceId">Instance id</param>
|
||
[AllowAnonymous]
|
||
[ProducesResponseType(typeof(List<SectionDTO>), 200)]
|
||
[ProducesResponseType(typeof(string), 404)]
|
||
[ProducesResponseType(typeof(string), 500)]
|
||
[HttpGet("beacons/{instanceId}")]
|
||
public ObjectResult GetAllBeaconsForInstance(string instanceId)
|
||
{
|
||
try
|
||
{
|
||
List<Section> sections = _myInfoMateDbContext.Sections.Where(s => s.InstanceId == instanceId && s.IsBeacon && s.BeaconId != null).ToList();
|
||
//List<OldSection> sections = _sectionService.GetAll(instanceId);
|
||
|
||
//sections = sections.Where(s => s.IsBeacon && s.BeaconId != null).ToList();
|
||
|
||
return new OkObjectResult(sections.Select(s => s.ToDTO()));
|
||
}
|
||
catch (KeyNotFoundException ex)
|
||
{
|
||
return new NotFoundObjectResult(ex.Message) { };
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return new ObjectResult(ex.Message) { StatusCode = 500 };
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Create a new section
|
||
/// </summary>
|
||
/// <param name="newSection">New section info</param>
|
||
[ProducesResponseType(typeof(SectionDTO), 200)]
|
||
[ProducesResponseType(typeof(string), 400)]
|
||
[ProducesResponseType(typeof(string), 409)]
|
||
[ProducesResponseType(typeof(string), 500)]
|
||
[HttpPost()]
|
||
public ObjectResult Create([FromBody] SectionDTO newSection)
|
||
{
|
||
try
|
||
{
|
||
if (newSection == null)
|
||
throw new ArgumentNullException("Section param is null");
|
||
|
||
if (newSection.configurationId == null)
|
||
throw new ArgumentNullException("Configuration param is null");
|
||
|
||
var configuration = _myInfoMateDbContext.Configurations.FirstOrDefault(c => c.Id == newSection.configurationId);
|
||
if (configuration == null)
|
||
throw new KeyNotFoundException("Configuration does not exist");
|
||
|
||
// Todo add some verification ?
|
||
Section section = new Section();
|
||
|
||
// Preparation
|
||
List<string> languages = _configuration.GetSection("SupportedLanguages").Get<List<string>>();
|
||
|
||
switch (newSection.type)
|
||
{
|
||
case SectionType.Agenda:
|
||
section = new SectionAgenda
|
||
{
|
||
AgendaResourceIds = new List<TranslationDTO>(),
|
||
EventAgendas = new List<EventAgenda>()
|
||
};
|
||
break;
|
||
case SectionType.Article:
|
||
section = new SectionArticle
|
||
{
|
||
ArticleContents = new List<ContentDTO>(),
|
||
ArticleContent = LanguageInit.Init("Content", languages),
|
||
ArticleAudioIds = LanguageInit.Init("Audio", languages, true)
|
||
};
|
||
break;
|
||
case SectionType.Event:
|
||
section = new SectionEvent
|
||
{
|
||
Programme = new List<ProgrammeBlock>(),
|
||
ParcoursIds = new List<string>()
|
||
};
|
||
break;
|
||
case SectionType.Map:
|
||
section = new SectionMap
|
||
{
|
||
MapMapType = MapTypeApp.hybrid,
|
||
MapTypeMapbox = MapTypeMapBox.standard,
|
||
MapMapProvider = MapProvider.Google,
|
||
MapZoom = 18,
|
||
MapPoints = new List<GeoPoint>(),
|
||
MapCategories = new List<CategorieDTO>()
|
||
};
|
||
break;
|
||
case SectionType.Menu:
|
||
section = new SectionMenu
|
||
{
|
||
MenuSections = new List<Section>(),
|
||
};
|
||
break;
|
||
case SectionType.PDF:
|
||
section = new SectionPdf
|
||
{
|
||
PDFOrderedTranslationAndResources = []
|
||
};
|
||
break;
|
||
case SectionType.Game:
|
||
section = new SectionGame
|
||
{
|
||
GameMessageDebut = [],
|
||
GameMessageFin = []
|
||
};
|
||
break;
|
||
case SectionType.Quiz:
|
||
section = new SectionQuiz
|
||
{
|
||
QuizQuestions = new List<QuizQuestion>(),
|
||
// TODO levels ?
|
||
};
|
||
break;
|
||
case SectionType.Slider:
|
||
section = new SectionSlider
|
||
{
|
||
SliderContents = new List<ContentDTO>()
|
||
};
|
||
break;
|
||
case SectionType.Video:
|
||
section = new SectionVideo
|
||
{
|
||
VideoSource = "",
|
||
};
|
||
break;
|
||
case SectionType.Weather:
|
||
section = new SectionWeather();
|
||
break;
|
||
case SectionType.Web:
|
||
section = new SectionWeb
|
||
{
|
||
WebSource = "",
|
||
};
|
||
break;
|
||
}
|
||
|
||
section.InstanceId = newSection.instanceId;
|
||
section.Label = newSection.label;
|
||
section.ImageId = newSection.imageId;
|
||
section.ImageSource = newSection.imageSource;
|
||
section.ConfigurationId = newSection.configurationId;
|
||
section.DateCreation = newSection.dateCreation == null ? DateTime.Now.ToUniversalTime() : newSection.dateCreation.Value;
|
||
section.IsSubSection = newSection.isSubSection;
|
||
section.ParentId = newSection.parentId;
|
||
section.Type = newSection.type;
|
||
|
||
// TODO test that in new format
|
||
section.Order = _myInfoMateDbContext.Sections.Count(s => s.ConfigurationId == newSection.configurationId && !s.IsSubSection) + 1;
|
||
|
||
/*if (configuration.IsMobile)
|
||
{
|
||
section.Order = _myInfoMateDbContext.Sections.Count(s => s.ConfigurationId == newSection.configurationId && !s.IsSubSection && (s.Type == SectionType.Article || s.Type == SectionType.Quiz)) + 1;
|
||
}
|
||
else
|
||
{
|
||
section.Order = 0; // _myInfoMateDbContext.Sections.Count(s => s.ConfigurationId == newSection.configurationId && !s.IsSubSection) + 1;
|
||
}*/
|
||
|
||
section.IsBeacon = newSection.isBeacon;
|
||
section.BeaconId = newSection.beaconId;
|
||
section.Latitude = newSection.latitude;
|
||
section.Longitude = newSection.longitude;
|
||
section.MeterZoneGPS = newSection.meterZoneGPS;
|
||
section.Title = LanguageInit.Init("Title", languages);
|
||
section.Description = LanguageInit.Init("Description", languages);
|
||
|
||
section.Id = idService.GenerateHexId();
|
||
//_sectionService.Create(section);
|
||
_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<61>e
|
||
sections.RemoveAll(q => q.Id == section.Id);
|
||
|
||
// Ins<6E>rer <20> la premi<6D>re position (d<>j<EFBFBD> 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)
|
||
{
|
||
return new BadRequestObjectResult(ex.Message) {};
|
||
}
|
||
catch (InvalidOperationException ex)
|
||
{
|
||
return new ConflictObjectResult(ex.Message) {};
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return new ObjectResult(ex.Message) { StatusCode = 500 };
|
||
}
|
||
}
|
||
|
||
/*/// <summary>
|
||
/// Create a new section - slider
|
||
/// </summary>
|
||
/// <param name="newSection">New section info - slider</param>
|
||
[ProducesResponseType(typeof(SliderDTO), 200)]
|
||
[ProducesResponseType(typeof(string), 400)]
|
||
[ProducesResponseType(typeof(string), 409)]
|
||
[ProducesResponseType(typeof(string), 500)]
|
||
[HttpPost("Slider")]
|
||
public ObjectResult CreateSlider([FromBody] SliderDTO newSectionSlider)
|
||
{
|
||
try
|
||
{
|
||
if (newSectionSlider == null)
|
||
throw new ArgumentNullException("Section param is null");
|
||
|
||
// Todo add some verification ?
|
||
Slider sliderSection = new Slider();
|
||
sliderSection.Label = newSectionSlider.Label;
|
||
sliderSection.ImageId = newSectionSlider.ImageId;
|
||
sliderSection.DateCreation = DateTime.Now;
|
||
|
||
sliderSection.IsSubSection = false;
|
||
sliderSection.ParentId = null;
|
||
sliderSection.Type = SectionType.Slider;
|
||
|
||
sliderSection.Images = newSectionSlider.Images.Select(p =>
|
||
new Image()
|
||
{
|
||
Title = p.Title,
|
||
Description = p.Description,
|
||
Source = p.Source,
|
||
}).ToList();
|
||
|
||
Slider sectionCreated = _sectionService.CreateSlider(sliderSection);
|
||
|
||
return new OkObjectResult(sectionCreated.ToDTO());
|
||
}
|
||
catch (ArgumentNullException ex)
|
||
{
|
||
return new BadRequestObjectResult(ex.Message) { };
|
||
}
|
||
catch (InvalidOperationException ex)
|
||
{
|
||
return new ConflictObjectResult(ex.Message) { };
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return new ObjectResult(ex.Message) { StatusCode = 500 };
|
||
}
|
||
}*/
|
||
|
||
/// <summary>
|
||
/// Update a section
|
||
/// </summary>
|
||
/// <param name="updatedSection">Section to update</param>
|
||
[ProducesResponseType(typeof(object), 200)]
|
||
[ProducesResponseType(typeof(string), 400)]
|
||
[ProducesResponseType(typeof(string), 404)]
|
||
[ProducesResponseType(typeof(string), 500)]
|
||
[HttpPut]
|
||
public ObjectResult Update([FromBody] dynamic updatedSection)
|
||
{
|
||
try
|
||
{
|
||
if (updatedSection.ValueKind == JsonValueKind.Null)
|
||
throw new ArgumentNullException("Section param is null");
|
||
|
||
SectionDTO sectionDTO;
|
||
if (updatedSection is JsonElement jsonElement)
|
||
{
|
||
if (jsonElement.ValueKind == JsonValueKind.Null)
|
||
throw new ArgumentNullException("Section param is null");
|
||
|
||
// D<>s<EFBFBD>rialisation de jsonElement en SectionDTO
|
||
sectionDTO = JsonConvert.DeserializeObject<SectionDTO>(jsonElement.ToString());
|
||
}
|
||
else
|
||
{
|
||
throw new InvalidOperationException("Expected a JsonElement");
|
||
}
|
||
|
||
Section existingSection = _myInfoMateDbContext.Sections.FirstOrDefault(s => s.Id == sectionDTO.id);
|
||
|
||
if (existingSection == null)
|
||
throw new KeyNotFoundException("Section does not exist");
|
||
|
||
if (existingSection.Type != sectionDTO.type)
|
||
return BadRequest("Type mismatch: cannot change section type");
|
||
|
||
if (existingSection.IsSubSection && sectionDTO.order != existingSection.Order)
|
||
{
|
||
// If subsection, check if order changed
|
||
var subSections = _myInfoMateDbContext.Sections.Where(s => s.ParentId == existingSection.ParentId).OrderBy(s => s.Order).ToList();
|
||
|
||
// Retirer la sous section d<>plac<61>e
|
||
subSections.RemoveAll(q => q.Id == existingSection.Id);
|
||
|
||
// Ins<6E>rer <20> la nouvelle position (d<>j<EFBFBD> en 0-based)
|
||
int newIndex = sectionDTO.order.Value;
|
||
newIndex = Math.Clamp(newIndex, 0, subSections.Count);
|
||
subSections.Insert(newIndex, existingSection);
|
||
|
||
// R<>assigner les ordres en 0-based
|
||
for (int i = 0; i < subSections.Count; i++)
|
||
{
|
||
subSections[i].Order = i;
|
||
}
|
||
_myInfoMateDbContext.SaveChanges();
|
||
}
|
||
else
|
||
{
|
||
// classic update
|
||
var updatedSectionDB = SectionFactory.Create(updatedSection, sectionDTO);
|
||
|
||
_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));
|
||
}
|
||
catch (ArgumentNullException ex)
|
||
{
|
||
return new BadRequestObjectResult(ex.Message) {};
|
||
}
|
||
catch (KeyNotFoundException ex)
|
||
{
|
||
return new NotFoundObjectResult(ex.Message) {};
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return new ObjectResult(ex.Message) { StatusCode = 500 };
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Update sections order
|
||
/// </summary>
|
||
/// <param name="updatedSectionsOrder">New sections order</param>
|
||
[ProducesResponseType(typeof(string), 200)]
|
||
[ProducesResponseType(typeof(string), 400)]
|
||
[ProducesResponseType(typeof(string), 404)]
|
||
[ProducesResponseType(typeof(string), 500)]
|
||
[HttpPut("order")]
|
||
public ObjectResult UpdateOrder([FromBody] List<SectionDTO> updatedSectionsOrder)
|
||
{
|
||
// TODO REWRITE LOGIC..
|
||
try
|
||
{
|
||
if (updatedSectionsOrder == null)
|
||
throw new ArgumentNullException("Sections param is null");
|
||
|
||
foreach (var section in updatedSectionsOrder)
|
||
{
|
||
var sectionDB = _myInfoMateDbContext.Sections.FirstOrDefault(s => s.Id == section.id);
|
||
if (sectionDB == null)
|
||
throw new KeyNotFoundException($"Section {section.label} with id {section.id} does not exist");
|
||
}
|
||
|
||
foreach (var updatedSection in updatedSectionsOrder)
|
||
{
|
||
var section = _myInfoMateDbContext.Sections.FirstOrDefault(s => s.Id == updatedSection.id);
|
||
//OldSection section = _sectionService.GetById(updatedSection.id);
|
||
section.Order = updatedSection.order.GetValueOrDefault();
|
||
_myInfoMateDbContext.SaveChanges();
|
||
|
||
//_sectionService.Update(section.Id, section);
|
||
}
|
||
|
||
if (updatedSectionsOrder.Count > 0) {
|
||
MqttClientService.PublishMessage($"config/{updatedSectionsOrder[0].configurationId}", JsonConvert.SerializeObject(new PlayerMessageDTO() { configChanged = true }));
|
||
}
|
||
|
||
return new ObjectResult("Sections order has been successfully modified") { StatusCode = 200 };
|
||
}
|
||
catch (ArgumentNullException ex)
|
||
{
|
||
return new BadRequestObjectResult(ex.Message) { };
|
||
}
|
||
catch (KeyNotFoundException ex)
|
||
{
|
||
return new NotFoundObjectResult(ex.Message) { };
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return new ObjectResult(ex.Message) { StatusCode = 500 };
|
||
}
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// Delete a section
|
||
/// </summary>
|
||
/// <param name="id">Id of section to delete</param>
|
||
[ProducesResponseType(typeof(string), 202)]
|
||
[ProducesResponseType(typeof(string), 400)]
|
||
[ProducesResponseType(typeof(string), 404)]
|
||
[ProducesResponseType(typeof(string), 500)]
|
||
[HttpDelete("{id}")]
|
||
public ObjectResult Delete(string id)
|
||
{
|
||
try
|
||
{
|
||
if (id == null)
|
||
throw new ArgumentNullException("Section param is null");
|
||
|
||
var section = _myInfoMateDbContext.Sections.FirstOrDefault(s => s.Id == id);
|
||
if (section == null)
|
||
throw new KeyNotFoundException("Section does not exist");
|
||
|
||
if (section.Type == SectionType.Agenda)
|
||
{
|
||
var sectionAgenda = _myInfoMateDbContext.Sections.OfType<SectionAgenda>().Include(sa => sa.EventAgendas).FirstOrDefault(sa => sa.Id == id);
|
||
|
||
_myInfoMateDbContext.RemoveRange(sectionAgenda.EventAgendas);
|
||
}
|
||
|
||
if (section.Type == SectionType.Event)
|
||
{
|
||
var sectionEvent = _myInfoMateDbContext.Sections.OfType<SectionEvent>().Include(se => se.Programme).ThenInclude(se => se.MapAnnotations).FirstOrDefault(s => s.Id == id);
|
||
|
||
foreach (var programBlock in sectionEvent.Programme)
|
||
{
|
||
_myInfoMateDbContext.RemoveRange(programBlock.MapAnnotations);
|
||
_myInfoMateDbContext.Remove(programBlock);
|
||
}
|
||
|
||
var guidedPaths = _myInfoMateDbContext.GuidedPaths.Include(gp => gp.Steps).Where(gp => gp.SectionEventId == id);
|
||
foreach (var guidedPath in guidedPaths)
|
||
{
|
||
_myInfoMateDbContext.RemoveRange(guidedPath.Steps);
|
||
_myInfoMateDbContext.Remove(guidedPath);
|
||
}
|
||
|
||
var applicationInstances = _myInfoMateDbContext.ApplicationInstances.Where(ai => ai.SectionEventId == id);
|
||
foreach (var applicationInstance in applicationInstances)
|
||
{
|
||
applicationInstance.SectionEventId = null;
|
||
}
|
||
}
|
||
|
||
if (section.Type == SectionType.Map)
|
||
{
|
||
// REMOVE ALL POINTS
|
||
var geoPoints = _myInfoMateDbContext.GeoPoints.Where(gp => gp.SectionMapId == section.Id).ToList();
|
||
_myInfoMateDbContext.RemoveRange(geoPoints);
|
||
|
||
var guidedPaths = _myInfoMateDbContext.GuidedPaths.Include(gp => gp.Steps).Where(gp => gp.SectionMapId == id);
|
||
foreach (var guidedPath in guidedPaths)
|
||
{
|
||
_myInfoMateDbContext.RemoveRange(guidedPath.Steps);
|
||
_myInfoMateDbContext.Remove(guidedPath);
|
||
}
|
||
}
|
||
|
||
if (section.Type == SectionType.Quiz)
|
||
{
|
||
// REMOVE ALL Questions
|
||
var quizQuestions = _myInfoMateDbContext.QuizQuestions.Where(qq => qq.SectionQuizId == section.Id).ToList();
|
||
_myInfoMateDbContext.RemoveRange(quizQuestions);
|
||
}
|
||
|
||
_myInfoMateDbContext.Remove(section);
|
||
|
||
var configuration = _myInfoMateDbContext.Configurations.FirstOrDefault(c => c.Id == section.ConfigurationId);
|
||
|
||
List<Section> sections = _myInfoMateDbContext.Sections.Where(s => s.ConfigurationId == section.ConfigurationId && !s.IsSubSection).ToList();
|
||
int i = 1;
|
||
List<Section> orderedSection = sections.OrderBy(s => s.Order).ToList();
|
||
foreach (var sectionDb in orderedSection)
|
||
{
|
||
sectionDb.Order = i;
|
||
i++;
|
||
}
|
||
|
||
_myInfoMateDbContext.SaveChanges();
|
||
|
||
return new ObjectResult("The section has been deleted") { StatusCode = 202 };
|
||
|
||
}
|
||
catch (ArgumentNullException ex)
|
||
{
|
||
return new BadRequestObjectResult(ex.Message) { };
|
||
}
|
||
catch (KeyNotFoundException ex)
|
||
{
|
||
return new NotFoundObjectResult(ex.Message) { };
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return new ObjectResult(ex.Message) { StatusCode = 500 };
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Useless, just to generate dto code
|
||
/// </summary>
|
||
[ProducesResponseType(typeof(MapDTO), 200)]
|
||
[HttpGet("MapDTO")]
|
||
public ObjectResult GetMapDTO()
|
||
{
|
||
return new ObjectResult("MapDTO") { StatusCode = 200 };
|
||
}
|
||
|
||
/// <summary>
|
||
/// Useless, just to generate dto code
|
||
/// </summary>
|
||
[ProducesResponseType(typeof(SliderDTO), 200)]
|
||
[HttpGet("SliderDTO")]
|
||
public ObjectResult GetSliderDTO()
|
||
{
|
||
return new ObjectResult("SliderDTO") { StatusCode = 200 };
|
||
}
|
||
|
||
/// <summary>
|
||
/// Useless, just to generate dto code
|
||
/// </summary>
|
||
[ProducesResponseType(typeof(VideoDTO), 200)]
|
||
[HttpGet("VideoDTO")]
|
||
public ObjectResult GetVideoDTO()
|
||
{
|
||
return new ObjectResult("VideoDTO") { StatusCode = 200 };
|
||
}
|
||
|
||
/// <summary>
|
||
/// Useless, just to generate dto code
|
||
/// </summary>
|
||
[ProducesResponseType(typeof(WebDTO), 200)]
|
||
[HttpGet("WebDTO")]
|
||
public ObjectResult GetWebDTO()
|
||
{
|
||
return new ObjectResult("WebDTO") { StatusCode = 200 };
|
||
}
|
||
|
||
/// <summary>
|
||
/// Useless, just to generate dto code
|
||
/// </summary>
|
||
[ProducesResponseType(typeof(MenuDTO), 200)]
|
||
[HttpGet("MenuDTO")]
|
||
public ObjectResult GetMenuDTO()
|
||
{
|
||
return new ObjectResult("MenuDTO") { StatusCode = 200 };
|
||
}
|
||
|
||
/// <summary>
|
||
/// Useless, just to generate dto code
|
||
/// </summary>
|
||
[ProducesResponseType(typeof(PlayerMessageDTO), 200)]
|
||
[HttpGet("PlayerMessageDTO")]
|
||
public ObjectResult PlayerMessageDTO()
|
||
{
|
||
return new ObjectResult("PlayerMessageDTO") { StatusCode = 200 };
|
||
}
|
||
|
||
/// <summary>
|
||
/// Useless, just to generate dto code
|
||
/// </summary>
|
||
[ProducesResponseType(typeof(QuizDTO), 200)]
|
||
[HttpGet("QuizDTO")]
|
||
public ObjectResult GetQuizDTO()
|
||
{
|
||
return new ObjectResult("QuizDTO") { StatusCode = 200 };
|
||
}
|
||
|
||
/// <summary>
|
||
/// Useless, just to generate dto code
|
||
/// </summary>
|
||
[ProducesResponseType(typeof(ArticleDTO), 200)]
|
||
[HttpGet("ArticleDTO")]
|
||
public ObjectResult GetArticleDTO()
|
||
{
|
||
return new ObjectResult("ArticleDTO") { StatusCode = 200 };
|
||
}
|
||
|
||
/// <summary>
|
||
/// Useless, just to generate dto code
|
||
/// </summary>
|
||
[ProducesResponseType(typeof(PdfDTO), 200)]
|
||
[HttpGet("PdfDTO")]
|
||
public ObjectResult GetPdfDTO()
|
||
{
|
||
return new ObjectResult("PdfDTO") { StatusCode = 200 };
|
||
}
|
||
|
||
/// <summary>
|
||
/// Useless, just to generate dto code
|
||
/// </summary>
|
||
[ProducesResponseType(typeof(GameDTO), 200)]
|
||
[HttpGet("PuzzleDTO")]
|
||
public ObjectResult GetPuzzleDTO()
|
||
{
|
||
return new ObjectResult("PuzzleDTO") { StatusCode = 200 };
|
||
}
|
||
|
||
/// <summary>
|
||
/// Useless, just to generate dto code
|
||
/// </summary>
|
||
[ProducesResponseType(typeof(AgendaDTO), 200)]
|
||
[HttpGet("AgendaDTO")]
|
||
public ObjectResult GetAgendaDTO()
|
||
{
|
||
return new ObjectResult("AgendaDTO") { StatusCode = 200 };
|
||
}
|
||
|
||
/// <summary>
|
||
/// Useless, just to generate dto code
|
||
/// </summary>
|
||
[ProducesResponseType(typeof(WeatherDTO), 200)]
|
||
[HttpGet("WeatherDTO")]
|
||
public ObjectResult GetWeatherDTO()
|
||
{
|
||
return new ObjectResult("WeatherDTO") { StatusCode = 200 };
|
||
}
|
||
|
||
/// <summary>
|
||
/// Useless, just to generate dto code
|
||
/// </summary>
|
||
[ProducesResponseType(typeof(SectionEventDTO), 200)]
|
||
[HttpGet("SectionEventDTO")]
|
||
public ObjectResult GetSectionEventDTO()
|
||
{
|
||
return new ObjectResult("SectionEventDTO") { StatusCode = 200 };
|
||
}
|
||
|
||
/// <summary>
|
||
/// Useless, just to generate dto code
|
||
/// </summary>
|
||
[ProducesResponseType(typeof(GuidedPathDTO), 200)]
|
||
[HttpGet("GuidedPathDTO")]
|
||
public ObjectResult GetGuidedPathDTO()
|
||
{
|
||
return new ObjectResult("GuidedPathDTO") { StatusCode = 200 };
|
||
}
|
||
}
|
||
}
|