From 78707bf3c574388e86816f8ce4e4d94c96c81146 Mon Sep 17 00:00:00 2001 From: mborzyszkowski Date: Sun, 8 Nov 2020 13:08:38 +0100 Subject: [PATCH] Edition Create/Edit --- src/InternshipSystem.Api/ApiProfile.cs | 2 +- .../EditionManagementController.cs | 51 ++++++++++++-- .../Queries/EditionForm.cs | 27 +++++--- ...nFullResult.cs => EditionDetailsResult.cs} | 2 +- src/InternshipSystem.Core/Entity/Edition.cs | 68 ++++++++++++++++++- 5 files changed, 131 insertions(+), 19 deletions(-) rename src/InternshipSystem.Api/Result/{EditionFullResult.cs => EditionDetailsResult.cs} (93%) diff --git a/src/InternshipSystem.Api/ApiProfile.cs b/src/InternshipSystem.Api/ApiProfile.cs index efbe56d..729a8ba 100644 --- a/src/InternshipSystem.Api/ApiProfile.cs +++ b/src/InternshipSystem.Api/ApiProfile.cs @@ -21,7 +21,7 @@ namespace InternshipSystem.Api CreateMap(); - CreateMap(); + CreateMap(); CreateMap(); diff --git a/src/InternshipSystem.Api/Controllers/EditionManagementController.cs b/src/InternshipSystem.Api/Controllers/EditionManagementController.cs index 71cecc2..d56543b 100644 --- a/src/InternshipSystem.Api/Controllers/EditionManagementController.cs +++ b/src/InternshipSystem.Api/Controllers/EditionManagementController.cs @@ -5,9 +5,11 @@ 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; @@ -46,7 +48,7 @@ namespace InternshipSystem.Api.Controllers [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status404NotFound)] [Authorize(Policy = Policies.IsOverseer)] - public async Task> GetFullEdition(CancellationToken token) + public async Task> GetFullEdition(Guid editionId, CancellationToken token) { var edition = await Context.Editions .Include(e => e.Course) @@ -54,7 +56,8 @@ namespace InternshipSystem.Api.Controllers .ThenInclude(s => s.Subject) .Include(e => e.AvailableInternshipTypes) .ThenInclude(i => i.InternshipType) - .ProjectTo(Mapper.ConfigurationProvider) + .Where(e => e.Id == editionId) + .ProjectTo(Mapper.ConfigurationProvider) .FirstOrDefaultAsync(token); if (edition == null) @@ -68,22 +71,58 @@ namespace InternshipSystem.Api.Controllers [HttpPut] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status404NotFound)] [Authorize(Policy = Policies.IsOverseer)] public async Task UpsertEdition(EditionForm editionForm, CancellationToken token) { var validator = new EditionForm.Validator(); - // TODO: complete validation rules var validationResult = await validator.ValidateAsync(editionForm, token); - + if (!validationResult.IsValid) { return BadRequest(validationResult.ToString()); } - - // TODO: complete add/update + //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(); } diff --git a/src/InternshipSystem.Api/Queries/EditionForm.cs b/src/InternshipSystem.Api/Queries/EditionForm.cs index 3b41aac..6c30d3e 100644 --- a/src/InternshipSystem.Api/Queries/EditionForm.cs +++ b/src/InternshipSystem.Api/Queries/EditionForm.cs @@ -4,23 +4,34 @@ using FluentValidation; using InternshipSystem.Core; using InternshipSystem.Core.Entity.Internship; -namespace InternshipSystem.Api.Controllers +namespace InternshipSystem.Api.Queries { public class EditionForm { - public Guid Id { get; set; } - public DateTime EditionStart { get; set; } - public DateTime EditionFinish { get; set; } - public DateTime ReportingStart { get; set; } + public Guid? Id { get; set; } + public DateTime? EditionStart { get; set; } + public DateTime? EditionFinish { get; set; } + public DateTime? ReportingStart { get; set; } public Course Course { get; set; } - public List AvailableSubjects { get; set; } - public List AvailableInternshipTypes { get; set; } + public List AvailableSubjectsIds { get; set; } = new List(); + public List AvailableInternshipTypesIds { get; set; } = new List(); public class Validator : AbstractValidator { public Validator() { - //TODO: later + RuleFor(e => e.Id).NotNull() + .When(e => !e.EditionStart.HasValue || !e.EditionFinish.HasValue + || !e.ReportingStart.HasValue || e.Course == null); + + RuleFor(e => e.EditionStart).NotEmpty() + .When(e => !e.Id.HasValue); + RuleFor(e => e.EditionFinish).NotEmpty() + .When(e => !e.Id.HasValue); + RuleFor(e => e.ReportingStart).NotEmpty() + .When(e => !e.Id.HasValue); + RuleFor(e => e.Course).NotNull() + .When(e => !e.Id.HasValue); } } } diff --git a/src/InternshipSystem.Api/Result/EditionFullResult.cs b/src/InternshipSystem.Api/Result/EditionDetailsResult.cs similarity index 93% rename from src/InternshipSystem.Api/Result/EditionFullResult.cs rename to src/InternshipSystem.Api/Result/EditionDetailsResult.cs index 57c9e29..19754bd 100644 --- a/src/InternshipSystem.Api/Result/EditionFullResult.cs +++ b/src/InternshipSystem.Api/Result/EditionDetailsResult.cs @@ -5,7 +5,7 @@ using InternshipSystem.Core.Entity.Internship; namespace InternshipSystem.Api.Result { - public class EditionFullResult + public class EditionDetailsResult { public Guid Id { get; set; } public DateTime EditionStart { get; set; } diff --git a/src/InternshipSystem.Core/Entity/Edition.cs b/src/InternshipSystem.Core/Entity/Edition.cs index c22eb53..567693f 100644 --- a/src/InternshipSystem.Core/Entity/Edition.cs +++ b/src/InternshipSystem.Core/Entity/Edition.cs @@ -18,17 +18,77 @@ namespace InternshipSystem.Core public List AvailableInternshipTypes { get; set; } public bool IsOpen => EditionFinish < DateTime.Today; - - public Edition CreateEdition(DateTime start, DateTime end, DateTime reportingStart) + + public static Edition CreateEdition(DateTime start, DateTime end, DateTime reportingStart, Course course, + IEnumerable subjectsIds, IEnumerable internshipTypesIds) + { + var newEdition = CreateEdition(start, end, reportingStart, course); + + newEdition.AvailableSubjects = + subjectsIds + .Select(s => new EditionSubject + { + Edition = newEdition, + InternshipSubjectId = s, + }) + .ToList(); + + newEdition.AvailableInternshipTypes = + internshipTypesIds + .Select(i => new EditionInternshipType + { + Edition = newEdition, + InternshipTypeId = i, + }) + .ToList(); + + return newEdition; + } + + public static Edition CreateEdition(DateTime start, DateTime end, DateTime reportingStart, Course course) { return new Edition { EditionStart = start, EditionFinish = end, - ReportingStart = reportingStart + ReportingStart = reportingStart, + Course = course, + AvailableSubjects = new List(), + AvailableInternshipTypes = new List(), }; } + public void UpdateEdition(DateTime? start, DateTime? end, DateTime? reportingStart, Course course, + IEnumerable subjectsIds, IEnumerable internshipTypesIds) + { + EditionStart = start ?? EditionStart; + EditionFinish = end ?? EditionFinish; + ReportingStart = reportingStart ?? ReportingStart; + Course = course; + + if (subjectsIds != null) + { + AvailableSubjects = + subjectsIds + .Select(s => new EditionSubject + { + InternshipSubjectId = s, + }) + .ToList(); + } + + if (internshipTypesIds != null) + { + AvailableInternshipTypes = + internshipTypesIds + .Select(i => new EditionInternshipType + { + InternshipTypeId = i, + }) + .ToList(); + } + } + public void RegisterInternship(Student student) { if (Internships.Any(i => i.Student.Id == student.Id)) @@ -55,5 +115,7 @@ namespace InternshipSystem.Core { return internshipSubjects.All(s => AvailableSubjects.Any(su => su.InternshipSubjectId == s)); } + + public bool IsValidDates => EditionStart <= EditionFinish; } } \ No newline at end of file