Added models for presentation layer with data annotations
This commit is contained in:
@@ -0,0 +1,27 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using Domains;
|
||||||
|
|
||||||
|
namespace ApplicationLayer.Services.Applicants.Models;
|
||||||
|
|
||||||
|
public class AddressModel
|
||||||
|
{
|
||||||
|
/// Country part of address
|
||||||
|
[Required]
|
||||||
|
[MaxLength(ConfigurationConstraints.CountryNameLength)]
|
||||||
|
public string Country { get; set; } = null!;
|
||||||
|
|
||||||
|
/// City part of address
|
||||||
|
[Required]
|
||||||
|
[MaxLength(ConfigurationConstraints.CityNameLength)]
|
||||||
|
public string City { get; set; } = null!;
|
||||||
|
|
||||||
|
/// Street part of address
|
||||||
|
[Required]
|
||||||
|
[MaxLength(ConfigurationConstraints.StreetNameLength)]
|
||||||
|
public string Street { get; set; } = null!;
|
||||||
|
|
||||||
|
/// Building part of address
|
||||||
|
[Required]
|
||||||
|
[MaxLength(ConfigurationConstraints.BuildingNumberLength)]
|
||||||
|
public string Building { get; set; } = null!;
|
||||||
|
}
|
||||||
@@ -2,48 +2,49 @@
|
|||||||
|
|
||||||
namespace ApplicationLayer.Services.Applicants.Models;
|
namespace ApplicationLayer.Services.Applicants.Models;
|
||||||
|
|
||||||
/// Model of <see cref="Applicant"/>
|
/// Model of
|
||||||
|
/// <see cref="Applicant" />
|
||||||
public class ApplicantModel
|
public class ApplicantModel
|
||||||
{
|
{
|
||||||
/// <inheritdoc cref="Applicant.Name"/>
|
/// <inheritdoc cref="Applicant.Name" />
|
||||||
public Name Name { get; set; } = null!;
|
public Name Name { get; set; } = null!;
|
||||||
|
|
||||||
/// <inheritdoc cref="Applicant.Passport"/>
|
/// <inheritdoc cref="Applicant.Passport" />
|
||||||
public Passport Passport { get; set; } = null!;
|
public Passport Passport { get; set; } = null!;
|
||||||
|
|
||||||
/// <inheritdoc cref="Applicant.BirthDate"/>
|
/// <inheritdoc cref="Applicant.BirthDate" />
|
||||||
public DateTime BirthDate { get; set; }
|
public DateTime BirthDate { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="Applicant.CountryOfBirth"/>
|
/// <inheritdoc cref="Applicant.CountryOfBirth" />
|
||||||
public string CountryOfBirth { get; set; } = null!;
|
public string CountryOfBirth { get; set; } = null!;
|
||||||
|
|
||||||
/// <inheritdoc cref="Applicant.CityOfBirth"/>
|
/// <inheritdoc cref="Applicant.CityOfBirth" />
|
||||||
public string CityOfBirth { get; set; } = null!;
|
public string CityOfBirth { get; set; } = null!;
|
||||||
|
|
||||||
/// <inheritdoc cref="Applicant.Citizenship"/>
|
/// <inheritdoc cref="Applicant.Citizenship" />
|
||||||
public string Citizenship { get; set; } = null!;
|
public string Citizenship { get; set; } = null!;
|
||||||
|
|
||||||
/// <inheritdoc cref="Applicant.CitizenshipByBirth"/>
|
/// <inheritdoc cref="Applicant.CitizenshipByBirth" />
|
||||||
public string CitizenshipByBirth { get; set; } = null!;
|
public string CitizenshipByBirth { get; set; } = null!;
|
||||||
|
|
||||||
/// <inheritdoc cref="Applicant.Gender"/>
|
/// <inheritdoc cref="Applicant.Gender" />
|
||||||
public Gender Gender { get; set; }
|
public Gender Gender { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="Applicant.MaritalStatus"/>
|
/// <inheritdoc cref="Applicant.MaritalStatus" />
|
||||||
public MaritalStatus MaritalStatus { get; set; }
|
public MaritalStatus MaritalStatus { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="Applicant.FatherName"/>
|
/// <inheritdoc cref="Applicant.FatherName" />
|
||||||
public Name FatherName { get; set; } = null!;
|
public Name FatherName { get; set; } = null!;
|
||||||
|
|
||||||
/// <inheritdoc cref="Applicant.MotherName"/>
|
/// <inheritdoc cref="Applicant.MotherName" />
|
||||||
public Name MotherName { get; set; } = null!;
|
public Name MotherName { get; set; } = null!;
|
||||||
|
|
||||||
/// <inheritdoc cref="Applicant.JobTitle"/>
|
/// <inheritdoc cref="Applicant.JobTitle" />
|
||||||
public string JobTitle { get; set; } = null!;
|
public string JobTitle { get; set; } = null!;
|
||||||
|
|
||||||
/// <inheritdoc cref="Applicant.PlaceOfWork"/>
|
/// <inheritdoc cref="Applicant.PlaceOfWork" />
|
||||||
public PlaceOfWork PlaceOfWork { get; set; } = null!;
|
public PlaceOfWork PlaceOfWork { get; set; } = null!;
|
||||||
|
|
||||||
/// <inheritdoc cref="Applicant.IsNonResident"/>
|
/// <inheritdoc cref="Applicant.IsNonResident" />
|
||||||
public bool IsNonResident { get; set; }
|
public bool IsNonResident { get; set; }
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using Domains;
|
||||||
|
|
||||||
|
namespace ApplicationLayer.Services.Applicants.Models;
|
||||||
|
|
||||||
|
/// Model of name for presentation layer
|
||||||
|
public class NameModel
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
[MaxLength(ConfigurationConstraints.NameLength)]
|
||||||
|
public string FirstName { get; set; } = null!;
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[MaxLength(ConfigurationConstraints.NameLength)]
|
||||||
|
public string Surname { get; set; } = null!;
|
||||||
|
|
||||||
|
[MaxLength(ConfigurationConstraints.NameLength)]
|
||||||
|
public string? Patronymic { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using Domains;
|
||||||
|
|
||||||
|
namespace ApplicationLayer.Services.Applicants.Models;
|
||||||
|
|
||||||
|
/// Model of passport fpr presentation layer
|
||||||
|
public class PassportModel
|
||||||
|
{
|
||||||
|
/// Number of passport
|
||||||
|
[Required]
|
||||||
|
[MaxLength(ConfigurationConstraints.PassportNumberLength)]
|
||||||
|
public string Number { get; set; } = null!;
|
||||||
|
|
||||||
|
/// Issuing authority of passport
|
||||||
|
[Required]
|
||||||
|
[MaxLength(ConfigurationConstraints.IssuerNameLength)]
|
||||||
|
public string Issuer { get; set; } = null!;
|
||||||
|
|
||||||
|
/// Date of issue
|
||||||
|
[Required]
|
||||||
|
public DateTime IssueDate { get; set; }
|
||||||
|
|
||||||
|
/// Date when the passport expires
|
||||||
|
[Required]
|
||||||
|
public DateTime ExpirationDate { get; set; }
|
||||||
|
}
|
||||||
@@ -1,15 +1,22 @@
|
|||||||
using Domains.ApplicantDomain;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using Domains;
|
||||||
|
|
||||||
namespace ApplicationLayer.Services.Applicants.Models;
|
namespace ApplicationLayer.Services.Applicants.Models;
|
||||||
|
|
||||||
public class PlaceOfWorkModel
|
public class PlaceOfWorkModel
|
||||||
{
|
{
|
||||||
/// Name of hirer
|
/// Name of hirer
|
||||||
|
[Required]
|
||||||
|
[MaxLength(ConfigurationConstraints.PlaceOfWorkNameLength)]
|
||||||
public string Name { get; set; } = null!;
|
public string Name { get; set; } = null!;
|
||||||
|
|
||||||
/// Address of hirer
|
/// Address of hirer
|
||||||
public Address Address { get; set; } = null!;
|
[Required]
|
||||||
|
public AddressModel Address { get; set; } = null!;
|
||||||
|
|
||||||
/// Phone number of hirer
|
/// Phone number of hirer
|
||||||
|
[Required]
|
||||||
|
[MaxLength(ConfigurationConstraints.PhoneNumberLength)]
|
||||||
|
[MinLength(ConfigurationConstraints.PhoneNumberMinLength)]
|
||||||
public string PhoneNum { get; set; } = null!;
|
public string PhoneNum { get; set; } = null!;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using Domains;
|
||||||
|
using FluentValidation;
|
||||||
|
|
||||||
|
namespace ApplicationLayer.Services.Applicants.Models.Validation;
|
||||||
|
|
||||||
|
public class NameModelValidator : AbstractValidator<NameModel>
|
||||||
|
{
|
||||||
|
public NameModelValidator()
|
||||||
|
{
|
||||||
|
RuleFor(m => m.FirstName)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage("First Name can not be empty")
|
||||||
|
.MaximumLength(ConfigurationConstraints.NameLength)
|
||||||
|
.WithMessage($"First Name length must be less than {ConfigurationConstraints.NameLength}");
|
||||||
|
|
||||||
|
RuleFor(m => m.Surname)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage("Surname can not be empty")
|
||||||
|
.MaximumLength(ConfigurationConstraints.NameLength)
|
||||||
|
.WithMessage($"Surname length must be less than {ConfigurationConstraints.NameLength}");
|
||||||
|
|
||||||
|
RuleFor(m => m.Patronymic)
|
||||||
|
.MaximumLength(ConfigurationConstraints.NameLength)
|
||||||
|
.WithMessage($"Patronymic length must be less than {ConfigurationConstraints.NameLength}");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
using ApplicationLayer.InfrastructureServicesInterfaces;
|
||||||
|
using Domains;
|
||||||
|
using FluentValidation;
|
||||||
|
|
||||||
|
namespace ApplicationLayer.Services.Applicants.Models.Validation;
|
||||||
|
|
||||||
|
public class PassportModelValidator : AbstractValidator<PassportModel>
|
||||||
|
{
|
||||||
|
public PassportModelValidator(IDateTimeProvider dateTimeProvider)
|
||||||
|
{
|
||||||
|
RuleFor(r => r.Issuer)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage("Passport issuer can not be empty")
|
||||||
|
.MaximumLength(ConfigurationConstraints.IssuerNameLength)
|
||||||
|
.WithMessage($"Passport issuer length must be less than {ConfigurationConstraints.IssuerNameLength}");
|
||||||
|
|
||||||
|
RuleFor(r => r.Number)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage("Passport number can not be empty")
|
||||||
|
.MaximumLength(ConfigurationConstraints.PassportNumberLength)
|
||||||
|
.WithMessage($"Passport number length must be less than {ConfigurationConstraints.PassportNumberLength}");
|
||||||
|
|
||||||
|
RuleFor(r => r.ExpirationDate)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage("Passport expiration date can not be empty")
|
||||||
|
.GreaterThan(dateTimeProvider.Now())
|
||||||
|
.WithMessage("Can not approve visa for applicants with expired passport");
|
||||||
|
|
||||||
|
RuleFor(r => r.IssueDate)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage("Passport issue date can not be empty")
|
||||||
|
.LessThanOrEqualTo(dateTimeProvider.Now())
|
||||||
|
.WithMessage("Passport issue date must be in past");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
using Domains;
|
||||||
|
using FluentValidation;
|
||||||
|
|
||||||
|
namespace ApplicationLayer.Services.Applicants.Models.Validation;
|
||||||
|
|
||||||
|
public class PlaceOfWorkModelValidator : AbstractValidator<PlaceOfWorkModel>
|
||||||
|
{
|
||||||
|
public PlaceOfWorkModelValidator()
|
||||||
|
{
|
||||||
|
RuleFor(p => p.Name)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage("Place of work name can not be empty")
|
||||||
|
.MaximumLength(ConfigurationConstraints.PlaceOfWorkNameLength)
|
||||||
|
.WithMessage($"Place of work name length must be less than {ConfigurationConstraints.PlaceOfWorkNameLength}");
|
||||||
|
|
||||||
|
RuleFor(p => p.PhoneNum)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage("Place of work phone number can not be empty")
|
||||||
|
.MaximumLength(ConfigurationConstraints.PhoneNumberLength)
|
||||||
|
.WithMessage(
|
||||||
|
$"Phone number length must be in range from {ConfigurationConstraints.PhoneNumberMinLength} to {ConfigurationConstraints.PhoneNumberLength}")
|
||||||
|
.MinimumLength(ConfigurationConstraints.PhoneNumberMinLength)
|
||||||
|
.WithMessage(
|
||||||
|
$"Phone number length must be in range from {ConfigurationConstraints.PhoneNumberMinLength} to {ConfigurationConstraints.PhoneNumberLength}");
|
||||||
|
|
||||||
|
RuleFor(p => p.Address.Country)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage("Country name of place of work can not be empty")
|
||||||
|
.MaximumLength(ConfigurationConstraints.CountryNameLength)
|
||||||
|
.WithMessage($"Country name of place of work length must be less than {ConfigurationConstraints.CountryNameLength}");
|
||||||
|
|
||||||
|
RuleFor(p => p.Address.City)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage("City name of place of work can not be empty")
|
||||||
|
.MaximumLength(ConfigurationConstraints.CityNameLength)
|
||||||
|
.WithMessage($"City name of place of work length must be less than {ConfigurationConstraints.CityNameLength}");
|
||||||
|
|
||||||
|
RuleFor(p => p.Address.Street)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage("Street name of place of work can not be empty")
|
||||||
|
.MaximumLength(ConfigurationConstraints.StreetNameLength)
|
||||||
|
.WithMessage($"Street name of place of work length must be less than {ConfigurationConstraints.StreetNameLength}");
|
||||||
|
|
||||||
|
RuleFor(p => p.Address.Building)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage("Building of place of work can not be empty")
|
||||||
|
.MaximumLength(ConfigurationConstraints.CountryNameLength)
|
||||||
|
.WithMessage($"Building of place of work length must be less than {ConfigurationConstraints.BuildingNumberLength}");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,15 @@
|
|||||||
namespace ApplicationLayer.Services.AuthServices.Common;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using Domains;
|
||||||
|
|
||||||
public record AuthData(string Email, string Password);
|
namespace ApplicationLayer.Services.AuthServices.Common;
|
||||||
|
|
||||||
|
public class AuthData
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
[MaxLength(ConfigurationConstraints.EmailLength)]
|
||||||
|
public string Email { get; set; } = null!;
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[MaxLength(ConfigurationConstraints.PasswordLength)]
|
||||||
|
public string Password { get; set; } = null!;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,22 +1,23 @@
|
|||||||
using ApplicationLayer.Services.AuthServices.LoginService.Exceptions;
|
using ApplicationLayer.Services.AuthServices.LoginService.Exceptions;
|
||||||
using ApplicationLayer.Services.AuthServices.NeededServices;
|
using ApplicationLayer.Services.AuthServices.NeededServices;
|
||||||
|
using ApplicationLayer.Services.AuthServices.Requests;
|
||||||
using Domains.Users;
|
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(LoginRequest request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (email == "admin@mail.ru" && password == "admin")
|
if (request.AuthData is { Email: "admin@mail.ru", Password: "admin" })
|
||||||
{
|
{
|
||||||
var admin = new User { Role = Role.Admin };
|
var admin = new User { Role = Role.Admin };
|
||||||
|
|
||||||
return tokenGenerator.CreateToken(admin);
|
return tokenGenerator.CreateToken(admin);
|
||||||
}
|
}
|
||||||
|
|
||||||
var user = await users.FindByEmailAsync(email, cancellationToken);
|
var user = await users.FindByEmailAsync(request.AuthData.Email, cancellationToken);
|
||||||
if (user is null || user.Password != password)
|
if (user is null || user.Password != request.AuthData.Password)
|
||||||
{
|
{
|
||||||
throw new IncorrectLoginDataException();
|
throw new IncorrectLoginDataException();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
namespace ApplicationLayer.Services.AuthServices.LoginService;
|
using ApplicationLayer.Services.AuthServices.Requests;
|
||||||
|
|
||||||
|
namespace ApplicationLayer.Services.AuthServices.LoginService;
|
||||||
|
|
||||||
/// Handles login requests
|
/// Handles login requests
|
||||||
public interface ILoginService
|
public interface ILoginService
|
||||||
{
|
{
|
||||||
/// Handle login request
|
/// Handle login request
|
||||||
/// <returns>JWT-token</returns>
|
/// <returns>JWT-token</returns>
|
||||||
Task<string> LoginAsync(string email, string password, CancellationToken cancellationToken);
|
Task<string> LoginAsync(LoginRequest request, CancellationToken cancellationToken);
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,16 @@
|
|||||||
using ApplicationLayer.Services.AuthServices.LoginService.Exceptions;
|
using ApplicationLayer.Services.AuthServices.LoginService.Exceptions;
|
||||||
using ApplicationLayer.Services.AuthServices.NeededServices;
|
using ApplicationLayer.Services.AuthServices.NeededServices;
|
||||||
|
using ApplicationLayer.Services.AuthServices.Requests;
|
||||||
|
|
||||||
namespace ApplicationLayer.Services.AuthServices.LoginService;
|
namespace ApplicationLayer.Services.AuthServices.LoginService;
|
||||||
|
|
||||||
/// <inheritdoc cref="ILoginService"/>
|
/// <inheritdoc cref="ILoginService" />
|
||||||
public class LoginService(IUsersRepository users, ITokenGenerator tokenGenerator) : 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(LoginRequest request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var user = await users.FindByEmailAsync(email, cancellationToken);
|
var user = await users.FindByEmailAsync(request.AuthData.Email, cancellationToken);
|
||||||
if (user is null || user.Password != password)
|
if (user is null || user.Password != request.AuthData.Password)
|
||||||
{
|
{
|
||||||
throw new IncorrectLoginDataException();
|
throw new IncorrectLoginDataException();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public class RegisterService(
|
|||||||
{
|
{
|
||||||
async Task IRegisterService.RegisterApplicant(RegisterApplicantRequest request, CancellationToken cancellationToken)
|
async Task IRegisterService.RegisterApplicant(RegisterApplicantRequest request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var user = mapper.Map<User>(request.AuthData);
|
var user = mapper.Map<User>(request.RegisterRequest.AuthData);
|
||||||
user.Role = Role.Applicant;
|
user.Role = Role.Applicant;
|
||||||
|
|
||||||
var applicant = mapper.Map<Applicant>(request);
|
var applicant = mapper.Map<Applicant>(request);
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using ApplicationLayer.Services.AuthServices.Common;
|
||||||
|
|
||||||
|
namespace ApplicationLayer.Services.AuthServices.Requests;
|
||||||
|
|
||||||
|
public class LoginRequest
|
||||||
|
{
|
||||||
|
[Required] public AuthData AuthData { get; set; } = null!;
|
||||||
|
}
|
||||||
@@ -1,22 +1,49 @@
|
|||||||
using ApplicationLayer.Services.Applicants.Models;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using ApplicationLayer.Services.AuthServices.Common;
|
using ApplicationLayer.Services.Applicants.Models;
|
||||||
|
using Domains;
|
||||||
using Domains.ApplicantDomain;
|
using Domains.ApplicantDomain;
|
||||||
|
|
||||||
namespace ApplicationLayer.Services.AuthServices.Requests;
|
namespace ApplicationLayer.Services.AuthServices.Requests;
|
||||||
|
|
||||||
public record RegisterApplicantRequest(
|
public record RegisterApplicantRequest
|
||||||
AuthData AuthData,
|
{
|
||||||
Name ApplicantName,
|
[Required] public RegisterRequest RegisterRequest { get; set; } = null!;
|
||||||
Passport Passport,
|
|
||||||
DateTime BirthDate,
|
[Required] public NameModel ApplicantName { get; set; } = null!;
|
||||||
string CityOfBirth,
|
|
||||||
string CountryOfBirth,
|
[Required] public PassportModel Passport { get; set; } = null!;
|
||||||
string Citizenship,
|
|
||||||
string CitizenshipByBirth,
|
[Required] public DateTime BirthDate { get; set; }
|
||||||
Gender Gender,
|
|
||||||
MaritalStatus MaritalStatus,
|
[Required]
|
||||||
Name FatherName,
|
[MaxLength(ConfigurationConstraints.CityNameLength)]
|
||||||
Name MotherName,
|
public string CityOfBirth { get; set; } = null!;
|
||||||
string JobTitle,
|
|
||||||
PlaceOfWorkModel PlaceOfWork,
|
[Required]
|
||||||
bool IsNonResident) : RegisterRequest(AuthData);
|
[MaxLength(ConfigurationConstraints.CountryNameLength)]
|
||||||
|
public string CountryOfBirth { get; set; } = null!;
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[MaxLength(ConfigurationConstraints.CitizenshipLength)]
|
||||||
|
public string Citizenship { get; set; } = null!;
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[MaxLength(ConfigurationConstraints.CitizenshipLength)]
|
||||||
|
public string CitizenshipByBirth { get; set; } = null!;
|
||||||
|
|
||||||
|
[Required] public Gender Gender { get; set; }
|
||||||
|
|
||||||
|
[Required] public MaritalStatus MaritalStatus { get; set; }
|
||||||
|
|
||||||
|
[Required] public NameModel FatherName { get; set; } = null!;
|
||||||
|
|
||||||
|
[Required] public NameModel MotherName { get; set; } = null!;
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[MaxLength(ConfigurationConstraints.JobTitleLength)]
|
||||||
|
public string JobTitle { get; set; } = null!;
|
||||||
|
|
||||||
|
[Required] public PlaceOfWorkModel PlaceOfWork { get; set; } = null!;
|
||||||
|
|
||||||
|
[Required] public bool IsNonResident { get; set; }
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
using ApplicationLayer.Services.AuthServices.Common;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using ApplicationLayer.Services.AuthServices.Common;
|
||||||
|
|
||||||
namespace ApplicationLayer.Services.AuthServices.Requests;
|
namespace ApplicationLayer.Services.AuthServices.Requests;
|
||||||
|
|
||||||
public record RegisterRequest(AuthData AuthData);
|
public class RegisterRequest
|
||||||
|
{
|
||||||
|
[Required] public AuthData AuthData { get; set; } = null!;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using ApplicationLayer.Services.AuthServices.Common;
|
using ApplicationLayer.Services.AuthServices.Common;
|
||||||
using ApplicationLayer.Services.AuthServices.NeededServices;
|
|
||||||
using Domains;
|
using Domains;
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
|
|
||||||
@@ -7,7 +6,7 @@ namespace ApplicationLayer.Services.AuthServices.Requests.Validation;
|
|||||||
|
|
||||||
public class AuthDataValidator : AbstractValidator<AuthData>
|
public class AuthDataValidator : AbstractValidator<AuthData>
|
||||||
{
|
{
|
||||||
public AuthDataValidator(IUsersRepository users)
|
public AuthDataValidator()
|
||||||
{
|
{
|
||||||
RuleFor(d => d.Email)
|
RuleFor(d => d.Email)
|
||||||
.NotEmpty()
|
.NotEmpty()
|
||||||
@@ -15,12 +14,7 @@ public class AuthDataValidator : AbstractValidator<AuthData>
|
|||||||
.EmailAddress()
|
.EmailAddress()
|
||||||
.WithMessage("Email must be valid")
|
.WithMessage("Email must be valid")
|
||||||
.MaximumLength(ConfigurationConstraints.EmailLength)
|
.MaximumLength(ConfigurationConstraints.EmailLength)
|
||||||
.WithMessage($"Email length must be less than {ConfigurationConstraints.EmailLength}")
|
.WithMessage($"Email length must be less than {ConfigurationConstraints.EmailLength}");
|
||||||
.MustAsync(async (email, ct) =>
|
|
||||||
{
|
|
||||||
return await users.FindByEmailAsync(email, ct) is null;
|
|
||||||
})
|
|
||||||
.WithMessage("Email already exists");
|
|
||||||
|
|
||||||
RuleFor(d => d.Password)
|
RuleFor(d => d.Password)
|
||||||
.NotEmpty()
|
.NotEmpty()
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
using Domains;
|
|
||||||
using Domains.ApplicantDomain;
|
|
||||||
using FluentValidation;
|
|
||||||
|
|
||||||
namespace ApplicationLayer.Services.AuthServices.Requests.Validation;
|
|
||||||
|
|
||||||
public class NameValidator : AbstractValidator<Name>
|
|
||||||
{
|
|
||||||
public NameValidator()
|
|
||||||
{
|
|
||||||
RuleFor(m => m.FirstName)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("First Name can not be empty")
|
|
||||||
.MaximumLength(ConfigurationConstraints.NameLength)
|
|
||||||
.WithMessage($"First Name length must be less than {ConfigurationConstraints.NameLength}");
|
|
||||||
|
|
||||||
RuleFor(m => m.Surname)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("Surname can not be empty")
|
|
||||||
.MaximumLength(ConfigurationConstraints.NameLength)
|
|
||||||
.WithMessage($"Surname length must be less than {ConfigurationConstraints.NameLength}");
|
|
||||||
|
|
||||||
RuleFor(m => m.Patronymic)
|
|
||||||
.MaximumLength(ConfigurationConstraints.NameLength)
|
|
||||||
.WithMessage($"Patronymic length must be less than {ConfigurationConstraints.NameLength}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
using ApplicationLayer.InfrastructureServicesInterfaces;
|
|
||||||
using Domains;
|
|
||||||
using Domains.ApplicantDomain;
|
|
||||||
using FluentValidation;
|
|
||||||
|
|
||||||
namespace ApplicationLayer.Services.AuthServices.Requests.Validation;
|
|
||||||
|
|
||||||
public class PassportValidator : AbstractValidator<Passport>
|
|
||||||
{
|
|
||||||
public PassportValidator(IDateTimeProvider dateTimeProvider)
|
|
||||||
{
|
|
||||||
RuleFor(r => r.Issuer)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("Passport issuer can not be empty")
|
|
||||||
.MaximumLength(ConfigurationConstraints.IssuerNameLength)
|
|
||||||
.WithMessage($"Passport issuer length must be less than {ConfigurationConstraints.IssuerNameLength}");
|
|
||||||
|
|
||||||
RuleFor(r => r.Number)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("Passport number can not be empty")
|
|
||||||
.MaximumLength(ConfigurationConstraints.PassportNumberLength)
|
|
||||||
.WithMessage($"Passport number length must be less than {ConfigurationConstraints.PassportNumberLength}");
|
|
||||||
|
|
||||||
RuleFor(r => r.ExpirationDate)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("Passport expiration date can not be empty")
|
|
||||||
.GreaterThan(dateTimeProvider.Now())
|
|
||||||
.WithMessage("Can not approve visa for applicants with expired passport");
|
|
||||||
|
|
||||||
RuleFor(r => r.IssueDate)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("Passport issue date can not be empty")
|
|
||||||
.LessThanOrEqualTo(dateTimeProvider.Now())
|
|
||||||
.WithMessage("Passport issue date must be in past");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
using ApplicationLayer.Services.Applicants.Models;
|
|
||||||
using Domains;
|
|
||||||
using FluentValidation;
|
|
||||||
|
|
||||||
namespace ApplicationLayer.Services.AuthServices.Requests.Validation;
|
|
||||||
|
|
||||||
public class PlaceOfWorkModelValidator : AbstractValidator<PlaceOfWorkModel>
|
|
||||||
{
|
|
||||||
public PlaceOfWorkModelValidator()
|
|
||||||
{
|
|
||||||
RuleFor(p => p.Name)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("Place of work name can not be empty")
|
|
||||||
.MaximumLength(ConfigurationConstraints.PlaceOfWorkNameLength)
|
|
||||||
.WithMessage($"Place of work name length must be less than {ConfigurationConstraints.PlaceOfWorkNameLength}");
|
|
||||||
|
|
||||||
RuleFor(p => p.PhoneNum)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("Place of work phone number can not be empty")
|
|
||||||
.MaximumLength(ConfigurationConstraints.PhoneNumberLength)
|
|
||||||
.WithMessage($"Phone number length must be in range from {ConfigurationConstraints.PhoneNumberMinLength} to {ConfigurationConstraints.PhoneNumberLength}")
|
|
||||||
.MinimumLength(ConfigurationConstraints.PhoneNumberMinLength)
|
|
||||||
.WithMessage($"Phone number length must be in range from {ConfigurationConstraints.PhoneNumberMinLength} to {ConfigurationConstraints.PhoneNumberLength}");
|
|
||||||
|
|
||||||
RuleFor(p => p.Address.Country)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("Country name of place of work can not be empty")
|
|
||||||
.MaximumLength(ConfigurationConstraints.CountryNameLength)
|
|
||||||
.WithMessage($"Country name of place of work length must be less than {ConfigurationConstraints.CountryNameLength}");
|
|
||||||
|
|
||||||
RuleFor(p => p.Address.City)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("City name of place of work can not be empty")
|
|
||||||
.MaximumLength(ConfigurationConstraints.CityNameLength)
|
|
||||||
.WithMessage($"City name of place of work length must be less than {ConfigurationConstraints.CityNameLength}");
|
|
||||||
|
|
||||||
RuleFor(p => p.Address.Street)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("Street name of place of work can not be empty")
|
|
||||||
.MaximumLength(ConfigurationConstraints.StreetNameLength)
|
|
||||||
.WithMessage($"Street name of place of work length must be less than {ConfigurationConstraints.StreetNameLength}");
|
|
||||||
|
|
||||||
RuleFor(p => p.Address.Building)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("Building of place of work can not be empty")
|
|
||||||
.MaximumLength(ConfigurationConstraints.CountryNameLength)
|
|
||||||
.WithMessage($"Building of place of work length must be less than {ConfigurationConstraints.BuildingNumberLength}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
using ApplicationLayer.InfrastructureServicesInterfaces;
|
using ApplicationLayer.InfrastructureServicesInterfaces;
|
||||||
using ApplicationLayer.Services.Applicants.Models;
|
using ApplicationLayer.Services.Applicants.Models;
|
||||||
using ApplicationLayer.Services.AuthServices.Common;
|
|
||||||
using Domains;
|
using Domains;
|
||||||
using Domains.ApplicantDomain;
|
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
|
|
||||||
namespace ApplicationLayer.Services.AuthServices.Requests.Validation;
|
namespace ApplicationLayer.Services.AuthServices.Requests.Validation;
|
||||||
@@ -11,13 +9,13 @@ public class RegisterApplicantRequestValidator : AbstractValidator<RegisterAppli
|
|||||||
{
|
{
|
||||||
public RegisterApplicantRequestValidator(
|
public RegisterApplicantRequestValidator(
|
||||||
IDateTimeProvider dateTimeProvider,
|
IDateTimeProvider dateTimeProvider,
|
||||||
IValidator<Name> nameValidator,
|
IValidator<NameModel> nameValidator,
|
||||||
IValidator<AuthData> authDataValidator,
|
IValidator<RegisterRequest> registerRequestValidator,
|
||||||
IValidator<Passport> passportValidator,
|
IValidator<PassportModel> passportValidator,
|
||||||
IValidator<PlaceOfWorkModel> placeOfWorkModelValidator)
|
IValidator<PlaceOfWorkModel> placeOfWorkModelValidator)
|
||||||
{
|
{
|
||||||
RuleFor(r => r.AuthData)
|
RuleFor(r => r.RegisterRequest)
|
||||||
.SetValidator(authDataValidator);
|
.SetValidator(registerRequestValidator);
|
||||||
|
|
||||||
RuleFor(r => r.ApplicantName)
|
RuleFor(r => r.ApplicantName)
|
||||||
.SetValidator(nameValidator);
|
.SetValidator(nameValidator);
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using ApplicationLayer.Services.AuthServices.Common;
|
||||||
|
using ApplicationLayer.Services.AuthServices.NeededServices;
|
||||||
|
using FluentValidation;
|
||||||
|
|
||||||
|
namespace ApplicationLayer.Services.AuthServices.Requests.Validation;
|
||||||
|
|
||||||
|
public class RegisterRequestValidator : AbstractValidator<RegisterRequest>
|
||||||
|
{
|
||||||
|
public RegisterRequestValidator(IUsersRepository users, IValidator<AuthData> authDataValidator)
|
||||||
|
{
|
||||||
|
RuleFor(r => r.AuthData)
|
||||||
|
.SetValidator(authDataValidator)
|
||||||
|
.MustAsync(async (authData, ct) => await users.FindByEmailAsync(authData.Email, ct) is null)
|
||||||
|
.WithMessage("Email already exists");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
using ApplicationLayer.Services.GeneralExceptions;
|
||||||
|
using Domains.Users;
|
||||||
|
|
||||||
|
namespace ApplicationLayer.Services.Users.Exceptions;
|
||||||
|
|
||||||
|
public class WrongRoleException(Guid userId) : EntityNotFoundByIdException<User>(userId);
|
||||||
@@ -10,13 +10,13 @@ public interface IUsersService
|
|||||||
/// <param name="cancellationToken">Cancellation token</param>
|
/// <param name="cancellationToken">Cancellation token</param>
|
||||||
Task<List<User>> GetAuthoritiesAccountsAsync(CancellationToken cancellationToken);
|
Task<List<User>> GetAuthoritiesAccountsAsync(CancellationToken cancellationToken);
|
||||||
|
|
||||||
/// Changes authentication data for an account
|
/// Changes authentication data for an authority account
|
||||||
/// <param name="request"> Request object with identifier of user and new authentication data</param>
|
/// <param name="request"> Request object with identifier of user and new authentication data</param>
|
||||||
/// <param name="cancellationToken">Cancellation token</param>
|
/// <param name="cancellationToken">Cancellation token</param>
|
||||||
Task ChangeAccountAuthDataAsync(ChangeUserAuthDataRequest request, CancellationToken cancellationToken);
|
Task ChangeAuthorityAuthDataAsync(ChangeUserAuthDataRequest request, CancellationToken cancellationToken);
|
||||||
|
|
||||||
/// Removes user account
|
/// Removes account of authority
|
||||||
/// <param name="userId">Identifier of account</param>
|
/// <param name="userId">Identifier of account</param>
|
||||||
/// <param name="cancellationToken">Cancellation token</param>
|
/// <param name="cancellationToken">Cancellation token</param>
|
||||||
Task RemoveUserAccount(Guid userId, CancellationToken cancellationToken);
|
Task RemoveAuthorityAccount(Guid userId, CancellationToken cancellationToken);
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,11 @@
|
|||||||
using ApplicationLayer.Services.AuthServices.Common;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using ApplicationLayer.Services.AuthServices.Common;
|
||||||
|
|
||||||
namespace ApplicationLayer.Services.Users.Requests;
|
namespace ApplicationLayer.Services.Users.Requests;
|
||||||
|
|
||||||
public record ChangeUserAuthDataRequest(Guid UserId, AuthData NewAuthData);
|
public class ChangeUserAuthDataRequest(Guid userId, AuthData newAuthData)
|
||||||
|
{
|
||||||
|
[Required] public Guid UserId { get; set; } = userId;
|
||||||
|
|
||||||
|
[Required] public AuthData NewAuthData { get; set; } = newAuthData;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
using ApplicationLayer.InfrastructureServicesInterfaces;
|
using ApplicationLayer.InfrastructureServicesInterfaces;
|
||||||
|
using ApplicationLayer.Services.AuthServices.Common;
|
||||||
using ApplicationLayer.Services.AuthServices.NeededServices;
|
using ApplicationLayer.Services.AuthServices.NeededServices;
|
||||||
|
using ApplicationLayer.Services.Users.Exceptions;
|
||||||
using ApplicationLayer.Services.Users.Requests;
|
using ApplicationLayer.Services.Users.Requests;
|
||||||
using Domains.Users;
|
using Domains.Users;
|
||||||
|
|
||||||
@@ -7,27 +9,59 @@ 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) =>
|
||||||
{
|
await users.GetAllOfRoleAsync(Role.ApprovingAuthority, cancellationToken);
|
||||||
return await users.GetAllOfRoleAsync(Role.ApprovingAuthority, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
async Task IUsersService.ChangeAccountAuthDataAsync(ChangeUserAuthDataRequest request, CancellationToken cancellationToken)
|
async Task IUsersService.ChangeAuthorityAuthDataAsync(ChangeUserAuthDataRequest request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var user = await users.GetByIdAsync(request.UserId, cancellationToken);
|
var user = await users.GetByIdAsync(request.UserId, cancellationToken);
|
||||||
|
|
||||||
user.Email = request.NewAuthData.Email;
|
ValidateRole(user, Role.ApprovingAuthority);
|
||||||
user.Password = request.NewAuthData.Password;
|
|
||||||
|
await ChangeAccountAuthDataAsync(user, request.NewAuthData, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task IUsersService.RemoveAuthorityAccount(Guid userId, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var user = await users.GetByIdAsync(userId, cancellationToken);
|
||||||
|
|
||||||
|
ValidateRole(user, Role.ApprovingAuthority);
|
||||||
|
|
||||||
|
await RemoveUserAccount(user, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Updates user account auth data
|
||||||
|
/// <param name="user">User to remove</param>
|
||||||
|
/// <param name="authData">New auth data</param>
|
||||||
|
/// <param name="cancellationToken">Cancellation token</param>
|
||||||
|
private async Task ChangeAccountAuthDataAsync(User user, AuthData authData, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
user.Email = authData.Email;
|
||||||
|
user.Password = authData.Password;
|
||||||
await users.UpdateAsync(user, cancellationToken);
|
await users.UpdateAsync(user, cancellationToken);
|
||||||
|
|
||||||
await unitOfWork.SaveAsync(cancellationToken);
|
await unitOfWork.SaveAsync(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
async Task IUsersService.RemoveUserAccount(Guid userId, CancellationToken cancellationToken)
|
/// Removes user account from DB
|
||||||
|
/// <param name="user">User to remove</param>
|
||||||
|
/// <param name="cancellationToken">Cancellation token</param>
|
||||||
|
private async Task RemoveUserAccount(User user, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var user = await users.GetByIdAsync(userId, cancellationToken);
|
|
||||||
users.Remove(user);
|
users.Remove(user);
|
||||||
|
|
||||||
await unitOfWork.SaveAsync(cancellationToken);
|
await unitOfWork.SaveAsync(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Checks if role of user equals expected
|
||||||
|
/// <param name="user">User to check</param>
|
||||||
|
/// <param name="expectedRole">Expected role</param>
|
||||||
|
/// <exception cref="WrongRoleException">Role is not expected</exception>
|
||||||
|
private static void ValidateRole(User user, Role expectedRole)
|
||||||
|
{
|
||||||
|
if (user.Role != expectedRole)
|
||||||
|
{
|
||||||
|
throw new WrongRoleException(user.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -29,18 +29,6 @@ public class VisaApplicationRequestsHandler(
|
|||||||
return applicationModels;
|
return applicationModels;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<VisaApplicationModelForAuthority> MapVisaApplicationToModelForAuthorities(VisaApplication visaApplication,
|
|
||||||
CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var applicant = await applicants.GetByIdAsync(visaApplication.ApplicantId, cancellationToken);
|
|
||||||
var applicantModel = mapper.Map<ApplicantModel>(applicant);
|
|
||||||
|
|
||||||
var model = mapper.Map<VisaApplicationModelForAuthority>(visaApplication);
|
|
||||||
model.Applicant = applicantModel;
|
|
||||||
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<List<VisaApplicationModelForApplicant>> GetForApplicantAsync(CancellationToken cancellationToken)
|
public async Task<List<VisaApplicationModelForApplicant>> GetForApplicantAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var applicantId = await applicants.GetApplicantIdByUserId(userIdProvider.GetUserId(), cancellationToken);
|
var applicantId = await applicants.GetApplicantIdByUserId(userIdProvider.GetUserId(), cancellationToken);
|
||||||
@@ -83,7 +71,7 @@ public class VisaApplicationRequestsHandler(
|
|||||||
throw new ApplicationAlreadyProcessedException();
|
throw new ApplicationAlreadyProcessedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplicationStatus statusToSet = status switch
|
var statusToSet = status switch
|
||||||
{
|
{
|
||||||
AuthorityRequestStatuses.Approved => ApplicationStatus.Approved,
|
AuthorityRequestStatuses.Approved => ApplicationStatus.Approved,
|
||||||
AuthorityRequestStatuses.Rejected => ApplicationStatus.Rejected,
|
AuthorityRequestStatuses.Rejected => ApplicationStatus.Rejected,
|
||||||
@@ -95,4 +83,16 @@ public class VisaApplicationRequestsHandler(
|
|||||||
|
|
||||||
await unitOfWork.SaveAsync(cancellationToken);
|
await unitOfWork.SaveAsync(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<VisaApplicationModelForAuthority> MapVisaApplicationToModelForAuthorities(VisaApplication visaApplication,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var applicant = await applicants.GetByIdAsync(visaApplication.ApplicantId, cancellationToken);
|
||||||
|
var applicantModel = mapper.Map<ApplicantModel>(applicant);
|
||||||
|
|
||||||
|
var model = mapper.Map<VisaApplicationModelForAuthority>(visaApplication);
|
||||||
|
model.Applicant = applicantModel;
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using Domains;
|
||||||
|
|
||||||
|
namespace ApplicationLayer.Services.VisaApplications.Models;
|
||||||
|
|
||||||
|
/// Model of past visa for presentation layer
|
||||||
|
public class PastVisaModel
|
||||||
|
{
|
||||||
|
// Date of issue
|
||||||
|
[Required]
|
||||||
|
public DateTime IssueDate { get; set; }
|
||||||
|
|
||||||
|
/// Name of visa
|
||||||
|
[Required]
|
||||||
|
[MaxLength(ConfigurationConstraints.VisaNameLength)]
|
||||||
|
public string Name { get; set; } = null!;
|
||||||
|
|
||||||
|
/// Date when visa expires
|
||||||
|
[Required]
|
||||||
|
public DateTime ExpirationDate { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using Domains;
|
||||||
|
|
||||||
|
namespace ApplicationLayer.Services.VisaApplications.Models;
|
||||||
|
|
||||||
|
/// Model of past visit for presentation layer
|
||||||
|
public class PastVisitModel
|
||||||
|
{
|
||||||
|
/// First day of past visit
|
||||||
|
[Required]
|
||||||
|
public DateTime StartDate { get; set; }
|
||||||
|
|
||||||
|
/// Last day of past visit
|
||||||
|
[Required]
|
||||||
|
public DateTime EndDate { get; set; }
|
||||||
|
|
||||||
|
/// Destination country of past visit
|
||||||
|
[Required]
|
||||||
|
[MaxLength(ConfigurationConstraints.CountryNameLength)]
|
||||||
|
public string DestinationCountry { get; set; } = null!;
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using Domains;
|
||||||
|
|
||||||
|
namespace ApplicationLayer.Services.VisaApplications.Models;
|
||||||
|
|
||||||
|
/// Model of permission to destination country for presentation layer
|
||||||
|
public class PermissionToDestCountryModel
|
||||||
|
{
|
||||||
|
/// Date when permission to destination country expires
|
||||||
|
[Required]
|
||||||
|
public DateTime ExpirationDate { get; set; }
|
||||||
|
|
||||||
|
/// Issuing authority
|
||||||
|
[Required]
|
||||||
|
[MaxLength(ConfigurationConstraints.IssuerNameLength)]
|
||||||
|
public string Issuer { get; set; } = null!;
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using Domains;
|
||||||
|
|
||||||
|
namespace ApplicationLayer.Services.VisaApplications.Models;
|
||||||
|
|
||||||
|
/// Model of re-entry permit for presentation layer
|
||||||
|
public class ReentryPermitModel
|
||||||
|
{
|
||||||
|
/// Number of re-entry permit
|
||||||
|
[Required]
|
||||||
|
[MaxLength(ConfigurationConstraints.ReentryPermitNumberLength)]
|
||||||
|
public string Number { get; set; } = null!;
|
||||||
|
|
||||||
|
/// Date when re-entry permit expires
|
||||||
|
[Required]
|
||||||
|
public DateTime ExpirationDate { get; set; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using ApplicationLayer.InfrastructureServicesInterfaces;
|
||||||
|
using FluentValidation;
|
||||||
|
|
||||||
|
namespace ApplicationLayer.Services.VisaApplications.Models.Validation;
|
||||||
|
|
||||||
|
public class PastVisaModelValidator : AbstractValidator<PastVisaModel>
|
||||||
|
{
|
||||||
|
public PastVisaModelValidator(IDateTimeProvider dateTimeProvider)
|
||||||
|
{
|
||||||
|
RuleFor(v => v.ExpirationDate)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage("Expiration date of past visa can not be empty")
|
||||||
|
.GreaterThan(v => v.IssueDate)
|
||||||
|
.WithMessage("Past visa expiration date can not be earlier than issue date");
|
||||||
|
|
||||||
|
RuleFor(v => v.IssueDate)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage("Issue date of past visa can not be empty")
|
||||||
|
.LessThan(dateTimeProvider.Now())
|
||||||
|
.WithMessage("Issue date of past visa must be in past");
|
||||||
|
|
||||||
|
RuleFor(v => v.Name)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage("Name of past visa can not be empty");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
using ApplicationLayer.InfrastructureServicesInterfaces;
|
||||||
|
using Domains;
|
||||||
|
using FluentValidation;
|
||||||
|
|
||||||
|
namespace ApplicationLayer.Services.VisaApplications.Models.Validation;
|
||||||
|
|
||||||
|
public class PastVisitModelValidator : AbstractValidator<PastVisitModel>
|
||||||
|
{
|
||||||
|
public PastVisitModelValidator(IDateTimeProvider dateTimeProvider)
|
||||||
|
{
|
||||||
|
RuleFor(v => v.StartDate)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage("Start date of past visit can not be empty")
|
||||||
|
.LessThan(v => v.EndDate)
|
||||||
|
.WithMessage("Start date of past visit must be earlier than end date")
|
||||||
|
.LessThan(dateTimeProvider.Now())
|
||||||
|
.WithMessage("Start date of past visit must be in past");
|
||||||
|
|
||||||
|
RuleFor(v => v.EndDate)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage("End date of past visit can not be empty");
|
||||||
|
|
||||||
|
RuleFor(v => v.DestinationCountry)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage("Destination Country of past visit can not be null")
|
||||||
|
.MaximumLength(ConfigurationConstraints.CountryNameLength)
|
||||||
|
.WithMessage($"Destination Country of past visit length must be less than {ConfigurationConstraints.CountryNameLength}");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using ApplicationLayer.InfrastructureServicesInterfaces;
|
||||||
|
using Domains;
|
||||||
|
using FluentValidation;
|
||||||
|
|
||||||
|
namespace ApplicationLayer.Services.VisaApplications.Models.Validation;
|
||||||
|
|
||||||
|
public class PermissionToDestCountryModelValidator : AbstractValidator<PermissionToDestCountryModel?>
|
||||||
|
{
|
||||||
|
public PermissionToDestCountryModelValidator(IDateTimeProvider dateTimeProvider)
|
||||||
|
{
|
||||||
|
RuleFor(p => p!.ExpirationDate)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage("Expiration date of permission to destination Country can not be empty")
|
||||||
|
.GreaterThan(dateTimeProvider.Now())
|
||||||
|
.WithMessage("Permission to destination Country must not be expired");
|
||||||
|
|
||||||
|
RuleFor(p => p!.Issuer)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage("Issuer of permission for destination Country can not be empty")
|
||||||
|
.MaximumLength(ConfigurationConstraints.IssuerNameLength)
|
||||||
|
.WithMessage($"Issuer of permission to destination Country length must be less than {ConfigurationConstraints.IssuerNameLength}");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using ApplicationLayer.InfrastructureServicesInterfaces;
|
||||||
|
using Domains;
|
||||||
|
using FluentValidation;
|
||||||
|
|
||||||
|
namespace ApplicationLayer.Services.VisaApplications.Models.Validation;
|
||||||
|
|
||||||
|
public class ReentryPermitModelValidator : AbstractValidator<ReentryPermitModel?>
|
||||||
|
{
|
||||||
|
public ReentryPermitModelValidator(IDateTimeProvider dateTimeProvider)
|
||||||
|
{
|
||||||
|
RuleFor(p => p!.Number)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage("Re-entry permit number can not be empty")
|
||||||
|
.MaximumLength(ConfigurationConstraints.ReentryPermitNumberLength)
|
||||||
|
.WithMessage($"Re-entry permit number length must be less than {ConfigurationConstraints.ReentryPermitNumberLength}");
|
||||||
|
|
||||||
|
RuleFor(p => p!.ExpirationDate)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage("Re-entry permit expiration date can not be empty")
|
||||||
|
.GreaterThan(dateTimeProvider.Now())
|
||||||
|
.WithMessage("Re-entry permit must not be expired");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,42 +2,42 @@
|
|||||||
|
|
||||||
namespace ApplicationLayer.Services.VisaApplications.Models;
|
namespace ApplicationLayer.Services.VisaApplications.Models;
|
||||||
|
|
||||||
/// Model of <see cref="VisaApplication"/>
|
/// Model of <see cref="VisaApplication" />
|
||||||
public class VisaApplicationModelForApplicant
|
public class VisaApplicationModelForApplicant
|
||||||
{
|
{
|
||||||
/// <inheritdoc cref="VisaApplication.Id"/>
|
/// <inheritdoc cref="VisaApplication.Id" />
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="VisaApplication.Status"/>
|
/// <inheritdoc cref="VisaApplication.Status" />
|
||||||
public ApplicationStatus Status { get; set; }
|
public ApplicationStatus Status { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="VisaApplication.ReentryPermit"/>
|
/// <inheritdoc cref="VisaApplication.ReentryPermit" />
|
||||||
public ReentryPermit? ReentryPermit { get; set; }
|
public ReentryPermitModel? ReentryPermit { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="VisaApplication.DestinationCountry"/>
|
/// <inheritdoc cref="VisaApplication.DestinationCountry" />
|
||||||
public string DestinationCountry { get; set; } = null!;
|
public string DestinationCountry { get; set; } = null!;
|
||||||
|
|
||||||
/// <inheritdoc cref="VisaApplication.PastVisas"/>
|
/// <inheritdoc cref="VisaApplication.PastVisas" />
|
||||||
public List<PastVisa> PastVisas { get; set; } = null!;
|
public List<PastVisaModel> PastVisas { get; set; } = null!;
|
||||||
|
|
||||||
/// <inheritdoc cref="VisaApplication.PermissionToDestCountry"/>
|
/// <inheritdoc cref="VisaApplication.PermissionToDestCountry" />
|
||||||
public PermissionToDestCountry? PermissionToDestCountry { get; set; }
|
public PermissionToDestCountryModel? PermissionToDestCountry { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="VisaApplication.PastVisits"/>
|
/// <inheritdoc cref="VisaApplication.PastVisits" />
|
||||||
public List<PastVisit> PastVisits { get; set; } = null!;
|
public List<PastVisitModel> PastVisits { get; set; } = null!;
|
||||||
|
|
||||||
/// <inheritdoc cref="VisaApplication.VisaCategory"/>
|
/// <inheritdoc cref="VisaApplication.VisaCategory" />
|
||||||
public VisaCategory VisaCategory { get; set; }
|
public VisaCategory VisaCategory { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="VisaApplication.ForGroup"/>
|
/// <inheritdoc cref="VisaApplication.ForGroup" />
|
||||||
public bool ForGroup { get; set; }
|
public bool ForGroup { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="VisaApplication.RequestedNumberOfEntries"/>
|
/// <inheritdoc cref="VisaApplication.RequestedNumberOfEntries" />
|
||||||
public RequestedNumberOfEntries RequestedNumberOfEntries { get; set; }
|
public RequestedNumberOfEntries RequestedNumberOfEntries { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="VisaApplication.RequestDate"/>
|
/// <inheritdoc cref="VisaApplication.RequestDate" />
|
||||||
public DateTime RequestDate { get; set; }
|
public DateTime RequestDate { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="VisaApplication.ValidDaysRequested"/>
|
/// <inheritdoc cref="VisaApplication.ValidDaysRequested" />
|
||||||
public int ValidDaysRequested { get; set; }
|
public int ValidDaysRequested { get; set; }
|
||||||
}
|
}
|
||||||
@@ -3,44 +3,44 @@ using Domains.VisaApplicationDomain;
|
|||||||
|
|
||||||
namespace ApplicationLayer.Services.VisaApplications.Models;
|
namespace ApplicationLayer.Services.VisaApplications.Models;
|
||||||
|
|
||||||
/// Model of <see cref="VisaApplication"/> with applicant property
|
/// Model of <see cref="VisaApplication" /> with applicant property
|
||||||
public class VisaApplicationModelForAuthority
|
public class VisaApplicationModelForAuthority
|
||||||
{
|
{
|
||||||
/// <inheritdoc cref="VisaApplication.Id"/>
|
/// <inheritdoc cref="VisaApplication.Id" />
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
/// Applicant of application
|
/// Applicant of application
|
||||||
public ApplicantModel Applicant { get; set; } = null!;
|
public ApplicantModel Applicant { get; set; } = null!;
|
||||||
|
|
||||||
/// <inheritdoc cref="VisaApplication.Status"/>
|
/// <inheritdoc cref="VisaApplication.Status" />
|
||||||
public ApplicationStatus Status { get; set; }
|
public ApplicationStatus Status { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="VisaApplication.ReentryPermit"/>
|
/// <inheritdoc cref="VisaApplication.ReentryPermit" />
|
||||||
public ReentryPermit? ReentryPermit { get; set; }
|
public ReentryPermitModel? ReentryPermit { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="VisaApplication.DestinationCountry"/>
|
/// <inheritdoc cref="VisaApplication.DestinationCountry" />
|
||||||
public string DestinationCountry { get; set; } = null!;
|
public string DestinationCountry { get; set; } = null!;
|
||||||
|
|
||||||
/// <inheritdoc cref="VisaApplication.PastVisas"/>
|
/// <inheritdoc cref="VisaApplication.PastVisas" />
|
||||||
public List<PastVisa> PastVisas { get; set; } = null!;
|
public List<PastVisaModel> PastVisas { get; set; } = null!;
|
||||||
|
|
||||||
/// <inheritdoc cref="VisaApplication.PermissionToDestCountry"/>
|
/// <inheritdoc cref="VisaApplication.PermissionToDestCountry" />
|
||||||
public PermissionToDestCountry? PermissionToDestCountry { get; set; }
|
public PermissionToDestCountryModel? PermissionToDestCountry { get; set; }
|
||||||
|
|
||||||
public List<PastVisit> PastVisits { get; set; } = null!;
|
public List<PastVisitModel> PastVisits { get; set; } = null!;
|
||||||
|
|
||||||
/// <inheritdoc cref="VisaApplication.VisaCategory"/>
|
/// <inheritdoc cref="VisaApplication.VisaCategory" />
|
||||||
public VisaCategory VisaCategory { get; set; }
|
public VisaCategory VisaCategory { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="VisaApplication.ForGroup"/>
|
/// <inheritdoc cref="VisaApplication.ForGroup" />
|
||||||
public bool ForGroup { get; set; }
|
public bool ForGroup { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="VisaApplication.RequestedNumberOfEntries"/>
|
/// <inheritdoc cref="VisaApplication.RequestedNumberOfEntries" />
|
||||||
public RequestedNumberOfEntries RequestedNumberOfEntries { get; set; }
|
public RequestedNumberOfEntries RequestedNumberOfEntries { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="VisaApplication.RequestDate"/>
|
/// <inheritdoc cref="VisaApplication.RequestDate" />
|
||||||
public DateTime RequestDate { get; set; }
|
public DateTime RequestDate { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc cref="VisaApplication.ValidDaysRequested"/>
|
/// <inheritdoc cref="VisaApplication.ValidDaysRequested" />
|
||||||
public int ValidDaysRequested { get; set; }
|
public int ValidDaysRequested { get; set; }
|
||||||
}
|
}
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
using ApplicationLayer.InfrastructureServicesInterfaces;
|
|
||||||
using Domains.VisaApplicationDomain;
|
|
||||||
using FluentValidation;
|
|
||||||
|
|
||||||
namespace ApplicationLayer.Services.VisaApplications.Requests.Validation;
|
|
||||||
|
|
||||||
public class PastVisaValidator : AbstractValidator<PastVisa>
|
|
||||||
{
|
|
||||||
public PastVisaValidator(IDateTimeProvider dateTimeProvider)
|
|
||||||
{
|
|
||||||
RuleFor(v => v.ExpirationDate)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("Expiration date of past visa can not be empty")
|
|
||||||
.GreaterThan(v => v.IssueDate)
|
|
||||||
.WithMessage("Past visa expiration date can not be earlier than issue date");
|
|
||||||
|
|
||||||
RuleFor(v => v.IssueDate)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("Issue date of past visa can not be empty")
|
|
||||||
.LessThan(dateTimeProvider.Now())
|
|
||||||
.WithMessage("Issue date of past visa must be in past");
|
|
||||||
|
|
||||||
RuleFor(v => v.Name)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("Name of past visa can not be empty");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using ApplicationLayer.InfrastructureServicesInterfaces;
|
|
||||||
using Domains;
|
|
||||||
using Domains.VisaApplicationDomain;
|
|
||||||
using FluentValidation;
|
|
||||||
|
|
||||||
namespace ApplicationLayer.Services.VisaApplications.Requests.Validation;
|
|
||||||
|
|
||||||
public class PastVisitValidator : AbstractValidator<PastVisit>
|
|
||||||
{
|
|
||||||
public PastVisitValidator(IDateTimeProvider dateTimeProvider)
|
|
||||||
{
|
|
||||||
RuleFor(v => v.StartDate)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("Start date of past visit can not be empty")
|
|
||||||
.LessThan(v => v.EndDate)
|
|
||||||
.WithMessage("Start date of past visit must be earlier than end date")
|
|
||||||
.LessThan(dateTimeProvider.Now())
|
|
||||||
.WithMessage("Start date of past visit must be in past");
|
|
||||||
|
|
||||||
RuleFor(v => v.EndDate)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("End date of past visit can not be empty");
|
|
||||||
|
|
||||||
RuleFor(v => v.DestinationCountry)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("Destination Country of past visit can not be null")
|
|
||||||
.MaximumLength(ConfigurationConstraints.CountryNameLength)
|
|
||||||
.WithMessage($"Destination Country of past visit length must be less than {ConfigurationConstraints.CountryNameLength}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
using ApplicationLayer.InfrastructureServicesInterfaces;
|
|
||||||
using Domains;
|
|
||||||
using Domains.VisaApplicationDomain;
|
|
||||||
using FluentValidation;
|
|
||||||
|
|
||||||
namespace ApplicationLayer.Services.VisaApplications.Requests.Validation;
|
|
||||||
|
|
||||||
public class PermissionToDestCountryValidator : AbstractValidator<PermissionToDestCountry?>
|
|
||||||
{
|
|
||||||
public PermissionToDestCountryValidator(IDateTimeProvider dateTimeProvider)
|
|
||||||
{
|
|
||||||
RuleFor(p => p!.ExpirationDate)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("Expiration date of permission to destination Country can not be empty")
|
|
||||||
.GreaterThan(dateTimeProvider.Now())
|
|
||||||
.WithMessage("Permission to destination Country must not be expired");
|
|
||||||
|
|
||||||
RuleFor(p => p!.Issuer)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("Issuer of permission for destination Country can not be empty")
|
|
||||||
.MaximumLength(ConfigurationConstraints.IssuerNameLength)
|
|
||||||
.WithMessage($"Issuer of permission to destination Country length must be less than {ConfigurationConstraints.IssuerNameLength}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
using ApplicationLayer.InfrastructureServicesInterfaces;
|
|
||||||
using Domains;
|
|
||||||
using Domains.VisaApplicationDomain;
|
|
||||||
using FluentValidation;
|
|
||||||
|
|
||||||
namespace ApplicationLayer.Services.VisaApplications.Requests.Validation;
|
|
||||||
|
|
||||||
public class ReentryPermitValidator : AbstractValidator<ReentryPermit?>
|
|
||||||
{
|
|
||||||
public ReentryPermitValidator(IDateTimeProvider dateTimeProvider)
|
|
||||||
{
|
|
||||||
RuleFor(p => p!.Number)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("Re-entry permit number can not be empty")
|
|
||||||
.MaximumLength(ConfigurationConstraints.ReentryPermitNumberLength)
|
|
||||||
.WithMessage($"Re-entry permit number length must be less than {ConfigurationConstraints.ReentryPermitNumberLength}");
|
|
||||||
|
|
||||||
RuleFor(p => p!.ExpirationDate)
|
|
||||||
.NotEmpty()
|
|
||||||
.WithMessage("Re-entry permit expiration date can not be empty")
|
|
||||||
.GreaterThan(dateTimeProvider.Now())
|
|
||||||
.WithMessage("Re-entry permit must not be expired");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using ApplicationLayer.InfrastructureServicesInterfaces;
|
using ApplicationLayer.InfrastructureServicesInterfaces;
|
||||||
using ApplicationLayer.Services.Applicants.NeededServices;
|
using ApplicationLayer.Services.Applicants.NeededServices;
|
||||||
|
using ApplicationLayer.Services.VisaApplications.Models;
|
||||||
using Domains;
|
using Domains;
|
||||||
using Domains.VisaApplicationDomain;
|
using Domains.VisaApplicationDomain;
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
@@ -9,17 +10,17 @@ namespace ApplicationLayer.Services.VisaApplications.Requests.Validation;
|
|||||||
public class VisaApplicationCreateRequestValidator : AbstractValidator<VisaApplicationCreateRequest>
|
public class VisaApplicationCreateRequestValidator : AbstractValidator<VisaApplicationCreateRequest>
|
||||||
{
|
{
|
||||||
public VisaApplicationCreateRequestValidator(
|
public VisaApplicationCreateRequestValidator(
|
||||||
IValidator<ReentryPermit?> reentryPermitValidator,
|
IValidator<ReentryPermitModel?> reentryPermitModelValidator,
|
||||||
IValidator<PastVisa> pastVisaValidator,
|
IValidator<PastVisaModel> pastVisaModelValidator,
|
||||||
IValidator<PermissionToDestCountry?> permissionToDestCountryValidator,
|
IValidator<PermissionToDestCountryModel?> permissionToDestCountryModelValidator,
|
||||||
IValidator<PastVisit> pastVisitValidator,
|
IValidator<PastVisitModel> pastVisitModelValidator,
|
||||||
IApplicantsRepository applicants,
|
IApplicantsRepository applicants,
|
||||||
IUserIdProvider userIdProvider)
|
IUserIdProvider userIdProvider)
|
||||||
{
|
{
|
||||||
RuleFor(r => r.ReentryPermit)
|
RuleFor(r => r.ReentryPermit)
|
||||||
.NotEmpty()
|
.NotEmpty()
|
||||||
.WithMessage("Non-residents must provide re-entry permission")
|
.WithMessage("Non-residents must provide re-entry permission")
|
||||||
.SetValidator(reentryPermitValidator)
|
.SetValidator(reentryPermitModelValidator)
|
||||||
.WhenAsync(async (_, ct) =>
|
.WhenAsync(async (_, ct) =>
|
||||||
await applicants.IsApplicantNonResidentByUserId(userIdProvider.GetUserId(), ct));
|
await applicants.IsApplicantNonResidentByUserId(userIdProvider.GetUserId(), ct));
|
||||||
|
|
||||||
@@ -40,14 +41,14 @@ public class VisaApplicationCreateRequestValidator : AbstractValidator<VisaAppli
|
|||||||
.WithMessage($"Valid days requested must be less than or equal to {ConfigurationConstraints.MaxValidDays}");
|
.WithMessage($"Valid days requested must be less than or equal to {ConfigurationConstraints.MaxValidDays}");
|
||||||
|
|
||||||
RuleForEach(r => r.PastVisas)
|
RuleForEach(r => r.PastVisas)
|
||||||
.SetValidator(pastVisaValidator);
|
.SetValidator(pastVisaModelValidator);
|
||||||
|
|
||||||
When(r => r.VisaCategory == VisaCategory.Transit,
|
When(r => r.VisaCategory == VisaCategory.Transit,
|
||||||
() =>
|
() =>
|
||||||
RuleFor(r => r.PermissionToDestCountry)
|
RuleFor(r => r.PermissionToDestCountry)
|
||||||
.SetValidator(permissionToDestCountryValidator));
|
.SetValidator(permissionToDestCountryModelValidator));
|
||||||
|
|
||||||
RuleForEach(r => r.PastVisits)
|
RuleForEach(r => r.PastVisits)
|
||||||
.SetValidator(pastVisitValidator);
|
.SetValidator(pastVisitModelValidator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,40 @@
|
|||||||
using Domains.VisaApplicationDomain;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using ApplicationLayer.Services.VisaApplications.Models;
|
||||||
|
using Domains;
|
||||||
|
using Domains.VisaApplicationDomain;
|
||||||
|
|
||||||
namespace ApplicationLayer.Services.VisaApplications.Requests;
|
namespace ApplicationLayer.Services.VisaApplications.Requests;
|
||||||
|
|
||||||
/// Model of visa request from user
|
/// Model of visa request from user
|
||||||
public record VisaApplicationCreateRequest(
|
public class VisaApplicationCreateRequest
|
||||||
ReentryPermit? ReentryPermit,
|
{
|
||||||
string DestinationCountry,
|
|
||||||
VisaCategory VisaCategory,
|
[Required]
|
||||||
bool IsForGroup,
|
public ReentryPermitModel? ReentryPermit { get; set; }
|
||||||
RequestedNumberOfEntries RequestedNumberOfEntries,
|
|
||||||
int ValidDaysRequested,
|
[Required]
|
||||||
PastVisa[] PastVisas,
|
[MaxLength(ConfigurationConstraints.CountryNameLength)]
|
||||||
PermissionToDestCountry? PermissionToDestCountry,
|
public string DestinationCountry { get; set; } = null!;
|
||||||
PastVisit[] PastVisits
|
|
||||||
);
|
[Required]
|
||||||
|
public VisaCategory VisaCategory { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public bool IsForGroup { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public RequestedNumberOfEntries RequestedNumberOfEntries { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[Range(0, ConfigurationConstraints.MaxValidDays)]
|
||||||
|
public int ValidDaysRequested { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public PastVisaModel[] PastVisas { get; set; } = null!;
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public PermissionToDestCountryModel? PermissionToDestCountry { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public PastVisitModel[] PastVisits { get; set; } = null!;
|
||||||
|
}
|
||||||
|
|||||||
@@ -56,9 +56,9 @@ public class UsersController(
|
|||||||
[HttpGet("login")]
|
[HttpGet("login")]
|
||||||
[ProducesResponseType<string>(StatusCodes.Status200OK)]
|
[ProducesResponseType<string>(StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
public async Task<IActionResult> Login(string email, string password, CancellationToken cancellationToken)
|
public async Task<IActionResult> Login(LoginRequest request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var result = await loginService.LoginAsync(email, password, cancellationToken);
|
var result = await loginService.LoginAsync(request, cancellationToken);
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ public class UsersController(
|
|||||||
{
|
{
|
||||||
await authDataValidator.ValidateAndThrowAsync(authData, cancellationToken);
|
await authDataValidator.ValidateAndThrowAsync(authData, cancellationToken);
|
||||||
|
|
||||||
await usersService.ChangeAccountAuthDataAsync(new ChangeUserAuthDataRequest(authorityAccountId, authData), cancellationToken);
|
await usersService.ChangeAuthorityAuthDataAsync(new ChangeUserAuthDataRequest(authorityAccountId, authData), cancellationToken);
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ public class UsersController(
|
|||||||
[Authorize(policy: PolicyConstants.AdminPolicy)]
|
[Authorize(policy: PolicyConstants.AdminPolicy)]
|
||||||
public async Task<IActionResult> RemoveAuthorityAccount(Guid authorityAccountId, CancellationToken cancellationToken)
|
public async Task<IActionResult> RemoveAuthorityAccount(Guid authorityAccountId, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
await usersService.RemoveUserAccount(authorityAccountId, cancellationToken);
|
await usersService.RemoveAuthorityAccount(authorityAccountId, cancellationToken);
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,6 +82,9 @@ public class VisaApplicationController(
|
|||||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||||
[Authorize(policy: PolicyConstants.ApprovingAuthorityPolicy)]
|
[Authorize(policy: PolicyConstants.ApprovingAuthorityPolicy)]
|
||||||
public async Task<IActionResult> SetStatusFromAuthority(Guid applicationId, AuthorityRequestStatuses status, CancellationToken cancellationToken)
|
public async Task<IActionResult> SetStatusFromAuthority(Guid applicationId, AuthorityRequestStatuses status, CancellationToken cancellationToken)
|
||||||
|
public async Task<IActionResult> SetStatusFromAuthority(Guid applicationId,
|
||||||
|
AuthorityRequestStatuses status,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
await visaApplicationRequestsHandler.SetApplicationStatusFromAuthorityAsync(applicationId, status, cancellationToken);
|
await visaApplicationRequestsHandler.SetApplicationStatusFromAuthorityAsync(applicationId, status, cancellationToken);
|
||||||
return Ok();
|
return Ok();
|
||||||
|
|||||||
Reference in New Issue
Block a user