Files
aviq-boilerplate/CityInfo.API/Controllers/PointsOfInterestController.cs
2026-03-20 23:52:10 +01:00

184 lines
7.1 KiB
C#

using AutoMapper;
using CityInfo.API.Entities;
using CityInfo.API.Models;
using CityInfo.API.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.JsonPatch;
using Microsoft.AspNetCore.Mvc;
namespace CityInfo.API.Controllers
{
[Route("api/cities/{cityId}/pointsofinterest/", Name = "GetPointsOfInterest")]
[Authorize(Policy = "MustBeFromCharleroi")]
[ApiController]
public class PointsOfInterestController : ControllerBase
{
private readonly ILogger<PointsOfInterestController> _logger;
private readonly IMailService _mailService;
private readonly ICityInfoRepository _cityInfoRepository;
private readonly IMapper _mapper;
public PointsOfInterestController(
ILogger<PointsOfInterestController> logger,
IMailService mailService,
ICityInfoRepository cityInfoRepository,
IMapper mapper)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_mailService = mailService ?? throw new ArgumentNullException(nameof(mailService));
_cityInfoRepository = cityInfoRepository ?? throw new ArgumentNullException(nameof(cityInfoRepository));
_mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
}
[HttpGet]
public async Task<ActionResult<IEnumerable<PointOfInterestDto>>> GetPointsOfInterest(int cityId)
{
//throw new Exception("pipi");
try
{
//throw new Exception("caca prout");
var cityName = User.Claims.FirstOrDefault(claim => claim.Type == "city")?.Value;
if (!await _cityInfoRepository.CityNameMatchesCityId(cityName, cityId))
{
return Forbid();
}
if(!await _cityInfoRepository.CityExistAsync(cityId))
{
_logger.LogInformation($"City with Id {cityId} wasn't found when accessing points of interest.");
return NotFound();
}
var pointsOfInterest = await _cityInfoRepository.GetPointsOfinterestForCityAsync(cityId);
return Ok(_mapper.Map<IEnumerable<PointOfInterestDto>>(pointsOfInterest));
}
catch (Exception ex)
{
_logger.LogCritical($"Exception while getting points of interest for city with id {cityId}", ex);
return StatusCode(500, "A problem happened while handling your request.");
}
}
[HttpGet("{pointOfInterestId}", Name = "GetPointOfInterest")]
public async Task<ActionResult<PointOfInterestDto>> GetPointOfInterest(int cityId, int pointOfInterestId)
{
if (!await _cityInfoRepository.CityExistAsync(cityId))
{
_logger.LogInformation($"City with Id {cityId} wasn't found when accessing point of interest.");
return NotFound();
}
var pointOfInterest = await _cityInfoRepository.GetPointOfInterestForCityAsync(cityId, pointOfInterestId);
if (pointOfInterest == null)
{
return NotFound();
}
return Ok(_mapper.Map<PointOfInterestDto>(pointOfInterest));
}
[HttpPost(Name = "CreatePointOfInterest")]
public async Task<ActionResult<PointOfInterestDto>> CreatePointOfInterest(
int cityId,
PointOfInterestForCreationDto pointOfInterest)
{
if (!await _cityInfoRepository.CityExistAsync(cityId))
{
return NotFound();
}
var finalPointOfInterest = _mapper.Map<PointOfInterest>(pointOfInterest);
await _cityInfoRepository.CreatePointOfInterestForCityAsync(cityId, finalPointOfInterest);
await _cityInfoRepository.SaveChangesAsync();
var createdPointOfInterestToReturn = _mapper.Map<PointOfInterestDto>(finalPointOfInterest);
return CreatedAtRoute("GetPointOfInterest",
new
{
cityId = cityId,
pointOfInterestId = createdPointOfInterestToReturn.Id
},
createdPointOfInterestToReturn);
}
[HttpPut("{pointOfInterestId}", Name = "UpdatePointOfInterest")]
public async Task<ActionResult> UpdatePointOfInterest(
int cityId,
int pointOfInterestId,
PointOfInterestForUpdateDto pointOfInterest)
{
if (!await _cityInfoRepository.CityExistAsync(cityId))
{
return NotFound();
}
var pointofInterestEntity = await _cityInfoRepository.GetPointOfInterestForCityAsync(cityId, pointOfInterestId);
if (pointofInterestEntity == null)
{
return NotFound();
}
_mapper.Map(pointOfInterest, pointofInterestEntity);
await _cityInfoRepository.SaveChangesAsync();
return NoContent();
}
[HttpPatch("{pointOfInterestId}", Name = "PartiallyUpdatePointOfInterest")]
public async Task<ActionResult> PartiallyUpdatePointOfInterest(
int cityId,
int pointOfInterestId,
JsonPatchDocument<PointOfInterestForUpdateDto> patchDocument)
{
if (!await _cityInfoRepository.CityExistAsync(cityId))
{
return NotFound();
}
var pointofInterestEntity = await _cityInfoRepository.GetPointOfInterestForCityAsync(cityId, pointOfInterestId);
if (pointofInterestEntity == null)
{
return NotFound();
}
var pointOfInterestToPatch = _mapper.Map<PointOfInterestForUpdateDto>(pointofInterestEntity);
patchDocument.ApplyTo(pointOfInterestToPatch, ModelState);
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (!TryValidateModel(pointOfInterestToPatch))
{
return BadRequest(ModelState);
}
_mapper.Map(pointOfInterestToPatch, pointofInterestEntity);
await _cityInfoRepository.SaveChangesAsync();
return NoContent();
}
[HttpDelete("{pointOfInterestId}")]
public async Task<ActionResult> DeletePointOfInterest(
int cityId,
int pointOfInterestId)
{
if (!await _cityInfoRepository.CityExistAsync(cityId))
{
return NotFound();
}
var pointofInterestEntity = await _cityInfoRepository.GetPointOfInterestForCityAsync(cityId, pointOfInterestId);
if (pointofInterestEntity == null)
{
return NotFound();
}
_cityInfoRepository.DeletePointOfInterest(pointofInterestEntity);
await _cityInfoRepository.SaveChangesAsync();
_mailService.Send("Point of interest deleted",
$"Point of Interest {pointofInterestEntity.Name} with Id {pointofInterestEntity.Id} was deleted.");
return NoContent();
}
}
}