system-praktyk-api/src/InternshipSystem.Api/Controllers/EditionManagementController.cs

166 lines
6.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AutoMapper;
using AutoMapper.QueryableExtensions;
using InternshipSystem.Api.Queries;
using InternshipSystem.Api.Queries.SearchQuery;
using InternshipSystem.Api.Result;
using InternshipSystem.Api.Security;
using InternshipSystem.Core;
using InternshipSystem.Repository;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace InternshipSystem.Api.Controllers
{
[ApiController]
[Route("editionManagement")]
public class EditionManagementController : ControllerBase
{
private InternshipDbContext Context { get; }
private IMapper Mapper { get; }
public EditionManagementController(IMapper mapper, InternshipDbContext context)
{
Context = context;
Mapper = mapper;
}
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[Authorize(Policy = Policies.IsOverseer)]
public async Task<ActionResult<IReadOnlyCollection<EditionManagementResult>>> GetEditions([FromQuery] EditionSearchQuery searchQuery, CancellationToken token) =>
await Context.Editions
.Include(e => e.Course)
.ProjectTo<EditionManagementResult>(Mapper.ConfigurationProvider)
.Skip(searchQuery.Page * searchQuery.PerPage)
.Take(searchQuery.PerPage)
.ToListAsync(token);
[HttpGet("{editionId}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[Authorize(Policy = Policies.IsOverseer)]
public async Task<ActionResult<EditionDetailsResult>> GetFullEdition(Guid editionId, CancellationToken token)
{
var edition = await Context.Editions
.Include(e => e.Course)
.Include(e => e.AvailableSubjects)
.ThenInclude(s => s.Subject)
.Include(e => e.AvailableInternshipTypes)
.ThenInclude(i => i.InternshipType)
.Where(e => e.Id == editionId)
.ProjectTo<EditionDetailsResult>(Mapper.ConfigurationProvider)
.FirstOrDefaultAsync(token);
if (edition == null)
{
return NotFound();
}
return Ok(edition);
}
[HttpPut]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[Authorize(Policy = Policies.IsOverseer)]
public async Task<ActionResult> UpsertEdition(EditionForm editionForm, CancellationToken token)
{
var validator = new EditionForm.Validator();
var validationResult = await validator.ValidateAsync(editionForm, token);
if (!validationResult.IsValid)
{
return BadRequest(validationResult.ToString());
}
//TODO: resolve courses (one for each edition or dictionary)
editionForm.Course.Id = 0;
if (editionForm.Id.HasValue)
{
var editionToUpdate = await Context.Editions
.Include(e => e.AvailableSubjects)
.Include(e => e.AvailableInternshipTypes)
.FirstOrDefaultAsync(e => e.Id == editionForm.Id.Value, token);
if (editionToUpdate == null)
{
return NotFound();
}
editionToUpdate.UpdateEdition(editionForm.EditionStart, editionForm.EditionFinish, editionForm.ReportingStart,
editionForm.Course, editionForm.AvailableSubjectsIds, editionForm.AvailableInternshipTypesIds);
if (!editionToUpdate.IsValidDates)
{
return BadRequest();
}
}
else
{
var newEdition =
Edition.CreateEdition(editionForm.EditionStart.Value, editionForm.EditionFinish.Value, editionForm.ReportingStart.Value,
editionForm.Course, editionForm.AvailableSubjectsIds, editionForm.AvailableInternshipTypesIds);
if (!newEdition.IsValidDates)
{
return BadRequest();
}
await Context.Editions.AddAsync(newEdition, token);
}
await Context.SaveChangesAsync(token);
return Ok();
}
[HttpDelete("{editionId}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status409Conflict)]
[Authorize(Policy = Policies.IsOverseer)]
public async Task<ActionResult> DeleteEdition(Guid editionId, CancellationToken token)
{
var editionToDelete = await Context.Editions
.Include(e => e.AvailableSubjects)
.Include(e => e.AvailableInternshipTypes)
.FirstOrDefaultAsync(e => e.Id.Equals(editionId), token);
if (editionToDelete == null)
{
return NotFound();
}
var referencedInternships =
await Context
.Entry(editionToDelete)
.Collection(e => e.Internships)
.Query()
.CountAsync(token);
if (referencedInternships > 0)
{
return Conflict();
}
Context.Editions.Attach(editionToDelete);
Context.Editions.Remove(editionToDelete);
await Context.SaveChangesAsync(token);
return Ok();
}
}
}