diff --git a/src/InternshipSystem.Api/ApiProfile.cs b/src/InternshipSystem.Api/ApiProfile.cs index a25d338..2f593e0 100644 --- a/src/InternshipSystem.Api/ApiProfile.cs +++ b/src/InternshipSystem.Api/ApiProfile.cs @@ -1,4 +1,5 @@ -using AutoMapper; +using System; +using AutoMapper; using InternshipSystem.Api.Queries; using InternshipSystem.Core; diff --git a/src/InternshipSystem.Api/Controllers/EditionController.cs b/src/InternshipSystem.Api/Controllers/EditionController.cs index a104275..39e69f7 100644 --- a/src/InternshipSystem.Api/Controllers/EditionController.cs +++ b/src/InternshipSystem.Api/Controllers/EditionController.cs @@ -1,7 +1,6 @@ using System; using System.Threading.Tasks; using InternshipSystem.Api.Result; -using InternshipSystem.Core; using InternshipSystem.Repository; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; diff --git a/src/InternshipSystem.Api/Controllers/InternshipRegistrationController.cs b/src/InternshipSystem.Api/Controllers/InternshipRegistrationController.cs index cb48ea4..3747050 100644 --- a/src/InternshipSystem.Api/Controllers/InternshipRegistrationController.cs +++ b/src/InternshipSystem.Api/Controllers/InternshipRegistrationController.cs @@ -1,10 +1,14 @@ using System; +using System.Linq; using System.Threading; using System.Threading.Tasks; +using AutoMapper; 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 { @@ -12,10 +16,12 @@ namespace InternshipSystem.Api.Controllers public class InternshipRegistrationController : ControllerBase { private InternshipDbContext Context { get; } + private IMapper Mapper { get; } - public InternshipRegistrationController(InternshipDbContext context) + public InternshipRegistrationController(InternshipDbContext context, IMapper mapper) { Context = context; + Mapper = mapper; } /// @@ -29,7 +35,84 @@ namespace InternshipSystem.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] - public async Task SubmitRegistrationForm([FromBody] RegistrationFormQuery registrationQuery, CancellationToken cancellationToken) => - throw new NotImplementedException(); + public async Task SubmitRegistrationForm([FromBody] RegistrationFormQuery registrationQuery, + CancellationToken cancellationToken) + { + var validator = new RegistrationFormQuery.Validator(); + var validationResult = await validator.ValidateAsync(registrationQuery, cancellationToken); + + if (!validationResult.IsValid) + { + return BadRequest(validationResult.ToString()); + } + + var internship = await GetCurrentStudentInternship(); + + var internshipRegistration = internship.InternshipRegistration; + + if (registrationQuery.Company != null) + { + var company = registrationQuery.Company.Id.HasValue + ? await Context.Companies.SingleAsync(c => c.Id == registrationQuery.Company.Id, + cancellationToken: cancellationToken) + : Company.CreateCompany(registrationQuery.Company.Nip, registrationQuery.Company.Name); + + internshipRegistration.UpdateCompany(company); + } + + var officeForm = registrationQuery.BranchOffice; + if (officeForm != null) + { + BranchOffice branch; + + if (officeForm.Id.HasValue) + { + branch = await Context.Entry(internshipRegistration.Company) + .Collection(c => c.Branches) + .Query() + .SingleAsync(o => o.Id == officeForm.Id, cancellationToken: cancellationToken); + } + else + { + branch = BranchOffice.CreateBranch(officeForm.Country, officeForm.City, officeForm.PostalCode, + officeForm.Street, officeForm.Building); + internshipRegistration.Company.AddBranchOffice(branch); + } + + internshipRegistration.UpdateBranch(branch); + } + + internshipRegistration.Start = registrationQuery.Start ?? internshipRegistration.Start; + internshipRegistration.End = registrationQuery.End ?? internshipRegistration.End; + + var editionId = Guid.Parse(User.Claims.First(c => c.Type == "Edition").Value); + + var edition = await Context.Editions + .FirstAsync(e => e.Id == editionId, cancellationToken); + + if (registrationQuery.Type.HasValue && edition.IsInternshipTypeAllowed(registrationQuery.Type.Value)) + { + return BadRequest("Edycja nie posiada takiego rodzaju zatrudnienia w dostępnych zatrudnieniach"); + } + + internshipRegistration.Type = registrationQuery.Type ?? internshipRegistration.Type; + + await Context.SaveChangesAsync(cancellationToken); + return Ok(); + } + + private async Task GetCurrentStudentInternship() + { + // TODO: rewrite when authentication will be implemented + var edition = await Context + .Editions + .FirstAsync(); + + return await Context.Entry(edition) + .Collection(e => e.Internships) + .Query() + .Include(i => i.InternshipRegistration) + .FirstAsync(); + } } } \ No newline at end of file diff --git a/src/InternshipSystem.Api/Queries/BranchOfficeForm.cs b/src/InternshipSystem.Api/Queries/BranchOfficeForm.cs new file mode 100644 index 0000000..5fbbafc --- /dev/null +++ b/src/InternshipSystem.Api/Queries/BranchOfficeForm.cs @@ -0,0 +1,36 @@ +using FluentValidation; + +namespace InternshipSystem.Api.Queries +{ + public class BranchOfficeForm + { + public long? Id { get; set; } + public string Street { get; set; } + public string Building { get; set; } + public string City { get; set; } + public string PostalCode { get; set; } + public string Country { get; set; } + + public class Validator : AbstractValidator + { + public Validator() + { + RuleFor(b => b.Id).NotNull() + .When(c => + !string.IsNullOrEmpty(c.Country) || !string.IsNullOrEmpty(c.City) || + !string.IsNullOrEmpty(c.PostalCode) || !string.IsNullOrEmpty(c.Street) || + !string.IsNullOrEmpty(c.Building)); + RuleFor(b => b.Country).NotNull() + .When(b => !b.Id.HasValue); + RuleFor(b => b.City).NotNull() + .When(b => !b.Id.HasValue); + RuleFor(b => b.PostalCode).NotNull() + .When(b => !b.Id.HasValue); + RuleFor(b => b.Street).NotNull() + .When(b => !b.Id.HasValue); + RuleFor(b => b.Building).NotNull() + .When(b => !b.Id.HasValue); + } + } + } +} \ No newline at end of file diff --git a/src/InternshipSystem.Api/Queries/CompanyForm.cs b/src/InternshipSystem.Api/Queries/CompanyForm.cs new file mode 100644 index 0000000..330a8f5 --- /dev/null +++ b/src/InternshipSystem.Api/Queries/CompanyForm.cs @@ -0,0 +1,24 @@ +using FluentValidation; + +namespace InternshipSystem.Api.Queries +{ + public class CompanyForm + { + public long? Id { get; set; } + public string Nip { get; set; } + public string Name { get; set; } + + public class Validator : AbstractValidator + { + public Validator() + { + RuleFor(c => c.Id).NotNull() + .When(c => !string.IsNullOrEmpty(c.Nip) || !string.IsNullOrEmpty(c.Name)); + RuleFor(c => c.Nip).NotEmpty() + .When(c => !c.Id.HasValue); + RuleFor(c => c.Name).NotEmpty() + .When(c => !c.Id.HasValue); + } + } + } +} \ No newline at end of file diff --git a/src/InternshipSystem.Api/Queries/RegistrationFormQuery.cs b/src/InternshipSystem.Api/Queries/RegistrationFormQuery.cs index fe30ded..77122c9 100644 --- a/src/InternshipSystem.Api/Queries/RegistrationFormQuery.cs +++ b/src/InternshipSystem.Api/Queries/RegistrationFormQuery.cs @@ -1,15 +1,28 @@ using System; -using InternshipSystem.Core; +using FluentValidation; 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; } + public CompanyForm Company { get; set; } + public BranchOfficeForm BranchOffice { get; set; } + public DateTime? Start { get; set; } + public DateTime? End { get; set; } + public InternshipType? Type { get; set; } + + public class Validator : AbstractValidator + { + public Validator() + { + RuleFor(rfq => rfq.Company) + .SetValidator(new CompanyForm.Validator()); + RuleFor(rfq => rfq.BranchOffice) + .SetValidator(new BranchOfficeForm.Validator()); + RuleFor(rfq => rfq.BranchOffice).NotNull() + .When(rfq => rfq.Company != null); + } + } } } \ No newline at end of file diff --git a/src/InternshipSystem.Core/Entity/BranchOffice.cs b/src/InternshipSystem.Core/Entity/BranchOffice.cs index 9f3dac9..78e41c8 100644 --- a/src/InternshipSystem.Core/Entity/BranchOffice.cs +++ b/src/InternshipSystem.Core/Entity/BranchOffice.cs @@ -2,8 +2,30 @@ { public class BranchOffice { + public BranchOffice() + { + } + private BranchOffice(BranchAddress address) + { + Address = address; + } + public long Id { get; set; } public BranchAddress Address { get; set; } + + public static BranchOffice CreateBranch(string country, string city, string postalCode, string street, string building) + { + var address = new BranchAddress + { + Building = building, + City = city, + Country = country, + Street = street, + PostalCode = postalCode + }; + + return new BranchOffice(address); + } } } \ No newline at end of file diff --git a/src/InternshipSystem.Core/Entity/Company.cs b/src/InternshipSystem.Core/Entity/Company.cs index ddbeeb4..67b640d 100644 --- a/src/InternshipSystem.Core/Entity/Company.cs +++ b/src/InternshipSystem.Core/Entity/Company.cs @@ -8,22 +8,22 @@ namespace InternshipSystem.Core public long Id { get; set; } public Nip Nip { get; set; } public string Name { get; set; } - public RangeOfActivity Range { get; set; } public List Branches { get; set; } - public Uri SiteAddress { get; set; } - public Company CreateCompany(string nip, RangeOfActivity range, string name) - { - return new Company + public static Company CreateCompany(string nip, string name) => + new Company { Nip = nip, - Range = range, Name = name }; - } public void AddBranchAddress(BranchAddress branch) { } + + public void AddBranchOffice(BranchOffice createBranch) + { + Branches.Add(createBranch); + } } } \ No newline at end of file diff --git a/src/InternshipSystem.Core/Entity/Edition.cs b/src/InternshipSystem.Core/Entity/Edition.cs index 165b31c..bd058ed 100644 --- a/src/InternshipSystem.Core/Entity/Edition.cs +++ b/src/InternshipSystem.Core/Entity/Edition.cs @@ -14,6 +14,7 @@ namespace InternshipSystem.Core public Course Course { get; set; } public List Internships { get; set; } public List AvailableSubjects { get; set; } + public List AvailableInternshipTypes { get; set; } public Edition CreateEdition(DateTime start, DateTime end, DateTime reportingStart) { @@ -24,5 +25,10 @@ namespace InternshipSystem.Core ReportingStart = reportingStart }; } + + public bool IsInternshipTypeAllowed(InternshipType registrationQueryType) + { + return AvailableInternshipTypes.Contains(registrationQueryType); + } } } \ 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 52aaf69..666d1e5 100644 --- a/src/InternshipSystem.Core/Entity/Internship/Internship.cs +++ b/src/InternshipSystem.Core/Entity/Internship/Internship.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.Linq; -using InternshipSystem.Core.ValueObject; namespace InternshipSystem.Core { @@ -14,12 +13,14 @@ namespace InternshipSystem.Core public List Approvals { get; set; } public List Documentation { get; set; } + public Edition Edition { 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.Description = document.Description ?? oldDocument.Description; + oldDocument.Scan = document.Scan ?? oldDocument.Scan; oldDocument.Type = document.Type; oldDocument.State = DocumentState.Submitted; } diff --git a/src/InternshipSystem.Core/Entity/Internship/InternshipRegistration.cs b/src/InternshipSystem.Core/Entity/Internship/InternshipRegistration.cs index 449230e..e7e8790 100644 --- a/src/InternshipSystem.Core/Entity/Internship/InternshipRegistration.cs +++ b/src/InternshipSystem.Core/Entity/Internship/InternshipRegistration.cs @@ -12,5 +12,15 @@ namespace InternshipSystem.Core public DateTime End { get; set; } public InternshipType Type { get; set; } public DocumentState State { get; set; } + + public void UpdateCompany(Company newCompany) + { + Company = newCompany; + } + + public void UpdateBranch(BranchOffice branch) + { + BranchAddress = branch; + } } } \ No newline at end of file diff --git a/src/InternshipSystem.Core/Entity/Internship/InternshipType.cs b/src/InternshipSystem.Core/Entity/Internship/InternshipType.cs index d9fb97f..0f554e0 100644 --- a/src/InternshipSystem.Core/Entity/Internship/InternshipType.cs +++ b/src/InternshipSystem.Core/Entity/Internship/InternshipType.cs @@ -1,9 +1,14 @@ namespace InternshipSystem.Core.Entity.Internship { - public class InternshipType + public enum InternshipType { - public long Id { get; set; } - public string Type { get; set; } - public string Description { get; set; } + FreeInternship, + GraduateInternship, + FreeApprenticeship, + PaidApprenticeship, + ForeignInternship, + UOP, + UD, + UZ } } \ No newline at end of file diff --git a/src/InternshipSystem.Core/Entity/Report.cs b/src/InternshipSystem.Core/Entity/Report.cs index 944678d..4eeb8e9 100644 --- a/src/InternshipSystem.Core/Entity/Report.cs +++ b/src/InternshipSystem.Core/Entity/Report.cs @@ -1,8 +1,12 @@ -namespace InternshipSystem.Core +using System; + +namespace InternshipSystem.Core { public class Report { public long Id { get; set; } public DocumentState State { get; set; } + public RangeOfActivity Range { get; set; } + public Uri SiteAddress { get; set; } } } \ No newline at end of file diff --git a/src/InternshipSystem.Repository/DatabaseFiller.cs b/src/InternshipSystem.Repository/DatabaseFiller.cs index bee6e4b..1b898d1 100644 --- a/src/InternshipSystem.Repository/DatabaseFiller.cs +++ b/src/InternshipSystem.Repository/DatabaseFiller.cs @@ -26,9 +26,8 @@ namespace InternshipSystem.Repository { Id = 1, Name = "Intel", - SiteAddress = new Uri("https://www.intel.com/content/www/us/en/jobs/locations/poland.html"), + // SiteAddress = new Uri("https://www.intel.com/content/www/us/en/jobs/locations/poland.html"), Nip = "9570752316", - Range = RangeOfActivity.International, Branches = new List { new BranchOffice @@ -70,9 +69,8 @@ namespace InternshipSystem.Repository { Id = 2, Name = "Asseco Poland", - SiteAddress = new Uri("http://pl.asseco.com"), + // SiteAddress = new Uri("http://pl.asseco.com"), Nip = "5842068320", - Range = RangeOfActivity.National, Branches = new List { new BranchOffice @@ -141,6 +139,13 @@ namespace InternshipSystem.Repository { Name = "Informatyka", }, + AvailableInternshipTypes = new List + { + InternshipType.UOP, + InternshipType.UZ, + InternshipType.UD, + InternshipType.FreeInternship + }, Internships = new List(), } }; @@ -162,10 +167,7 @@ namespace InternshipSystem.Repository InternshipRegistration = new InternshipRegistration { Company = Context.Companies.First(c => c.Id.Equals(1)), //Intel - Type = new InternshipType - { - Type = "UOP" - }, + Type = InternshipType.UOP, Start = new DateTime(2000, 7, 1), End = new DateTime(2000, 8, 30), State = DocumentState.Submitted, @@ -215,10 +217,7 @@ namespace InternshipSystem.Repository InternshipRegistration = new InternshipRegistration { Company = Context.Companies.First(c => c.Id.Equals(2)), //Asseco - Type = new InternshipType - { - Type = "UZ" - }, + Type = InternshipType.UZ, Start = new DateTime(2000, 7, 1), End = new DateTime(2000, 8, 30), State = DocumentState.Submitted,