From b6669351c4c9f02fcacd3ca07cc49d5b50cebf1f Mon Sep 17 00:00:00 2001 From: mborzyszkowski Date: Mon, 17 Aug 2020 18:59:57 +0200 Subject: [PATCH 1/4] Add document the beginning of implementation --- .../Controllers/DocumentsController.cs | 53 +++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/src/InternshipSystem.Api/Controllers/DocumentsController.cs b/src/InternshipSystem.Api/Controllers/DocumentsController.cs index 5172d9b..d3c6394 100644 --- a/src/InternshipSystem.Api/Controllers/DocumentsController.cs +++ b/src/InternshipSystem.Api/Controllers/DocumentsController.cs @@ -1,12 +1,16 @@ -using System; +using System.Linq; using System.Threading.Tasks; using InternshipSystem.Api.Queries; +using InternshipSystem.Core; using InternshipSystem.Repository; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; namespace InternshipSystem.Api.Controllers { + [ApiController] + [Route("document")] public class DocumentsController : ControllerBase { private InternshipDbContext Context { get; } @@ -30,7 +34,50 @@ namespace InternshipSystem.Api.Controllers [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public async Task AddDocumentToInternship([FromBody] DocumentPublishRequest document) => - throw new NotImplementedException(); + public async Task AddDocumentToInternship([FromBody] DocumentPublishRequest document) + { + // TODO: + // if not authorised then + // return Unauthorized(); + + // TODO: + // is request is valid?? + // if not then + // return BadRequest(); + + var studentInternship = await GetCurrentStudentInternship(); + if (document.Id != null) + { + var doc = studentInternship.Documentation + .Find(d => d.Id == document.Id); + if (doc == null) + return NotFound(); + doc.Description = document.Description; + doc.Scan = document.Scan; + doc.Type = document.Type; + doc.State = DocumentState.Submitted; + } + else + { + studentInternship.Documentation.Add( + new Document() + { + Description = document.Description, + Scan = document.Scan, + Type = document.Type, + State = DocumentState.Submitted + }); + } + return Ok(); + } + + //TODO: rewrite when authentication will be implemented + private async Task GetCurrentStudentInternship() + { + return Context.Editions + .FirstAsync().Result + .Internships + .First(); + } } } \ No newline at end of file -- 2.45.2 From fd3759120107a061230ad94c55cb2ba97d34ea27 Mon Sep 17 00:00:00 2001 From: mborzyszkowski Date: Mon, 17 Aug 2020 19:05:30 +0200 Subject: [PATCH 2/4] save changes --- src/InternshipSystem.Api/Controllers/DocumentsController.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/InternshipSystem.Api/Controllers/DocumentsController.cs b/src/InternshipSystem.Api/Controllers/DocumentsController.cs index d3c6394..00ef234 100644 --- a/src/InternshipSystem.Api/Controllers/DocumentsController.cs +++ b/src/InternshipSystem.Api/Controllers/DocumentsController.cs @@ -68,6 +68,8 @@ namespace InternshipSystem.Api.Controllers State = DocumentState.Submitted }); } + + await Context.SaveChangesAsync(); return Ok(); } -- 2.45.2 From f0dba347c5048fc77d93ab46158b019ad9eddef3 Mon Sep 17 00:00:00 2001 From: mborzyszkowski Date: Mon, 17 Aug 2020 20:14:52 +0200 Subject: [PATCH 3/4] document mapping and validation --- src/InternshipSystem.Api/ApiProfile.cs | 14 ++++ .../Controllers/DocumentsController.cs | 70 ++++++++++--------- .../InternshipSystem.Api.csproj | 3 + .../Queries/DocumentPublishRequest.cs | 2 +- src/InternshipSystem.Api/Startup.cs | 2 + .../DocumentPublishRequestValidator.cs | 15 ++++ .../Entity/Internship/Internship.cs | 19 +++++ .../InternshipSystem.Core.csproj | 4 ++ 8 files changed, 95 insertions(+), 34 deletions(-) create mode 100644 src/InternshipSystem.Api/ApiProfile.cs create mode 100644 src/InternshipSystem.Api/Validators/DocumentPublishRequestValidator.cs diff --git a/src/InternshipSystem.Api/ApiProfile.cs b/src/InternshipSystem.Api/ApiProfile.cs new file mode 100644 index 0000000..a25d338 --- /dev/null +++ b/src/InternshipSystem.Api/ApiProfile.cs @@ -0,0 +1,14 @@ +using AutoMapper; +using InternshipSystem.Api.Queries; +using InternshipSystem.Core; + +namespace InternshipSystem.Api +{ + public class ApiProfile : Profile + { + public ApiProfile() + { + CreateMap(); + } + } +} \ No newline at end of file diff --git a/src/InternshipSystem.Api/Controllers/DocumentsController.cs b/src/InternshipSystem.Api/Controllers/DocumentsController.cs index 00ef234..b601bc6 100644 --- a/src/InternshipSystem.Api/Controllers/DocumentsController.cs +++ b/src/InternshipSystem.Api/Controllers/DocumentsController.cs @@ -1,6 +1,9 @@ -using System.Linq; +using System; +using System.Linq; using System.Threading.Tasks; +using AutoMapper; using InternshipSystem.Api.Queries; +using InternshipSystem.Api.Validators; using InternshipSystem.Core; using InternshipSystem.Repository; using Microsoft.AspNetCore.Http; @@ -14,16 +17,18 @@ namespace InternshipSystem.Api.Controllers public class DocumentsController : ControllerBase { private InternshipDbContext Context { get; } + private IMapper Mapper { get; } - public DocumentsController(InternshipDbContext context) + public DocumentsController(InternshipDbContext context, IMapper mapper) { Context = context; + Mapper = mapper; } /// /// Fill out required document, /// - /// Documents Scan and description, and Id of filled document + /// Documents Scan and description, and Id of filled document /// /// If change was successfully registered /// If the provided query was malformed @@ -34,52 +39,51 @@ namespace InternshipSystem.Api.Controllers [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public async Task AddDocumentToInternship([FromBody] DocumentPublishRequest document) + public async Task AddDocumentToInternship([FromBody] DocumentPublishRequest documentRequest) { - // TODO: - // if not authorised then - // return Unauthorized(); + var validator = new DocumentPublishRequestValidator(); + var validationResult = await validator.ValidateAsync(documentRequest); - // TODO: - // is request is valid?? - // if not then - // return BadRequest(); + if (!validationResult.IsValid) + { + return BadRequest(validationResult.ToString()); + } var studentInternship = await GetCurrentStudentInternship(); - if (document.Id != null) - { - var doc = studentInternship.Documentation - .Find(d => d.Id == document.Id); - if (doc == null) + + var document = Mapper.Map(documentRequest); + + if (documentRequest.Id.HasValue) + { + try + { + studentInternship.UpdateDocument(document); + } + catch (InvalidOperationException) + { return NotFound(); - doc.Description = document.Description; - doc.Scan = document.Scan; - doc.Type = document.Type; - doc.State = DocumentState.Submitted; + } } else { - studentInternship.Documentation.Add( - new Document() - { - Description = document.Description, - Scan = document.Scan, - Type = document.Type, - State = DocumentState.Submitted - }); + studentInternship.AddNewDocument(document); } await Context.SaveChangesAsync(); return Ok(); } - //TODO: rewrite when authentication will be implemented private async Task GetCurrentStudentInternship() { - return Context.Editions - .FirstAsync().Result - .Internships - .First(); + // TODO: rewrite when authentication will be implemented + var edition = await Context + .Editions + .FirstAsync(); + + return await Context.Entry(edition) + .Collection(e => e.Internships) + .Query() + .FirstAsync(); } } } \ No newline at end of file diff --git a/src/InternshipSystem.Api/InternshipSystem.Api.csproj b/src/InternshipSystem.Api/InternshipSystem.Api.csproj index 1252f96..d5c17c0 100644 --- a/src/InternshipSystem.Api/InternshipSystem.Api.csproj +++ b/src/InternshipSystem.Api/InternshipSystem.Api.csproj @@ -8,6 +8,9 @@ + + + diff --git a/src/InternshipSystem.Api/Queries/DocumentPublishRequest.cs b/src/InternshipSystem.Api/Queries/DocumentPublishRequest.cs index fe6b5b2..c57bdfe 100644 --- a/src/InternshipSystem.Api/Queries/DocumentPublishRequest.cs +++ b/src/InternshipSystem.Api/Queries/DocumentPublishRequest.cs @@ -4,7 +4,7 @@ namespace InternshipSystem.Api.Queries { public class DocumentPublishRequest { - public long Id { get; set; } + public long? Id { get; set; } public string Description { get; set; } public byte[] Scan { get; set; } public DocumentType Type { get; set; } diff --git a/src/InternshipSystem.Api/Startup.cs b/src/InternshipSystem.Api/Startup.cs index aa5f0c8..1f46ea9 100644 --- a/src/InternshipSystem.Api/Startup.cs +++ b/src/InternshipSystem.Api/Startup.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Reflection; +using AutoMapper; using InternshipSystem.Repository; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; @@ -30,6 +31,7 @@ namespace InternshipSystem.Api options.IncludeXmlComments(xmlPath); }) .AddScoped() + .AddAutoMapper(cfg => cfg.AddProfile()) .AddControllers() ; diff --git a/src/InternshipSystem.Api/Validators/DocumentPublishRequestValidator.cs b/src/InternshipSystem.Api/Validators/DocumentPublishRequestValidator.cs new file mode 100644 index 0000000..1d1b270 --- /dev/null +++ b/src/InternshipSystem.Api/Validators/DocumentPublishRequestValidator.cs @@ -0,0 +1,15 @@ +using FluentValidation; +using InternshipSystem.Api.Queries; +using InternshipSystem.Core; + +namespace InternshipSystem.Api.Validators +{ + public class DocumentPublishRequestValidator : AbstractValidator + { + public DocumentPublishRequestValidator() + { + RuleFor(document => document.Scan).NotEmpty(); + RuleFor(document => document.Type).NotEmpty(); + } + } +} \ No newline at end of file diff --git a/src/InternshipSystem.Core/Entity/Internship/Internship.cs b/src/InternshipSystem.Core/Entity/Internship/Internship.cs index 61f0c2b..52aaf69 100644 --- a/src/InternshipSystem.Core/Entity/Internship/Internship.cs +++ b/src/InternshipSystem.Core/Entity/Internship/Internship.cs @@ -1,4 +1,6 @@ using System.Collections.Generic; +using System.Linq; +using InternshipSystem.Core.ValueObject; namespace InternshipSystem.Core { @@ -11,5 +13,22 @@ namespace InternshipSystem.Core public Report Report { get; set; } public List Approvals { get; set; } public List Documentation { get; set; } + + public void UpdateDocument(Document document) + { + var oldDocument = Documentation.First(d => d.Id == document.Id); + + oldDocument.Description = document.Description; + oldDocument.Scan = document.Scan; + oldDocument.Type = document.Type; + oldDocument.State = DocumentState.Submitted; + } + + public void AddNewDocument(Document document) + { + document.State = DocumentState.Submitted; + + Documentation.Add(document); + } } } \ No newline at end of file diff --git a/src/InternshipSystem.Core/InternshipSystem.Core.csproj b/src/InternshipSystem.Core/InternshipSystem.Core.csproj index 6de04cb..bd77dfa 100644 --- a/src/InternshipSystem.Core/InternshipSystem.Core.csproj +++ b/src/InternshipSystem.Core/InternshipSystem.Core.csproj @@ -5,4 +5,8 @@ latest + + + + -- 2.45.2 From 7258c456ff433240af849c768e1f8d7355a13e83 Mon Sep 17 00:00:00 2001 From: mborzyszkowski Date: Mon, 17 Aug 2020 20:23:37 +0200 Subject: [PATCH 4/4] Move validator --- .../Controllers/DocumentsController.cs | 4 +--- .../Queries/DocumentPublishRequest.cs | 12 +++++++++++- .../Validators/DocumentPublishRequestValidator.cs | 15 --------------- .../InternshipSystem.Core.csproj | 4 ---- 4 files changed, 12 insertions(+), 23 deletions(-) delete mode 100644 src/InternshipSystem.Api/Validators/DocumentPublishRequestValidator.cs diff --git a/src/InternshipSystem.Api/Controllers/DocumentsController.cs b/src/InternshipSystem.Api/Controllers/DocumentsController.cs index b601bc6..938bbe6 100644 --- a/src/InternshipSystem.Api/Controllers/DocumentsController.cs +++ b/src/InternshipSystem.Api/Controllers/DocumentsController.cs @@ -1,9 +1,7 @@ using System; -using System.Linq; using System.Threading.Tasks; using AutoMapper; using InternshipSystem.Api.Queries; -using InternshipSystem.Api.Validators; using InternshipSystem.Core; using InternshipSystem.Repository; using Microsoft.AspNetCore.Http; @@ -41,7 +39,7 @@ namespace InternshipSystem.Api.Controllers [ProducesResponseType(StatusCodes.Status401Unauthorized)] public async Task AddDocumentToInternship([FromBody] DocumentPublishRequest documentRequest) { - var validator = new DocumentPublishRequestValidator(); + var validator = new DocumentPublishRequest.Validator(); var validationResult = await validator.ValidateAsync(documentRequest); if (!validationResult.IsValid) diff --git a/src/InternshipSystem.Api/Queries/DocumentPublishRequest.cs b/src/InternshipSystem.Api/Queries/DocumentPublishRequest.cs index c57bdfe..975b704 100644 --- a/src/InternshipSystem.Api/Queries/DocumentPublishRequest.cs +++ b/src/InternshipSystem.Api/Queries/DocumentPublishRequest.cs @@ -1,4 +1,5 @@ -using InternshipSystem.Core.ValueObject; +using FluentValidation; +using InternshipSystem.Core.ValueObject; namespace InternshipSystem.Api.Queries { @@ -8,5 +9,14 @@ namespace InternshipSystem.Api.Queries public string Description { get; set; } public byte[] Scan { get; set; } public DocumentType Type { get; set; } + + public class Validator : AbstractValidator + { + public Validator() + { + RuleFor(document => document.Scan).NotEmpty(); + RuleFor(document => document.Type).NotEmpty(); + } + } } } \ No newline at end of file diff --git a/src/InternshipSystem.Api/Validators/DocumentPublishRequestValidator.cs b/src/InternshipSystem.Api/Validators/DocumentPublishRequestValidator.cs deleted file mode 100644 index 1d1b270..0000000 --- a/src/InternshipSystem.Api/Validators/DocumentPublishRequestValidator.cs +++ /dev/null @@ -1,15 +0,0 @@ -using FluentValidation; -using InternshipSystem.Api.Queries; -using InternshipSystem.Core; - -namespace InternshipSystem.Api.Validators -{ - public class DocumentPublishRequestValidator : AbstractValidator - { - public DocumentPublishRequestValidator() - { - RuleFor(document => document.Scan).NotEmpty(); - RuleFor(document => document.Type).NotEmpty(); - } - } -} \ No newline at end of file diff --git a/src/InternshipSystem.Core/InternshipSystem.Core.csproj b/src/InternshipSystem.Core/InternshipSystem.Core.csproj index bd77dfa..6de04cb 100644 --- a/src/InternshipSystem.Core/InternshipSystem.Core.csproj +++ b/src/InternshipSystem.Core/InternshipSystem.Core.csproj @@ -5,8 +5,4 @@ latest - - - - -- 2.45.2