using ManagerService.Data; using ManagerService.Data.SubSection; 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 NSwag.Annotations; using System; using System.Collections.Generic; using System.Linq; using static ManagerService.Data.SubSection.SectionEvent; namespace ManagerService.Controllers { [Authorize] // TODO Add ROLES (Roles = "Admin") [ApiController, Route("api/[controller]")] [OpenApiTag("Section event", Description = "Section event management")] public class SectionEventController : ControllerBase { private readonly MyInfoMateDbContext _myInfoMateDbContext; private readonly ILogger _logger; private readonly IConfiguration _configuration; IHexIdGeneratorService idService = new HexIdGeneratorService(); public SectionEventController(IConfiguration configuration, ILogger logger, MyInfoMateDbContext myInfoMateDbContext) { _logger = logger; _configuration = configuration; _myInfoMateDbContext = myInfoMateDbContext; } /// /// Get all programme block from section /// /// Section id [AllowAnonymous] [ProducesResponseType(typeof(List), 200)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpGet("{sectionId}/programmes")] public ObjectResult GetAllProgrammeBlockFromSection(string sectionEventId) { try { SectionEvent sectionEvent = _myInfoMateDbContext.Sections.OfType().Include(se => se.Programme).ThenInclude(se => se.MapAnnotations).ThenInclude(se => se.IconResource).FirstOrDefault(se => se.Id == sectionEventId); if (sectionEvent == null) throw new KeyNotFoundException("Section event does not exist"); /*List programmeBlocks = new List(); foreach (var program in sectionEvent.Programme) { foreach (var mapAnnotation in program.MapAnnotations) { var resource = _myInfoMateDbContext.Resources.FirstOrDefault(r => r.Id == mapAnnotation.IconResourceId); if (resource != null) { mapAnnotation.IconResource = resource; // TO check.. use DTO instead ? } } }*/ return new OkObjectResult(sectionEvent.Programme); } catch (KeyNotFoundException ex) { return new NotFoundObjectResult(ex.Message) { }; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Create new programme block /// /// Section event Id /// Programme block [ProducesResponseType(typeof(ProgrammeBlockDTO), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 409)] [ProducesResponseType(typeof(string), 500)] [HttpPost("{sectionEventId}/programmes")] public ObjectResult CreateProgrammeBlock(string sectionEventId, [FromBody] ProgrammeBlockDTO programmeBlockDTO) { try { if (sectionEventId == null) throw new ArgumentNullException("Section param is null"); if (programmeBlockDTO == null) throw new ArgumentNullException("ProgrammeBlock param is null"); var existingSection = _myInfoMateDbContext.Sections.OfType().Include(se => se.Programme).FirstOrDefault(se => se.Id == sectionEventId); if (existingSection == null) throw new KeyNotFoundException("Section event does not exist"); ProgrammeBlock programmeBlock = new ProgrammeBlock().FromDTO(programmeBlockDTO); programmeBlock.Id = idService.GenerateHexId(); existingSection.Programme.Add(programmeBlock); _myInfoMateDbContext.SaveChanges(); return new OkObjectResult(programmeBlock.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 }; } } /// /// Update a program block /// /// ProgramBlock to update [ProducesResponseType(typeof(ProgrammeBlockDTO), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpPut("programmes")] public ObjectResult UpdateProgrammeBlock([FromBody] ProgrammeBlockDTO programmeBlockDTO) { try { if (programmeBlockDTO == null) throw new ArgumentNullException("ProgrammeBlock param is null"); var existingProgramBlock = _myInfoMateDbContext.ProgrammeBlocks.FirstOrDefault(pb => pb.Id == programmeBlockDTO.Id); if (existingProgramBlock == null) throw new KeyNotFoundException("ProgrammeBlock does not exist"); existingProgramBlock.Title = programmeBlockDTO.Title; existingProgramBlock.Description = programmeBlockDTO.Description; existingProgramBlock.StartTime = programmeBlockDTO.StartTime; existingProgramBlock.EndTime = programmeBlockDTO.EndTime; _myInfoMateDbContext.SaveChanges(); return new OkObjectResult(existingProgramBlock); } 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 programBlock /// /// Id of program block to delete [ProducesResponseType(typeof(string), 202)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpDelete("programmes/{programBlockId}")] public ObjectResult DeleteProgrammeBlock(string programBlockId) { try { var programBlock = _myInfoMateDbContext.ProgrammeBlocks.Include(pb => pb.MapAnnotations).FirstOrDefault(pb => pb.Id == programBlockId); if (programBlock == null) throw new KeyNotFoundException("ProgramBlock does not exist"); foreach (var mapAnnotation in programBlock.MapAnnotations) // Is it really needed? { _myInfoMateDbContext.Remove(mapAnnotation); } _myInfoMateDbContext.Remove(programBlock); _myInfoMateDbContext.SaveChanges(); return new ObjectResult("The programBlock 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 }; } } /// /// Get all map annotation from program block /// /// Program block id [AllowAnonymous] [ProducesResponseType(typeof(List), 200)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpGet("{programBlockId}/map-annotations")] public ObjectResult GetAllMapAnnotationsFromProgrammeBlock(string programBlockId) { try { ProgrammeBlock programmeBlock = _myInfoMateDbContext.ProgrammeBlocks.Include(pb => pb.MapAnnotations).ThenInclude(pb => pb.IconResource).FirstOrDefault(pb => pb.Id == programBlockId); if (programmeBlock == null) throw new KeyNotFoundException("ProgrammeBlock does not exist"); /*List programmeBlocks = new List(); foreach (var program in sectionEvent.Programme) { foreach (var mapAnnotation in program.MapAnnotations) { var resource = _myInfoMateDbContext.Resources.FirstOrDefault(r => r.Id == mapAnnotation.IconResourceId); if (resource != null) { mapAnnotation.IconResource = resource; // TO check.. use DTO instead ? } } }*/ return new OkObjectResult(programmeBlock.MapAnnotations.Select(ma => ma.ToDTO())); } catch (KeyNotFoundException ex) { return new NotFoundObjectResult(ex.Message) { }; } catch (Exception ex) { return new ObjectResult(ex.Message) { StatusCode = 500 }; } } /// /// Create new map annotation /// /// Programme block id /// Map annotation [ProducesResponseType(typeof(MapAnnotationDTO), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 409)] [ProducesResponseType(typeof(string), 500)] [HttpPost("{programmeBlockId}/map-annotations")] public ObjectResult CreateMapAnnotation(string programmeBlockId, [FromBody] MapAnnotationDTO mapAnnotationDTO) { try { if (programmeBlockId == null) throw new ArgumentNullException("ProgrammeBlockId param is null"); if (mapAnnotationDTO == null) throw new ArgumentNullException("MapAnnotation param is null"); var existingProgrammeBloc = _myInfoMateDbContext.ProgrammeBlocks.Include(pb => pb.MapAnnotations).FirstOrDefault(pb => pb.Id == programmeBlockId); if (existingProgrammeBloc == null) throw new KeyNotFoundException("ProgrammeBlock does not exist"); // TODO verification ? MapAnnotation mapAnnotation = new MapAnnotation().FromDTO(mapAnnotationDTO); mapAnnotation.Id = idService.GenerateHexId(); existingProgrammeBloc.MapAnnotations.Add(mapAnnotation); _myInfoMateDbContext.SaveChanges(); return new OkObjectResult(mapAnnotation); } 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 map annotation /// /// mapAnnotation to update [ProducesResponseType(typeof(MapAnnotationDTO), 200)] [ProducesResponseType(typeof(string), 400)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpPut("map-annotations")] public ObjectResult UpdateMapAnnotation([FromBody] MapAnnotationDTO mapAnnotationDTO) { try { if (mapAnnotationDTO == null) throw new ArgumentNullException("MapAnnotation param is null"); var existingMapAnnotation = _myInfoMateDbContext.MapAnnotations.Include(ma => ma.IconResource).FirstOrDefault(ma => ma.Id == mapAnnotationDTO.Id); if (existingMapAnnotation == null) throw new KeyNotFoundException("MapAnnotation does not exist"); existingMapAnnotation.Type = mapAnnotationDTO.Type; existingMapAnnotation.Label = mapAnnotationDTO.Label; existingMapAnnotation.GeometryType = mapAnnotationDTO.GeometryType; existingMapAnnotation.Geometry = mapAnnotationDTO.Geometry; existingMapAnnotation.PolyColor = mapAnnotationDTO.PolyColor; existingMapAnnotation.Icon = mapAnnotationDTO.Icon; existingMapAnnotation.IconResourceId = mapAnnotationDTO.IconResourceId; _myInfoMateDbContext.SaveChanges(); return new OkObjectResult(existingMapAnnotation); } 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 mapAnnotation /// /// Id of map annotation to delete [ProducesResponseType(typeof(string), 202)] [ProducesResponseType(typeof(string), 404)] [ProducesResponseType(typeof(string), 500)] [HttpDelete("map-annotations/{mapAnnotationId}")] public ObjectResult DeleteMapAnnotation(string mapAnnotationId) { try { var mapAnnotation = _myInfoMateDbContext.MapAnnotations.FirstOrDefault(ma => ma.Id == mapAnnotationId); if (mapAnnotation == null) throw new KeyNotFoundException("MapAnnotation does not exist"); _myInfoMateDbContext.Remove(mapAnnotation); _myInfoMateDbContext.SaveChanges(); return new ObjectResult("The mapAnnotation 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 }; } } } }