diff --git a/SchengenVisaApi/ApplicationLayer/Applicants/IApplicantsRepository.cs b/SchengenVisaApi/ApplicationLayer/Applicants/NeededServices/IApplicantsRepository.cs similarity index 56% rename from SchengenVisaApi/ApplicationLayer/Applicants/IApplicantsRepository.cs rename to SchengenVisaApi/ApplicationLayer/Applicants/NeededServices/IApplicantsRepository.cs index 54266aa..5fc23ae 100644 --- a/SchengenVisaApi/ApplicationLayer/Applicants/IApplicantsRepository.cs +++ b/SchengenVisaApi/ApplicationLayer/Applicants/NeededServices/IApplicantsRepository.cs @@ -1,7 +1,7 @@ -using ApplicationLayer.Common; +using ApplicationLayer.GeneralNeededServices; using Domains.ApplicantDomain; -namespace ApplicationLayer.Applicants; +namespace ApplicationLayer.Applicants.NeededServices; /// Repository pattern for -public interface IApplicantsRepository : IGenericRepository { } \ No newline at end of file +public interface IApplicantsRepository : IGenericRepository { } diff --git a/SchengenVisaApi/ApplicationLayer/ApplicationLayer.csproj b/SchengenVisaApi/ApplicationLayer/ApplicationLayer.csproj index 9ceef99..bc6298d 100644 --- a/SchengenVisaApi/ApplicationLayer/ApplicationLayer.csproj +++ b/SchengenVisaApi/ApplicationLayer/ApplicationLayer.csproj @@ -10,4 +10,8 @@ + + + + diff --git a/SchengenVisaApi/ApplicationLayer/DependencyInjection.cs b/SchengenVisaApi/ApplicationLayer/DependencyInjection.cs new file mode 100644 index 0000000..b5534a3 --- /dev/null +++ b/SchengenVisaApi/ApplicationLayer/DependencyInjection.cs @@ -0,0 +1,16 @@ +using ApplicationLayer.VisaApplications.Handlers; +using Microsoft.Extensions.DependencyInjection; + +namespace ApplicationLayer; + +/// Provides methods to add services to DI-container +public static class DependencyInjection +{ + /// Add services for Application layer + public static IServiceCollection AddApplicationLayer(this IServiceCollection services) + { + services.AddScoped(); + + return services; + } +} diff --git a/SchengenVisaApi/ApplicationLayer/Common/IGenericRepository.cs b/SchengenVisaApi/ApplicationLayer/GeneralNeededServices/IGenericRepository.cs similarity index 91% rename from SchengenVisaApi/ApplicationLayer/Common/IGenericRepository.cs rename to SchengenVisaApi/ApplicationLayer/GeneralNeededServices/IGenericRepository.cs index cfcb5e6..d8474f7 100644 --- a/SchengenVisaApi/ApplicationLayer/Common/IGenericRepository.cs +++ b/SchengenVisaApi/ApplicationLayer/GeneralNeededServices/IGenericRepository.cs @@ -1,6 +1,6 @@ using Domains; -namespace ApplicationLayer.Common; +namespace ApplicationLayer.GeneralNeededServices; /// /// Generic repository pattern @@ -15,7 +15,7 @@ public interface IGenericRepository where T : class, IEntity /// Get one entity with specific id /// Identifier of entity /// Cancellation token - Task GetOneAsync(Guid id, CancellationToken cancellationToken); + Task GetByIdAsync(Guid id, CancellationToken cancellationToken); /// Add entity to storage /// Entity to add diff --git a/SchengenVisaApi/ApplicationLayer/Locations/ICitiesRepository.cs b/SchengenVisaApi/ApplicationLayer/Locations/ICitiesRepository.cs deleted file mode 100644 index d0dd17c..0000000 --- a/SchengenVisaApi/ApplicationLayer/Locations/ICitiesRepository.cs +++ /dev/null @@ -1,14 +0,0 @@ -using ApplicationLayer.Common; -using Domains.LocationDomain; - -namespace ApplicationLayer.Locations; - -public interface ICitiesRepository : IGenericRepository -{ - /// Find the city by its name and its country name - /// City's name - /// City's country name - /// Cancellation token - /// City with specific name and country - Task GetByNameAsync(string name, string countryName, CancellationToken cancellationToken); -} diff --git a/SchengenVisaApi/ApplicationLayer/Locations/NeededServices/ICitiesRepository.cs b/SchengenVisaApi/ApplicationLayer/Locations/NeededServices/ICitiesRepository.cs new file mode 100644 index 0000000..cfed58a --- /dev/null +++ b/SchengenVisaApi/ApplicationLayer/Locations/NeededServices/ICitiesRepository.cs @@ -0,0 +1,6 @@ +using ApplicationLayer.GeneralNeededServices; +using Domains.LocationDomain; + +namespace ApplicationLayer.Locations.NeededServices; + +public interface ICitiesRepository : IGenericRepository { } diff --git a/SchengenVisaApi/ApplicationLayer/Locations/ICountriesRepository.cs b/SchengenVisaApi/ApplicationLayer/Locations/NeededServices/ICountriesRepository.cs similarity index 50% rename from SchengenVisaApi/ApplicationLayer/Locations/ICountriesRepository.cs rename to SchengenVisaApi/ApplicationLayer/Locations/NeededServices/ICountriesRepository.cs index 1811214..e2ced02 100644 --- a/SchengenVisaApi/ApplicationLayer/Locations/ICountriesRepository.cs +++ b/SchengenVisaApi/ApplicationLayer/Locations/NeededServices/ICountriesRepository.cs @@ -1,6 +1,6 @@ -using ApplicationLayer.Common; +using ApplicationLayer.GeneralNeededServices; using Domains.LocationDomain; -namespace ApplicationLayer.Locations; +namespace ApplicationLayer.Locations.NeededServices; public interface ICountriesRepository : IGenericRepository { } diff --git a/SchengenVisaApi/ApplicationLayer/VisaApplications/Handlers/IVisaApplicationsRequestHandler.cs b/SchengenVisaApi/ApplicationLayer/VisaApplications/Handlers/IVisaApplicationsRequestHandler.cs new file mode 100644 index 0000000..61905d5 --- /dev/null +++ b/SchengenVisaApi/ApplicationLayer/VisaApplications/Handlers/IVisaApplicationsRequestHandler.cs @@ -0,0 +1,11 @@ +using ApplicationLayer.VisaApplications.Requests; +using Domains.VisaApplicationDomain; + +namespace ApplicationLayer.VisaApplications.Handlers; + +public interface IVisaApplicationsRequestHandler +{ + Task> Get(CancellationToken cancellationToken); + + void HandleCreateRequest(VisaApplicationCreateRequest request, CancellationToken cancellationToken); +} diff --git a/SchengenVisaApi/ApplicationLayer/VisaApplications/Handlers/VisaApplicationRequestsHandler.cs b/SchengenVisaApi/ApplicationLayer/VisaApplications/Handlers/VisaApplicationRequestsHandler.cs index bde7e4a..37e2b17 100644 --- a/SchengenVisaApi/ApplicationLayer/VisaApplications/Handlers/VisaApplicationRequestsHandler.cs +++ b/SchengenVisaApi/ApplicationLayer/VisaApplications/Handlers/VisaApplicationRequestsHandler.cs @@ -1,14 +1,78 @@ -using ApplicationLayer.Applicants; +using ApplicationLayer.Locations.NeededServices; +using ApplicationLayer.VisaApplications.Models; +using ApplicationLayer.VisaApplications.NeededServices; using ApplicationLayer.VisaApplications.Requests; +using Domains.ApplicantDomain; +using Domains.VisaApplicationDomain; -namespace ApplicationLayer.VisaApplications.Handlers +namespace ApplicationLayer.VisaApplications.Handlers; + +/// Handles visa requests +public class VisaApplicationRequestsHandler( + IVisaApplicationsRepository applications, + ICitiesRepository cities, + ICountriesRepository countries) : IVisaApplicationsRequestHandler { - /// Handles visa requests - public class VisaApplicationRequestsHandler(IApplicantsRepository) - { - public void HandleCreateRequest(CreateVisaApplicationRequest request) - { + public async Task> Get(CancellationToken cancellationToken) => await applications.GetAllAsync(cancellationToken); - } + public async void HandleCreateRequest(VisaApplicationCreateRequest request, CancellationToken cancellationToken) + { + //TODO mapper + var cityOfBirth = await cities.GetByIdAsync(request.BirthCityId, cancellationToken); + var cityOfWork = await cities.GetByIdAsync(request.PlaceOfWork.Address.CityId, cancellationToken); + + var addressOfWork = new Address + { + City = cityOfWork, + Country = cityOfWork.Country, + Building = request.PlaceOfWork.Address.Building, + Street = request.PlaceOfWork.Address.Street + }; + + var applicant = new Applicant + { + MaritalStatus = request.MaritalStatus, + Name = request.FullName, + Passport = request.Passport, + Gender = request.Gender, + Citizenship = request.CitizenShip, + BirthDate = request.BirthDate, + FatherName = request.FatherName, + JobTitle = request.JobTitle, + MotherName = request.MotherName, + CitizenshipByBirth = request.CitizenshipByBirth, + CityOfBirth = cityOfBirth, + CountryOfBirth = cityOfBirth.Country, + IsNonResident = request.IsNonResident, + PlaceOfWork = new PlaceOfWork { Address = addressOfWork, Name = request.PlaceOfWork.Name, PhoneNum = request.PlaceOfWork.PhoneNum } + }; + + var pastVisits = request.PastVisits.Select(m => ConvertPastVisitModelToPastVisit(m, cancellationToken).Result).ToList(); + var visaApplication = new VisaApplication + { + Applicant = applicant, + RequestedNumberOfEntries = request.RequestedNumberOfEntries, + ValidDaysRequested = request.ValidDaysRequested, + ReentryPermit = request.ReentryPermit, + VisaCategory = request.VisaCategory, + PermissionToDestCountry = request.PermissionToDestCountry, + DestinationCountry = await countries.GetByIdAsync(request.DestinationCountryId, cancellationToken), + PastVisas = request.PastVisas.ToList(), + PastVisits = pastVisits, + ForGroup = request.IsForGroup, + RequestDate = DateTime.Today + }; + + await applications.AddAsync(visaApplication, cancellationToken); + } + + private async Task ConvertPastVisitModelToPastVisit(PastVisitModel model, CancellationToken cancellationToken) + { + return new PastVisit + { + DestinationCountry = await countries.GetByIdAsync(model.DestinationCountryId, cancellationToken), + StartDate = model.StartDate, + EndDate = model.EndDate + }; } } diff --git a/SchengenVisaApi/ApplicationLayer/VisaApplications/IVisaApplicationsRepository.cs b/SchengenVisaApi/ApplicationLayer/VisaApplications/IVisaApplicationsRepository.cs deleted file mode 100644 index 2d620f7..0000000 --- a/SchengenVisaApi/ApplicationLayer/VisaApplications/IVisaApplicationsRepository.cs +++ /dev/null @@ -1,6 +0,0 @@ -using ApplicationLayer.Common; -using Domains.VisaApplicationDomain; - -namespace ApplicationLayer.VisaApplications; - -public interface IVisaApplicationsRepository : IGenericRepository { } \ No newline at end of file diff --git a/SchengenVisaApi/ApplicationLayer/VisaApplications/Models/AddressModel.cs b/SchengenVisaApi/ApplicationLayer/VisaApplications/Models/AddressModel.cs index c6afb8c..0a36077 100644 --- a/SchengenVisaApi/ApplicationLayer/VisaApplications/Models/AddressModel.cs +++ b/SchengenVisaApi/ApplicationLayer/VisaApplications/Models/AddressModel.cs @@ -2,11 +2,8 @@ public class AddressModel { - /// Country part of address - public string Country { get; set; } = null!; - /// City part of address - public string City { get; set; } = null!; + public Guid CityId { get; set; } /// Street part of address public string Street { get; set; } = null!; diff --git a/SchengenVisaApi/ApplicationLayer/VisaApplications/Models/PastVisitModel.cs b/SchengenVisaApi/ApplicationLayer/VisaApplications/Models/PastVisitModel.cs new file mode 100644 index 0000000..fe1396c --- /dev/null +++ b/SchengenVisaApi/ApplicationLayer/VisaApplications/Models/PastVisitModel.cs @@ -0,0 +1,14 @@ +namespace ApplicationLayer.VisaApplications.Models +{ + public class PastVisitModel + { + /// First day of + public DateTime StartDate { get; set; } + + /// Last day of + public DateTime EndDate { get; set; } + + /// Identifier of destination country of + public Guid DestinationCountryId { get; set; } + } +} diff --git a/SchengenVisaApi/ApplicationLayer/VisaApplications/NeededServices/IVisaApplicationsRepository.cs b/SchengenVisaApi/ApplicationLayer/VisaApplications/NeededServices/IVisaApplicationsRepository.cs new file mode 100644 index 0000000..8a8921e --- /dev/null +++ b/SchengenVisaApi/ApplicationLayer/VisaApplications/NeededServices/IVisaApplicationsRepository.cs @@ -0,0 +1,6 @@ +using ApplicationLayer.GeneralNeededServices; +using Domains.VisaApplicationDomain; + +namespace ApplicationLayer.VisaApplications.NeededServices; + +public interface IVisaApplicationsRepository : IGenericRepository { } \ No newline at end of file diff --git a/SchengenVisaApi/ApplicationLayer/VisaApplications/Requests/CreateVisaApplicationRequest.cs b/SchengenVisaApi/ApplicationLayer/VisaApplications/Requests/VisaApplicationCreateRequest.cs similarity index 83% rename from SchengenVisaApi/ApplicationLayer/VisaApplications/Requests/CreateVisaApplicationRequest.cs rename to SchengenVisaApi/ApplicationLayer/VisaApplications/Requests/VisaApplicationCreateRequest.cs index 36f0c94..5d95817 100644 --- a/SchengenVisaApi/ApplicationLayer/VisaApplications/Requests/CreateVisaApplicationRequest.cs +++ b/SchengenVisaApi/ApplicationLayer/VisaApplications/Requests/VisaApplicationCreateRequest.cs @@ -5,12 +5,11 @@ using Domains.VisaApplicationDomain; namespace ApplicationLayer.VisaApplications.Requests; /// Model of visa request from user -public record CreateVisaApplicationRequest( +public record VisaApplicationCreateRequest( Name FullName, Passport Passport, DateTime BirthDate, - string BirthCity, - string BirthCountry, + Guid BirthCityId, string CitizenShip, string CitizenshipByBirth, Gender Gender, @@ -21,12 +20,12 @@ public record CreateVisaApplicationRequest( ReentryPermit ReentryPermit, string JobTitle, PlaceOfWorkModel PlaceOfWork, - string DestinationCountry, + Guid DestinationCountryId, VisaCategory VisaCategory, bool IsForGroup, RequestedNumberOfEntries RequestedNumberOfEntries, int ValidDaysRequested, PastVisa[] PastVisas, PermissionToDestCountry? PermissionToDestCountry, - PastVisit[] PastVisits + PastVisitModel[] PastVisits ); diff --git a/SchengenVisaApi/Domains/ApplicantDomain/Applicant.cs b/SchengenVisaApi/Domains/ApplicantDomain/Applicant.cs index 77f2bdb..dc2efa4 100644 --- a/SchengenVisaApi/Domains/ApplicantDomain/Applicant.cs +++ b/SchengenVisaApi/Domains/ApplicantDomain/Applicant.cs @@ -1,5 +1,4 @@ using Domains.LocationDomain; -using Domains.VisaApplicationDomain; namespace Domains.ApplicantDomain; @@ -50,7 +49,4 @@ public class Applicant : IEntity /// Is a non-resident public bool IsNonResident { get; set; } - - /// List of 's applications - public List VisaApplications { get; set; } = null!; -} \ No newline at end of file +} diff --git a/SchengenVisaApi/Domains/ApplicantDomain/Name.cs b/SchengenVisaApi/Domains/ApplicantDomain/Name.cs index 237297c..e9199a7 100644 --- a/SchengenVisaApi/Domains/ApplicantDomain/Name.cs +++ b/SchengenVisaApi/Domains/ApplicantDomain/Name.cs @@ -9,4 +9,4 @@ public class Name public string Surname { get; set; } = null!; public string? Patronymic { get; set; } -} \ No newline at end of file +} diff --git a/SchengenVisaApi/Domains/VisaApplicationDomain/PastVisit.cs b/SchengenVisaApi/Domains/VisaApplicationDomain/PastVisit.cs index b7017ed..cdc285e 100644 --- a/SchengenVisaApi/Domains/VisaApplicationDomain/PastVisit.cs +++ b/SchengenVisaApi/Domains/VisaApplicationDomain/PastVisit.cs @@ -1,4 +1,5 @@ using Domains.ApplicantDomain; +using Domains.LocationDomain; namespace Domains.VisaApplicationDomain; @@ -11,4 +12,7 @@ public class PastVisit /// Last day of public DateTime EndDate { get; set; } + + /// Destination country of + public Country DestinationCountry { get; set; } = null!; } diff --git a/SchengenVisaApi/Infrastructure/DependencyInjection.cs b/SchengenVisaApi/Infrastructure/DependencyInjection.cs index da92abd..6f59149 100644 --- a/SchengenVisaApi/Infrastructure/DependencyInjection.cs +++ b/SchengenVisaApi/Infrastructure/DependencyInjection.cs @@ -1,6 +1,6 @@ -using ApplicationLayer.Applicants; -using ApplicationLayer.Locations; -using ApplicationLayer.VisaApplications; +using ApplicationLayer.Applicants.NeededServices; +using ApplicationLayer.Locations.NeededServices; +using ApplicationLayer.VisaApplications.NeededServices; using Infrastructure.Database; using Infrastructure.Database.Applicants.Repositories; using Infrastructure.Database.Generic; @@ -20,7 +20,7 @@ public static class DependencyInjection public static IServiceCollection AddInfrastructure(this IServiceCollection services) { //TODO строка подключения - services.AddDbContext(opts => + services.AddDbContextFactory(opts => opts.UseSqlServer("Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=visadb;Integrated Security=True;")); services.AddScoped(serviceProvider => serviceProvider.GetRequiredService()); @@ -34,4 +34,4 @@ public static class DependencyInjection return services; } -} \ No newline at end of file +} diff --git a/SchengenVisaApi/SchengenVisaApi/Controllers/VisaApplicationController.cs b/SchengenVisaApi/SchengenVisaApi/Controllers/VisaApplicationController.cs index b8c5be8..3eca65b 100644 --- a/SchengenVisaApi/SchengenVisaApi/Controllers/VisaApplicationController.cs +++ b/SchengenVisaApi/SchengenVisaApi/Controllers/VisaApplicationController.cs @@ -1,3 +1,4 @@ +using ApplicationLayer.VisaApplications.Handlers; using ApplicationLayer.VisaApplications.Requests; using Microsoft.AspNetCore.Mvc; @@ -5,17 +6,18 @@ namespace SchengenVisaApi.Controllers; [ApiController] [Route("[controller]")] -public class VisaApplicationController : ControllerBase +public class VisaApplicationController(IVisaApplicationsRequestHandler visaApplicationsRequestHandler) : ControllerBase { - - public VisaApplicationController() + [HttpGet] + public async Task Get(CancellationToken cancellationToken) { - - } + var result = await visaApplicationsRequestHandler.Get(cancellationToken); + return Ok(result); + } [HttpPost] - public void Create(CreateVisaApplicationRequest request) + public void Create(VisaApplicationCreateRequest request, CancellationToken cancellationToken) { - throw new NotImplementedException(); - } + visaApplicationsRequestHandler.HandleCreateRequest(request, cancellationToken); + } } diff --git a/SchengenVisaApi/SchengenVisaApi/DependencyInjection.cs b/SchengenVisaApi/SchengenVisaApi/DependencyInjection.cs index 7851b66..9e8a820 100644 --- a/SchengenVisaApi/SchengenVisaApi/DependencyInjection.cs +++ b/SchengenVisaApi/SchengenVisaApi/DependencyInjection.cs @@ -1,4 +1,5 @@ using System.Reflection; +using ApplicationLayer; using Infrastructure; namespace SchengenVisaApi; @@ -11,6 +12,7 @@ public static class DependencyInjection { services .AddInfrastructure() + .AddApplicationLayer() .AddPresentation(); return services; @@ -27,4 +29,4 @@ public static class DependencyInjection options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename)); }); } -} \ No newline at end of file +} diff --git a/SchengenVisaApi/SchengenVisaApi/SchengenVisaApi.csproj b/SchengenVisaApi/SchengenVisaApi/SchengenVisaApi.csproj index 6d4c558..6a3fbdf 100644 --- a/SchengenVisaApi/SchengenVisaApi/SchengenVisaApi.csproj +++ b/SchengenVisaApi/SchengenVisaApi/SchengenVisaApi.csproj @@ -4,7 +4,6 @@ net8.0 enable enable - true true