Validation fixes, finished application creation, added required char (*) for required fields
This commit is contained in:
13
SchengenVisaApi/ApplicationLayer/Constants.cs
Normal file
13
SchengenVisaApi/ApplicationLayer/Constants.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace ApplicationLayer
|
||||
{
|
||||
public static class Constants
|
||||
{
|
||||
public readonly static Regex EnglishWordRegex = new("^[a-zA-Z]*$");
|
||||
|
||||
public readonly static Regex EnglishPhraseRegex = new(@"^[a-zA-Z№0-9?><;,{}[\]\-_+=!@#$%\^&*|']*$");
|
||||
|
||||
public readonly static Regex PhoneNumRegex = new(@"^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$");
|
||||
}
|
||||
}
|
||||
@@ -10,16 +10,22 @@ public class NameModelValidator : AbstractValidator<NameModel>
|
||||
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}");
|
||||
}
|
||||
|
||||
@@ -11,12 +11,16 @@ public class PassportModelValidator : AbstractValidator<PassportModel>
|
||||
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}");
|
||||
|
||||
|
||||
@@ -10,12 +10,16 @@ public class PlaceOfWorkModelValidator : AbstractValidator<PlaceOfWorkModel>
|
||||
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}")
|
||||
@@ -23,27 +27,39 @@ public class PlaceOfWorkModelValidator : AbstractValidator<PlaceOfWorkModel>
|
||||
.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}");
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ public class AuthDataValidator : AbstractValidator<AuthData>
|
||||
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}");
|
||||
}
|
||||
|
||||
@@ -15,18 +15,23 @@ public class RegisterApplicantRequestValidator : AbstractValidator<RegisterAppli
|
||||
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)
|
||||
@@ -38,38 +43,51 @@ public class RegisterApplicantRequestValidator : AbstractValidator<RegisterAppli
|
||||
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.Gender)
|
||||
.IsInEnum();
|
||||
|
||||
RuleFor(r => r.MaritalStatus).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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ public class RegisterRequestValidator : AbstractValidator<RegisterRequest>
|
||||
public RegisterRequestValidator(IUsersRepository users, IValidator<AuthData> authDataValidator)
|
||||
{
|
||||
RuleFor(r => r.AuthData)
|
||||
.NotEmpty()
|
||||
.SetValidator(authDataValidator)
|
||||
.MustAsync(async (authData, ct) => await users.FindByEmailAsync(authData.Email, ct) is null)
|
||||
.WithMessage("Email already exists");
|
||||
|
||||
@@ -12,6 +12,7 @@ public class PastVisaModel
|
||||
|
||||
/// Name of visa
|
||||
[MaxLength(ConfigurationConstraints.VisaNameLength)]
|
||||
[Required]
|
||||
public string Name { get; set; } = null!;
|
||||
|
||||
/// Date when visa expires
|
||||
|
||||
@@ -16,5 +16,6 @@ public class PastVisitModel
|
||||
|
||||
/// Destination country of past visit
|
||||
[MaxLength(ConfigurationConstraints.CountryNameLength)]
|
||||
[Required]
|
||||
public string DestinationCountry { get; set; } = null!;
|
||||
}
|
||||
|
||||
@@ -12,5 +12,6 @@ public class PermissionToDestCountryModel
|
||||
|
||||
/// Issuing authority
|
||||
[MaxLength(ConfigurationConstraints.IssuerNameLength)]
|
||||
[Required]
|
||||
public string Issuer { get; set; } = null!;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using ApplicationLayer.InfrastructureServicesInterfaces;
|
||||
using Domains;
|
||||
using FluentValidation;
|
||||
|
||||
namespace ApplicationLayer.Services.VisaApplications.Models.Validation;
|
||||
@@ -21,6 +22,10 @@ public class PastVisaModelValidator : AbstractValidator<PastVisaModel>
|
||||
|
||||
RuleFor(v => v.Name)
|
||||
.NotEmpty()
|
||||
.WithMessage("Name of past visa can not be empty");
|
||||
.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}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ public class PastVisitModelValidator : AbstractValidator<PastVisitModel>
|
||||
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}");
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ public class PermissionToDestCountryModelValidator : AbstractValidator<Permissio
|
||||
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}");
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ public class ReentryPermitModelValidator : AbstractValidator<ReentryPermitModel?
|
||||
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}");
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
Client.AuthToken = token;
|
||||
AuthData = authData;
|
||||
|
||||
Status?.SetSucces("Logged in successfully.");
|
||||
Status?.SetSuccess("Logged in successfully.");
|
||||
}
|
||||
catch (ApiException<ProblemDetails> e)
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div>
|
||||
<div >
|
||||
<label>
|
||||
First name:<br/>
|
||||
First name@(Constants.RequiredFieldMarkup):<br/>
|
||||
<InputText DisplayName="First name" class="rounded" @bind-Value="Name.FirstName"/>
|
||||
</label><br/>
|
||||
<ValidationMessage For="() => Name.FirstName"></ValidationMessage>
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
<div >
|
||||
<label>
|
||||
Surname:<br/>
|
||||
Surname@(Constants.RequiredFieldMarkup):<br/>
|
||||
<InputText class="rounded" @bind-Value="Name.Surname"/>
|
||||
</label><br/>
|
||||
<ValidationMessage For="() => Name.Surname"></ValidationMessage>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
public void SetSucces(string message)
|
||||
public void SetSuccess(string message)
|
||||
{
|
||||
statusClass = "text-success";
|
||||
StatusText = message;
|
||||
|
||||
16
SchengenVisaApi/BlazorWebAssemblyVisaApiClient/Constants.cs
Normal file
16
SchengenVisaApi/BlazorWebAssemblyVisaApiClient/Constants.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace BlazorWebAssemblyVisaApiClient
|
||||
{
|
||||
public static class Constants
|
||||
{
|
||||
public readonly static Regex EnglishWordRegex = new("^[a-zA-Z]*$");
|
||||
|
||||
public readonly static Regex EnglishPhraseRegex = new(@"^[a-zA-Z№0-9?><;,{}[\]\-_+=!@#$%\^&*|']*$");
|
||||
|
||||
public readonly static Regex PhoneNumRegex = new(@"^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$");
|
||||
|
||||
public readonly static MarkupString RequiredFieldMarkup = (MarkupString)"<span style=\"color: red;\">*</span>";
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@
|
||||
<ObjectGraphDataAnnotationsValidator/>
|
||||
|
||||
<div class="form-block">
|
||||
<h5>Visa</h5>
|
||||
<h5>Visa@(Constants.RequiredFieldMarkup)</h5>
|
||||
<label>
|
||||
Destination Country:<br/>
|
||||
<InputText DisplayName="Destination Country" class="rounded" @bind-Value="requestModel.DestinationCountry"/>
|
||||
@@ -56,7 +56,7 @@
|
||||
|
||||
<div class="form-block">
|
||||
<h5>Past visas</h5>
|
||||
@if (currentPastVisa > 0)
|
||||
@if (requestModel.PastVisas.Count > 0)
|
||||
{
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
@@ -65,9 +65,8 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@for (var i = 0; i < currentPastVisa; i++)
|
||||
@foreach (var visa in requestModel.PastVisas)
|
||||
{
|
||||
var visa = requestModel.PastVisas[i];
|
||||
<tr>
|
||||
<th>@visa.Name</th>
|
||||
<th>@visa.IssueDate.ToString("d.MM.yyyy")</th>
|
||||
@@ -81,39 +80,94 @@
|
||||
</table>
|
||||
}
|
||||
<label>
|
||||
Name:
|
||||
<InputText DisplayName="Past visa name" @bind-Value="requestModel.PastVisas[currentPastVisa].Name"/>
|
||||
Name:<br/>
|
||||
<InputText DisplayName="Past visa name" class="rounded" @bind-Value="editableVisa.Name"/>
|
||||
</label><br/>
|
||||
<ValidationMessage For="() => requestModel.PastVisas[currentPastVisa].Name"></ValidationMessage><br/>
|
||||
<ValidationMessage For="() => editableVisa.Name"></ValidationMessage><br/>
|
||||
|
||||
<label>
|
||||
Issue date:<br/>
|
||||
<InputDate DisplayName="Past visa issue date"
|
||||
class="rounded"
|
||||
@bind-Value="requestModel.PastVisas[currentPastVisa].IssueDate"
|
||||
@bind-Value="editableVisa.IssueDate"
|
||||
max="@formattedNow"/>
|
||||
</label><br/>
|
||||
<ValidationMessage For="() => requestModel.PastVisas[currentPastVisa].IssueDate"></ValidationMessage><br/>
|
||||
<ValidationMessage For="() => editableVisa.IssueDate"></ValidationMessage><br/>
|
||||
|
||||
<label>
|
||||
Expiration date:<br/>
|
||||
<InputDate DisplayName="Past visa expiration date"
|
||||
class="rounded"
|
||||
@bind-Value="requestModel.PastVisas[currentPastVisa].ExpirationDate"
|
||||
min="@formattedNow"/>
|
||||
@bind-Value="editableVisa.ExpirationDate"/>
|
||||
</label><br/>
|
||||
<ValidationMessage For="() => requestModel.PastVisas[currentPastVisa].ExpirationDate"></ValidationMessage><br/>
|
||||
<ValidationMessage For="() => editableVisa.ExpirationDate"></ValidationMessage><br/>
|
||||
|
||||
<input type="button" class="btn-outline-primary"
|
||||
disabled="@(currentPastVisa == requestModel.PastVisas.Length - 1)"
|
||||
disabled="@(requestModel.PastVisas.Count == ConfigurationConstraints.MaxPastVisas)"
|
||||
@onclick="AddPastVisa" value="Add"/>
|
||||
<Status @ref="pastVisaStatus"/>
|
||||
</div>
|
||||
|
||||
<div class="form-block">
|
||||
<h5>Past visits</h5>
|
||||
@if (requestModel.PastVisits.Count > 0)
|
||||
{
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Destination Country</th><th>Start date</th><th>End date</th><th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var visit in requestModel.PastVisits)
|
||||
{
|
||||
<tr>
|
||||
<th>@visit.DestinationCountry</th>
|
||||
<th>@visit.StartDate.ToString("d.MM.yyyy")</th>
|
||||
<th>@visit.EndDate.ToString("d.MM.yyyy")</th>
|
||||
<th>
|
||||
<input type="button" class="border-danger" @onclick="() => RemovePastVisit(visit)" value="X"/>
|
||||
</th>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
<label>
|
||||
Destination Country:<br/>
|
||||
<InputText DisplayName="Past visit destination Country" class="rounded" @bind-Value="editableVisit.DestinationCountry"/>
|
||||
</label><br/>
|
||||
<ValidationMessage For="() => editableVisit.DestinationCountry"></ValidationMessage><br/>
|
||||
|
||||
<label>
|
||||
Start date:<br/>
|
||||
<InputDate DisplayName="Past visit start date"
|
||||
class="rounded"
|
||||
@bind-Value="editableVisit.StartDate"
|
||||
max="@formattedNow"/>
|
||||
</label><br/>
|
||||
<ValidationMessage For="() => editableVisit.StartDate"></ValidationMessage><br/>
|
||||
|
||||
<label>
|
||||
End date:<br/>
|
||||
<InputDate DisplayName="Past visit end date"
|
||||
class="rounded"
|
||||
@bind-Value="editableVisit.EndDate"
|
||||
max="@formattedNow"/>
|
||||
</label><br/>
|
||||
<ValidationMessage For="() => editableVisit.EndDate"></ValidationMessage><br/>
|
||||
|
||||
<input type="button" class="btn-outline-primary"
|
||||
disabled="@(requestModel.PastVisits.Count == ConfigurationConstraints.MaxPastVisits)"
|
||||
@onclick="AddPastVisit" value="Add"/>
|
||||
<Status @ref="pastVisitStatus"/>
|
||||
</div>
|
||||
|
||||
@if (requestModel.VisaCategory is VisaCategory.Transit)
|
||||
{
|
||||
requestModel.PermissionToDestCountry ??= NewPermissionToDestCountry();
|
||||
<div class="form-block">
|
||||
<h5>Permission to destination Country</h5>
|
||||
<h5>Permission to destination Country@(Constants.RequiredFieldMarkup)</h5>
|
||||
<PermissionToDestCountryInput PermissionToDestCountry="requestModel.PermissionToDestCountry"/>
|
||||
</div>
|
||||
}
|
||||
@@ -124,14 +178,14 @@
|
||||
|
||||
@if (isNonResident)
|
||||
{
|
||||
requestModel.ReentryPermit = NewReentryPermit();
|
||||
<div class="form-block">
|
||||
<h5>Re-entry permission</h5>
|
||||
<h5>Re-entry permission@(Constants.RequiredFieldMarkup)</h5>
|
||||
<ReentryPermitInput ReentryPermit="requestModel.ReentryPermit"/>
|
||||
</div>
|
||||
<br/>
|
||||
}
|
||||
|
||||
<input type="submit" class="btn-outline-primary" value="Register"/>
|
||||
<br/><input type="submit" class="btn-outline-primary" value="Register"/>
|
||||
<ValidationSummary/>
|
||||
<Status @ref="status"/>
|
||||
</EditForm>
|
||||
@@ -143,10 +197,11 @@
|
||||
private VisaApplicationCreateRequestModel requestModel = new();
|
||||
private Status status = null!;
|
||||
private Status pastVisaStatus = null!;
|
||||
private Status pastVisitStatus = null!;
|
||||
private bool isNonResident;
|
||||
private int currentPastVisa;
|
||||
private int currentPastVisit;
|
||||
private string formattedNow = null!;
|
||||
private PastVisaModel editableVisa = null!;
|
||||
private PastVisitModel editableVisit = null!;
|
||||
|
||||
[Inject] IDateTimeProvider DateTimeProvider { get; set; } = null!;
|
||||
|
||||
@@ -156,19 +211,16 @@
|
||||
|
||||
[Inject] IValidator<PastVisaModel> PastVisaModelValidator { get; set; } = null!;
|
||||
|
||||
[Inject] IValidator<PastVisitModel> PastVisitModelValidator { get; set; } = null!;
|
||||
|
||||
[Inject] IMapper Mapper { get; set; } = null!;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
requestModel.PastVisas = new PastVisaModel[ConfigurationConstraints.MaxPastVisas];
|
||||
for (var i = 0; i < requestModel.PastVisas.Length; i++)
|
||||
{
|
||||
requestModel.PastVisas[i] = new()
|
||||
{
|
||||
IssueDate = DateTimeProvider.Now(),
|
||||
ExpirationDate = DateTimeProvider.Now()
|
||||
};
|
||||
}
|
||||
editableVisa = NewPastVisa();
|
||||
editableVisit = NewPastVisit();
|
||||
requestModel.PermissionToDestCountry = NewPermissionToDestCountry();
|
||||
formattedNow = DateTimeProvider.FormattedNow();
|
||||
|
||||
try
|
||||
{
|
||||
@@ -178,16 +230,10 @@
|
||||
{
|
||||
ErrorHandler.Handle(e);
|
||||
}
|
||||
|
||||
formattedNow = DateTimeProvider.FormattedNow();
|
||||
requestModel.PermissionToDestCountry!.ExpirationDate = DateTimeProvider.Now();
|
||||
}
|
||||
|
||||
private async Task TryCreate()
|
||||
{
|
||||
requestModel.PastVisas = currentPastVisa == 0 ? [] : requestModel.PastVisas[..currentPastVisa];
|
||||
requestModel.PastVisits = currentPastVisit == 0 ? [] : requestModel.PastVisits[..currentPastVisit];
|
||||
|
||||
var validationResult = await VisaApplicationCreateRequestValidator.ValidateAsync(requestModel);
|
||||
if (!validationResult.IsValid)
|
||||
{
|
||||
@@ -201,7 +247,7 @@
|
||||
try
|
||||
{
|
||||
await Client.CreateApplicationAsync(request);
|
||||
status.SetSucces("Application created successfully.");
|
||||
status.SetSuccess("Application created successfully.");
|
||||
}
|
||||
catch (ApiException<ProblemDetails> e)
|
||||
{
|
||||
@@ -230,49 +276,87 @@
|
||||
}
|
||||
}
|
||||
|
||||
private PastVisaModel NewPastVisa()
|
||||
{
|
||||
return new()
|
||||
{
|
||||
ExpirationDate = DateTimeProvider.Now(),
|
||||
IssueDate = DateTimeProvider.Now()
|
||||
};
|
||||
}
|
||||
|
||||
private ReentryPermitModel NewReentryPermit()
|
||||
{
|
||||
return new()
|
||||
{
|
||||
ExpirationDate = DateTimeProvider.Now()
|
||||
};
|
||||
}
|
||||
|
||||
private PermissionToDestCountryModel NewPermissionToDestCountry()
|
||||
{
|
||||
return new()
|
||||
{
|
||||
ExpirationDate = DateTimeProvider.Now()
|
||||
};
|
||||
}
|
||||
|
||||
private PastVisitModel NewPastVisit()
|
||||
{
|
||||
return new()
|
||||
{
|
||||
StartDate = DateTimeProvider.Now(),
|
||||
EndDate = DateTimeProvider.Now()
|
||||
};
|
||||
}
|
||||
|
||||
private void AddPastVisa()
|
||||
{
|
||||
var validationResult = PastVisaModelValidator.Validate(requestModel.PastVisas[currentPastVisa]);
|
||||
if (requestModel.PastVisas.Count >= ConfigurationConstraints.MaxPastVisas)
|
||||
{
|
||||
pastVisaStatus.SetError($"{ConfigurationConstraints.MaxPastVisas} past visas is maximum");
|
||||
return;
|
||||
}
|
||||
|
||||
var validationResult = PastVisaModelValidator.Validate(editableVisa);
|
||||
if (!validationResult.IsValid)
|
||||
{
|
||||
pastVisaStatus.SetError(validationResult.ToErrorsString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentPastVisa < requestModel.PastVisas.Length - 1)
|
||||
{
|
||||
currentPastVisa++;
|
||||
pastVisaStatus.SetSucces("Added");
|
||||
}
|
||||
else
|
||||
{
|
||||
pastVisaStatus.SetError($"{requestModel.PastVisas.Length} past visas is maximum");
|
||||
}
|
||||
requestModel.PastVisas.Add(editableVisa);
|
||||
editableVisa = NewPastVisa();
|
||||
pastVisaStatus.SetSuccess("Added successfully");
|
||||
}
|
||||
|
||||
private void RemovePastVisa(PastVisaModel visa)
|
||||
{
|
||||
currentPastVisa--;
|
||||
var found = false;
|
||||
requestModel.PastVisas.Remove(visa);
|
||||
}
|
||||
|
||||
if (requestModel.PastVisas[^1] == visa)
|
||||
private void AddPastVisit()
|
||||
{
|
||||
requestModel.PastVisas[^1] = new();
|
||||
if (requestModel.PastVisits.Count >= ConfigurationConstraints.MaxPastVisits)
|
||||
{
|
||||
pastVisitStatus.SetError($"{ConfigurationConstraints.MaxPastVisits} past visits is maximum");
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < requestModel.PastVisas.Length - 1; i++)
|
||||
var validationResult = PastVisitModelValidator.Validate(editableVisit);
|
||||
if (!validationResult.IsValid)
|
||||
{
|
||||
if (requestModel.PastVisas[i] == visa)
|
||||
{
|
||||
found = true;
|
||||
pastVisitStatus.SetError(validationResult.ToErrorsString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
requestModel.PastVisas[i] = requestModel.PastVisas[i + 1];
|
||||
}
|
||||
}
|
||||
requestModel.PastVisits.Add(editableVisit);
|
||||
editableVisit = NewPastVisit();
|
||||
pastVisitStatus.SetSuccess("Added successfully");
|
||||
}
|
||||
|
||||
private void RemovePastVisit(PastVisitModel visit)
|
||||
{
|
||||
requestModel.PastVisits.Remove(visit);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
@using BlazorWebAssemblyVisaApiClient.Components
|
||||
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Helpers
|
||||
@using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.DateTimeProvider
|
||||
@using BlazorWebAssemblyVisaApiClient.Validation
|
||||
@using BlazorWebAssemblyVisaApiClient.Validation.Applicants.Models
|
||||
@inherits BlazorWebAssemblyVisaApiClient.Components.Base.VisaClientComponentBase
|
||||
|
||||
@@ -20,7 +21,7 @@
|
||||
<ObjectGraphDataAnnotationsValidator/>
|
||||
|
||||
<div class="form-block">
|
||||
<h5>Authentication data</h5>
|
||||
<h5>Authentication data@(Constants.RequiredFieldMarkup)</h5>
|
||||
<AuthDataInput AuthData="requestModel.RegisterRequest.AuthData"/>
|
||||
</div>
|
||||
|
||||
@@ -40,12 +41,12 @@
|
||||
</div>
|
||||
|
||||
<div class="form-block">
|
||||
<h5>Your passport</h5>
|
||||
<h5>Your passport@(Constants.RequiredFieldMarkup)</h5>
|
||||
<PassportInput Passport="requestModel.Passport"/>
|
||||
</div>
|
||||
|
||||
<div class="form-block">
|
||||
<h5>Birth data</h5>
|
||||
<h5>Birth data@(Constants.RequiredFieldMarkup)</h5>
|
||||
<div >
|
||||
<label>
|
||||
Country of birth:<br/>
|
||||
@@ -59,14 +60,14 @@
|
||||
<ValidationMessage For="() => requestModel.CityOfBirth"></ValidationMessage><br/>
|
||||
<label>
|
||||
Birth date:<br/>
|
||||
<InputDate DisplayName="Birth date" class="rounded" @bind-Value="requestModel.BirthDate" max="@DateTimeProvider.FormattedNow()"/>
|
||||
<InputDate DisplayName="Birth date" class="rounded" @bind-Value="requestModel.BirthDate" max="@formattedMaxBirthdayDate"/>
|
||||
</label><br/>
|
||||
<ValidationMessage For="() => requestModel.BirthDate"></ValidationMessage>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-block">
|
||||
<h5>Citizenship</h5>
|
||||
<h5>Citizenship@(Constants.RequiredFieldMarkup)</h5>
|
||||
<div >
|
||||
<label>
|
||||
Citizenship:<br/>
|
||||
@@ -82,14 +83,14 @@
|
||||
</div>
|
||||
|
||||
<div class="form-block">
|
||||
<h5>Address of your place of work</h5>
|
||||
<h5>Address of your place of work@(Constants.RequiredFieldMarkup)</h5>
|
||||
<div >
|
||||
<AddressInput Address="requestModel.PlaceOfWork.Address"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-block">
|
||||
<h5>Place of work data</h5>
|
||||
<h5>Place of work data@(Constants.RequiredFieldMarkup)</h5>
|
||||
<div >
|
||||
<PlaceOfWorkInput PlaceOfWork="requestModel.PlaceOfWork"/><br/>
|
||||
|
||||
@@ -132,6 +133,7 @@
|
||||
{
|
||||
private RegisterApplicantRequestModel requestModel = new();
|
||||
private Status status = null!;
|
||||
private string formattedMaxBirthdayDate = null!;
|
||||
|
||||
[Inject] IValidator<RegisterApplicantRequestModel> RegisterApplicantRequestValidator { get; set; } = null!;
|
||||
|
||||
@@ -141,7 +143,8 @@
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
requestModel.BirthDate = DateTime.Now;
|
||||
requestModel.BirthDate = DateTime.Now.AddYears(-ConfigurationConstraints.ApplicantMinAge);
|
||||
formattedMaxBirthdayDate = requestModel.BirthDate.ToString("yyyy-MM-dd");
|
||||
}
|
||||
|
||||
private async void TryRegisterApplicant()
|
||||
@@ -161,7 +164,7 @@
|
||||
try
|
||||
{
|
||||
await Client.RegisterAsync(request);
|
||||
status.SetSucces("Register successful. Now log in.");
|
||||
status.SetSuccess("Register successful. Now log in.");
|
||||
}
|
||||
catch (ApiException<ProblemDetails> e)
|
||||
{
|
||||
|
||||
@@ -10,16 +10,22 @@ public class NameModelValidator : AbstractValidator<NameModel>
|
||||
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}");
|
||||
}
|
||||
|
||||
@@ -11,12 +11,16 @@ public class PassportModelValidator : AbstractValidator<PassportModel>
|
||||
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}");
|
||||
|
||||
|
||||
@@ -10,12 +10,16 @@ public class PlaceOfWorkModelValidator : AbstractValidator<PlaceOfWorkModel>
|
||||
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}")
|
||||
@@ -23,27 +27,39 @@ public class PlaceOfWorkModelValidator : AbstractValidator<PlaceOfWorkModel>
|
||||
.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}");
|
||||
}
|
||||
|
||||
@@ -11,23 +11,28 @@ public class RegisterApplicantRequestValidator : AbstractValidator<RegisterAppli
|
||||
public RegisterApplicantRequestValidator(
|
||||
IDateTimeProvider dateTimeProvider,
|
||||
IValidator<NameModel> nameValidator,
|
||||
IValidator<RegisterRequestModel> registerRequestModelValidator,
|
||||
IValidator<RegisterRequestModel> registerRequestValidator,
|
||||
IValidator<PassportModel> passportValidator,
|
||||
IValidator<PlaceOfWorkModel> placeOfWorkModelValidator)
|
||||
{
|
||||
RuleFor(r => r.RegisterRequest)
|
||||
.SetValidator(registerRequestModelValidator);
|
||||
.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)
|
||||
@@ -39,38 +44,51 @@ public class RegisterApplicantRequestValidator : AbstractValidator<RegisterAppli
|
||||
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.Gender)
|
||||
.IsInEnum();
|
||||
|
||||
RuleFor(r => r.MaritalStatus).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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ public class AuthDataValidator : AbstractValidator<AuthData>
|
||||
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}");
|
||||
}
|
||||
|
||||
@@ -4,11 +4,12 @@ using VisaApiClient;
|
||||
|
||||
namespace BlazorWebAssemblyVisaApiClient.Validation.Common;
|
||||
|
||||
public class RegisterRequestModelValidator : AbstractValidator<RegisterRequestModel>
|
||||
public class RegisterRequestValidator : AbstractValidator<RegisterRequestModel>
|
||||
{
|
||||
public RegisterRequestModelValidator(IValidator<AuthData> authDataValidator)
|
||||
public RegisterRequestValidator(IValidator<AuthData> authDataValidator)
|
||||
{
|
||||
RuleFor(r => r.AuthData)
|
||||
.NotEmpty()
|
||||
.SetValidator(authDataValidator);
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ namespace BlazorWebAssemblyVisaApiClient.Validation.VisaApplications.Models
|
||||
public class VisaApplicationCreateRequestModel
|
||||
{
|
||||
[ValidateComplexType]
|
||||
public ReentryPermitModel? ReentryPermit { get; set; } = new();
|
||||
public ReentryPermitModel? ReentryPermit { get; set; } = default!;
|
||||
|
||||
[Required]
|
||||
[MaxLength(ConfigurationConstraints.CountryNameLength)]
|
||||
@@ -26,11 +26,13 @@ namespace BlazorWebAssemblyVisaApiClient.Validation.VisaApplications.Models
|
||||
[Range(0, ConfigurationConstraints.MaxValidDays)]
|
||||
public int ValidDaysRequested { get; set; }
|
||||
|
||||
[ValidateComplexType] public PastVisaModel[] PastVisas { get; set; } = default!;
|
||||
[ValidateComplexType]
|
||||
public List<PastVisaModel> PastVisas { get; set; } = [];
|
||||
|
||||
[ValidateComplexType]
|
||||
public PermissionToDestCountryModel? PermissionToDestCountry { get; set; } = new();
|
||||
public PermissionToDestCountryModel? PermissionToDestCountry { get; set; } = default!;
|
||||
|
||||
[ValidateComplexType] public PastVisitModel[] PastVisits { get; set; } = default!;
|
||||
[ValidateComplexType]
|
||||
public List<PastVisitModel> PastVisits { get; set; } = [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ public class PastVisaModelValidator : AbstractValidator<PastVisaModel>
|
||||
|
||||
RuleFor(v => v.Name)
|
||||
.NotEmpty()
|
||||
.WithMessage("Name of past visa can not be empty");
|
||||
.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}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ public class PastVisitModelValidator : AbstractValidator<PastVisitModel>
|
||||
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}");
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ public class PermissionToDestCountryModelValidator : AbstractValidator<Permissio
|
||||
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");
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,18 @@
|
||||
using BlazorWebAssemblyVisaApiClient.Validation.VisaApplications.Models;
|
||||
using BlazorWebAssemblyVisaApiClient.Infrastructure.Services.UserDataProvider;
|
||||
using BlazorWebAssemblyVisaApiClient.Validation.VisaApplications.Models;
|
||||
using FluentValidation;
|
||||
using VisaApiClient;
|
||||
|
||||
namespace BlazorWebAssemblyVisaApiClient.Validation.VisaApplications.Validators;
|
||||
|
||||
public class VisaApplicationCreateRequestModelValidator : AbstractValidator<VisaApplicationCreateRequestModel>
|
||||
public class VisaApplicationCreateRequestValidator : AbstractValidator<VisaApplicationCreateRequestModel>
|
||||
{
|
||||
public VisaApplicationCreateRequestModelValidator(
|
||||
public VisaApplicationCreateRequestValidator(
|
||||
IValidator<ReentryPermitModel?> reentryPermitModelValidator,
|
||||
IValidator<PastVisaModel> pastVisaModelValidator,
|
||||
IValidator<PermissionToDestCountryModel?> permissionToDestCountryModelValidator,
|
||||
IValidator<PastVisitModel> pastVisitModelValidator)
|
||||
IValidator<PastVisitModel> pastVisitModelValidator,
|
||||
IUserDataProvider userDataProvider)
|
||||
{
|
||||
RuleFor(r => r.PermissionToDestCountry)
|
||||
.NotEmpty()
|
||||
@@ -17,6 +20,13 @@ public class VisaApplicationCreateRequestModelValidator : AbstractValidator<Visa
|
||||
.SetValidator(permissionToDestCountryModelValidator)
|
||||
.When(r => r.VisaCategory is VisaCategory.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");
|
||||
@@ -1799,9 +1799,10 @@ namespace VisaApiClient
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
public System.DateTimeOffset IssueDate { get; set; } = default!;
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(70)]
|
||||
public string? Name { get; set; } = default!;
|
||||
[Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(70, MinimumLength = 1)]
|
||||
public string Name { get; set; } = default!;
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("expirationDate", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
@@ -1820,9 +1821,10 @@ namespace VisaApiClient
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
public System.DateTimeOffset EndDate { get; set; } = default!;
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("destinationCountry", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(70)]
|
||||
public string? DestinationCountry { get; set; } = default!;
|
||||
[Newtonsoft.Json.JsonProperty("destinationCountry", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(70, MinimumLength = 1)]
|
||||
public string DestinationCountry { get; set; } = default!;
|
||||
|
||||
}
|
||||
|
||||
@@ -1833,9 +1835,10 @@ namespace VisaApiClient
|
||||
[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
|
||||
public System.DateTimeOffset ExpirationDate { get; set; } = default!;
|
||||
|
||||
[Newtonsoft.Json.JsonProperty("issuer", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(200)]
|
||||
public string? Issuer { get; set; } = default!;
|
||||
[Newtonsoft.Json.JsonProperty("issuer", Required = Newtonsoft.Json.Required.Always)]
|
||||
[System.ComponentModel.DataAnnotations.Required]
|
||||
[System.ComponentModel.DataAnnotations.StringLength(200, MinimumLength = 1)]
|
||||
public string Issuer { get; set; } = default!;
|
||||
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user