Renamed folder
This commit is contained in:
		| @@ -0,0 +1,13 @@ | ||||
| namespace ApplicationLayer.Services.Applicants.Models; | ||||
|  | ||||
| public class AddressModel | ||||
| { | ||||
|     /// City part of address | ||||
|     public Guid CityId { get; set; } | ||||
|  | ||||
|     /// Street part of address | ||||
|     public string Street { get; set; } = null!; | ||||
|  | ||||
|     /// Building part of address | ||||
|     public string Building { get; set; } = null!; | ||||
| } | ||||
| @@ -0,0 +1,13 @@ | ||||
| namespace ApplicationLayer.Services.Applicants.Models; | ||||
|  | ||||
| public class PlaceOfWorkModel | ||||
| { | ||||
|     /// Name of hirer | ||||
|     public string Name { get; set; } = null!; | ||||
|  | ||||
|     /// <see cref="AddressModel"/> of hirer | ||||
|     public AddressModel Address { get; set; } = null!; | ||||
|  | ||||
|     /// Phone number of hirer | ||||
|     public string PhoneNum { get; set; } = null!; | ||||
| } | ||||
| @@ -0,0 +1,11 @@ | ||||
| using ApplicationLayer.GeneralNeededServices; | ||||
| using Domains.ApplicantDomain; | ||||
|  | ||||
| namespace ApplicationLayer.Services.Applicants.NeededServices; | ||||
|  | ||||
| /// Repository pattern for <see cref="Applicant"/> | ||||
| public interface IApplicantsRepository : IGenericRepository<Applicant> | ||||
| { | ||||
|     /// Find <see cref="Applicant"/> by Identifier | ||||
|     Task<Applicant> FindByUserIdAsync(Guid userId, CancellationToken cancellationToken); | ||||
| } | ||||
| @@ -0,0 +1,28 @@ | ||||
| using ApplicationLayer.Services.AuthServices.LoginService.Exceptions; | ||||
| using ApplicationLayer.Services.AuthServices.NeededServices; | ||||
| using ApplicationLayer.Services.AuthServices.Requests; | ||||
| using Domains.Users; | ||||
|  | ||||
| namespace ApplicationLayer.Services.AuthServices.LoginService | ||||
| { | ||||
|     public class DevelopmentLoginService(IUsersRepository users, ITokenGenerator tokenGenerator) : ILoginService | ||||
|     { | ||||
|         async Task<string> ILoginService.LoginAsync(UserLoginRequest request, CancellationToken cancellationToken) | ||||
|         { | ||||
|             if (request is { Email: "admin@mail.ru", Password: "admin" }) | ||||
|             { | ||||
|                 var admin = new User { Role = Role.Admin }; | ||||
|  | ||||
|                 return tokenGenerator.CreateToken(admin); | ||||
|             } | ||||
|  | ||||
|             var user = await users.FindByEmailAsync(request.Email, cancellationToken); | ||||
|             if (user is null || user.Password != request.Password) | ||||
|             { | ||||
|                 throw new IncorrectLoginDataException(); | ||||
|             } | ||||
|  | ||||
|             return tokenGenerator.CreateToken(user); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,6 @@ | ||||
| using ApplicationLayer.GeneralExceptions; | ||||
|  | ||||
| namespace ApplicationLayer.Services.AuthServices.LoginService.Exceptions | ||||
| { | ||||
|     public class IncorrectLoginDataException() : ApiException("Incorrect email or password"); | ||||
| } | ||||
| @@ -0,0 +1,12 @@ | ||||
| using ApplicationLayer.Services.AuthServices.Requests; | ||||
|  | ||||
| namespace ApplicationLayer.Services.AuthServices.LoginService | ||||
| { | ||||
|     /// Handles <see cref="UserLoginRequest"/> | ||||
|     public interface ILoginService | ||||
|     { | ||||
|         /// Handle <see cref="UserLoginRequest"/> | ||||
|         /// <returns>JWT-token</returns> | ||||
|         Task<string> LoginAsync(UserLoginRequest request, CancellationToken cancellationToken); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,21 @@ | ||||
| using ApplicationLayer.Services.AuthServices.LoginService.Exceptions; | ||||
| using ApplicationLayer.Services.AuthServices.NeededServices; | ||||
| using ApplicationLayer.Services.AuthServices.Requests; | ||||
|  | ||||
| namespace ApplicationLayer.Services.AuthServices.LoginService | ||||
| { | ||||
|     /// <inheritdoc cref="ILoginService"/> | ||||
|     public class LoginService(IUsersRepository users, ITokenGenerator tokenGenerator) : ILoginService | ||||
|     { | ||||
|         async Task<string> ILoginService.LoginAsync(UserLoginRequest request, CancellationToken cancellationToken) | ||||
|         { | ||||
|             var user = await users.FindByEmailAsync(request.Email, cancellationToken); | ||||
|             if (user is null || user.Password != request.Password) | ||||
|             { | ||||
|                 throw new IncorrectLoginDataException(); | ||||
|             } | ||||
|  | ||||
|             return tokenGenerator.CreateToken(user); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,9 @@ | ||||
| using Domains.Users; | ||||
|  | ||||
| namespace ApplicationLayer.Services.AuthServices.NeededServices | ||||
| { | ||||
|     public interface ITokenGenerator | ||||
|     { | ||||
|         string CreateToken(User user); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,15 @@ | ||||
| using ApplicationLayer.GeneralNeededServices; | ||||
| using Domains.Users; | ||||
|  | ||||
| namespace ApplicationLayer.Services.AuthServices.NeededServices | ||||
| { | ||||
|     /// Repository pattern for <see cref="User"/> | ||||
|     public interface IUsersRepository : IGenericRepository<User> | ||||
|     { | ||||
|         /// Find <see cref="User"/> by email | ||||
|         /// <param name="email"><see cref="User"/>'s email</param> | ||||
|         /// <param name="cancellationToken">Cancellation token</param> | ||||
|         /// <returns>User or null if not found</returns> | ||||
|         Task<User?> FindByEmailAsync(string email, CancellationToken cancellationToken); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,7 @@ | ||||
| using ApplicationLayer.GeneralExceptions; | ||||
| using ApplicationLayer.Services.AuthServices.Requests; | ||||
|  | ||||
| namespace ApplicationLayer.Services.AuthServices.RegisterService.Exceptions | ||||
| { | ||||
|     public class UserAlreadyExistsException(RegisterApplicantRequest request) : AlreadyExistsException($"User with email '{request.Email}' already exists"); | ||||
| } | ||||
| @@ -0,0 +1,11 @@ | ||||
| using ApplicationLayer.Services.AuthServices.Requests; | ||||
|  | ||||
| namespace ApplicationLayer.Services.AuthServices.RegisterService | ||||
| { | ||||
|     /// Handles <see cref="RegisterApplicantRequest"/> | ||||
|     public interface IRegisterService | ||||
|     { | ||||
|         /// Handle <see cref="RegisterApplicantRequest"/> | ||||
|         Task Register(RegisterApplicantRequest request, CancellationToken cancellationToken); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,71 @@ | ||||
| using ApplicationLayer.GeneralNeededServices; | ||||
| using ApplicationLayer.Services.Applicants.NeededServices; | ||||
| using ApplicationLayer.Services.AuthServices.NeededServices; | ||||
| using ApplicationLayer.Services.AuthServices.RegisterService.Exceptions; | ||||
| using ApplicationLayer.Services.AuthServices.Requests; | ||||
| using ApplicationLayer.Services.Locations.NeededServices; | ||||
| using Domains.ApplicantDomain; | ||||
| using Domains.Users; | ||||
|  | ||||
| namespace ApplicationLayer.Services.AuthServices.RegisterService | ||||
| { | ||||
|     /// <inheritdoc cref="IRegisterService"/> | ||||
|     public class RegisterService( | ||||
|         IUsersRepository users, | ||||
|         IApplicantsRepository applicants, | ||||
|         ICitiesRepository cities, | ||||
|         IUnitOfWork unitOfWork) : IRegisterService | ||||
|     { | ||||
|         async Task IRegisterService.Register(RegisterApplicantRequest request, CancellationToken cancellationToken) | ||||
|         { | ||||
|             if (await users.FindByEmailAsync(request.Email, cancellationToken) is not null) | ||||
|             { | ||||
|                 throw new UserAlreadyExistsException(request); | ||||
|             } | ||||
|  | ||||
|             //TODO mapper | ||||
|             var user = new User { Email = request.Email, Password = request.Password, Role = Role.Applicant }; | ||||
|  | ||||
|             var applicantCity = await cities.GetByIdAsync(request.CityOfBirthId, cancellationToken); | ||||
|             var placeOfWorkCity = await cities.GetByIdAsync(request.PlaceOfWork.Address.CityId, cancellationToken); | ||||
|             var placeOfWorkAddress = new Address | ||||
|             { | ||||
|                 Country = placeOfWorkCity.Country, | ||||
|                 City = placeOfWorkCity, | ||||
|                 Building = request.PlaceOfWork.Address.Building, | ||||
|                 Street = request.PlaceOfWork.Address.Street | ||||
|             }; | ||||
|  | ||||
|             var placeOfWork = new PlaceOfWork | ||||
|             { | ||||
|                 Name = request.PlaceOfWork.Name, | ||||
|                 Address = placeOfWorkAddress, | ||||
|                 PhoneNum = request.PlaceOfWork.PhoneNum | ||||
|             }; | ||||
|  | ||||
|             var applicant = new Applicant | ||||
|             { | ||||
|                 Citizenship = request.Citizenship, | ||||
|                 CitizenshipByBirth = request.CitizenshipByBirth, | ||||
|                 Gender = request.Gender, | ||||
|                 Name = request.ApplicantName, | ||||
|                 Passport = request.Passport, | ||||
|                 BirthDate = request.BirthDate, | ||||
|                 FatherName = request.FatherName, | ||||
|                 JobTitle = request.JobTitle, | ||||
|                 MaritalStatus = request.MaritalStatus, | ||||
|                 MotherName = request.MotherName, | ||||
|                 UserId = user.Id, | ||||
|                 CityOfBirth = applicantCity, | ||||
|                 CountryOfBirth = applicantCity.Country, | ||||
|                 IsNonResident = request.IsNonResident, | ||||
|                 PlaceOfWork = placeOfWork | ||||
|             }; | ||||
|  | ||||
|             await users.AddAsync(user, cancellationToken); | ||||
|             await applicants.AddAsync(applicant, cancellationToken); | ||||
|  | ||||
|             await unitOfWork.SaveAsync(cancellationToken); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,22 @@ | ||||
| using ApplicationLayer.Services.Applicants.Models; | ||||
| using Domains.ApplicantDomain; | ||||
|  | ||||
| namespace ApplicationLayer.Services.AuthServices.Requests | ||||
| { | ||||
|     public record RegisterApplicantRequest( | ||||
|         string Email, | ||||
|         string Password, | ||||
|         Name ApplicantName, | ||||
|         Passport Passport, | ||||
|         DateTime BirthDate, | ||||
|         Guid CityOfBirthId, | ||||
|         string Citizenship, | ||||
|         string CitizenshipByBirth, | ||||
|         Gender Gender, | ||||
|         MaritalStatus MaritalStatus, | ||||
|         Name FatherName, | ||||
|         Name MotherName, | ||||
|         string JobTitle, | ||||
|         PlaceOfWorkModel PlaceOfWork, | ||||
|         bool IsNonResident); | ||||
| } | ||||
| @@ -0,0 +1,4 @@ | ||||
| namespace ApplicationLayer.Services.AuthServices.Requests | ||||
| { | ||||
|     public record UserLoginRequest(string Email, string Password); | ||||
| } | ||||
| @@ -0,0 +1,6 @@ | ||||
| using ApplicationLayer.GeneralNeededServices; | ||||
| using Domains.LocationDomain; | ||||
|  | ||||
| namespace ApplicationLayer.Services.Locations.NeededServices; | ||||
|  | ||||
| public interface ICitiesRepository : IGenericRepository<City>; | ||||
| @@ -0,0 +1,13 @@ | ||||
| using ApplicationLayer.GeneralNeededServices; | ||||
| using Domains.LocationDomain; | ||||
|  | ||||
| namespace ApplicationLayer.Services.Locations.NeededServices; | ||||
|  | ||||
| public interface ICountriesRepository : IGenericRepository<Country> | ||||
| { | ||||
|     /// Gets country by name | ||||
|     /// <param name="countryName">Name of country to seek</param> | ||||
|     /// <param name="cancellationToken">Cancellation Token</param> | ||||
|     /// <returns>Country or null if not found</returns> | ||||
|     Task<Country?> FindByName(string countryName, CancellationToken cancellationToken); | ||||
| } | ||||
| @@ -0,0 +1,36 @@ | ||||
| using ApplicationLayer.GeneralNeededServices; | ||||
| using ApplicationLayer.Services.Locations.NeededServices; | ||||
| using ApplicationLayer.Services.Locations.RequestHandlers.AdminRequests.Exceptions; | ||||
| using ApplicationLayer.Services.Locations.Requests; | ||||
| using Domains.LocationDomain; | ||||
|  | ||||
| namespace ApplicationLayer.Services.Locations.RequestHandlers.AdminRequests | ||||
| { | ||||
|     /// <inheritdoc cref="IEditLocationsRequestsHandler"/> | ||||
|     public class EditLocationsRequestsHandler(ICountriesRepository countries, IUnitOfWork unitOfWork) : IEditLocationsRequestsHandler | ||||
|     { | ||||
|         async Task IEditLocationsRequestsHandler.AddCountryAsync(AddCountryRequest request, CancellationToken cancellationToken) | ||||
|         { | ||||
|             if (await countries.FindByName(request.CountryName, cancellationToken) is not null) | ||||
|             { | ||||
|                 throw new CountryAlreadyExists(request.CountryName); | ||||
|             } | ||||
|  | ||||
|             if (request.Cities.Distinct().Count() < request.Cities.Length) | ||||
|             { | ||||
|                 throw new MultipleIdenticalCitiesInCountryException(); | ||||
|             } | ||||
|  | ||||
|             var country = new Country | ||||
|             { | ||||
|                 Name = request.CountryName, | ||||
|                 IsSchengen = request.IsSchengen, | ||||
|                 Cities = request.Cities.Select(cityName => new City { Name = cityName }).ToList() | ||||
|             }; | ||||
|  | ||||
|             await countries.AddAsync(country, cancellationToken); | ||||
|  | ||||
|             await unitOfWork.SaveAsync(cancellationToken); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,6 @@ | ||||
| using ApplicationLayer.GeneralExceptions; | ||||
|  | ||||
| namespace ApplicationLayer.Services.Locations.RequestHandlers.AdminRequests.Exceptions | ||||
| { | ||||
|     public class CountryAlreadyExists(string countryName) : AlreadyExistsException($"{countryName} already exists."); | ||||
| } | ||||
| @@ -0,0 +1,6 @@ | ||||
| using ApplicationLayer.GeneralExceptions; | ||||
|  | ||||
| namespace ApplicationLayer.Services.Locations.RequestHandlers.AdminRequests.Exceptions | ||||
| { | ||||
|     public class MultipleIdenticalCitiesInCountryException() : ApiException("There are multiple cities with one name in the country."); | ||||
| } | ||||
| @@ -0,0 +1,11 @@ | ||||
| using ApplicationLayer.Services.Locations.Requests; | ||||
|  | ||||
| namespace ApplicationLayer.Services.Locations.RequestHandlers.AdminRequests | ||||
| { | ||||
|     /// Handles edit requests of locations from admins | ||||
|     public interface IEditLocationsRequestsHandler | ||||
|     { | ||||
|         /// Handles add country requests | ||||
|         Task AddCountryAsync(AddCountryRequest request, CancellationToken cancellationToken); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,12 @@ | ||||
| using Domains.LocationDomain; | ||||
|  | ||||
| namespace ApplicationLayer.Services.Locations.RequestHandlers.ApplicantRequests | ||||
| { | ||||
|     /// Handles location requests | ||||
|     public interface ILocationRequestsHandler | ||||
|     { | ||||
|         /// Handle get request | ||||
|         /// <returns>List of available countries</returns> | ||||
|         Task<List<Country>> HandleGetRequestAsync(CancellationToken cancellationToken); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,14 @@ | ||||
| using ApplicationLayer.Services.Locations.NeededServices; | ||||
| using Domains.LocationDomain; | ||||
|  | ||||
| namespace ApplicationLayer.Services.Locations.RequestHandlers.ApplicantRequests | ||||
| { | ||||
|     /// <inheritdoc cref="ILocationRequestsHandler"/> | ||||
|     public class LocationRequestsHandler(ICountriesRepository countries) : ILocationRequestsHandler | ||||
|     { | ||||
|         async Task<List<Country>> ILocationRequestsHandler.HandleGetRequestAsync(CancellationToken cancellationToken) | ||||
|         { | ||||
|             return await countries.GetAllAsync(cancellationToken); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,4 @@ | ||||
| namespace ApplicationLayer.Services.Locations.Requests | ||||
| { | ||||
|     public record AddCountryRequest(string CountryName, bool IsSchengen, string[] Cities); | ||||
| } | ||||
| @@ -0,0 +1,11 @@ | ||||
| using ApplicationLayer.Services.VisaApplications.Requests; | ||||
| using Domains.VisaApplicationDomain; | ||||
|  | ||||
| namespace ApplicationLayer.Services.VisaApplications.Handlers; | ||||
|  | ||||
| public interface IVisaApplicationRequestsHandler | ||||
| { | ||||
|     Task<List<VisaApplication>> Get(CancellationToken cancellationToken); | ||||
|  | ||||
|     void HandleCreateRequest(Guid userId, VisaApplicationCreateRequest request, CancellationToken cancellationToken); | ||||
| } | ||||
| @@ -0,0 +1,57 @@ | ||||
| using ApplicationLayer.GeneralNeededServices; | ||||
| using ApplicationLayer.Services.Applicants.NeededServices; | ||||
| using ApplicationLayer.Services.Locations.NeededServices; | ||||
| using ApplicationLayer.Services.VisaApplications.Models; | ||||
| using ApplicationLayer.Services.VisaApplications.NeededServices; | ||||
| using ApplicationLayer.Services.VisaApplications.Requests; | ||||
| using Domains.VisaApplicationDomain; | ||||
|  | ||||
| namespace ApplicationLayer.Services.VisaApplications.Handlers; | ||||
|  | ||||
| /// Handles visa requests | ||||
| public class VisaApplicationRequestsHandler( | ||||
|     IVisaApplicationsRepository applications, | ||||
|     IApplicantsRepository applicants, | ||||
|     ICountriesRepository countries, | ||||
|     IUnitOfWork unitOfWork) : IVisaApplicationRequestsHandler | ||||
| { | ||||
|     public async Task<List<VisaApplication>> Get(CancellationToken cancellationToken) => await applications.GetAllAsync(cancellationToken); | ||||
|  | ||||
|     public async void HandleCreateRequest(Guid userId, VisaApplicationCreateRequest request, CancellationToken cancellationToken) | ||||
|     { | ||||
|         //TODO fix | ||||
|         //TODO mapper | ||||
|  | ||||
|         var applicant = await applicants.FindByUserIdAsync(userId, cancellationToken); | ||||
|  | ||||
|         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); | ||||
|  | ||||
|         await unitOfWork.SaveAsync(cancellationToken); | ||||
|     } | ||||
|  | ||||
|     private async Task<PastVisit> ConvertPastVisitModelToPastVisit(PastVisitModel model, CancellationToken cancellationToken) | ||||
|     { | ||||
|         return new PastVisit | ||||
|         { | ||||
|             DestinationCountry = await countries.GetByIdAsync(model.DestinationCountryId, cancellationToken), | ||||
|             StartDate = model.StartDate, | ||||
|             EndDate = model.EndDate | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,14 @@ | ||||
| namespace ApplicationLayer.Services.VisaApplications.Models | ||||
| { | ||||
|     public class PastVisitModel | ||||
|     { | ||||
|         /// First day of <see cref="PastVisitModel"/> | ||||
|         public DateTime StartDate { get; set; } | ||||
|  | ||||
|         /// Last day of <see cref="PastVisitModel"/> | ||||
|         public DateTime EndDate { get; set; } | ||||
|  | ||||
|         /// Identifier of destination country of <see cref="PastVisitModel"/> | ||||
|         public Guid DestinationCountryId { get; set; } | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,6 @@ | ||||
| using ApplicationLayer.GeneralNeededServices; | ||||
| using Domains.VisaApplicationDomain; | ||||
|  | ||||
| namespace ApplicationLayer.Services.VisaApplications.NeededServices; | ||||
|  | ||||
| public interface IVisaApplicationsRepository : IGenericRepository<VisaApplication>; | ||||
| @@ -0,0 +1,17 @@ | ||||
| using ApplicationLayer.Services.VisaApplications.Models; | ||||
| using Domains.VisaApplicationDomain; | ||||
|  | ||||
| namespace ApplicationLayer.Services.VisaApplications.Requests; | ||||
|  | ||||
| /// Model of visa request from user | ||||
| public record VisaApplicationCreateRequest( | ||||
|     ReentryPermit ReentryPermit, | ||||
|     Guid DestinationCountryId, | ||||
|     VisaCategory VisaCategory, | ||||
|     bool IsForGroup, | ||||
|     RequestedNumberOfEntries RequestedNumberOfEntries, | ||||
|     int ValidDaysRequested, | ||||
|     PastVisa[] PastVisas, | ||||
|     PermissionToDestCountry? PermissionToDestCountry, | ||||
|     PastVisitModel[] PastVisits | ||||
| ); | ||||
		Reference in New Issue
	
	Block a user