using Manager.DTOs; using ManagerService.Data; using ManagerService.Data.SubSection; using ManagerService.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using NSwag.Annotations; using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; namespace ManagerService.Controllers { [Authorize] // TODO Add ROLES (Roles = "Admin") [ApiController, Route("api/[controller]")] [OpenApiTag("Section map", Description = "Section map management")] public class SectionMapController : ControllerBase { private readonly MyInfoMateDbContext _myInfoMateDbContext; private readonly ILogger _logger; private readonly IConfiguration _configuration; IHexIdGeneratorService idService = new HexIdGeneratorService(); public SectionMapController(IConfiguration configuration, ILogger logger, MyInfoMateDbContext myInfoMateDbContext) { _logger = logger; _configuration = configuration; _myInfoMateDbContext = myInfoMateDbContext; } /// /// Get all points from section /// /// Section id [AllowAnonymous] [ProducesResponseType(typeof(List), 200)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpGet("{sectionId}/points")] public ObjectResult GetAllGeoPointsFromSection(string sectionId) { try { SectionMap sectionMap = _myInfoMateDbContext.Sections.OfType().Include(sm => sm.MapPoints).FirstOrDefault(sm => sm.Id == sectionId); List geoPointDTOs = new List(); foreach (var point in sectionMap.MapPoints) { foreach (var content in point.Contents) { var resource = _myInfoMateDbContext.Resources.FirstOrDefault(r => r.Id == content.resourceId); if (resource != null) { content.resource = resource.ToDTO(); } } geoPointDTOs.Add(new GeoPointDTO() { id = point.Id, title = point.Title, description = point.Description, contents = point.Contents, categorieId = point.CategorieId, geometryType = point.GeometryType, coordinates = point.Coordinates, // TODO test that polyColor = point.PolyColor, imageResourceId = point.ImageResourceId, imageUrl = point.ImageUrl, schedules = point.Schedules, prices = point.Prices, phone = point.Phone, email = point.Email, site = point.Site }); } return new OkObjectResult(geoPointDTOs); } catch (KeyNotFoundException ex) { return new NotFoundObjectResult(ex.Message) { }; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Create new point /// /// Section Id /// geoPoint [ProducesResponseType(typeof(GeoPointDTO), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 409)] [ProducesResponseType(typeof(string), 500)] [HttpPost("{sectionId}/points")] public ObjectResult Create(string sectionId, [FromBody] GeoPointDTO geoPointDTO) { try { if (sectionId == null) throw new ArgumentNullException("Section param is null"); if (geoPointDTO == null) throw new ArgumentNullException("GeoPoint is null"); var existingSection = _myInfoMateDbContext.Sections.OfType().Include(s => s.MapPoints).FirstOrDefault(s => s.Id == sectionId); if (existingSection == null) throw new KeyNotFoundException("Section map does not exist"); // TODO verification ? GeoPoint geoPoint = new GeoPoint(); geoPoint.Title = geoPointDTO.title; geoPoint.Description = geoPointDTO.description; geoPoint.Contents = geoPointDTO.contents; geoPoint.CategorieId = geoPointDTO.categorieId; geoPoint.GeometryType = geoPointDTO.geometryType; geoPoint.Coordinates = geoPointDTO.coordinates; // TODO TEST geoPoint.PolyColor = geoPointDTO.polyColor; geoPoint.ImageResourceId = geoPointDTO.imageResourceId; geoPoint.ImageUrl = geoPointDTO.imageUrl; // TO BE TESTED ? Depends on front geoPoint.Schedules = geoPointDTO.schedules; geoPoint.Prices = geoPointDTO.prices; geoPoint.Phone = geoPointDTO.phone; geoPoint.Email = geoPointDTO.email; geoPoint.Site = geoPointDTO.site; if (existingSection.MapPoints == null) { existingSection.MapPoints = []; } existingSection.MapPoints.Add(geoPoint); _myInfoMateDbContext.SaveChanges(); var geoPointDto = new GeoPointDTO() { id = geoPoint.Id, title = geoPoint.Title, description = geoPoint.Description, contents = geoPoint.Contents, categorieId = geoPoint.CategorieId, geometryType = geoPointDTO.geometryType, coordinates = geoPointDTO.coordinates, // TODO TEST polyColor = geoPointDTO.polyColor, imageResourceId = geoPoint.ImageResourceId, imageUrl = geoPoint.ImageUrl, schedules = geoPoint.Schedules, prices = geoPoint.Prices, phone = geoPoint.Phone, email = geoPoint.Email, site = geoPoint.Site }; return new OkObjectResult(geoPointDto); } 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 }; } } /// /// Update a geo point /// /// GeoPoint to update [ProducesResponseType(typeof(GeoPoint), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpPut] public ObjectResult Update([FromBody] GeoPointDTO geoPointDTO) { try { if (geoPointDTO == null) throw new ArgumentNullException("GeoPoint param is null"); var existingGeoPoint = _myInfoMateDbContext.GeoPoints.FirstOrDefault(gp => gp.Id == geoPointDTO.id); if (existingGeoPoint == null) throw new KeyNotFoundException("GeoPoint does not exist"); existingGeoPoint.Title = geoPointDTO.title; existingGeoPoint.Description = geoPointDTO.description; existingGeoPoint.Contents = geoPointDTO.contents; existingGeoPoint.CategorieId = geoPointDTO.categorieId; existingGeoPoint.GeometryType = geoPointDTO.geometryType; existingGeoPoint.Coordinates = geoPointDTO.coordinates; // TODO TEST existingGeoPoint.PolyColor = geoPointDTO.polyColor; existingGeoPoint.ImageResourceId = geoPointDTO.imageResourceId; existingGeoPoint.ImageUrl = geoPointDTO.imageUrl; existingGeoPoint.Schedules = geoPointDTO.schedules; existingGeoPoint.Prices = geoPointDTO.prices; existingGeoPoint.Phone = geoPointDTO.phone; existingGeoPoint.Email = geoPointDTO.email; existingGeoPoint.Site = geoPointDTO.site; _myInfoMateDbContext.SaveChanges(); return new OkObjectResult(existingGeoPoint); } 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 }; } } /// /// Update sections order /// /// New sections order /*[ProducesResponseType(typeof(string), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpPut("order")] public ObjectResult UpdateOrder([FromBody] List 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 }; } }*/ /// /// Delete a geopoint /// /// Id of geopoint to delete [ProducesResponseType(typeof(string), 202)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpDelete("points/delete/{geoPointId}")] public ObjectResult Delete(int geoPointId) { try { var geoPoint = _myInfoMateDbContext.GeoPoints.FirstOrDefault(gp => gp.Id == geoPointId); if (geoPoint == null) throw new KeyNotFoundException("GeoPoint does not exist"); _myInfoMateDbContext.Remove(geoPoint); _myInfoMateDbContext.SaveChanges(); return new ObjectResult("The geopoint 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 }; } } } }