Вытащил солюшен на уровень выше, чтобы прощё было дотнетить
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is failing
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	continuous-integration/drone/push Build is failing
				
			This commit is contained in:
		| @@ -0,0 +1,18 @@ | ||||
| using System.ComponentModel.DataAnnotations; | ||||
|  | ||||
| namespace BlazorWebAssemblyVisaApiClient.Validation.Applicants.Models | ||||
| { | ||||
|     public enum MaritalStatusModel | ||||
|     { | ||||
|         Other = 0, | ||||
|  | ||||
|         Married = 1, | ||||
|  | ||||
|         Unmarried = 2, | ||||
|  | ||||
|         Separated = 3, | ||||
|  | ||||
|         [Display(Name = "Widow or widower")] | ||||
|         WidowOrWidower = 4 | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,20 @@ | ||||
| using System.ComponentModel.DataAnnotations; | ||||
| using VisaApiClient; | ||||
|  | ||||
| namespace BlazorWebAssemblyVisaApiClient.Validation.Applicants.Models; | ||||
|  | ||||
| /// Model of place of work with attributes required for validation to work | ||||
| public class PlaceOfWorkModel | ||||
| { | ||||
|     [Required] | ||||
|     [StringLength(ConfigurationConstraints.PlaceOfWorkNameLength, MinimumLength = 1)] | ||||
|     public string Name { get; set; } = default!; | ||||
|  | ||||
|     [Required] | ||||
|     [ValidateComplexType] | ||||
|     public AddressModel Address { get; set; } = new AddressModel(); | ||||
|  | ||||
|     [Required] | ||||
|     [StringLength(ConfigurationConstraints.PhoneNumberLength, MinimumLength = ConfigurationConstraints.PhoneNumberMinLength)] | ||||
|     public string PhoneNum { get; set; } = default!; | ||||
| } | ||||
| @@ -0,0 +1,67 @@ | ||||
| using System.ComponentModel.DataAnnotations; | ||||
| using Newtonsoft.Json; | ||||
| using Newtonsoft.Json.Converters; | ||||
| using VisaApiClient; | ||||
|  | ||||
| namespace BlazorWebAssemblyVisaApiClient.Validation.Applicants.Models; | ||||
|  | ||||
| /// Model of request with attributes required for validation to work | ||||
| public class RegisterApplicantRequestModel | ||||
| { | ||||
|     [Required] | ||||
|     [ValidateComplexType] | ||||
|     public RegisterRequestModel RegisterRequest { get; set; } = new(); | ||||
|  | ||||
|     [Required] | ||||
|     [ValidateComplexType] | ||||
|     public NameModel ApplicantName { get; set; } = new(); | ||||
|  | ||||
|     [Required] | ||||
|     [ValidateComplexType] | ||||
|     public PassportModel Passport { get; set; } = new(); | ||||
|  | ||||
|     [Required(AllowEmptyStrings = true)] | ||||
|     public DateTimeOffset BirthDate { get; set; } | ||||
|  | ||||
|     [Required] | ||||
|     [StringLength(70, MinimumLength = 1)] | ||||
|     public string CityOfBirth { get; set; } = default!; | ||||
|  | ||||
|     [Required] | ||||
|     [StringLength(70, MinimumLength = 1)] | ||||
|     public string CountryOfBirth { get; set; } = default!; | ||||
|  | ||||
|     [Required] | ||||
|     [StringLength(30, MinimumLength = 1)] | ||||
|     public string Citizenship { get; set; } = default!; | ||||
|  | ||||
|     [Required] | ||||
|     [StringLength(30, MinimumLength = 1)] | ||||
|     public string CitizenshipByBirth { get; set; } = default!; | ||||
|  | ||||
|     [Required(AllowEmptyStrings = true)] | ||||
|     [JsonConverter(typeof(StringEnumConverter))] | ||||
|     public Gender Gender { get; set; } | ||||
|  | ||||
|     [Required(AllowEmptyStrings = true)] | ||||
|     [JsonConverter(typeof(StringEnumConverter))] | ||||
|     public MaritalStatusModel MaritalStatus { get; set; } | ||||
|  | ||||
|     [Required] | ||||
|     [ValidateComplexType] | ||||
|     public NameModel FatherName { get; set; } = new(); | ||||
|  | ||||
|     [Required] | ||||
|     [ValidateComplexType] | ||||
|     public NameModel MotherName { get; set; } = new(); | ||||
|  | ||||
|     [Required] | ||||
|     [StringLength(50, MinimumLength = 1)] | ||||
|     public string JobTitle { get; set; } = default!; | ||||
|  | ||||
|     [Required] | ||||
|     [ValidateComplexType] | ||||
|     public PlaceOfWorkModel PlaceOfWork { get; set; } = new(); | ||||
|  | ||||
|     public bool IsNonResident { get; set; } | ||||
| } | ||||
| @@ -0,0 +1,12 @@ | ||||
| using System.ComponentModel.DataAnnotations; | ||||
| using VisaApiClient; | ||||
|  | ||||
| namespace BlazorWebAssemblyVisaApiClient.Validation.Applicants.Models; | ||||
|  | ||||
| /// Model of request with attributes required for validation to work | ||||
| public class RegisterRequestModel | ||||
| { | ||||
|     [Required] | ||||
|     [ValidateComplexType] | ||||
|     public AuthData AuthData { get; set; } = new AuthData(); | ||||
| } | ||||
| @@ -0,0 +1,32 @@ | ||||
| using FluentValidation; | ||||
| using VisaApiClient; | ||||
|  | ||||
| namespace BlazorWebAssemblyVisaApiClient.Validation.Applicants.Validators; | ||||
|  | ||||
| public class NameModelValidator : AbstractValidator<NameModel> | ||||
| { | ||||
|     public NameModelValidator() | ||||
|     { | ||||
|         RuleFor(m => m.FirstName) | ||||
|             .NotEmpty() | ||||
|             .WithMessage("First Name can not be empty") | ||||
|             .Matches(Constants.EnglishWordRegex) | ||||
|             .WithMessage("First name must be in english characters") | ||||
|             .MaximumLength(ConfigurationConstraints.NameLength) | ||||
|             .WithMessage($"First Name length must be less than {ConfigurationConstraints.NameLength}"); | ||||
|  | ||||
|         RuleFor(m => m.Surname) | ||||
|             .NotEmpty() | ||||
|             .WithMessage("Surname can not be empty") | ||||
|             .Matches(Constants.EnglishWordRegex) | ||||
|             .WithMessage("Surname must be in english characters") | ||||
|             .MaximumLength(ConfigurationConstraints.NameLength) | ||||
|             .WithMessage($"Surname length must be less than {ConfigurationConstraints.NameLength}"); | ||||
|  | ||||
|         RuleFor(m => m.Patronymic) | ||||
|             .Matches(Constants.EnglishWordRegex) | ||||
|             .WithMessage("Patronymic must be in english characters") | ||||
|             .MaximumLength(ConfigurationConstraints.NameLength) | ||||
|             .WithMessage($"Patronymic length must be less than {ConfigurationConstraints.NameLength}"); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,39 @@ | ||||
| using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.DateTimeProvider; | ||||
| using FluentValidation; | ||||
| using VisaApiClient; | ||||
|  | ||||
| namespace BlazorWebAssemblyVisaApiClient.Validation.Applicants.Validators; | ||||
|  | ||||
| public class PassportModelValidator : AbstractValidator<PassportModel> | ||||
| { | ||||
|     public PassportModelValidator(IDateTimeProvider dateTimeProvider) | ||||
|     { | ||||
|         RuleFor(r => r.Issuer) | ||||
|             .NotEmpty() | ||||
|             .WithMessage("Passport issuer can not be empty") | ||||
|             .Matches(Constants.EnglishPhraseRegex) | ||||
|             .WithMessage("Passport issuer field can contain only english letters, digits and special symbols") | ||||
|             .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") | ||||
|             .Matches(Constants.EnglishPhraseRegex) | ||||
|             .WithMessage("Passport number field can contain only english letters, digits and special symbols") | ||||
|             .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,66 @@ | ||||
| using BlazorWebAssemblyVisaApiClient.Validation.Applicants.Models; | ||||
| using FluentValidation; | ||||
|  | ||||
| namespace BlazorWebAssemblyVisaApiClient.Validation.Applicants.Validators; | ||||
|  | ||||
| public class PlaceOfWorkModelValidator : AbstractValidator<PlaceOfWorkModel> | ||||
| { | ||||
|     public PlaceOfWorkModelValidator() | ||||
|     { | ||||
|         RuleFor(p => p.Name) | ||||
|             .NotEmpty() | ||||
|             .WithMessage("Place of work name can not be empty") | ||||
|             .Matches(Constants.EnglishPhraseRegex) | ||||
|             .WithMessage("Place of work name field can contain only english letters, digits and special symbols") | ||||
|             .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") | ||||
|             .Matches(Constants.PhoneNumRegex) | ||||
|             .WithMessage("Place of work phone number field must be valid") | ||||
|             .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) | ||||
|             .NotEmpty() | ||||
|             .WithMessage("Place of work address can not be empty"); | ||||
|  | ||||
|         RuleFor(p => p.Address.Country) | ||||
|             .NotEmpty() | ||||
|             .WithMessage("Country name of place of work can not be empty") | ||||
|             .Matches(Constants.EnglishPhraseRegex) | ||||
|             .WithMessage("Place of work Country field can contain only english letters, digits and special symbols") | ||||
|             .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") | ||||
|             .Matches(Constants.EnglishPhraseRegex) | ||||
|             .WithMessage("Place of work City field can contain only english letters, digits and special symbols") | ||||
|             .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") | ||||
|             .Matches(Constants.EnglishPhraseRegex) | ||||
|             .WithMessage("Place of work Street field can contain only english letters, digits and special symbols") | ||||
|             .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") | ||||
|             .Matches(Constants.EnglishPhraseRegex) | ||||
|             .WithMessage("Place of work building field can contain only english letters, digits and special symbols") | ||||
|             .MaximumLength(ConfigurationConstraints.CountryNameLength) | ||||
|             .WithMessage($"Building of place of work length must be less than {ConfigurationConstraints.BuildingNumberLength}"); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,94 @@ | ||||
| using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.DateTimeProvider; | ||||
| using BlazorWebAssemblyVisaApiClient.Validation.Applicants.Models; | ||||
| using FluentValidation; | ||||
| using VisaApiClient; | ||||
| using PlaceOfWorkModel = BlazorWebAssemblyVisaApiClient.Validation.Applicants.Models.PlaceOfWorkModel; | ||||
|  | ||||
| namespace BlazorWebAssemblyVisaApiClient.Validation.Applicants.Validators; | ||||
|  | ||||
| public class RegisterApplicantRequestValidator : AbstractValidator<RegisterApplicantRequestModel> | ||||
| { | ||||
|     public RegisterApplicantRequestValidator( | ||||
|         IDateTimeProvider dateTimeProvider, | ||||
|         IValidator<NameModel> nameValidator, | ||||
|         IValidator<RegisterRequestModel> registerRequestValidator, | ||||
|         IValidator<PassportModel> passportValidator, | ||||
|         IValidator<PlaceOfWorkModel> placeOfWorkModelValidator) | ||||
|     { | ||||
|         RuleFor(r => r.RegisterRequest) | ||||
|             .NotEmpty() | ||||
|             .SetValidator(registerRequestValidator); | ||||
|  | ||||
|         RuleFor(r => r.ApplicantName) | ||||
|             .NotEmpty() | ||||
|             .SetValidator(nameValidator); | ||||
|  | ||||
|         RuleFor(r => r.FatherName) | ||||
|             .NotEmpty() | ||||
|             .SetValidator(nameValidator); | ||||
|  | ||||
|         RuleFor(r => r.MotherName) | ||||
|             .NotEmpty() | ||||
|             .SetValidator(nameValidator); | ||||
|  | ||||
|         RuleFor(r => r.Passport) | ||||
|             .NotEmpty() | ||||
|             .SetValidator(passportValidator); | ||||
|  | ||||
|         RuleFor(r => r.BirthDate) | ||||
|             .NotEmpty() | ||||
|             .WithMessage("Birth date can not be empty") | ||||
|             .LessThanOrEqualTo(dateTimeProvider.Now().AddYears(-ConfigurationConstraints.ApplicantMinAge)) | ||||
|             .WithMessage($"Applicant must be older than {ConfigurationConstraints.ApplicantMinAge}"); | ||||
|  | ||||
|         RuleFor(r => r.CountryOfBirth) | ||||
|             .NotEmpty() | ||||
|             .WithMessage("Country of birth can not be empty") | ||||
|             .Matches(Constants.EnglishPhraseRegex) | ||||
|             .WithMessage("Country of birth field can contain only english letters, digits and special symbols") | ||||
|             .MaximumLength(ConfigurationConstraints.CountryNameLength) | ||||
|             .WithMessage($"Country of birth name length must be less than {ConfigurationConstraints.CountryNameLength}"); | ||||
|  | ||||
|         RuleFor(r => r.CityOfBirth) | ||||
|             .NotEmpty() | ||||
|             .WithMessage("City of birth can not be empty") | ||||
|             .Matches(Constants.EnglishPhraseRegex) | ||||
|             .WithMessage("City of birth field can contain only english letters, digits and special symbols") | ||||
|             .MaximumLength(ConfigurationConstraints.CityNameLength) | ||||
|             .WithMessage($"City of birth name length must be less than {ConfigurationConstraints.CityNameLength}"); | ||||
|  | ||||
|         RuleFor(r => r.Citizenship) | ||||
|             .NotEmpty() | ||||
|             .WithMessage("Citizenship can not be empty") | ||||
|             .Matches(Constants.EnglishPhraseRegex) | ||||
|             .WithMessage("Citizenship field can contain only english letters, digits and special symbols") | ||||
|             .MaximumLength(ConfigurationConstraints.CitizenshipLength) | ||||
|             .WithMessage($"Citizenship length must be less than {ConfigurationConstraints.CitizenshipLength}"); | ||||
|  | ||||
|         RuleFor(r => r.CitizenshipByBirth) | ||||
|             .NotEmpty() | ||||
|             .WithMessage("Citizenship by birth can not be empty") | ||||
|             .Matches(Constants.EnglishPhraseRegex) | ||||
|             .WithMessage("Citizenship by birth field can contain only english letters, digits and special symbols") | ||||
|             .MaximumLength(ConfigurationConstraints.CitizenshipLength) | ||||
|             .WithMessage($"Citizenship by birth length must be less than {ConfigurationConstraints.CitizenshipLength}"); | ||||
|  | ||||
|         RuleFor(r => r.Gender) | ||||
|             .IsInEnum(); | ||||
|  | ||||
|         RuleFor(r => r.MaritalStatus) | ||||
|             .IsInEnum(); | ||||
|  | ||||
|         RuleFor(r => r.JobTitle) | ||||
|             .NotEmpty() | ||||
|             .WithMessage("Title of job can not be empty") | ||||
|             .Matches(Constants.EnglishPhraseRegex) | ||||
|             .WithMessage("Title of job field can contain only english letters, digits and special symbols") | ||||
|             .MaximumLength(ConfigurationConstraints.JobTitleLength) | ||||
|             .WithMessage($"Title of job length must be less than {ConfigurationConstraints.JobTitleLength}"); | ||||
|  | ||||
|         RuleFor(r => r.PlaceOfWork) | ||||
|             .NotEmpty() | ||||
|             .SetValidator(placeOfWorkModelValidator); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,26 @@ | ||||
| using FluentValidation; | ||||
| using VisaApiClient; | ||||
|  | ||||
| namespace BlazorWebAssemblyVisaApiClient.Validation.Auth; | ||||
|  | ||||
| public class AuthDataValidator : AbstractValidator<AuthData> | ||||
| { | ||||
|     public AuthDataValidator() | ||||
|     { | ||||
|         RuleFor(d => d.Email) | ||||
|             .NotEmpty() | ||||
|             .WithMessage("Email can not be empty") | ||||
|             .EmailAddress() | ||||
|             .WithMessage("Email must be valid") | ||||
|             .MaximumLength(ConfigurationConstraints.EmailLength) | ||||
|             .WithMessage($"Email length must be less than {ConfigurationConstraints.EmailLength}"); | ||||
|  | ||||
|         RuleFor(d => d.Password) | ||||
|             .NotEmpty() | ||||
|             .WithMessage("Password can not be empty") | ||||
|             .Matches(Constants.EnglishPhraseRegex) | ||||
|             .WithMessage("Password can contain only english letters, digits and special symbols") | ||||
|             .MaximumLength(ConfigurationConstraints.PasswordLength) | ||||
|             .WithMessage($"Password length must be less than {ConfigurationConstraints.PasswordLength}"); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,20 @@ | ||||
| using FluentValidation; | ||||
| using VisaApiClient; | ||||
|  | ||||
| namespace BlazorWebAssemblyVisaApiClient.Validation.Auth; | ||||
|  | ||||
| public class ChangeUserAuthDataRequestValidator : AbstractValidator<ChangeUserAuthDataRequest> | ||||
| { | ||||
|     public ChangeUserAuthDataRequestValidator() | ||||
|     { | ||||
|             RuleFor(r => r.NewAuthData) | ||||
|                 .NotEmpty(); | ||||
|  | ||||
|             RuleFor(r => r.NewAuthData.Email) | ||||
|                 .NotEmpty() | ||||
|                 .EmailAddress() | ||||
|                 .WithMessage("Email should be valid") | ||||
|                 .MaximumLength(ConfigurationConstraints.EmailLength) | ||||
|                 .WithMessage($"Email address length must be less than {ConfigurationConstraints.EmailLength}"); | ||||
|         } | ||||
| } | ||||
| @@ -0,0 +1,15 @@ | ||||
| using BlazorWebAssemblyVisaApiClient.Validation.Applicants.Models; | ||||
| using FluentValidation; | ||||
| using VisaApiClient; | ||||
|  | ||||
| namespace BlazorWebAssemblyVisaApiClient.Validation.Auth; | ||||
|  | ||||
| public class RegisterRequestModelValidator : AbstractValidator<RegisterRequestModel> | ||||
| { | ||||
|     public RegisterRequestModelValidator(IValidator<AuthData> authDataValidator) | ||||
|     { | ||||
|         RuleFor(r => r.AuthData) | ||||
|             .NotEmpty() | ||||
|             .SetValidator(authDataValidator); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,25 @@ | ||||
| namespace BlazorWebAssemblyVisaApiClient.Validation; | ||||
|  | ||||
| public static class ConfigurationConstraints | ||||
| { | ||||
|     public const int CityNameLength = 70; | ||||
|     public const int CountryNameLength = 70; | ||||
|     public const int CitizenshipLength = 30; | ||||
|     public const int ReentryPermitNumberLength = 25; | ||||
|     public const int IssuerNameLength = 200; | ||||
|     public const int VisaNameLength = 70; | ||||
|     public const int StreetNameLength = 100; | ||||
|     public const int PlaceOfWorkNameLength = 200; | ||||
|     public const int NameLength = 50; | ||||
|     public const int BuildingNumberLength = 10; | ||||
|     public const int PassportNumberLength = 20; | ||||
|     public const int PhoneNumberLength = 13; | ||||
|     public const int PhoneNumberMinLength = 11; | ||||
|     public const int EmailLength = 254; | ||||
|     public const int PasswordLength = 50; | ||||
|     public const int ApplicantMinAge = 14; | ||||
|     public const int JobTitleLength = 50; | ||||
|     public const int MaxValidDays = 90; | ||||
|     public const int MaxPastVisas = 10; | ||||
|     public const int MaxPastVisits = 10; | ||||
| } | ||||
| @@ -0,0 +1,37 @@ | ||||
| using System.ComponentModel.DataAnnotations; | ||||
| using VisaApiClient; | ||||
|  | ||||
| namespace BlazorWebAssemblyVisaApiClient.Validation.VisaApplications.Models; | ||||
|  | ||||
| /// Model for request for data annotations validation to work | ||||
| public class VisaApplicationCreateRequestModel | ||||
| { | ||||
|     [ValidateComplexType] | ||||
|     public ReentryPermitModel? ReentryPermit { get; set; } = default!; | ||||
|  | ||||
|     [Required] | ||||
|     [MaxLength(ConfigurationConstraints.CountryNameLength)] | ||||
|     public string DestinationCountry { get; set; } = default!; | ||||
|  | ||||
|     [Required] | ||||
|     public VisaCategoryModel 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; } | ||||
|  | ||||
|     [ValidateComplexType] | ||||
|     public List<PastVisaModel> PastVisas { get; set; } = []; | ||||
|  | ||||
|     [ValidateComplexType] | ||||
|     public PermissionToDestCountryModel? PermissionToDestCountry { get; set; } = default!; | ||||
|  | ||||
|     [ValidateComplexType] | ||||
|     public List<PastVisitModel> PastVisits { get; set; } = []; | ||||
| } | ||||
| @@ -0,0 +1,11 @@ | ||||
| using System.ComponentModel.DataAnnotations; | ||||
|  | ||||
| namespace BlazorWebAssemblyVisaApiClient.Validation.VisaApplications.Models | ||||
| { | ||||
|     public enum VisaCategoryModel | ||||
|     { | ||||
|         Transit = 0, | ||||
|         [Display(Name = "Short dated")] | ||||
|         ShortDated = 1 | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,31 @@ | ||||
| using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.DateTimeProvider; | ||||
| using FluentValidation; | ||||
| using VisaApiClient; | ||||
|  | ||||
| namespace BlazorWebAssemblyVisaApiClient.Validation.VisaApplications.Validators; | ||||
|  | ||||
| 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") | ||||
|             .Matches(Constants.EnglishPhraseRegex) | ||||
|             .WithMessage("Name of past visa can contain only english letters, digits and special symbols") | ||||
|             .MaximumLength(ConfigurationConstraints.VisaNameLength) | ||||
|             .WithMessage($"Past visa name length must be less than {ConfigurationConstraints.VisaNameLength}"); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,31 @@ | ||||
| using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.DateTimeProvider; | ||||
| using FluentValidation; | ||||
| using VisaApiClient; | ||||
|  | ||||
| namespace BlazorWebAssemblyVisaApiClient.Validation.VisaApplications.Validators; | ||||
|  | ||||
| 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") | ||||
|             .Matches(Constants.EnglishPhraseRegex) | ||||
|             .WithMessage("Destination Country of past visit can contain only english letters, digits and special symbols") | ||||
|             .MaximumLength(ConfigurationConstraints.CountryNameLength) | ||||
|             .WithMessage($"Destination Country of past visit length must be less than {ConfigurationConstraints.CountryNameLength}"); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,25 @@ | ||||
| using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.DateTimeProvider; | ||||
| using FluentValidation; | ||||
| using VisaApiClient; | ||||
|  | ||||
| namespace BlazorWebAssemblyVisaApiClient.Validation.VisaApplications.Validators; | ||||
|  | ||||
| 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") | ||||
|             .Matches(Constants.EnglishPhraseRegex) | ||||
|             .WithMessage("Issuer of permission for destination Country can contain only english letters, digits and special symbols") | ||||
|             .MaximumLength(ConfigurationConstraints.IssuerNameLength) | ||||
|             .WithMessage($"Issuer of permission to destination Country length must be less than {ConfigurationConstraints.IssuerNameLength}"); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,25 @@ | ||||
| using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.DateTimeProvider; | ||||
| using FluentValidation; | ||||
| using VisaApiClient; | ||||
|  | ||||
| namespace BlazorWebAssemblyVisaApiClient.Validation.VisaApplications.Validators; | ||||
|  | ||||
| public class ReentryPermitModelValidator : AbstractValidator<ReentryPermitModel?> | ||||
| { | ||||
|     public ReentryPermitModelValidator(IDateTimeProvider dateTimeProvider) | ||||
|     { | ||||
|         RuleFor(p => p!.Number) | ||||
|             .NotEmpty() | ||||
|             .WithMessage("Re-entry permit number can not be empty") | ||||
|             .Matches(Constants.EnglishPhraseRegex) | ||||
|             .WithMessage("Re-entry permit number can contain only english letters, digits and special symbols") | ||||
|             .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"); | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,52 @@ | ||||
| using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.UserDataProvider; | ||||
| using BlazorWebAssemblyVisaApiClient.Validation.VisaApplications.Models; | ||||
| using FluentValidation; | ||||
| using VisaApiClient; | ||||
|  | ||||
| namespace BlazorWebAssemblyVisaApiClient.Validation.VisaApplications.Validators; | ||||
|  | ||||
| public class VisaApplicationCreateRequestValidator : AbstractValidator<VisaApplicationCreateRequestModel> | ||||
| { | ||||
|     public VisaApplicationCreateRequestValidator( | ||||
|         IValidator<ReentryPermitModel?> reentryPermitModelValidator, | ||||
|         IValidator<PastVisaModel> pastVisaModelValidator, | ||||
|         IValidator<PermissionToDestCountryModel?> permissionToDestCountryModelValidator, | ||||
|         IValidator<PastVisitModel> pastVisitModelValidator, | ||||
|         IUserDataProvider userDataProvider) | ||||
|     { | ||||
|         RuleFor(r => r.PermissionToDestCountry) | ||||
|             .NotEmpty() | ||||
|             .WithMessage("For transit you must provide permission to destination country") | ||||
|             .SetValidator(permissionToDestCountryModelValidator) | ||||
|             .When(r => r.VisaCategory is VisaCategoryModel.Transit); | ||||
|  | ||||
|         RuleFor(r => r.ReentryPermit) | ||||
|             .NotEmpty() | ||||
|             .WithMessage("Non-residents must provide re-entry permission") | ||||
|             .SetValidator(reentryPermitModelValidator) | ||||
|             .WhenAsync(async (_, _) => | ||||
|                 (await userDataProvider.GetApplicant()).IsNonResident); | ||||
|  | ||||
|         RuleFor(r => r.DestinationCountry) | ||||
|             .NotEmpty() | ||||
|             .WithMessage("Destination country can not be empty"); | ||||
|  | ||||
|         RuleFor(r => r.VisaCategory) | ||||
|             .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}"); | ||||
|  | ||||
|         RuleForEach(r => r.PastVisas) | ||||
|             .SetValidator(pastVisaModelValidator); | ||||
|  | ||||
|         RuleForEach(r => r.PastVisits) | ||||
|             .SetValidator(pastVisitModelValidator); | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user