Skip to content

Commit

Permalink
feat: Add validator interfaces and register to DI (#89)
Browse files Browse the repository at this point in the history
* feat: Add validator interfaces and register to DI
* feat:  Add AddressIsEmpty property to CsvMember
  • Loading branch information
alexeyshibanov committed Feb 1, 2024
1 parent 4cebc42 commit 3fe248b
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 47 deletions.
Expand Up @@ -84,6 +84,14 @@ public abstract class CsvMember : IExportable, IHasOuterId, IHasDynamicPropertie
[Ignore, JsonIgnore]
public string ObjectType { get; set; }

[Ignore, JsonIgnore]
public bool AddressIsEmpty =>
string.IsNullOrEmpty(AddressType) && string.IsNullOrEmpty(AddressFirstName) && string.IsNullOrEmpty(AddressLastName) &&
string.IsNullOrEmpty(AddressCountry) && string.IsNullOrEmpty(AddressCountryCode) &&
string.IsNullOrEmpty(AddressRegion) && string.IsNullOrEmpty(AddressRegionCode) &&
string.IsNullOrEmpty(AddressCity) && string.IsNullOrEmpty(AddressLine1) && string.IsNullOrEmpty(AddressLine2) &&
string.IsNullOrEmpty(AddressZipCode) && string.IsNullOrEmpty(AddressEmail) && string.IsNullOrEmpty(AddressPhone);

public ICollection<DynamicObjectProperty> DynamicProperties { get; set; }

public bool IdsEquals(Member member) =>
Expand Down Expand Up @@ -122,8 +130,7 @@ protected void PatchDynamicProperties(Member target)
protected void PatchAddresses(Member target)
{
target.Addresses ??= new List<Address>();
var isAddressSpecified = new[] { AddressCountry, AddressCountryCode, AddressRegion, AddressCity, AddressLine1, AddressLine2, AddressZipCode }.Any(addressField => !string.IsNullOrEmpty(addressField));
if (!isAddressSpecified)
if (AddressIsEmpty)
{
return;
}
Expand Down
@@ -0,0 +1,9 @@
using FluentValidation;
using VirtoCommerce.CustomerExportImportModule.Core.Models;

namespace VirtoCommerce.CustomerExportImportModule.Data.Validation;

public interface IImportAddressValidator<T> : IValidator<ImportRecord<T>>
where T : CsvMember
{
}
@@ -0,0 +1,9 @@
using FluentValidation;
using VirtoCommerce.CustomerExportImportModule.Core.Models;

namespace VirtoCommerce.CustomerExportImportModule.Data.Validation;

public interface IImportMemberValidator<T> : IValidator<ImportRecord<T>>
where T : CsvMember
{
}
@@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using FluentValidation;
Expand All @@ -11,7 +10,7 @@

namespace VirtoCommerce.CustomerExportImportModule.Data.Validation
{
public class ImportAddressValidator<T> : AbstractValidator<ImportRecord<T>>
public class ImportAddressValidator<T> : AbstractValidator<ImportRecord<T>>, IImportAddressValidator<T>
where T : CsvMember
{
private readonly ICountriesService _countriesService;
Expand All @@ -27,12 +26,8 @@ public ImportAddressValidator(ICountriesService countriesService, ISettingsManag

private void AttachValidators()
{
When(x => Array.Exists(new[]
{
x.Record.AddressType, x.Record.AddressLine1, x.Record.AddressLine2, x.Record.AddressCity, x.Record.AddressRegion, x.Record.AddressRegionCode, x.Record.AddressCountryCode, x.Record.AddressCountry,
x.Record.AddressFirstName, x.Record.AddressLastName, x.Record.AddressPhone, x.Record.AddressEmail, x.Record.AddressZipCode,
}, field => !string.IsNullOrEmpty(field))
, () =>
When(x => !x.Record.AddressIsEmpty,
() =>
{
RuleFor(x => x.Record.AddressType)
.IsEnumName(typeof(AddressType))
Expand Down
Expand Up @@ -2,8 +2,6 @@
using Microsoft.AspNetCore.Identity;
using VirtoCommerce.CustomerExportImportModule.Core.Models;
using VirtoCommerce.CustomerModule.Core.Services;
using VirtoCommerce.Platform.Core.Common;
using VirtoCommerce.Platform.Core.DynamicProperties;
using VirtoCommerce.Platform.Core.Security;
using VirtoCommerce.Platform.Core.Settings;
using VirtoCommerce.StoreModule.Core.Services;
Expand All @@ -12,20 +10,22 @@ namespace VirtoCommerce.CustomerExportImportModule.Data.Validation
{
public sealed class ImportContactsValidator: AbstractValidator<ImportRecord<ImportableContact>[]>
{
private readonly ICountriesService _countriesService;
private readonly IDynamicPropertyDictionaryItemsSearchService _dynamicPropertyDictionaryItemsSearchService;
private readonly IImportMemberValidator<ImportableContact> _memberValidator;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly IPasswordValidator<ApplicationUser> _passwordValidator;
private readonly IMemberService _memberService;
private readonly IStoreSearchService _storeSearchService;
private readonly ISettingsManager _settingsManager;

public ImportContactsValidator(ICountriesService countriesService, IDynamicPropertyDictionaryItemsSearchService dynamicPropertyDictionaryItemsSearchService,
SignInManager<ApplicationUser> signInManager, IPasswordValidator<ApplicationUser> passwordValidator, IMemberService memberService,
IStoreSearchService storeSearchService, ISettingsManager settingsManager)
public ImportContactsValidator(
IImportMemberValidator<ImportableContact> memberValidator,
SignInManager<ApplicationUser> signInManager,
IPasswordValidator<ApplicationUser> passwordValidator,
IMemberService memberService,
IStoreSearchService storeSearchService,
ISettingsManager settingsManager)
{
_countriesService = countriesService;
_dynamicPropertyDictionaryItemsSearchService = dynamicPropertyDictionaryItemsSearchService;
_memberValidator = memberValidator;
_signInManager = signInManager;
_passwordValidator = passwordValidator;
_memberService = memberService;
Expand All @@ -39,7 +39,7 @@ private void AttachValidators()
{
RuleFor(importRecords => importRecords).SetValidator(_ => new ImportEntitiesAreNotDuplicatesValidator<ImportableContact>());
RuleFor(importRecords => importRecords).SetValidator(_ => new ImportEntitiesAdditionalLinesValidator<ImportableContact>());
RuleForEach(importRecords => importRecords).SetValidator(new ImportMemberValidator<ImportableContact>(_countriesService, _dynamicPropertyDictionaryItemsSearchService, _settingsManager));
RuleForEach(importRecords => importRecords).SetValidator(_memberValidator);
RuleForEach(importRecords => importRecords).SetValidator(allRecords => new ImportContactValidator(_signInManager.UserManager, _passwordValidator, _memberService, _storeSearchService, _settingsManager, allRecords));
}
}
Expand Down
@@ -1,30 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using FluentValidation;
using FluentValidation.Validators;
using VirtoCommerce.CustomerExportImportModule.Core;
using VirtoCommerce.CustomerExportImportModule.Core.Models;
using VirtoCommerce.CustomerExportImportModule.Data.Helpers;
using VirtoCommerce.Platform.Core.Common;
using VirtoCommerce.Platform.Core.DynamicProperties;
using VirtoCommerce.Platform.Core.Settings;

namespace VirtoCommerce.CustomerExportImportModule.Data.Validation
{
public class ImportMemberValidator<T>: AbstractValidator<ImportRecord<T>>
where T: CsvMember
public class ImportMemberValidator<T> : AbstractValidator<ImportRecord<T>>, IImportMemberValidator<T>
where T : CsvMember
{
private readonly IImportAddressValidator<T> _addressValidator;
private readonly ICountriesService _countriesService;
private readonly ISettingsManager _settingsManager;
private readonly IDynamicPropertyDictionaryItemsSearchService _dynamicPropertyDictionaryItemsSearchService;

public ImportMemberValidator(ICountriesService countriesService, IDynamicPropertyDictionaryItemsSearchService dynamicPropertyDictionaryItemsSearchService, ISettingsManager settingsManager)
public ImportMemberValidator(
IImportAddressValidator<T> addressValidator,
ICountriesService countriesService,
IDynamicPropertyDictionaryItemsSearchService dynamicPropertyDictionaryItemsSearchService)
{
_addressValidator = addressValidator;
_countriesService = countriesService;
_dynamicPropertyDictionaryItemsSearchService = dynamicPropertyDictionaryItemsSearchService;
_settingsManager = settingsManager;
AttachValidators();
}

Expand All @@ -33,18 +35,28 @@ private void AttachValidators()
RuleFor(x => x.Record.Emails)
.Must(emailsColumnValue =>
{
var emails = string.IsNullOrEmpty(emailsColumnValue) ? null : emailsColumnValue.Split(',').Select(email => email.Trim()).ToList();
if (string.IsNullOrEmpty(emailsColumnValue))
{
return true;
}
var emails = emailsColumnValue.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
var emailValidator = new EmailValidator();
return emails == null || emails.All(email => emailValidator.Validate(email).IsValid);
return Array.TrueForAll(emails, email => emailValidator.Validate(email).IsValid);
})
.WithInvalidValueCodeAndMessage("Emails")
.WithImportState()
.DependentRules(() => {
RuleFor(x => x.Record.Emails)
.Must(emailsColumnValue =>
{
var emails = string.IsNullOrEmpty(emailsColumnValue) ? null : emailsColumnValue.Split(',').Select(email => email.Trim()).ToList();
return emails == null || emails.All(email => email.Length <= 254);
if (string.IsNullOrEmpty(emailsColumnValue))
{
return true;
}
var emails = emailsColumnValue.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
return Array.TrueForAll(emails, email => email.Length <= 254);
})
.WithErrorCode(ModuleConstants.ValidationErrors.ArrayValuesExceedingMaxLength)
.WithMessage(string.Format(ModuleConstants.ValidationMessages[ModuleConstants.ValidationErrors.ArrayValuesExceedingMaxLength], "Emails", 254))
Expand All @@ -54,14 +66,19 @@ private void AttachValidators()
RuleFor(x => x.Record.Phones)
.Must(phonesColumnValue =>
{
var phones = string.IsNullOrEmpty(phonesColumnValue) ? null : phonesColumnValue.Split(',').Select(phone => phone.Trim()).ToList();
return phones == null || phones.All(phone => phone.Length <= 64);
if (string.IsNullOrEmpty(phonesColumnValue))
{
return true;
}
var phones = phonesColumnValue.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries);
return Array.TrueForAll(phones, phone => phone.Length <= 64);
})
.WithErrorCode(ModuleConstants.ValidationErrors.ArrayValuesExceedingMaxLength)
.WithMessage(string.Format(ModuleConstants.ValidationMessages[ModuleConstants.ValidationErrors.ArrayValuesExceedingMaxLength], "Phones", 64))
.WithImportState();

RuleFor(x => x).CustomAsync(LoadCountriesAsync).SetValidator(_ => new ImportAddressValidator<T>(_countriesService,_settingsManager));
RuleFor(x => x).CustomAsync(LoadCountriesAsync).SetValidator(_addressValidator);

RuleFor(x => x.Record.DynamicProperties).CustomAsync(LoadDynamicPropertyDictionaryItems).SetValidator(record => new ImportDynamicPropertiesValidator<T>(record));
}
Expand Down
@@ -1,30 +1,23 @@
using FluentValidation;
using VirtoCommerce.CustomerExportImportModule.Core.Models;
using VirtoCommerce.Platform.Core.Common;
using VirtoCommerce.Platform.Core.DynamicProperties;
using VirtoCommerce.Platform.Core.Settings;

namespace VirtoCommerce.CustomerExportImportModule.Data.Validation
{
public sealed class ImportOrganizationsValidator : AbstractValidator<ImportRecord<ImportableOrganization>[]>
{
private readonly ICountriesService _countriesService;
private readonly IDynamicPropertyDictionaryItemsSearchService _dynamicPropertyDictionaryItemsSearchService;
private readonly ISettingsManager _settingsManager;
private readonly IImportMemberValidator<ImportableOrganization> _memberValidator;

public ImportOrganizationsValidator(ICountriesService countriesService, IDynamicPropertyDictionaryItemsSearchService dynamicPropertyDictionaryItemsSearchService, ISettingsManager settingsManager)
public ImportOrganizationsValidator(IImportMemberValidator<ImportableOrganization> memberValidator)
{
_countriesService = countriesService;
_dynamicPropertyDictionaryItemsSearchService = dynamicPropertyDictionaryItemsSearchService;
_settingsManager = settingsManager;
_memberValidator = memberValidator;
AttachValidators();
}

private void AttachValidators()
{
RuleFor(importRecords => importRecords).SetValidator(_ => new ImportEntitiesAreNotDuplicatesValidator<ImportableOrganization>());
RuleFor(importRecords => importRecords).SetValidator(_ => new ImportEntitiesAdditionalLinesValidator<ImportableOrganization>());
RuleForEach(importRecords => importRecords).SetValidator(new ImportMemberValidator<ImportableOrganization>(_countriesService, _dynamicPropertyDictionaryItemsSearchService, _settingsManager));
RuleForEach(importRecords => importRecords).SetValidator(_memberValidator);
RuleForEach(importRecords => importRecords).SetValidator(new ImportOrganizationValidator());
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/VirtoCommerce.CustomerExportImportModule.Web/Module.cs
Expand Up @@ -41,6 +41,10 @@ public void Initialize(IServiceCollection serviceCollection)
serviceCollection.AddTransient<ICsvCustomerDataValidator, CsvCustomerDataValidator>();
serviceCollection.AddTransient<IValidator<ImportRecord<ImportableContact>[]>, ImportContactsValidator>();
serviceCollection.AddTransient<IValidator<ImportRecord<ImportableOrganization>[]>, ImportOrganizationsValidator>();
serviceCollection.AddTransient<IImportMemberValidator<ImportableContact>, ImportMemberValidator<ImportableContact>>();
serviceCollection.AddTransient<IImportMemberValidator<ImportableOrganization>, ImportMemberValidator<ImportableOrganization>>();
serviceCollection.AddTransient<IImportAddressValidator<ImportableContact>, ImportAddressValidator<ImportableContact>>();
serviceCollection.AddTransient<IImportAddressValidator<ImportableOrganization>, ImportAddressValidator<ImportableOrganization>>();

serviceCollection.AddTransient<IPasswordGenerator, PasswordGenerator>();

Expand Down
Expand Up @@ -752,8 +752,16 @@ private static ISettingsManager GetSettingsManager()
return settingsManagerMock.Object;
}

private static ImportContactsValidator GetContactsValidator() => new(GetCountriesService(), GetDynamicPropertyDictionaryItemsSearchService(), GetSignInManager(), GetPasswordValidator(), GetMemberService(), GetStoreSearchService(), GetSettingsManager());
private static ImportAddressValidator<ImportableContact> GetContactAddressValidator() => new(GetCountriesService(), GetSettingsManager());

private static ImportOrganizationsValidator GetOrganizationsValidator() => new(GetCountriesService(), GetDynamicPropertyDictionaryItemsSearchService(), GetSettingsManager());
private static ImportAddressValidator<ImportableOrganization> GetOrganizationAddressValidator() => new(GetCountriesService(), GetSettingsManager());

private static ImportMemberValidator<ImportableContact> GetContactMemberValidator() => new(GetContactAddressValidator(), GetCountriesService(), GetDynamicPropertyDictionaryItemsSearchService());

private static ImportMemberValidator<ImportableOrganization> GetOrganizationMemberValidator() => new(GetOrganizationAddressValidator(), GetCountriesService(), GetDynamicPropertyDictionaryItemsSearchService());

private static ImportContactsValidator GetContactsValidator() => new(GetContactMemberValidator(), GetSignInManager(), GetPasswordValidator(), GetMemberService(), GetStoreSearchService(), GetSettingsManager());

private static ImportOrganizationsValidator GetOrganizationsValidator() => new(GetOrganizationMemberValidator());
}
}

0 comments on commit 3fe248b

Please sign in to comment.