From c1d72eb3702fa0f6456ff63ff6bfaeff1957e593 Mon Sep 17 00:00:00 2001 From: mborzyszkowski Date: Thu, 24 Sep 2020 17:21:31 +0200 Subject: [PATCH] SearchQuery changes + new student endpoints --- src/InternshipSystem.Api/ApiProfile.cs | 2 + .../Controllers/CompaniesController.cs | 14 ++- .../Controllers/StudentController.cs | 56 ----------- .../Controllers/StudentsController.cs | 99 +++++++++++++++++++ .../Queries/CurrentStudentForm.cs | 12 +++ .../SearchQuery/BranchOfficeSearchQuery.cs | 9 ++ .../Queries/SearchQuery/CompanySearchQuery.cs | 10 ++ .../Queries/{ => SearchQuery}/SearchQuery.cs | 7 +- .../Queries/SearchQuery/StudentSearchQuery.cs | 11 +++ .../Queries/StudentForm.cs | 2 +- 10 files changed, 155 insertions(+), 67 deletions(-) delete mode 100644 src/InternshipSystem.Api/Controllers/StudentController.cs create mode 100644 src/InternshipSystem.Api/Controllers/StudentsController.cs create mode 100644 src/InternshipSystem.Api/Queries/CurrentStudentForm.cs create mode 100644 src/InternshipSystem.Api/Queries/SearchQuery/BranchOfficeSearchQuery.cs create mode 100644 src/InternshipSystem.Api/Queries/SearchQuery/CompanySearchQuery.cs rename src/InternshipSystem.Api/Queries/{ => SearchQuery}/SearchQuery.cs (62%) create mode 100644 src/InternshipSystem.Api/Queries/SearchQuery/StudentSearchQuery.cs diff --git a/src/InternshipSystem.Api/ApiProfile.cs b/src/InternshipSystem.Api/ApiProfile.cs index e28ca30..b7c6fce 100644 --- a/src/InternshipSystem.Api/ApiProfile.cs +++ b/src/InternshipSystem.Api/ApiProfile.cs @@ -22,6 +22,8 @@ namespace InternshipSystem.Api CreateMap(); CreateMap().IncludeMembers(es => es.Subject); + + CreateMap(); } } } \ No newline at end of file diff --git a/src/InternshipSystem.Api/Controllers/CompaniesController.cs b/src/InternshipSystem.Api/Controllers/CompaniesController.cs index 39011e6..59b99ad 100644 --- a/src/InternshipSystem.Api/Controllers/CompaniesController.cs +++ b/src/InternshipSystem.Api/Controllers/CompaniesController.cs @@ -3,8 +3,10 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using InternshipSystem.Api.Queries; +using InternshipSystem.Api.Queries.SearchQuery; using InternshipSystem.Core; using InternshipSystem.Repository; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; @@ -35,9 +37,9 @@ namespace InternshipSystem.Api.Controllers [HttpGet] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] - public async Task> SearchByNameAsync([FromQuery] SearchQuery searchQuery, CancellationToken cancellationToken) => + public async Task>> SearchByNameAsync([FromQuery] CompanySearchQuery searchQuery, CancellationToken cancellationToken) => await Context.Companies - .Where(c => c.Name.ToLower().Contains(searchQuery.Query.ToLower())) + .Where(c => c.Name.ToLower().Contains(searchQuery.Name.ToLower())) .OrderBy(o => o.Name) .Skip(searchQuery.Page * searchQuery.PerPage) .Take(searchQuery.PerPage) @@ -54,14 +56,14 @@ namespace InternshipSystem.Api.Controllers [HttpGet("{companyId}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] - public async Task> SearchBranchesByAddress([FromQuery] SearchQuery searchQuery, long companyId, CancellationToken token) + public async Task>> SearchBranchesByAddress([FromQuery] BranchOfficeSearchQuery searchQuery, long companyId, CancellationToken token) { var company = await Context.Companies.Where(c => c.Id == companyId).FirstAsync(token); return await Context.Entry(company) .Collection(c => c.Branches) .Query() - .Where(office => office.Address.City.Contains(searchQuery.Query.ToLower())) + .Where(office => office.Address.City.ToLower().Contains(searchQuery.City.ToLower())) .Skip(searchQuery.Page * searchQuery.PerPage) .Take(searchQuery.PerPage) .ToListAsync(token); @@ -79,6 +81,7 @@ namespace InternshipSystem.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] + [Authorize] public async Task UpdateCompany([FromBody] CompanyForm companyForm, CancellationToken cancellationToken) { var validator = new CompanyForm.Validator(); @@ -129,6 +132,7 @@ namespace InternshipSystem.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] + [Authorize] public async Task DeleteCompany(long companyId, CancellationToken cancellationToken) { var companyToDelete = await PractiseSupervisorDbContext.Companies @@ -159,6 +163,7 @@ namespace InternshipSystem.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] + [Authorize] public async Task UpdateBranch([FromBody] BranchOfficeForm branchOfficeForm, long companyId, CancellationToken cancellationToken) { var validator = new BranchOfficeForm.Validator(); @@ -225,6 +230,7 @@ namespace InternshipSystem.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] + [Authorize] public async Task DeleteBranch(long branchOfficeId, CancellationToken cancellationToken) { var company = diff --git a/src/InternshipSystem.Api/Controllers/StudentController.cs b/src/InternshipSystem.Api/Controllers/StudentController.cs deleted file mode 100644 index 165dc6f..0000000 --- a/src/InternshipSystem.Api/Controllers/StudentController.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System.Threading; -using System.Threading.Tasks; -using InternshipSystem.Api.Queries; -using InternshipSystem.Api.Security; -using InternshipSystem.Core; -using InternshipSystem.Repository; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; - -namespace InternshipSystem.Api.Controllers -{ - [Route("student")] - [ApiController] - public class StudentController : ControllerBase - { - private readonly InternshipDbContext _context; - - public StudentController(InternshipDbContext context) - { - _context = context; - } - - [HttpGet("current")] - [Authorize] - public async Task GetCurrentStudentData([FromServices] User user, CancellationToken cancellationToken) - { - return await _context.Students.FindAsync(user.PersonNumber); - } - - [HttpPut("updateCurrent")] - [Authorize] - public async Task UpdateStudentData([FromBody] StudentForm studentNewData, [FromServices] User user, CancellationToken cancellationToken) - { - var validator = new StudentForm.Validator(); - var validationResult = await validator.ValidateAsync(studentNewData, cancellationToken); - - if (!validationResult.IsValid || !user.PersonNumber.Equals(studentNewData.Id)) - { - return BadRequest(); - } - - var currentStudent = await _context.Students.FindAsync(user.PersonNumber); - - currentStudent.AlbumNumber = studentNewData.AlbumNumber ?? currentStudent.AlbumNumber; - currentStudent.FirstName = string.IsNullOrEmpty(studentNewData.FirstName) ? currentStudent.FirstName : studentNewData.FirstName; - currentStudent.LastName = string.IsNullOrEmpty(studentNewData.LastName) ? currentStudent.LastName : studentNewData.LastName; - currentStudent.Email = string.IsNullOrEmpty(studentNewData.Email) ? currentStudent.Email : studentNewData.Email; - currentStudent.Course = string.IsNullOrEmpty(studentNewData.Course) ? currentStudent.Course : studentNewData.Course; - currentStudent.Semester = studentNewData.Semester ?? currentStudent.Semester; - - await _context.SaveChangesAsync(cancellationToken); - - return Ok(); - } - } -} \ No newline at end of file diff --git a/src/InternshipSystem.Api/Controllers/StudentsController.cs b/src/InternshipSystem.Api/Controllers/StudentsController.cs new file mode 100644 index 0000000..52de493 --- /dev/null +++ b/src/InternshipSystem.Api/Controllers/StudentsController.cs @@ -0,0 +1,99 @@ +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; +using InternshipSystem.Repository; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace InternshipSystem.Api.Controllers +{ + [Route("students")] + [ApiController] + public class StudentsController : ControllerBase + { + private readonly InternshipDbContext _context; + + public StudentsController(InternshipDbContext context) + { + _context = context; + } + + [HttpGet("current")] + [Authorize] + public async Task> GetCurrentStudentData([FromServices] User user, CancellationToken cancellationToken) + { + return await _context.Students.FindAsync(user.PersonNumber); + } + + [HttpPut("current")] + [Authorize] + public async Task UpdateCurrentStudentData([FromBody] CurrentStudentForm studentNewData, [FromServices] User user, CancellationToken cancellationToken) + { + var currentStudent = await _context.Students.FindAsync(user.PersonNumber); + + currentStudent.AlbumNumber = studentNewData.AlbumNumber ?? currentStudent.AlbumNumber; + currentStudent.FirstName = string.IsNullOrEmpty(studentNewData.FirstName) ? currentStudent.FirstName : studentNewData.FirstName; + currentStudent.LastName = string.IsNullOrEmpty(studentNewData.LastName) ? currentStudent.LastName : studentNewData.LastName; + currentStudent.Email = string.IsNullOrEmpty(studentNewData.Email) ? currentStudent.Email : studentNewData.Email; + currentStudent.Course = string.IsNullOrEmpty(studentNewData.Course) ? currentStudent.Course : studentNewData.Course; + currentStudent.Semester = studentNewData.Semester ?? currentStudent.Semester; + + await _context.SaveChangesAsync(cancellationToken); + + return Ok($"Student updated successfully"); + } + + [HttpGet("{studentPersonNumber}")] + [Authorize] + public async Task> GetStudentByPersonNumber(long studentPersonNumber, CancellationToken cancellationToken) => + await _context.Students.FindAsync(studentPersonNumber); + + [HttpGet] + [Authorize] + public async Task>> GetStudents([FromBody] StudentSearchQuery searchQuery, CancellationToken cancellationToken) => + await _context.Students + .Where(s => !searchQuery.AlbumNumber.HasValue || s.AlbumNumber.Equals(searchQuery.AlbumNumber)) + .Where(s => string.IsNullOrEmpty(searchQuery.FirstName) || s.FirstName.ToLower().Contains(searchQuery.FirstName.ToLower())) + .Where(s => string.IsNullOrEmpty(searchQuery.LastName) || s.LastName.ToLower().Contains(searchQuery.LastName.ToLower())) + .OrderBy(s => s.AlbumNumber) + .Skip(searchQuery.Page * searchQuery.PerPage) + .Take(searchQuery.PerPage) + .ToListAsync(cancellationToken); + + [HttpPut] + [Authorize] + public async Task UpdateStudentData([FromBody] StudentForm studentNewData, CancellationToken cancellationToken) + { + var validator = new StudentForm.Validator(); + var validationResult = await validator.ValidateAsync(studentNewData, cancellationToken); + + if (!validationResult.IsValid) + { + return BadRequest(validationResult); + } + + var currentStudent = await _context.Students.FindAsync(studentNewData.Id); + + if (currentStudent == null) + { + return NotFound($"Student with id: {studentNewData.Id} does not exist"); + } + + currentStudent.AlbumNumber = studentNewData.AlbumNumber ?? currentStudent.AlbumNumber; + currentStudent.FirstName = string.IsNullOrEmpty(studentNewData.FirstName) ? currentStudent.FirstName : studentNewData.FirstName; + currentStudent.LastName = string.IsNullOrEmpty(studentNewData.LastName) ? currentStudent.LastName : studentNewData.LastName; + currentStudent.Email = string.IsNullOrEmpty(studentNewData.Email) ? currentStudent.Email : studentNewData.Email; + currentStudent.Course = string.IsNullOrEmpty(studentNewData.Course) ? currentStudent.Course : studentNewData.Course; + currentStudent.Semester = studentNewData.Semester ?? currentStudent.Semester; + + await _context.SaveChangesAsync(cancellationToken); + + return Ok($"Student updated successfully"); + } + } +} \ No newline at end of file diff --git a/src/InternshipSystem.Api/Queries/CurrentStudentForm.cs b/src/InternshipSystem.Api/Queries/CurrentStudentForm.cs new file mode 100644 index 0000000..134302a --- /dev/null +++ b/src/InternshipSystem.Api/Queries/CurrentStudentForm.cs @@ -0,0 +1,12 @@ +namespace InternshipSystem.Api.Queries +{ + public class CurrentStudentForm + { + public int? AlbumNumber { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public string Email { get; set; } + public string Course { get; set; } + public int? Semester { get; set; } + } +} \ No newline at end of file diff --git a/src/InternshipSystem.Api/Queries/SearchQuery/BranchOfficeSearchQuery.cs b/src/InternshipSystem.Api/Queries/SearchQuery/BranchOfficeSearchQuery.cs new file mode 100644 index 0000000..d91df7c --- /dev/null +++ b/src/InternshipSystem.Api/Queries/SearchQuery/BranchOfficeSearchQuery.cs @@ -0,0 +1,9 @@ +using InternshipSystem.Api.Queries.SearchQuery; + +namespace InternshipSystem.Api.Controllers +{ + public class BranchOfficeSearchQuery : SearchQuery + { + public string City { get; set; } = ""; + } +} \ No newline at end of file diff --git a/src/InternshipSystem.Api/Queries/SearchQuery/CompanySearchQuery.cs b/src/InternshipSystem.Api/Queries/SearchQuery/CompanySearchQuery.cs new file mode 100644 index 0000000..b1723c7 --- /dev/null +++ b/src/InternshipSystem.Api/Queries/SearchQuery/CompanySearchQuery.cs @@ -0,0 +1,10 @@ +namespace InternshipSystem.Api.Queries.SearchQuery +{ + public class CompanySearchQuery : SearchQuery + { + /// + /// Value against which collection will be queried + /// + public string Name { get; set; } = ""; + } +} \ No newline at end of file diff --git a/src/InternshipSystem.Api/Queries/SearchQuery.cs b/src/InternshipSystem.Api/Queries/SearchQuery/SearchQuery.cs similarity index 62% rename from src/InternshipSystem.Api/Queries/SearchQuery.cs rename to src/InternshipSystem.Api/Queries/SearchQuery/SearchQuery.cs index fc49350..23eb580 100644 --- a/src/InternshipSystem.Api/Queries/SearchQuery.cs +++ b/src/InternshipSystem.Api/Queries/SearchQuery/SearchQuery.cs @@ -1,12 +1,7 @@ -namespace InternshipSystem.Api.Queries +namespace InternshipSystem.Api.Queries.SearchQuery { public class SearchQuery { - /// - /// Value against which collection will be queried - /// - public string Query { get; set; } = ""; - /// /// Which part of the collections to retrieve /// diff --git a/src/InternshipSystem.Api/Queries/SearchQuery/StudentSearchQuery.cs b/src/InternshipSystem.Api/Queries/SearchQuery/StudentSearchQuery.cs new file mode 100644 index 0000000..ff36db0 --- /dev/null +++ b/src/InternshipSystem.Api/Queries/SearchQuery/StudentSearchQuery.cs @@ -0,0 +1,11 @@ +using InternshipSystem.Api.Queries.SearchQuery; + +namespace InternshipSystem.Api.Controllers +{ + public class StudentSearchQuery : SearchQuery + { + public int? AlbumNumber { get; set; } + public string FirstName { get; set; } + public string LastName { 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 d9ab467..f58b19c 100644 --- a/src/InternshipSystem.Api/Queries/StudentForm.cs +++ b/src/InternshipSystem.Api/Queries/StudentForm.cs @@ -5,7 +5,7 @@ namespace InternshipSystem.Api.Queries { public class StudentForm { - public long? Id { get; set; } + public long Id { get; set; } public int? AlbumNumber { get; set; } public string FirstName { get; set; } public string LastName { get; set; }