From 78ebdbe33df6b2896d0f7d00bce8b6a68333d757 Mon Sep 17 00:00:00 2001
From: mborzyszkowski <maciej.borzyszkowski@gmail.com>
Date: Thu, 24 Sep 2020 20:51:18 +0200
Subject: [PATCH] CRUD internshipType

---
 .../Controllers/InternshipTypesController.cs  | 102 +++++++++++++++++-
 .../Controllers/StaticPagesController.cs      |  32 ++++--
 .../Queries/InternshipTypeFrom.cs             |  28 +++++
 .../SearchQuery/InternshipTypeSearchQuery.cs  |   9 ++
 .../Queries/StudentForm.cs                    |   1 -
 5 files changed, 155 insertions(+), 17 deletions(-)
 create mode 100644 src/InternshipSystem.Api/Queries/InternshipTypeFrom.cs
 create mode 100644 src/InternshipSystem.Api/Queries/SearchQuery/InternshipTypeSearchQuery.cs

diff --git a/src/InternshipSystem.Api/Controllers/InternshipTypesController.cs b/src/InternshipSystem.Api/Controllers/InternshipTypesController.cs
index e7ac0df..eb4c5ef 100644
--- a/src/InternshipSystem.Api/Controllers/InternshipTypesController.cs
+++ b/src/InternshipSystem.Api/Controllers/InternshipTypesController.cs
@@ -1,8 +1,8 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
+using InternshipSystem.Api.Queries;
 using InternshipSystem.Api.Security;
 using InternshipSystem.Core.Entity.Internship;
 using InternshipSystem.Repository;
@@ -14,21 +14,21 @@ using Microsoft.EntityFrameworkCore;
 namespace InternshipSystem.Api.Controllers
 {
     [ApiController]
-    [Route("internshipType")]
+    [Route("internshipTypes")]
     public class InternshipTypesController : ControllerBase
     {
+        private InternshipDbContext Context { get; }
         
         public InternshipTypesController(InternshipDbContext context)
         {
             Context = context;
         }
-        private InternshipDbContext Context { get; }
         
         /// <summary>
         /// Get static page
         /// </summary>
         /// <returns>List of internship types for edition</returns>
-        [HttpGet]
+        [HttpGet("forCurrentEdition")]
         [ProducesResponseType(StatusCodes.Status200OK)]
         [ProducesResponseType(StatusCodes.Status401Unauthorized)]
         [ProducesResponseType(StatusCodes.Status404NotFound)]
@@ -48,5 +48,97 @@ namespace InternshipSystem.Api.Controllers
 
             return Ok(edition.AvailableInternshipTypes);
         }
+
+        [HttpGet("{internshipTypeId}")]
+        [ProducesResponseType(StatusCodes.Status200OK)]
+        [ProducesResponseType(StatusCodes.Status401Unauthorized)]
+        [ProducesResponseType(StatusCodes.Status404NotFound)]
+        [Authorize]
+        public async Task<ActionResult<InternshipType>> GetInternshipType(long internshipTypeId, CancellationToken cancellationToken)
+        {
+            return await Context.InternshipTypes.FindAsync(internshipTypeId);
+        }
+        
+        [HttpGet]
+        [ProducesResponseType(StatusCodes.Status200OK)]
+        [ProducesResponseType(StatusCodes.Status401Unauthorized)]
+        [ProducesResponseType(StatusCodes.Status404NotFound)]
+        [Authorize]
+        public async Task<ActionResult<IList<InternshipType>>> SearchInternshipTypes([FromBody] InternshipTypeSearchQuery searchQuery, CancellationToken cancellationToken)
+        {
+            return await Context.InternshipTypes
+                .Where(t => string.IsNullOrEmpty(searchQuery.Type) || t.Type.Contains(searchQuery.Type))
+                .OrderBy(t => t.Type)
+                .Skip(searchQuery.Page * searchQuery.PerPage)
+                .Take(searchQuery.PerPage)
+                .ToListAsync(cancellationToken);
+        }
+
+        [HttpPut]
+        [ProducesResponseType(StatusCodes.Status200OK)]
+        [ProducesResponseType(StatusCodes.Status400BadRequest)]
+        [ProducesResponseType(StatusCodes.Status401Unauthorized)]
+        [ProducesResponseType(StatusCodes.Status404NotFound)]
+        [Authorize]
+        public async Task<ActionResult> UpdateInternshipType([FromBody] InternshipTypeFrom internshipTypeFrom, CancellationToken cancellationToken)
+        {
+            var validator = new InternshipTypeFrom.Validator();
+            var validationResult = await validator.ValidateAsync(internshipTypeFrom, cancellationToken);
+
+            if (!validationResult.IsValid)
+            {
+                return BadRequest(validationResult.ToString());
+            }
+
+            if (internshipTypeFrom.Id.HasValue)
+            {
+                var internshipType = await Context.InternshipTypes.FindAsync(internshipTypeFrom.Id.Value);
+
+                if (internshipType == null)
+                {
+                    return NotFound($"Internship type with id {internshipTypeFrom.Id} not found");
+                }
+
+                internshipType.Type = string.IsNullOrEmpty(internshipTypeFrom.Type) ? internshipType.Type : internshipTypeFrom.Type;
+                internshipType.Description = string.IsNullOrEmpty(internshipTypeFrom.Description) ? internshipType.Description : internshipTypeFrom.Description;
+                internshipType.DescriptionEng = string.IsNullOrEmpty(internshipTypeFrom.DescriptionEng) ? internshipType.DescriptionEng : internshipTypeFrom.DescriptionEng;
+            }
+            else
+            {
+                var newInternshipType = new InternshipType
+                {
+                    Type = internshipTypeFrom.Type,
+                    Description = internshipTypeFrom.Description,
+                    DescriptionEng = internshipTypeFrom.DescriptionEng,
+                };
+
+                await Context.InternshipTypes.AddAsync(newInternshipType, cancellationToken);
+            }
+
+            await Context.SaveChangesAsync(cancellationToken);
+            return Ok($"Internship type updated successfully");
+        }
+
+        [HttpDelete("{internshipTypeId}")]
+        [ProducesResponseType(StatusCodes.Status200OK)]
+        [ProducesResponseType(StatusCodes.Status400BadRequest)]
+        [ProducesResponseType(StatusCodes.Status401Unauthorized)]
+        [ProducesResponseType(StatusCodes.Status404NotFound)]
+        [Authorize]
+        public async Task<ActionResult> DeleteInternshipType(long internshipTypeId, CancellationToken cancellationToken)
+        {
+            var internshipTypeToDelete = await Context.InternshipTypes
+                .FirstOrDefaultAsync(t => t.Id.Equals(internshipTypeId), cancellationToken: cancellationToken);
+
+            if (internshipTypeToDelete == null)
+            {
+                return NotFound($"Internship type with id: {internshipTypeId} does not exist");
+            }
+
+            Context.InternshipTypes.Attach(internshipTypeToDelete);
+            Context.InternshipTypes.Remove(internshipTypeToDelete);
+            await Context.SaveChangesAsync(cancellationToken);
+            return Ok($"Internship type with id: {internshipTypeId} deleted successfully");
+        }
     }
 }
\ No newline at end of file
diff --git a/src/InternshipSystem.Api/Controllers/StaticPagesController.cs b/src/InternshipSystem.Api/Controllers/StaticPagesController.cs
index 67fdde1..6eecde2 100644
--- a/src/InternshipSystem.Api/Controllers/StaticPagesController.cs
+++ b/src/InternshipSystem.Api/Controllers/StaticPagesController.cs
@@ -58,6 +58,7 @@ namespace InternshipSystem.Api.Controllers
         [HttpPut]
         [ProducesResponseType(StatusCodes.Status200OK)]
         [ProducesResponseType(StatusCodes.Status400BadRequest)]
+        [ProducesResponseType(StatusCodes.Status401Unauthorized)]
         [ProducesResponseType(StatusCodes.Status404NotFound)]
         [Authorize]
         public async Task<ActionResult> UpdateStaticPage([FromBody] StaticPageForm staticPageForm, CancellationToken cancellationToken)
@@ -70,17 +71,6 @@ namespace InternshipSystem.Api.Controllers
                 return BadRequest(validationResult.ToString());
             }
 
-            if (!string.IsNullOrEmpty(staticPageForm.AccessName))
-            {
-                var pageWithSameAccessName = await Context.StaticPages
-                    .FirstOrDefaultAsync(sp => sp.AccessName.ToLower().Trim().Equals(staticPageForm.AccessName.ToLower().Trim()), cancellationToken: cancellationToken);
-
-                if (pageWithSameAccessName != null)
-                {
-                    return BadRequest($"Static page with access name: {staticPageForm.AccessName} already exist");
-                }
-            }
-            
             if (staticPageForm.Id.HasValue)
             {
                 var pageToUpdate = await Context.StaticPages.FindAsync(staticPageForm.Id);
@@ -89,6 +79,17 @@ namespace InternshipSystem.Api.Controllers
                 {
                     return NotFound($"Static page with id: {staticPageForm.Id} does not exist");
                 }
+                
+                if (!string.IsNullOrEmpty(staticPageForm.AccessName))
+                {
+                    var pageWithSameAccessName = await Context.StaticPages
+                        .FirstOrDefaultAsync(sp => sp.AccessName.ToLower().Trim().Equals(staticPageForm.AccessName.ToLower().Trim()), cancellationToken: cancellationToken);
+
+                    if (pageWithSameAccessName != null && !pageWithSameAccessName.Id.Equals(pageToUpdate.Id))
+                    {
+                        return BadRequest($"Static page with access name: {staticPageForm.AccessName} already exist");
+                    }
+                }
 
                 pageToUpdate.AccessName = string.IsNullOrEmpty(staticPageForm.AccessName) ? pageToUpdate.AccessName : staticPageForm.AccessName;
                 pageToUpdate.Title = string.IsNullOrEmpty(staticPageForm.Title) ? pageToUpdate.Title : staticPageForm.Title;
@@ -98,6 +99,14 @@ namespace InternshipSystem.Api.Controllers
             }
             else
             {
+                var pageWithSameAccessName = await Context.StaticPages
+                    .FirstOrDefaultAsync(sp => sp.AccessName.ToLower().Trim().Equals(staticPageForm.AccessName.ToLower().Trim()), cancellationToken: cancellationToken);
+
+                if (pageWithSameAccessName != null)
+                {
+                    return BadRequest($"Static page with access name: {staticPageForm.AccessName} already exist");
+                }
+                
                 var newStaticPage = new StaticPage
                 {
                     AccessName = staticPageForm.AccessName.ToLower().Trim(),
@@ -118,6 +127,7 @@ namespace InternshipSystem.Api.Controllers
         [HttpDelete("{accessName}")]
         [ProducesResponseType(StatusCodes.Status200OK)]
         [ProducesResponseType(StatusCodes.Status400BadRequest)]
+        [ProducesResponseType(StatusCodes.Status401Unauthorized)]
         [ProducesResponseType(StatusCodes.Status404NotFound)]
         [Authorize]
         public async Task<ActionResult> DeleteStaticPage(string accessName, CancellationToken cancellationToken)
diff --git a/src/InternshipSystem.Api/Queries/InternshipTypeFrom.cs b/src/InternshipSystem.Api/Queries/InternshipTypeFrom.cs
new file mode 100644
index 0000000..14abd25
--- /dev/null
+++ b/src/InternshipSystem.Api/Queries/InternshipTypeFrom.cs
@@ -0,0 +1,28 @@
+using FluentValidation;
+
+namespace InternshipSystem.Api.Queries
+{
+    public class InternshipTypeFrom
+    {
+        public long? Id { get; set; }
+        public string Type { get; set; }
+        public string Description { get; set; }
+        public string DescriptionEng { get; set; }
+        
+        public class Validator : AbstractValidator<InternshipTypeFrom>
+        {
+            public Validator()
+            {
+                RuleFor(t => t.Id).NotNull()
+                    .When(t =>
+                        string.IsNullOrEmpty(t.Description) || string.IsNullOrEmpty(t.Type) || string.IsNullOrEmpty(t.DescriptionEng));
+                RuleFor(t => t.Type).NotEmpty()
+                    .When(t => !t.Id.HasValue);
+                RuleFor(t => t.Description).NotEmpty()
+                    .When(t => !t.Id.HasValue);
+                RuleFor(t => t.DescriptionEng).NotEmpty()
+                    .When(t => !t.Id.HasValue);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/InternshipSystem.Api/Queries/SearchQuery/InternshipTypeSearchQuery.cs b/src/InternshipSystem.Api/Queries/SearchQuery/InternshipTypeSearchQuery.cs
new file mode 100644
index 0000000..b8034b7
--- /dev/null
+++ b/src/InternshipSystem.Api/Queries/SearchQuery/InternshipTypeSearchQuery.cs
@@ -0,0 +1,9 @@
+using InternshipSystem.Api.Queries.SearchQuery;
+
+namespace InternshipSystem.Api.Controllers
+{
+    public class InternshipTypeSearchQuery : SearchQuery
+    {
+        public string Type { get; set; } = "";
+    }
+}
\ No newline at end of file
diff --git a/src/InternshipSystem.Api/Queries/StudentForm.cs b/src/InternshipSystem.Api/Queries/StudentForm.cs
index f58b19c..f4ceafe 100644
--- a/src/InternshipSystem.Api/Queries/StudentForm.cs
+++ b/src/InternshipSystem.Api/Queries/StudentForm.cs
@@ -1,5 +1,4 @@
 using FluentValidation;
-using InternshipSystem.Core;
 
 namespace InternshipSystem.Api.Queries
 {