From 357b7637ceab1d3f60fceb232c620d67e5b36257 Mon Sep 17 00:00:00 2001 From: MaxchilKH Date: Mon, 10 Aug 2020 16:38:25 +0200 Subject: [PATCH 1/2] Add specialized objects to model --- .../InternshipSystem.Api.csproj | 5 +---- src/InternshipSystem.Core/Entity/Company.cs | 2 +- .../ValueObject/Mentor.cs | 2 +- src/InternshipSystem.Core/ValueObject/Nip.cs | 18 ++++++++++++++++++ .../ValueObject/PhoneNumber.cs | 18 ++++++++++++++++++ .../InternshipDbContext.cs | 12 +++++++++++- 6 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 src/InternshipSystem.Core/ValueObject/Nip.cs create mode 100644 src/InternshipSystem.Core/ValueObject/PhoneNumber.cs diff --git a/src/InternshipSystem.Api/InternshipSystem.Api.csproj b/src/InternshipSystem.Api/InternshipSystem.Api.csproj index e084254..1252f96 100644 --- a/src/InternshipSystem.Api/InternshipSystem.Api.csproj +++ b/src/InternshipSystem.Api/InternshipSystem.Api.csproj @@ -4,6 +4,7 @@ netcoreapp3.1 true latest + $(NoWarn);1591;1573 @@ -16,10 +17,6 @@ - - - - diff --git a/src/InternshipSystem.Core/Entity/Company.cs b/src/InternshipSystem.Core/Entity/Company.cs index 6b98e0f..ddbeeb4 100644 --- a/src/InternshipSystem.Core/Entity/Company.cs +++ b/src/InternshipSystem.Core/Entity/Company.cs @@ -6,7 +6,7 @@ namespace InternshipSystem.Core public class Company { public long Id { get; set; } - public string Nip { get; set; } + public Nip Nip { get; set; } public string Name { get; set; } public RangeOfActivity Range { get; set; } public List Branches { get; set; } diff --git a/src/InternshipSystem.Core/ValueObject/Mentor.cs b/src/InternshipSystem.Core/ValueObject/Mentor.cs index d7be213..4af5c24 100644 --- a/src/InternshipSystem.Core/ValueObject/Mentor.cs +++ b/src/InternshipSystem.Core/ValueObject/Mentor.cs @@ -5,6 +5,6 @@ public string FirstName { get; set; } public string LastName { get; set; } public string Email { get; set; } - public string PhoneNumber { get; set; } + public PhoneNumber PhoneNumber { get; set; } } } \ No newline at end of file diff --git a/src/InternshipSystem.Core/ValueObject/Nip.cs b/src/InternshipSystem.Core/ValueObject/Nip.cs new file mode 100644 index 0000000..903b59e --- /dev/null +++ b/src/InternshipSystem.Core/ValueObject/Nip.cs @@ -0,0 +1,18 @@ +namespace InternshipSystem.Core +{ + public struct Nip + { + private readonly string _nip; + + public Nip(string nip) + { + _nip = nip; + } + + public static implicit operator string(Nip nip) => + nip._nip; + + public static implicit operator Nip(string maybeNip) => + new Nip(maybeNip); + } +} \ No newline at end of file diff --git a/src/InternshipSystem.Core/ValueObject/PhoneNumber.cs b/src/InternshipSystem.Core/ValueObject/PhoneNumber.cs new file mode 100644 index 0000000..e72d355 --- /dev/null +++ b/src/InternshipSystem.Core/ValueObject/PhoneNumber.cs @@ -0,0 +1,18 @@ +namespace InternshipSystem.Core +{ + public struct PhoneNumber + { + private readonly string _phoneNumber; + + public PhoneNumber(string phoneNumber) + { + _phoneNumber = phoneNumber; + } + + public static implicit operator string(PhoneNumber number) => + number._phoneNumber; + + public static implicit operator PhoneNumber(string maybeNumber) => + new PhoneNumber(maybeNumber); + } +} \ No newline at end of file diff --git a/src/InternshipSystem.Repository/InternshipDbContext.cs b/src/InternshipSystem.Repository/InternshipDbContext.cs index 83ed627..716aef9 100644 --- a/src/InternshipSystem.Repository/InternshipDbContext.cs +++ b/src/InternshipSystem.Repository/InternshipDbContext.cs @@ -21,11 +21,21 @@ namespace InternshipSystem.Repository protected override void OnModelCreating(ModelBuilder modelBuilder) { + modelBuilder.Entity() + .Property(company => company.Nip) + .HasConversion( + nip => nip, + s => (Nip)s); + modelBuilder.Entity() .OwnsOne(bo => bo.Address); modelBuilder.Entity() - .OwnsOne(ip => ip.Mentor); + .OwnsOne(ip => ip.Mentor) + .Property(mentor => mentor.PhoneNumber) + .HasConversion( + number => number, + s => (PhoneNumber)s); modelBuilder.Entity(builder => { -- 2.45.2 From 1dc100f817dd4168f47539587adf22122b4f34ec Mon Sep 17 00:00:00 2001 From: MaxchilKH Date: Mon, 10 Aug 2020 19:03:26 +0200 Subject: [PATCH 2/2] Add api draft --- .../Controllers/CompaniesController.cs | 105 +++++++++++------- .../Controllers/DocumentsController.cs | 36 ++++++ .../Controllers/EditionController.cs | 32 ++++++ .../InternshipRegistrationController.cs | 35 ++++++ .../Controllers/RegistrationController.cs | 30 +++++ .../Queries/DocumentPublishRequest.cs | 12 ++ .../Queries/RegistrationFormQuery.cs | 15 +++ .../Result/EditionResult.cs | 13 +++ src/InternshipSystem.Core/Entity/Approval.cs | 9 -- src/InternshipSystem.Core/Entity/Document.cs | 6 +- .../Entity/Internship/Internship.cs | 7 +- .../ValueObject/DocumentState.cs | 2 +- .../ValueObject/DocumentType.cs | 7 ++ 13 files changed, 254 insertions(+), 55 deletions(-) create mode 100644 src/InternshipSystem.Api/Controllers/DocumentsController.cs create mode 100644 src/InternshipSystem.Api/Controllers/EditionController.cs create mode 100644 src/InternshipSystem.Api/Controllers/InternshipRegistrationController.cs create mode 100644 src/InternshipSystem.Api/Controllers/RegistrationController.cs create mode 100644 src/InternshipSystem.Api/Queries/DocumentPublishRequest.cs create mode 100644 src/InternshipSystem.Api/Queries/RegistrationFormQuery.cs create mode 100644 src/InternshipSystem.Api/Result/EditionResult.cs delete mode 100644 src/InternshipSystem.Core/Entity/Approval.cs create mode 100644 src/InternshipSystem.Core/ValueObject/DocumentType.cs diff --git a/src/InternshipSystem.Api/Controllers/CompaniesController.cs b/src/InternshipSystem.Api/Controllers/CompaniesController.cs index fb8f49c..430e81d 100644 --- a/src/InternshipSystem.Api/Controllers/CompaniesController.cs +++ b/src/InternshipSystem.Api/Controllers/CompaniesController.cs @@ -1,40 +1,65 @@ -// using System.Collections.Generic; -// using System.Linq; -// using System.Threading; -// 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("companies")] -// public class CompaniesController : ControllerBase -// { -// public CompaniesController(InternshipDbContext context) -// { -// Context = context; -// } -// private InternshipDbContext Context { get; } -// -// /// -// /// Get companies matching provided paginated query -// /// -// /// Paginated query description -// /// Part of companies collection -// [HttpGet] -// [ProducesResponseType(StatusCodes.Status200OK)] -// public async Task> SearchByNameAsync([FromQuery] SearchQuery searchQuery, CancellationToken cancellationToken) => -// await Context.Companies -// .Where(c => c.Name.ToLower().Contains(searchQuery.Query.ToLower())) -// .OrderBy(o => o.Name) -// .Skip(searchQuery.Page * searchQuery.PerPage) -// .Take(searchQuery.PerPage) -// .ToListAsync(cancellationToken); -// } -// -// } \ No newline at end of file +using System.Collections.Generic; +using System.Linq; +using System.Threading; +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("companies")] + public class CompaniesController : ControllerBase + { + public CompaniesController(InternshipDbContext context) + { + Context = context; + } + private InternshipDbContext Context { get; } + + /// + /// Get companies matching provided paginated query + /// + /// Paginated query description + /// Part of companies collection + [HttpGet] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + public async Task> SearchByNameAsync([FromQuery] SearchQuery searchQuery, CancellationToken cancellationToken) => + await Context.Companies + .Where(c => c.Name.ToLower().Contains(searchQuery.Query.ToLower())) + .OrderBy(o => o.Name) + .Skip(searchQuery.Page * searchQuery.PerPage) + .Take(searchQuery.PerPage) + .ToListAsync(cancellationToken); + + /// + /// Get companies matching provided paginated query + /// + /// Paginated query description + /// + /// Successfully retrieved matching offices + /// Search query was malformed + /// Part of companies collection + [HttpGet("{companyId}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + public async Task> SearchBranchesByAddress([FromQuery] SearchQuery 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())) + .Skip(searchQuery.Page * searchQuery.PerPage) + .Take(searchQuery.PerPage) + .ToListAsync(token); + } + } + +} \ No newline at end of file diff --git a/src/InternshipSystem.Api/Controllers/DocumentsController.cs b/src/InternshipSystem.Api/Controllers/DocumentsController.cs new file mode 100644 index 0000000..5172d9b --- /dev/null +++ b/src/InternshipSystem.Api/Controllers/DocumentsController.cs @@ -0,0 +1,36 @@ +using System; +using System.Threading.Tasks; +using InternshipSystem.Api.Queries; +using InternshipSystem.Repository; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace InternshipSystem.Api.Controllers +{ + public class DocumentsController : ControllerBase + { + private InternshipDbContext Context { get; } + + public DocumentsController(InternshipDbContext context) + { + Context = context; + } + + /// + /// Fill out required document, + /// + /// Documents Scan and description, and Id of filled document + /// + /// If change was successfully registered + /// If the provided query was malformed + /// Id doesn't match any required document + /// This action is only available for authorized student registered for current edition + [HttpPost] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + public async Task AddDocumentToInternship([FromBody] DocumentPublishRequest document) => + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/src/InternshipSystem.Api/Controllers/EditionController.cs b/src/InternshipSystem.Api/Controllers/EditionController.cs new file mode 100644 index 0000000..a104275 --- /dev/null +++ b/src/InternshipSystem.Api/Controllers/EditionController.cs @@ -0,0 +1,32 @@ +using System; +using System.Threading.Tasks; +using InternshipSystem.Api.Result; +using InternshipSystem.Core; +using InternshipSystem.Repository; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace InternshipSystem.Api.Controllers +{ + [Route("edition")] + public class EditionController : ControllerBase + { + private InternshipDbContext Context { get; } + + public EditionController(InternshipDbContext context) + { + Context = context; + } + + /// + /// Get current edition parameters + /// + /// Parameters of edition registered for by student + /// This action is only available for authorized student registered for current edition + /// + [HttpGet] + [ProducesResponseType(StatusCodes.Status200OK)] + public async Task> GetCurrentEdition() => + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/src/InternshipSystem.Api/Controllers/InternshipRegistrationController.cs b/src/InternshipSystem.Api/Controllers/InternshipRegistrationController.cs new file mode 100644 index 0000000..cb48ea4 --- /dev/null +++ b/src/InternshipSystem.Api/Controllers/InternshipRegistrationController.cs @@ -0,0 +1,35 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using InternshipSystem.Api.Queries; +using InternshipSystem.Repository; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace InternshipSystem.Api.Controllers +{ + [Route("internshipRegistration")] + public class InternshipRegistrationController : ControllerBase + { + private InternshipDbContext Context { get; } + + public InternshipRegistrationController(InternshipDbContext context) + { + Context = context; + } + + /// + /// Validate and add filled internship registration form + /// + /// Internship registration data + /// If registration form was successfully added + /// If the provided registration query was malformed + /// This action is only available for authorized student registered for current edition + [HttpPut] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + public async Task SubmitRegistrationForm([FromBody] RegistrationFormQuery registrationQuery, CancellationToken cancellationToken) => + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/src/InternshipSystem.Api/Controllers/RegistrationController.cs b/src/InternshipSystem.Api/Controllers/RegistrationController.cs new file mode 100644 index 0000000..76bc0db --- /dev/null +++ b/src/InternshipSystem.Api/Controllers/RegistrationController.cs @@ -0,0 +1,30 @@ +using System; +using System.Threading.Tasks; +using InternshipSystem.Api.Result; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace InternshipSystem.Api.Controllers +{ + [ApiController] + [Route("register")] + public class RegistrationController : ControllerBase + { + /// + /// Register student for edition using provided registration code + /// + /// GUID of edition + /// + /// If the student was successfully registered + /// If the provided registration code was malformed + /// The registration code doesn't match any open edition + [HttpPost] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task RegisterStudentForEdition([FromBody] Guid registrationCode) => + throw new NotImplementedException(); + + + } +} \ No newline at end of file diff --git a/src/InternshipSystem.Api/Queries/DocumentPublishRequest.cs b/src/InternshipSystem.Api/Queries/DocumentPublishRequest.cs new file mode 100644 index 0000000..fe6b5b2 --- /dev/null +++ b/src/InternshipSystem.Api/Queries/DocumentPublishRequest.cs @@ -0,0 +1,12 @@ +using InternshipSystem.Core.ValueObject; + +namespace InternshipSystem.Api.Queries +{ + public class DocumentPublishRequest + { + public long Id { get; set; } + public string Description { get; set; } + public byte[] Scan { get; set; } + public DocumentType Type { get; set; } + } +} \ No newline at end of file diff --git a/src/InternshipSystem.Api/Queries/RegistrationFormQuery.cs b/src/InternshipSystem.Api/Queries/RegistrationFormQuery.cs new file mode 100644 index 0000000..fe30ded --- /dev/null +++ b/src/InternshipSystem.Api/Queries/RegistrationFormQuery.cs @@ -0,0 +1,15 @@ +using System; +using InternshipSystem.Core; +using InternshipSystem.Core.Entity.Internship; + +namespace InternshipSystem.Api.Queries +{ + public class RegistrationFormQuery + { + public Company Company { get; set; } + public BranchOffice BranchAddress { get; set; } + public DateTime Start { get; set; } + public DateTime End { get; set; } + public InternshipType Type { get; set; } + } +} \ No newline at end of file diff --git a/src/InternshipSystem.Api/Result/EditionResult.cs b/src/InternshipSystem.Api/Result/EditionResult.cs new file mode 100644 index 0000000..6436990 --- /dev/null +++ b/src/InternshipSystem.Api/Result/EditionResult.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using InternshipSystem.Core; +using InternshipSystem.Core.Entity.Internship; + +namespace InternshipSystem.Api.Result +{ + public struct EditionResult + { + public List Types { get; set; } + public List Subjects { get; set; } + public Student Student { get; set; } + } +} \ No newline at end of file diff --git a/src/InternshipSystem.Core/Entity/Approval.cs b/src/InternshipSystem.Core/Entity/Approval.cs deleted file mode 100644 index f79d782..0000000 --- a/src/InternshipSystem.Core/Entity/Approval.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace InternshipSystem.Core -{ - public class Approval - { - public long Id { get; set; } - public byte[] Scan { get; set; } - public DocumentState State { get; set; } - } -} \ No newline at end of file diff --git a/src/InternshipSystem.Core/Entity/Document.cs b/src/InternshipSystem.Core/Entity/Document.cs index 6a75cc2..8e7ed74 100644 --- a/src/InternshipSystem.Core/Entity/Document.cs +++ b/src/InternshipSystem.Core/Entity/Document.cs @@ -1,9 +1,13 @@ -namespace InternshipSystem.Core +using InternshipSystem.Core.ValueObject; + +namespace InternshipSystem.Core { public class Document { public long Id { get; set; } public string Description { get; set; } + public byte[] Scan { get; set; } + public DocumentType Type { get; set; } public DocumentState State { get; set; } } } \ 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 3d3bc20..61f0c2b 100644 --- a/src/InternshipSystem.Core/Entity/Internship/Internship.cs +++ b/src/InternshipSystem.Core/Entity/Internship/Internship.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; namespace InternshipSystem.Core { @@ -10,7 +9,7 @@ namespace InternshipSystem.Core public InternshipRegistration InternshipRegistration { get; set; } public InternshipProgram InternshipProgram { get; set; } public Report Report { get; set; } - public List Approvals { get; set; } - public List Documents { get; set; } + public List Approvals { get; set; } + public List Documentation { get; set; } } } \ No newline at end of file diff --git a/src/InternshipSystem.Core/ValueObject/DocumentState.cs b/src/InternshipSystem.Core/ValueObject/DocumentState.cs index 465aa58..2a8d863 100644 --- a/src/InternshipSystem.Core/ValueObject/DocumentState.cs +++ b/src/InternshipSystem.Core/ValueObject/DocumentState.cs @@ -2,7 +2,7 @@ { public enum DocumentState { - Draft, + NotSubmitted, Submitted, Accepted, Rejected diff --git a/src/InternshipSystem.Core/ValueObject/DocumentType.cs b/src/InternshipSystem.Core/ValueObject/DocumentType.cs new file mode 100644 index 0000000..5acb99a --- /dev/null +++ b/src/InternshipSystem.Core/ValueObject/DocumentType.cs @@ -0,0 +1,7 @@ +namespace InternshipSystem.Core.ValueObject +{ + public enum DocumentType + { + IPPScan + } +} \ No newline at end of file -- 2.45.2