file-scoped namespaces

This commit is contained in:
2024-08-26 11:33:31 +03:00
parent bfce112a59
commit 0d8e30004d
56 changed files with 650 additions and 708 deletions

View File

@@ -1,4 +1,3 @@
namespace ApplicationLayer.GeneralExceptions
{
public class AlreadyExistsException(string message) : ApiException(message);
}
namespace ApplicationLayer.GeneralExceptions;
public class AlreadyExistsException(string message) : ApiException(message);

View File

@@ -1,4 +1,3 @@
namespace ApplicationLayer.GeneralExceptions
{
public class ApiException(string message) : Exception(message);
}
namespace ApplicationLayer.GeneralExceptions;
public class ApiException(string message) : Exception(message);

View File

@@ -1,8 +1,7 @@
namespace ApplicationLayer.InfrastructureServicesInterfaces
namespace ApplicationLayer.InfrastructureServicesInterfaces;
public interface IDateTimeProvider
{
public interface IDateTimeProvider
{
/// Returns current date and time
DateTime Now();
}
}
/// Returns current date and time
DateTime Now();
}

View File

@@ -1,8 +1,7 @@
namespace ApplicationLayer.InfrastructureServicesInterfaces
namespace ApplicationLayer.InfrastructureServicesInterfaces;
public interface IUserIdProvider
{
public interface IUserIdProvider
{
/// Returns identifier of authenticated user who sent the request
Guid GetUserId();
}
}
/// Returns identifier of authenticated user who sent the request
Guid GetUserId();
}

View File

@@ -1,50 +1,49 @@
using Domains.ApplicantDomain;
namespace ApplicationLayer.Services.Applicants.Models
namespace ApplicationLayer.Services.Applicants.Models;
/// Model of <see cref="Applicant"/>
public class ApplicantModel
{
/// Model of <see cref="Applicant"/>
public class ApplicantModel
{
/// <inheritdoc cref="Applicant.Name"/>
public Name Name { get; set; } = null!;
/// <inheritdoc cref="Applicant.Name"/>
public Name Name { get; set; } = null!;
/// <inheritdoc cref="Applicant.Passport"/>
public Passport Passport { get; set; } = null!;
/// <inheritdoc cref="Applicant.Passport"/>
public Passport Passport { get; set; } = null!;
/// <inheritdoc cref="Applicant.BirthDate"/>
public DateTime BirthDate { get; set; }
/// <inheritdoc cref="Applicant.BirthDate"/>
public DateTime BirthDate { get; set; }
/// <inheritdoc cref="Applicant.CountryOfBirth"/>
public string CountryOfBirth { get; set; } = null!;
/// <inheritdoc cref="Applicant.CountryOfBirth"/>
public string CountryOfBirth { get; set; } = null!;
/// <inheritdoc cref="Applicant.CityOfBirth"/>
public string CityOfBirth { get; set; } = null!;
/// <inheritdoc cref="Applicant.CityOfBirth"/>
public string CityOfBirth { get; set; } = null!;
/// <inheritdoc cref="Applicant.Citizenship"/>
public string Citizenship { get; set; } = null!;
/// <inheritdoc cref="Applicant.Citizenship"/>
public string Citizenship { get; set; } = null!;
/// <inheritdoc cref="Applicant.CitizenshipByBirth"/>
public string CitizenshipByBirth { get; set; } = null!;
/// <inheritdoc cref="Applicant.CitizenshipByBirth"/>
public string CitizenshipByBirth { get; set; } = null!;
/// <inheritdoc cref="Applicant.Gender"/>
public Gender Gender { get; set; }
/// <inheritdoc cref="Applicant.Gender"/>
public Gender Gender { get; set; }
/// <inheritdoc cref="Applicant.MaritalStatus"/>
public MaritalStatus MaritalStatus { get; set; }
/// <inheritdoc cref="Applicant.MaritalStatus"/>
public MaritalStatus MaritalStatus { get; set; }
/// <inheritdoc cref="Applicant.FatherName"/>
public Name FatherName { get; set; } = null!;
/// <inheritdoc cref="Applicant.FatherName"/>
public Name FatherName { get; set; } = null!;
/// <inheritdoc cref="Applicant.MotherName"/>
public Name MotherName { get; set; } = null!;
/// <inheritdoc cref="Applicant.MotherName"/>
public Name MotherName { get; set; } = null!;
/// <inheritdoc cref="Applicant.JobTitle"/>
public string JobTitle { get; set; } = null!;
/// <inheritdoc cref="Applicant.JobTitle"/>
public string JobTitle { get; set; } = null!;
/// <inheritdoc cref="Applicant.PlaceOfWork"/>
public PlaceOfWork PlaceOfWork { get; set; } = null!;
/// <inheritdoc cref="Applicant.PlaceOfWork"/>
public PlaceOfWork PlaceOfWork { get; set; } = null!;
/// <inheritdoc cref="Applicant.IsNonResident"/>
public bool IsNonResident { get; set; }
}
}
/// <inheritdoc cref="Applicant.IsNonResident"/>
public bool IsNonResident { get; set; }
}

View File

@@ -1,16 +1,15 @@
using Domains.ApplicantDomain;
namespace ApplicationLayer.Services.Applicants.Models
namespace ApplicationLayer.Services.Applicants.Models;
public class PlaceOfWorkModel
{
public class PlaceOfWorkModel
{
/// Name of hirer
public string Name { get; set; } = null!;
/// Name of hirer
public string Name { get; set; } = null!;
/// Address of hirer
public Address Address { get; set; } = null!;
/// Address of hirer
public Address Address { get; set; } = null!;
/// Phone number of hirer
public string PhoneNum { get; set; } = null!;
}
}
/// Phone number of hirer
public string PhoneNum { get; set; } = null!;
}

View File

@@ -1,4 +1,3 @@
namespace ApplicationLayer.Services.AuthServices.Common
{
public record AuthData(string Email, string Password);
}
namespace ApplicationLayer.Services.AuthServices.Common;
public record AuthData(string Email, string Password);

View File

@@ -2,12 +2,12 @@
using ApplicationLayer.Services.AuthServices.NeededServices;
using Domains.Users;
namespace ApplicationLayer.Services.AuthServices.LoginService
namespace ApplicationLayer.Services.AuthServices.LoginService;
public class DevelopmentLoginService(IUsersRepository users, ITokenGenerator tokenGenerator) : ILoginService
{
public class DevelopmentLoginService(IUsersRepository users, ITokenGenerator tokenGenerator) : ILoginService
async Task<string> ILoginService.LoginAsync(string email, string password, CancellationToken cancellationToken)
{
async Task<string> ILoginService.LoginAsync(string email, string password, CancellationToken cancellationToken)
{
if (email == "admin@mail.ru" && password == "admin")
{
var admin = new User { Role = Role.Admin };
@@ -23,5 +23,4 @@ namespace ApplicationLayer.Services.AuthServices.LoginService
return tokenGenerator.CreateToken(user);
}
}
}
}

View File

@@ -1,6 +1,5 @@
using ApplicationLayer.GeneralExceptions;
namespace ApplicationLayer.Services.AuthServices.LoginService.Exceptions
{
public class IncorrectLoginDataException() : ApiException("Incorrect email or password");
}
namespace ApplicationLayer.Services.AuthServices.LoginService.Exceptions;
public class IncorrectLoginDataException() : ApiException("Incorrect email or password");

View File

@@ -1,10 +1,9 @@
namespace ApplicationLayer.Services.AuthServices.LoginService
namespace ApplicationLayer.Services.AuthServices.LoginService;
/// Handles login requests
public interface ILoginService
{
/// Handles login requests
public interface ILoginService
{
/// Handle login request
/// <returns>JWT-token</returns>
Task<string> LoginAsync(string email, string password, CancellationToken cancellationToken);
}
}
/// Handle login request
/// <returns>JWT-token</returns>
Task<string> LoginAsync(string email, string password, CancellationToken cancellationToken);
}

View File

@@ -1,13 +1,13 @@
using ApplicationLayer.Services.AuthServices.LoginService.Exceptions;
using ApplicationLayer.Services.AuthServices.NeededServices;
namespace ApplicationLayer.Services.AuthServices.LoginService
namespace ApplicationLayer.Services.AuthServices.LoginService;
/// <inheritdoc cref="ILoginService"/>
public class LoginService(IUsersRepository users, ITokenGenerator tokenGenerator) : ILoginService
{
/// <inheritdoc cref="ILoginService"/>
public class LoginService(IUsersRepository users, ITokenGenerator tokenGenerator) : ILoginService
async Task<string> ILoginService.LoginAsync(string email, string password, CancellationToken cancellationToken)
{
async Task<string> ILoginService.LoginAsync(string email, string password, CancellationToken cancellationToken)
{
var user = await users.FindByEmailAsync(email, cancellationToken);
if (user is null || user.Password != password)
{
@@ -16,5 +16,4 @@ namespace ApplicationLayer.Services.AuthServices.LoginService
return tokenGenerator.CreateToken(user);
}
}
}
}

View File

@@ -1,9 +1,8 @@
using Domains.Users;
namespace ApplicationLayer.Services.AuthServices.NeededServices
namespace ApplicationLayer.Services.AuthServices.NeededServices;
public interface ITokenGenerator
{
public interface ITokenGenerator
{
string CreateToken(User user);
}
}
string CreateToken(User user);
}

View File

@@ -1,21 +1,20 @@
using ApplicationLayer.InfrastructureServicesInterfaces;
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);
namespace ApplicationLayer.Services.AuthServices.NeededServices;
/// Returns all accounts with specific role
/// <param name="role">role</param>
/// <param name="cancellationToken">cancellation token</param>
/// <returns>list of accounts</returns>
Task<List<User>> GetAllOfRoleAsync(Role role, CancellationToken cancellationToken);
}
}
/// 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);
/// Returns all accounts with specific role
/// <param name="role">role</param>
/// <param name="cancellationToken">cancellation token</param>
/// <returns>list of accounts</returns>
Task<List<User>> GetAllOfRoleAsync(Role role, CancellationToken cancellationToken);
}

View File

@@ -1,14 +1,13 @@
using ApplicationLayer.Services.AuthServices.Requests;
namespace ApplicationLayer.Services.AuthServices.RegisterService
{
/// Handles register request
public interface IRegisterService
{
/// Handle <see cref="RegisterApplicantRequest"/>
Task RegisterApplicant(RegisterApplicantRequest request, CancellationToken cancellationToken);
namespace ApplicationLayer.Services.AuthServices.RegisterService;
/// Handles <see cref="RegisterRequest"/> and adds approving authority account
Task RegisterAuthority(RegisterRequest request, CancellationToken cancellationToken);
}
}
/// Handles register request
public interface IRegisterService
{
/// Handle <see cref="RegisterApplicantRequest"/>
Task RegisterApplicant(RegisterApplicantRequest request, CancellationToken cancellationToken);
/// Handles <see cref="RegisterRequest"/> and adds approving authority account
Task RegisterAuthority(RegisterRequest request, CancellationToken cancellationToken);
}

View File

@@ -6,37 +6,36 @@ using AutoMapper;
using Domains.ApplicantDomain;
using Domains.Users;
namespace ApplicationLayer.Services.AuthServices.RegisterService
namespace ApplicationLayer.Services.AuthServices.RegisterService;
/// <inheritdoc cref="IRegisterService"/>
public class RegisterService(
IUsersRepository users,
IApplicantsRepository applicants,
IUnitOfWork unitOfWork,
IMapper mapper) : IRegisterService
{
/// <inheritdoc cref="IRegisterService"/>
public class RegisterService(
IUsersRepository users,
IApplicantsRepository applicants,
IUnitOfWork unitOfWork,
IMapper mapper) : IRegisterService
async Task IRegisterService.RegisterApplicant(RegisterApplicantRequest request, CancellationToken cancellationToken)
{
async Task IRegisterService.RegisterApplicant(RegisterApplicantRequest request, CancellationToken cancellationToken)
{
var user = mapper.Map<User>(request.AuthData);
user.Role = Role.Applicant;
var user = mapper.Map<User>(request.AuthData);
user.Role = Role.Applicant;
var applicant = mapper.Map<Applicant>(request);
applicant.UserId = user.Id;
var applicant = mapper.Map<Applicant>(request);
applicant.UserId = user.Id;
await users.AddAsync(user, cancellationToken);
await applicants.AddAsync(applicant, cancellationToken);
await users.AddAsync(user, cancellationToken);
await applicants.AddAsync(applicant, cancellationToken);
await unitOfWork.SaveAsync(cancellationToken);
}
async Task IRegisterService.RegisterAuthority(RegisterRequest request, CancellationToken cancellationToken)
{
var user = mapper.Map<User>(request.AuthData);
user.Role = Role.ApprovingAuthority;
await users.AddAsync(user, cancellationToken);
await unitOfWork.SaveAsync(cancellationToken);
}
await unitOfWork.SaveAsync(cancellationToken);
}
}
async Task IRegisterService.RegisterAuthority(RegisterRequest request, CancellationToken cancellationToken)
{
var user = mapper.Map<User>(request.AuthData);
user.Role = Role.ApprovingAuthority;
await users.AddAsync(user, cancellationToken);
await unitOfWork.SaveAsync(cancellationToken);
}
}

View File

@@ -2,22 +2,21 @@
using ApplicationLayer.Services.AuthServices.Common;
using Domains.ApplicantDomain;
namespace ApplicationLayer.Services.AuthServices.Requests
{
public record RegisterApplicantRequest(
AuthData AuthData,
Name ApplicantName,
Passport Passport,
DateTime BirthDate,
string CityOfBirth,
string CountryOfBirth,
string Citizenship,
string CitizenshipByBirth,
Gender Gender,
MaritalStatus MaritalStatus,
Name FatherName,
Name MotherName,
string JobTitle,
PlaceOfWorkModel PlaceOfWork,
bool IsNonResident) : RegisterRequest(AuthData);
}
namespace ApplicationLayer.Services.AuthServices.Requests;
public record RegisterApplicantRequest(
AuthData AuthData,
Name ApplicantName,
Passport Passport,
DateTime BirthDate,
string CityOfBirth,
string CountryOfBirth,
string Citizenship,
string CitizenshipByBirth,
Gender Gender,
MaritalStatus MaritalStatus,
Name FatherName,
Name MotherName,
string JobTitle,
PlaceOfWorkModel PlaceOfWork,
bool IsNonResident) : RegisterRequest(AuthData);

View File

@@ -1,6 +1,5 @@
using ApplicationLayer.Services.AuthServices.Common;
namespace ApplicationLayer.Services.AuthServices.Requests
{
public record RegisterRequest(AuthData AuthData);
}
namespace ApplicationLayer.Services.AuthServices.Requests;
public record RegisterRequest(AuthData AuthData);

View File

@@ -3,12 +3,12 @@ using ApplicationLayer.Services.AuthServices.NeededServices;
using Domains;
using FluentValidation;
namespace ApplicationLayer.Services.AuthServices.Requests.Validation
namespace ApplicationLayer.Services.AuthServices.Requests.Validation;
public class AuthDataValidator : AbstractValidator<AuthData>
{
public class AuthDataValidator : AbstractValidator<AuthData>
public AuthDataValidator(IUsersRepository users)
{
public AuthDataValidator(IUsersRepository users)
{
RuleFor(d => d.Email)
.NotEmpty()
.WithMessage("Email can not be empty")
@@ -28,5 +28,4 @@ namespace ApplicationLayer.Services.AuthServices.Requests.Validation
.MaximumLength(ConfigurationConstraints.PasswordLength)
.WithMessage($"Password length must be less than {ConfigurationConstraints.PasswordLength}");
}
}
}
}

View File

@@ -2,12 +2,12 @@
using Domains.ApplicantDomain;
using FluentValidation;
namespace ApplicationLayer.Services.AuthServices.Requests.Validation
namespace ApplicationLayer.Services.AuthServices.Requests.Validation;
public class NameValidator : AbstractValidator<Name>
{
public class NameValidator : AbstractValidator<Name>
public NameValidator()
{
public NameValidator()
{
RuleFor(m => m.FirstName)
.NotEmpty()
.WithMessage("First Name can not be empty")
@@ -24,5 +24,4 @@ namespace ApplicationLayer.Services.AuthServices.Requests.Validation
.MaximumLength(ConfigurationConstraints.NameLength)
.WithMessage($"Patronymic length must be less than {ConfigurationConstraints.NameLength}");
}
}
}
}

View File

@@ -3,12 +3,12 @@ using Domains;
using Domains.ApplicantDomain;
using FluentValidation;
namespace ApplicationLayer.Services.AuthServices.Requests.Validation
namespace ApplicationLayer.Services.AuthServices.Requests.Validation;
public class PassportValidator : AbstractValidator<Passport>
{
public class PassportValidator : AbstractValidator<Passport>
public PassportValidator(IDateTimeProvider dateTimeProvider)
{
public PassportValidator(IDateTimeProvider dateTimeProvider)
{
RuleFor(r => r.Issuer)
.NotEmpty()
.WithMessage("Passport issuer can not be empty")
@@ -33,5 +33,4 @@ namespace ApplicationLayer.Services.AuthServices.Requests.Validation
.LessThanOrEqualTo(dateTimeProvider.Now())
.WithMessage("Passport issue date must be in past");
}
}
}
}

View File

@@ -2,12 +2,12 @@
using Domains;
using FluentValidation;
namespace ApplicationLayer.Services.AuthServices.Requests.Validation
namespace ApplicationLayer.Services.AuthServices.Requests.Validation;
public class PlaceOfWorkModelValidator : AbstractValidator<PlaceOfWorkModel>
{
public class PlaceOfWorkModelValidator : AbstractValidator<PlaceOfWorkModel>
public PlaceOfWorkModelValidator()
{
public PlaceOfWorkModelValidator()
{
RuleFor(p => p.Name)
.NotEmpty()
.WithMessage("Place of work name can not be empty")
@@ -46,5 +46,4 @@ namespace ApplicationLayer.Services.AuthServices.Requests.Validation
.MaximumLength(ConfigurationConstraints.CountryNameLength)
.WithMessage($"Building of place of work length must be less than {ConfigurationConstraints.BuildingNumberLength}");
}
}
}
}

View File

@@ -5,17 +5,17 @@ using Domains;
using Domains.ApplicantDomain;
using FluentValidation;
namespace ApplicationLayer.Services.AuthServices.Requests.Validation
namespace ApplicationLayer.Services.AuthServices.Requests.Validation;
public class RegisterApplicantRequestValidator : AbstractValidator<RegisterApplicantRequest>
{
public class RegisterApplicantRequestValidator : AbstractValidator<RegisterApplicantRequest>
public RegisterApplicantRequestValidator(
IDateTimeProvider dateTimeProvider,
IValidator<Name> nameValidator,
IValidator<AuthData> authDataValidator,
IValidator<Passport> passportValidator,
IValidator<PlaceOfWorkModel> placeOfWorkModelValidator)
{
public RegisterApplicantRequestValidator(
IDateTimeProvider dateTimeProvider,
IValidator<Name> nameValidator,
IValidator<AuthData> authDataValidator,
IValidator<Passport> passportValidator,
IValidator<PlaceOfWorkModel> placeOfWorkModelValidator)
{
RuleFor(r => r.AuthData)
.SetValidator(authDataValidator);
@@ -74,5 +74,4 @@ namespace ApplicationLayer.Services.AuthServices.Requests.Validation
RuleFor(r => r.PlaceOfWork)
.SetValidator(placeOfWorkModelValidator);
}
}
}
}

View File

@@ -1,23 +1,22 @@
using ApplicationLayer.Services.Users.Requests;
using Domains.Users;
namespace ApplicationLayer.Services.Users
namespace ApplicationLayer.Services.Users;
/// user accounts service
public interface IUsersService
{
/// user accounts service
public interface IUsersService
{
/// Returns all user accounts with role of approving authority
/// <param name="cancellationToken">Cancellation token</param>
Task<List<User>> GetAuthoritiesAccountsAsync(CancellationToken cancellationToken);
/// Returns all user accounts with role of approving authority
/// <param name="cancellationToken">Cancellation token</param>
Task<List<User>> GetAuthoritiesAccountsAsync(CancellationToken cancellationToken);
/// Changes authentication data for an account
/// <param name="request"> Request object with identifier of user and new authentication data</param>
/// <param name="cancellationToken">Cancellation token</param>
Task ChangeAccountAuthDataAsync(ChangeUserAuthDataRequest request, CancellationToken cancellationToken);
/// Changes authentication data for an account
/// <param name="request"> Request object with identifier of user and new authentication data</param>
/// <param name="cancellationToken">Cancellation token</param>
Task ChangeAccountAuthDataAsync(ChangeUserAuthDataRequest request, CancellationToken cancellationToken);
/// Removes user account
/// <param name="userId">Identifier of account</param>
/// <param name="cancellationToken">Cancellation token</param>
Task RemoveUserAccount(Guid userId, CancellationToken cancellationToken);
}
}
/// Removes user account
/// <param name="userId">Identifier of account</param>
/// <param name="cancellationToken">Cancellation token</param>
Task RemoveUserAccount(Guid userId, CancellationToken cancellationToken);
}

View File

@@ -1,6 +1,5 @@
using ApplicationLayer.Services.AuthServices.Common;
namespace ApplicationLayer.Services.Users.Requests
{
public record ChangeUserAuthDataRequest(Guid UserId, AuthData NewAuthData);
}
namespace ApplicationLayer.Services.Users.Requests;
public record ChangeUserAuthDataRequest(Guid UserId, AuthData NewAuthData);

View File

@@ -3,17 +3,17 @@ using ApplicationLayer.Services.AuthServices.NeededServices;
using ApplicationLayer.Services.Users.Requests;
using Domains.Users;
namespace ApplicationLayer.Services.Users
namespace ApplicationLayer.Services.Users;
public class UsersService(IUsersRepository users, IUnitOfWork unitOfWork) : IUsersService
{
public class UsersService(IUsersRepository users, IUnitOfWork unitOfWork) : IUsersService
async Task<List<User>> IUsersService.GetAuthoritiesAccountsAsync(CancellationToken cancellationToken)
{
async Task<List<User>> IUsersService.GetAuthoritiesAccountsAsync(CancellationToken cancellationToken)
{
return await users.GetAllOfRoleAsync(Role.ApprovingAuthority, cancellationToken);
}
async Task IUsersService.ChangeAccountAuthDataAsync(ChangeUserAuthDataRequest request, CancellationToken cancellationToken)
{
async Task IUsersService.ChangeAccountAuthDataAsync(ChangeUserAuthDataRequest request, CancellationToken cancellationToken)
{
var user = await users.GetByIdAsync(request.UserId, cancellationToken);
user.Email = request.NewAuthData.Email;
@@ -23,12 +23,11 @@ namespace ApplicationLayer.Services.Users
await unitOfWork.SaveAsync(cancellationToken);
}
async Task IUsersService.RemoveUserAccount(Guid userId, CancellationToken cancellationToken)
{
async Task IUsersService.RemoveUserAccount(Guid userId, CancellationToken cancellationToken)
{
var user = await users.GetByIdAsync(userId, cancellationToken);
users.Remove(user);
await unitOfWork.SaveAsync(cancellationToken);
}
}
}
}

View File

@@ -1,6 +1,5 @@
using ApplicationLayer.GeneralExceptions;
namespace ApplicationLayer.Services.VisaApplications.Exceptions
{
public class ApplicationAlreadyProcessedException() : ApiException("This application already processed or closed by applicant.");
}
namespace ApplicationLayer.Services.VisaApplications.Exceptions;
public class ApplicationAlreadyProcessedException() : ApiException("This application already processed or closed by applicant.");

View File

@@ -1,8 +1,7 @@
namespace ApplicationLayer.Services.VisaApplications.Models
namespace ApplicationLayer.Services.VisaApplications.Models;
public enum AuthorityRequestStatuses
{
public enum AuthorityRequestStatuses
{
Approved,
Rejected
}
}
Approved,
Rejected
}

View File

@@ -1,44 +1,43 @@
using Domains.VisaApplicationDomain;
namespace ApplicationLayer.Services.VisaApplications.Models
namespace ApplicationLayer.Services.VisaApplications.Models;
/// Model of <see cref="VisaApplication"/>
public class VisaApplicationModelForApplicant
{
/// Model of <see cref="VisaApplication"/>
public class VisaApplicationModelForApplicant
{
/// <inheritdoc cref="VisaApplication.Id"/>
public Guid Id { get; set; }
/// <inheritdoc cref="VisaApplication.Id"/>
public Guid Id { get; set; }
/// <inheritdoc cref="VisaApplication.Status"/>
public ApplicationStatus Status { get; set; }
/// <inheritdoc cref="VisaApplication.Status"/>
public ApplicationStatus Status { get; set; }
/// <inheritdoc cref="VisaApplication.ReentryPermit"/>
public ReentryPermit? ReentryPermit { get; set; }
/// <inheritdoc cref="VisaApplication.ReentryPermit"/>
public ReentryPermit? ReentryPermit { get; set; }
/// <inheritdoc cref="VisaApplication.DestinationCountry"/>
public string DestinationCountry { get; set; } = null!;
/// <inheritdoc cref="VisaApplication.DestinationCountry"/>
public string DestinationCountry { get; set; } = null!;
/// <inheritdoc cref="VisaApplication.PastVisas"/>
public List<PastVisa> PastVisas { get; set; } = null!;
/// <inheritdoc cref="VisaApplication.PastVisas"/>
public List<PastVisa> PastVisas { get; set; } = null!;
/// <inheritdoc cref="VisaApplication.PermissionToDestCountry"/>
public PermissionToDestCountry? PermissionToDestCountry { get; set; }
/// <inheritdoc cref="VisaApplication.PermissionToDestCountry"/>
public PermissionToDestCountry? PermissionToDestCountry { get; set; }
/// <inheritdoc cref="VisaApplication.PastVisits"/>
public List<PastVisit> PastVisits { get; set; } = null!;
/// <inheritdoc cref="VisaApplication.PastVisits"/>
public List<PastVisit> PastVisits { get; set; } = null!;
/// <inheritdoc cref="VisaApplication.VisaCategory"/>
public VisaCategory VisaCategory { get; set; }
/// <inheritdoc cref="VisaApplication.VisaCategory"/>
public VisaCategory VisaCategory { get; set; }
/// <inheritdoc cref="VisaApplication.ForGroup"/>
public bool ForGroup { get; set; }
/// <inheritdoc cref="VisaApplication.ForGroup"/>
public bool ForGroup { get; set; }
/// <inheritdoc cref="VisaApplication.RequestedNumberOfEntries"/>
public RequestedNumberOfEntries RequestedNumberOfEntries { get; set; }
/// <inheritdoc cref="VisaApplication.RequestedNumberOfEntries"/>
public RequestedNumberOfEntries RequestedNumberOfEntries { get; set; }
/// <inheritdoc cref="VisaApplication.RequestDate"/>
public DateTime RequestDate { get; set; }
/// <inheritdoc cref="VisaApplication.RequestDate"/>
public DateTime RequestDate { get; set; }
/// <inheritdoc cref="VisaApplication.ValidDaysRequested"/>
public int ValidDaysRequested { get; set; }
}
}
/// <inheritdoc cref="VisaApplication.ValidDaysRequested"/>
public int ValidDaysRequested { get; set; }
}

View File

@@ -1,47 +1,46 @@
using ApplicationLayer.Services.Applicants.Models;
using Domains.VisaApplicationDomain;
namespace ApplicationLayer.Services.VisaApplications.Models
namespace ApplicationLayer.Services.VisaApplications.Models;
/// Model of <see cref="VisaApplication"/> with applicant property
public class VisaApplicationModelForAuthority
{
/// Model of <see cref="VisaApplication"/> with applicant property
public class VisaApplicationModelForAuthority
{
/// <inheritdoc cref="VisaApplication.Id"/>
public Guid Id { get; set; }
/// <inheritdoc cref="VisaApplication.Id"/>
public Guid Id { get; set; }
/// Applicant of application
public ApplicantModel Applicant { get; set; } = null!;
/// Applicant of application
public ApplicantModel Applicant { get; set; } = null!;
/// <inheritdoc cref="VisaApplication.Status"/>
public ApplicationStatus Status { get; set; }
/// <inheritdoc cref="VisaApplication.Status"/>
public ApplicationStatus Status { get; set; }
/// <inheritdoc cref="VisaApplication.ReentryPermit"/>
public ReentryPermit? ReentryPermit { get; set; }
/// <inheritdoc cref="VisaApplication.ReentryPermit"/>
public ReentryPermit? ReentryPermit { get; set; }
/// <inheritdoc cref="VisaApplication.DestinationCountry"/>
public string DestinationCountry { get; set; } = null!;
/// <inheritdoc cref="VisaApplication.DestinationCountry"/>
public string DestinationCountry { get; set; } = null!;
/// <inheritdoc cref="VisaApplication.PastVisas"/>
public List<PastVisa> PastVisas { get; set; } = null!;
/// <inheritdoc cref="VisaApplication.PastVisas"/>
public List<PastVisa> PastVisas { get; set; } = null!;
/// <inheritdoc cref="VisaApplication.PermissionToDestCountry"/>
public PermissionToDestCountry? PermissionToDestCountry { get; set; }
/// <inheritdoc cref="VisaApplication.PermissionToDestCountry"/>
public PermissionToDestCountry? PermissionToDestCountry { get; set; }
public List<PastVisit> PastVisits { get; set; } = null!;
public List<PastVisit> PastVisits { get; set; } = null!;
/// <inheritdoc cref="VisaApplication.VisaCategory"/>
public VisaCategory VisaCategory { get; set; }
/// <inheritdoc cref="VisaApplication.VisaCategory"/>
public VisaCategory VisaCategory { get; set; }
/// <inheritdoc cref="VisaApplication.ForGroup"/>
public bool ForGroup { get; set; }
/// <inheritdoc cref="VisaApplication.ForGroup"/>
public bool ForGroup { get; set; }
/// <inheritdoc cref="VisaApplication.RequestedNumberOfEntries"/>
public RequestedNumberOfEntries RequestedNumberOfEntries { get; set; }
/// <inheritdoc cref="VisaApplication.RequestedNumberOfEntries"/>
public RequestedNumberOfEntries RequestedNumberOfEntries { get; set; }
/// <inheritdoc cref="VisaApplication.RequestDate"/>
public DateTime RequestDate { get; set; }
/// <inheritdoc cref="VisaApplication.RequestDate"/>
public DateTime RequestDate { get; set; }
/// <inheritdoc cref="VisaApplication.ValidDaysRequested"/>
public int ValidDaysRequested { get; set; }
}
}
/// <inheritdoc cref="VisaApplication.ValidDaysRequested"/>
public int ValidDaysRequested { get; set; }
}

View File

@@ -2,12 +2,12 @@
using Domains.VisaApplicationDomain;
using FluentValidation;
namespace ApplicationLayer.Services.VisaApplications.Requests.Validation
namespace ApplicationLayer.Services.VisaApplications.Requests.Validation;
public class PastVisaValidator : AbstractValidator<PastVisa>
{
public class PastVisaValidator : AbstractValidator<PastVisa>
public PastVisaValidator(IDateTimeProvider dateTimeProvider)
{
public PastVisaValidator(IDateTimeProvider dateTimeProvider)
{
RuleFor(v => v.ExpirationDate)
.NotEmpty()
.WithMessage("Expiration date of past visa can not be empty")
@@ -24,5 +24,4 @@ namespace ApplicationLayer.Services.VisaApplications.Requests.Validation
.NotEmpty()
.WithMessage("Name of past visa can not be empty");
}
}
}
}

View File

@@ -3,12 +3,12 @@ using Domains;
using Domains.VisaApplicationDomain;
using FluentValidation;
namespace ApplicationLayer.Services.VisaApplications.Requests.Validation
namespace ApplicationLayer.Services.VisaApplications.Requests.Validation;
public class PastVisitValidator : AbstractValidator<PastVisit>
{
public class PastVisitValidator : AbstractValidator<PastVisit>
public PastVisitValidator(IDateTimeProvider dateTimeProvider)
{
public PastVisitValidator(IDateTimeProvider dateTimeProvider)
{
RuleFor(v => v.StartDate)
.NotEmpty()
.WithMessage("Start date of past visit can not be empty")
@@ -27,5 +27,4 @@ namespace ApplicationLayer.Services.VisaApplications.Requests.Validation
.MaximumLength(ConfigurationConstraints.CountryNameLength)
.WithMessage($"Destination Country of past visit length must be less than {ConfigurationConstraints.CountryNameLength}");
}
}
}
}

View File

@@ -3,12 +3,12 @@ using Domains;
using Domains.VisaApplicationDomain;
using FluentValidation;
namespace ApplicationLayer.Services.VisaApplications.Requests.Validation
namespace ApplicationLayer.Services.VisaApplications.Requests.Validation;
public class PermissionToDestCountryValidator : AbstractValidator<PermissionToDestCountry?>
{
public class PermissionToDestCountryValidator : AbstractValidator<PermissionToDestCountry?>
public PermissionToDestCountryValidator(IDateTimeProvider dateTimeProvider)
{
public PermissionToDestCountryValidator(IDateTimeProvider dateTimeProvider)
{
RuleFor(p => p!.ExpirationDate)
.NotEmpty()
.WithMessage("Expiration date of permission to destination Country can not be empty")
@@ -21,5 +21,4 @@ namespace ApplicationLayer.Services.VisaApplications.Requests.Validation
.MaximumLength(ConfigurationConstraints.IssuerNameLength)
.WithMessage($"Issuer of permission to destination Country length must be less than {ConfigurationConstraints.IssuerNameLength}");
}
}
}
}

View File

@@ -3,12 +3,12 @@ using Domains;
using Domains.VisaApplicationDomain;
using FluentValidation;
namespace ApplicationLayer.Services.VisaApplications.Requests.Validation
namespace ApplicationLayer.Services.VisaApplications.Requests.Validation;
public class ReentryPermitValidator : AbstractValidator<ReentryPermit?>
{
public class ReentryPermitValidator : AbstractValidator<ReentryPermit?>
public ReentryPermitValidator(IDateTimeProvider dateTimeProvider)
{
public ReentryPermitValidator(IDateTimeProvider dateTimeProvider)
{
RuleFor(p => p!.Number)
.NotEmpty()
.WithMessage("Re-entry permit number can not be empty")
@@ -21,5 +21,4 @@ namespace ApplicationLayer.Services.VisaApplications.Requests.Validation
.GreaterThan(dateTimeProvider.Now())
.WithMessage("Re-entry permit must not be expired");
}
}
}
}

View File

@@ -4,51 +4,50 @@ using Domains;
using Domains.VisaApplicationDomain;
using FluentValidation;
namespace ApplicationLayer.Services.VisaApplications.Requests.Validation
namespace ApplicationLayer.Services.VisaApplications.Requests.Validation;
public class VisaApplicationCreateRequestValidator : AbstractValidator<VisaApplicationCreateRequest>
{
public class VisaApplicationCreateRequestValidator : AbstractValidator<VisaApplicationCreateRequest>
public VisaApplicationCreateRequestValidator(
IValidator<ReentryPermit?> reentryPermitValidator,
IValidator<PastVisa> pastVisaValidator,
IValidator<PermissionToDestCountry?> permissionToDestCountryValidator,
IValidator<PastVisit> pastVisitValidator,
IApplicantsRepository applicants,
IUserIdProvider userIdProvider)
{
public VisaApplicationCreateRequestValidator(
IValidator<ReentryPermit?> reentryPermitValidator,
IValidator<PastVisa> pastVisaValidator,
IValidator<PermissionToDestCountry?> permissionToDestCountryValidator,
IValidator<PastVisit> pastVisitValidator,
IApplicantsRepository applicants,
IUserIdProvider userIdProvider)
{
RuleFor(r => r.ReentryPermit)
.NotEmpty()
.WithMessage("Non-residents must provide re-entry permission")
.SetValidator(reentryPermitValidator)
.WhenAsync(async (r, ct) =>
await applicants.IsApplicantNonResidentByUserId(userIdProvider.GetUserId(), ct));
RuleFor(r => r.ReentryPermit)
.NotEmpty()
.WithMessage("Non-residents must provide re-entry permission")
.SetValidator(reentryPermitValidator)
.WhenAsync(async (r, ct) =>
await applicants.IsApplicantNonResidentByUserId(userIdProvider.GetUserId(), ct));
RuleFor(r => r.DestinationCountry)
.NotEmpty()
.WithMessage("Destination country can not be empty");
RuleFor(r => r.DestinationCountry)
.NotEmpty()
.WithMessage("Destination country can not be empty");
RuleFor(r => r.VisaCategory)
.IsInEnum();
RuleFor(r => r.VisaCategory)
.IsInEnum();
RuleFor(r => r.RequestedNumberOfEntries)
.IsInEnum();
RuleFor(r => r.RequestedNumberOfEntries)
.IsInEnum();
RuleFor(r => r.ValidDaysRequested)
.GreaterThan(0)
.WithMessage($"Valid days requested should be positive number and less than {ConfigurationConstraints.MaxValidDays}")
.LessThanOrEqualTo(ConfigurationConstraints.MaxValidDays)
.WithMessage($"Valid days requested must be less than or equal to {ConfigurationConstraints.MaxValidDays}");
RuleFor(r => r.ValidDaysRequested)
.GreaterThan(0)
.WithMessage($"Valid days requested should be positive number and less than {ConfigurationConstraints.MaxValidDays}")
.LessThanOrEqualTo(ConfigurationConstraints.MaxValidDays)
.WithMessage($"Valid days requested must be less than or equal to {ConfigurationConstraints.MaxValidDays}");
RuleForEach(r => r.PastVisas)
.SetValidator(pastVisaValidator);
RuleForEach(r => r.PastVisas)
.SetValidator(pastVisaValidator);
When(r => r.VisaCategory == VisaCategory.Transit,
() =>
RuleFor(r => r.PermissionToDestCountry)
.SetValidator(permissionToDestCountryValidator));
When(r => r.VisaCategory == VisaCategory.Transit,
() =>
RuleFor(r => r.PermissionToDestCountry)
.SetValidator(permissionToDestCountryValidator));
RuleForEach(r => r.PastVisits)
.SetValidator(pastVisitValidator);
}
RuleForEach(r => r.PastVisits)
.SetValidator(pastVisitValidator);
}
}
}