Поправил вывод сообщений об ошибках валидации.
This commit is contained in:
psemenkov 2023-08-11 11:29:40 +03:00
parent 6769f5cd20
commit c2a1f4a20a
9 changed files with 248 additions and 31 deletions

View file

@ -12,18 +12,18 @@ import ru.spcex.clearing.platform.messaging.domain.cud.account.CorrespondentAcco
import ru.spcex.clearing.platform.messaging.domain.cud.account.CorrespondentAccountUpdateRequest; import ru.spcex.clearing.platform.messaging.domain.cud.account.CorrespondentAccountUpdateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonIdRequest; import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonIdRequest;
import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule; import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule;
import ru.spcex.clearing.validation.common.rules.FieldRequiredRule;
import ru.spcex.clearing.validation.common.rules.IdPresentRule; import ru.spcex.clearing.validation.common.rules.IdPresentRule;
import ru.spcex.clearing.validation.common.rules.specific.FieldRequiredSpecificRule;
import ru.spcex.clearing.validation.common.rules.specific.IdPresentSpecificRule;
import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.enumeration.AccountStatus; import ru.spcex.platform.enumeration.AccountStatus;
import ru.spcex.platform.enumeration.AccountType; import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.enumeration.ServiceStatus;
import ru.spcex.platform.enumeration.WorkflowStatus;
import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.IErrorEnumId; import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidator; import ru.spcex.platform.utils.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl; import ru.spcex.platform.utils.validation.ValidatorImpl;
@ -57,7 +57,7 @@ public class AccountValidationConfig {
AccountError.CompanyNotFound AccountError.CompanyNotFound
// company -> WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? null : AccountError.CompanyNotActive // company -> WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? null : AccountError.CompanyNotActive
), ),
FieldRequiredRule.instance("account", FieldRequiredSpecificRule.instance("account",
CorrespondentAccountNewRequest::getAccount, CorrespondentAccountNewRequest::getAccount,
AccountError.RequiredFieldEmpty, AccountError.RequiredFieldEmpty,
accountValue -> { accountValue -> {
@ -70,7 +70,7 @@ public class AccountValidationConfig {
ImdgPredicate finalPredicate = pb.and(accountValuePredicate, accountStatusPredicate); ImdgPredicate finalPredicate = pb.and(accountValuePredicate, accountStatusPredicate);
Collection<Account> accounts = accountImdg.getCollectionObjectsByPredicate(finalPredicate); Collection<Account> accounts = accountImdg.getCollectionObjectsByPredicate(finalPredicate);
if (accounts.isEmpty()) return null; if (accounts.isEmpty()) return null;
return AccountError.AccountAlreadyExist; return new EnumMessage(AccountError.AccountAlreadyExist, accounts.stream().findFirst().get().getAccount());
}), }),
DictionaryPresentRule.instance("status", DictionaryPresentRule.instance("status",
CorrespondentAccountNewRequest::getStatus, CorrespondentAccountNewRequest::getStatus,
@ -159,14 +159,15 @@ public class AccountValidationConfig {
Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s)); Consumer<String> addImdg = (s) -> context.addImdg(s, imdgForValidation.get(s));
addImdg.accept(IMDGDistributedNames.Map_Account); addImdg.accept(IMDGDistributedNames.Map_Account);
return new ValidatorImpl<>(context, return new ValidatorImpl<>(context,
IdPresentRule.instance("id", IdPresentSpecificRule.instance("id",
CommonIdRequest::getId, CommonIdRequest::getId,
IMDGDistributedNames.Map_Account, IMDGDistributedNames.Map_Account,
Account.class, Account.class,
AccountError.RequiredFieldEmpty, AccountError.RequiredFieldEmpty,
AccountError.AccountNotFound, AccountError.AccountNotFound,
account -> { account -> {
if (AccountStatus.BLOCKED.equalsByKey(account.getStatus())) return AccountError.AccountNotActive; if (AccountStatus.BLOCKED.equalsByKey(account.getStatus()))
return new EnumMessage(AccountError.AccountNotActive, account.getAccount());
return null; return null;
}) })
); );

View file

@ -7,7 +7,6 @@ import ru.clearing.classes.statics.data.account.BankAccount;
import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.platform.dictionary.CurrencyCodeDictionary; import ru.clearing.platform.dictionary.CurrencyCodeDictionary;
import ru.clearing.platform.dictionary.ServiceStatusDictionary; import ru.clearing.platform.dictionary.ServiceStatusDictionary;
import ru.clearing.platform.dictionary.WorkflowStatusDictionary;
import ru.spcex.clearing.account.errors.AccountError; import ru.spcex.clearing.account.errors.AccountError;
import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.account.BankAccountNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.account.BankAccountNewRequest;
@ -16,15 +15,17 @@ import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonIdRequest;
import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule; import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule;
import ru.spcex.clearing.validation.common.rules.FieldRequiredRule; import ru.spcex.clearing.validation.common.rules.FieldRequiredRule;
import ru.spcex.clearing.validation.common.rules.IdPresentRule; import ru.spcex.clearing.validation.common.rules.IdPresentRule;
import ru.spcex.clearing.validation.common.rules.specific.FieldRequiredSpecificRule;
import ru.spcex.clearing.validation.common.rules.specific.IdPresentSpecificRule;
import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.enumeration.AccountStatus; import ru.spcex.platform.enumeration.AccountStatus;
import ru.spcex.platform.enumeration.AccountType; import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.enumeration.ServiceStatus;
import ru.spcex.platform.enumeration.WorkflowStatus;
import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidator; import ru.spcex.platform.utils.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl; import ru.spcex.platform.utils.validation.ValidatorImpl;
@ -57,7 +58,7 @@ public class BankAccountValidationConfig {
AccountError.RequiredFieldEmpty, AccountError.RequiredFieldEmpty,
AccountError.CompanyNotFound, AccountError.CompanyNotFound,
false), false),
FieldRequiredRule.instance("account", FieldRequiredSpecificRule.instance("account",
BankAccountNewRequest::getAccount, BankAccountNewRequest::getAccount,
AccountError.RequiredFieldEmpty, AccountError.RequiredFieldEmpty,
accountValue -> { accountValue -> {
@ -73,7 +74,7 @@ public class BankAccountValidationConfig {
accountTypePredicate); accountTypePredicate);
Collection<Account> accounts = accountImdg.getCollectionObjectsByPredicate(finalPredicate); Collection<Account> accounts = accountImdg.getCollectionObjectsByPredicate(finalPredicate);
if (accounts.isEmpty()) return null; if (accounts.isEmpty()) return null;
return AccountError.AccountAlreadyExist; return new EnumMessage(AccountError.AccountAlreadyExist, accounts.stream().findFirst().get().getAccount());
}), }),
DictionaryPresentRule.instance("currency", DictionaryPresentRule.instance("currency",
BankAccountNewRequest::getCurrency, BankAccountNewRequest::getCurrency,
@ -149,7 +150,7 @@ public class BankAccountValidationConfig {
addImdg.accept(IMDGDistributedNames.Map_BankAccount); addImdg.accept(IMDGDistributedNames.Map_BankAccount);
addImdg.accept(IMDGDistributedNames.Map_Account); addImdg.accept(IMDGDistributedNames.Map_Account);
return new ValidatorImpl<>(context, return new ValidatorImpl<>(context,
IdPresentRule.instance("id", IdPresentSpecificRule.instance("id",
CommonIdRequest::getId, CommonIdRequest::getId,
IMDGDistributedNames.Map_BankAccount, IMDGDistributedNames.Map_BankAccount,
BankAccount.class, BankAccount.class,
@ -161,8 +162,10 @@ public class BankAccountValidationConfig {
IMDGDistributedNames.Map_Account, Account.class IMDGDistributedNames.Map_Account, Account.class
); );
Account account = accountImdg.getSingleObjectByID(accountId); Account account = accountImdg.getSingleObjectByID(accountId);
if (account == null) return AccountError.AccountNotFound; if (account == null)
if (AccountStatus.BLOCKED.equalsByKey(account.getStatus())) return AccountError.AccountNotActive; return new EnumMessage(AccountError.AccountNotFound, accountId);
if (AccountStatus.BLOCKED.equalsByKey(account.getStatus()))
return new EnumMessage(AccountError.AccountNotActive, account.getAccount());
return null; return null;
}) })
); );

View file

@ -13,6 +13,7 @@ import ru.spcex.clearing.platform.messaging.domain.cud.account.ClearingAccountUp
import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule; import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule;
import ru.spcex.clearing.validation.common.rules.FieldRequiredRule; import ru.spcex.clearing.validation.common.rules.FieldRequiredRule;
import ru.spcex.clearing.validation.common.rules.IdPresentRule; import ru.spcex.clearing.validation.common.rules.IdPresentRule;
import ru.spcex.clearing.validation.common.rules.specific.FieldRequiredSpecificRule;
import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.enumeration.AccountType; import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.enumeration.ServiceStatus;
@ -20,6 +21,7 @@ import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidator; import ru.spcex.platform.utils.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl; import ru.spcex.platform.utils.validation.ValidatorImpl;
@ -53,7 +55,7 @@ public class ClearingAccountValidationConfig {
AccountError.CompanyNotFound AccountError.CompanyNotFound
// company -> !WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? AccountError.CompanyNotActive : null // company -> !WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? AccountError.CompanyNotActive : null
), ),
FieldRequiredRule.instance("account", FieldRequiredSpecificRule.instance("account",
ClearingAccountNewRequest::getAccount, ClearingAccountNewRequest::getAccount,
AccountError.RequiredFieldEmpty, AccountError.RequiredFieldEmpty,
accountValue -> { accountValue -> {
@ -69,7 +71,7 @@ public class ClearingAccountValidationConfig {
accountTypePredicate); accountTypePredicate);
Collection<Account> accounts = accountImdg.getCollectionObjectsByPredicate(finalPredicate); Collection<Account> accounts = accountImdg.getCollectionObjectsByPredicate(finalPredicate);
if (accounts.isEmpty()) return null; if (accounts.isEmpty()) return null;
return AccountError.AccountAlreadyExist; return new EnumMessage(AccountError.AccountAlreadyExist, accounts.stream().findFirst().get().getAccount());
}), }),
DictionaryPresentRule.instance("clearingAccountType", DictionaryPresentRule.instance("clearingAccountType",
ClearingAccountNewRequest::getClearingAccountType, ClearingAccountNewRequest::getClearingAccountType,

View file

@ -11,6 +11,7 @@ import ru.spcex.clearing.platform.messaging.domain.cud.account.DepoAccountNewReq
import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule; import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule;
import ru.spcex.clearing.validation.common.rules.FieldRequiredRule; import ru.spcex.clearing.validation.common.rules.FieldRequiredRule;
import ru.spcex.clearing.validation.common.rules.IdPresentRule; import ru.spcex.clearing.validation.common.rules.IdPresentRule;
import ru.spcex.clearing.validation.common.rules.specific.FieldRequiredSpecificRule;
import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.enumeration.AccountType; import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.ServiceStatus; import ru.spcex.platform.enumeration.ServiceStatus;
@ -18,6 +19,7 @@ import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidator; import ru.spcex.platform.utils.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl; import ru.spcex.platform.utils.validation.ValidatorImpl;
@ -50,7 +52,7 @@ public class DepoAccountValidationConfig {
AccountError.CompanyNotFound AccountError.CompanyNotFound
// company -> !WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? AccountError.CompanyNotActive : null // company -> !WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? AccountError.CompanyNotActive : null
), ),
FieldRequiredRule.instance("account", FieldRequiredSpecificRule.instance("account",
DepoAccountNewRequest::getAccount, DepoAccountNewRequest::getAccount,
AccountError.RequiredFieldEmpty, AccountError.RequiredFieldEmpty,
accountValue -> { accountValue -> {
@ -66,7 +68,7 @@ public class DepoAccountValidationConfig {
accountTypePredicate); accountTypePredicate);
Collection<Account> accounts = accountImdg.getCollectionObjectsByPredicate(finalPredicate); Collection<Account> accounts = accountImdg.getCollectionObjectsByPredicate(finalPredicate);
if (accounts.isEmpty()) return null; if (accounts.isEmpty()) return null;
return AccountError.AccountAlreadyExist; return new EnumMessage(AccountError.AccountAlreadyExist, accounts.stream().findFirst().get().getAccount());
}), }),
FieldRequiredRule.instance("depoAccountType", FieldRequiredRule.instance("depoAccountType",
DepoAccountNewRequest::getDepoAccountType, DepoAccountNewRequest::getDepoAccountType,

View file

@ -16,6 +16,7 @@ import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingR
import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule; import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule;
import ru.spcex.clearing.validation.common.rules.FieldRequiredRule; import ru.spcex.clearing.validation.common.rules.FieldRequiredRule;
import ru.spcex.clearing.validation.common.rules.IdPresentRule; import ru.spcex.clearing.validation.common.rules.IdPresentRule;
import ru.spcex.clearing.validation.common.rules.specific.IdPresentSpecificRule;
import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.enumeration.AccountType; import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.CompanySymbol; import ru.spcex.platform.enumeration.CompanySymbol;
@ -33,7 +34,6 @@ import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors;
@Configuration @Configuration
public class TradingClearingRegistryValidationConfig { public class TradingClearingRegistryValidationConfig {
@ -55,7 +55,7 @@ public class TradingClearingRegistryValidationConfig {
addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary); addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary);
addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry); addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistry);
return new ValidatorImpl<>(context, return new ValidatorImpl<>(context,
IdPresentRule.instance("companyId", IdPresentSpecificRule.instance("companyId",
TradingClearingRegistryNewRequest::getCompanyId, TradingClearingRegistryNewRequest::getCompanyId,
IMDGDistributedNames.Map_Company, IMDGDistributedNames.Map_Company,
Company.class, Company.class,
@ -68,7 +68,8 @@ public class TradingClearingRegistryValidationConfig {
"companyId", company.getId(), "companyId", company.getId(),
"companySymbol", CompanySymbol.CLRC.getKey() "companySymbol", CompanySymbol.CLRC.getKey()
)); ));
if (symbol == null) return AccountError.ClearingCompanySymbolNotFound; if (symbol == null)
return new EnumMessage(AccountError.ClearingCompanySymbolNotFound, company.getShortName());
return null; return null;
}), }),
FieldRequiredRule.instance("moneyAccountId", FieldRequiredRule.instance("moneyAccountId",
@ -155,8 +156,12 @@ public class TradingClearingRegistryValidationConfig {
if (existTCR.isEmpty()) { if (existTCR.isEmpty()) {
return empty(); return empty();
} else { } else {
String tcrIds = existTCR.stream().map(tcr -> String.valueOf(tcr.getId())).collect(Collectors.joining(";")); Imdg<Account> accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
return of(AccountError.AccountForTradingClearingRegistryAlreadyUsed, tcrIds); Account account = accountImdg.getSingleObjectByID(validatedObject.getMoneyAccountId());
if (account == null && validatedObject.getDepoAccountId() != null) account = accountImdg.getSingleObjectByID(validatedObject.getDepoAccountId());
return of(AccountError.AccountForTradingClearingRegistryAlreadyUsed, account.getAccount());
// String tcrIds = existTCR.stream().map(tcr -> String.valueOf(tcr.getId())).collect(Collectors.joining(";"));
// return of(AccountError.AccountForTradingClearingRegistryAlreadyUsed, tcrIds);
} }
} }
} }

View file

@ -0,0 +1,84 @@
package ru.spcex.clearing.validation.common.rules.specific;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IErrorEnumId;
import ru.spcex.platform.utils.validation.IValidationRule;
import java.util.Optional;
import java.util.function.Function;
/**
* Проверка обязательности поля (not null)
*
* @param fieldName Название поля
* @param getter Метод получения значения
* @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое
* @param additionalChecks Дополнительные проверки, связанные с этим полем
* @param required Флаг обязательности поля
* @param <R> Класс проверяемого объекта
* @param <V> Класс проверяемого значения
*/
public record FieldRequiredSpecificRule<R, V>(
String fieldName,
Function<R, V> getter,
IErrorEnumId errorEmptyRequiredValue,
boolean required,
Function<V, EnumMessage>[] additionalChecks
) implements IValidationRule<ImdgValidationContext<R>> {
/**
* @param fieldName Название поля
* @param getter Метод получения значения
* @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое
* @param additionalChecks Дополнительные проверки, связанные с этим полем
* @param required Флаг обязательности поля
* @param <R> Класс проверяемого объекта
* @param <V> Класс проверяемого значения
*/
@SafeVarargs
public static <R, V> FieldRequiredSpecificRule<R, V> instance(String fieldName,
Function<R, V> getter,
IErrorEnumId errorEmptyRequiredValue,
boolean required,
Function<V, EnumMessage>... additionalChecks) {
if (required && errorEmptyRequiredValue == null) throw new IllegalArgumentException("Empty errorEmptyRequiredValue");
return new FieldRequiredSpecificRule<>(fieldName, getter, errorEmptyRequiredValue, required, additionalChecks);
}
/**
* @param fieldName Название поля
* @param getter Метод получения значения
* @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое
* @param additionalChecks Дополнительные проверки, связанные с этим полем
* @param <R> Класс проверяемого объекта
* @param <V> Класс проверяемого значения
*/
@SafeVarargs
public static <R, V> FieldRequiredSpecificRule<R, V> instance(String fieldName,
Function<R, V> getter,
IErrorEnumId errorEmptyRequiredValue,
Function<V, EnumMessage>... additionalChecks) {
if (errorEmptyRequiredValue == null) throw new IllegalArgumentException("Empty errorEmptyRequiredValue");
return new FieldRequiredSpecificRule<>(fieldName, getter, errorEmptyRequiredValue, true, additionalChecks);
}
@Override
// todo replace for error fieldName to fieldValue
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R validatedObject = context.getValidatedObject();
V value = getter.apply(validatedObject);
if (required && value == null) return of(errorEmptyRequiredValue, fieldName);
for (Function<V, EnumMessage> additionalCheck : additionalChecks) {
EnumMessage validationError = additionalCheck.apply(value);
if (validationError != null) return Optional.of(validationError);
}
return empty();
}
@Override
public String ruleName() {
return getClass().getSimpleName() + "{" + fieldName + "}";
}
}

View file

@ -0,0 +1,118 @@
package ru.spcex.clearing.validation.common.rules.specific;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IErrorEnumId;
import ru.spcex.platform.utils.validation.IValidationRule;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
/**
* Проверка наличия связанного по Id объекта в базе
*
* @param <R> Класс проверяемого объекта
* @param <V> Класс связанного объекта
*/
public record IdPresentSpecificRule<R, V extends SpcexObjectBase>(
String fieldName,
Function<R, Long> idGetter,
String mapName,
Class<V> mapClass,
IErrorEnumId errorEmptyRequiredValue,
IErrorEnumId errorIdNotPresent,
boolean required,
Function<V, EnumMessage>[] additionalChecks
) implements IValidationRule<ImdgValidationContext<R>> {
/**
* @param fieldName Название поля, содержащего Id
* @param idGetter Метод получения Id
* @param mapName Название мапы связанного объекта (см. IMDGDistributedNames)
* @param mapClass Класс связанного объекта
* @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое
* @param errorIdNotPresent Ошибка, которая будет возвращена, если Id не найден
* @param required Флаг обязательности
* @param additionalChecks Дополнительные проверки, которые можно провести со связанным объектом
* @param <R> Класс проверяемого объекта
* @param <V> Класс связанного объекта
*/
@SafeVarargs
public static <R, V extends SpcexObjectBase> IdPresentSpecificRule<R, V> instance(String fieldName,
Function<R, Long> idGetter,
String mapName,
Class<V> mapClass,
IErrorEnumId errorEmptyRequiredValue,
IErrorEnumId errorIdNotPresent,
boolean required,
Function<V, EnumMessage>... additionalChecks) {
if (required)
Objects.requireNonNull(errorEmptyRequiredValue, "errorEmptyRequiredValue");
Objects.requireNonNull(errorIdNotPresent, "errorIdNotPresent");
return new IdPresentSpecificRule<>(fieldName,
idGetter,
mapName,
mapClass,
errorEmptyRequiredValue,
errorIdNotPresent,
required,
additionalChecks);
}
/**
* @param fieldName Название поля, содержащего Id
* @param idGetter Метод получения Id
* @param mapName Название мапы связанного объекта (см. IMDGDistributedNames)
* @param mapClass Класс связанного объекта
* @param errorEmptyRequiredValue Ошибка, которая будет возвращена, если поле пустое
* @param errorIdNotPresent Ошибка, которая будет возвращена, если Id не найден
* @param additionalChecks Дополнительные проверки, которые можно провести со связанным объектом
* @param <R> Класс проверяемого объекта
* @param <V> Класс связанного объекта
*/
@SafeVarargs
public static <R, V extends SpcexObjectBase> IdPresentSpecificRule<R, V> instance(String fieldName,
Function<R, Long> idGetter,
String mapName,
Class<V> mapClass,
IErrorEnumId errorEmptyRequiredValue,
IErrorEnumId errorIdNotPresent,
Function<V, EnumMessage>... additionalChecks) {
Objects.requireNonNull(errorEmptyRequiredValue, "errorEmptyRequiredValue");
Objects.requireNonNull(errorIdNotPresent, "errorIdNotPresent");
return new IdPresentSpecificRule<>(fieldName,
idGetter,
mapName,
mapClass,
errorEmptyRequiredValue,
errorIdNotPresent,
true,
additionalChecks);
}
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R validatedObject = context.getValidatedObject();
Long id = idGetter.apply(validatedObject);
if (id == null) return required ? of(errorEmptyRequiredValue, fieldName) : empty();
Imdg<V> imdg = context.obtainMap(mapName, mapClass);
V fromMap = imdg.getSingleObjectByID(id);
if (fromMap == null) {
return of(errorIdNotPresent, id, fieldName);
}
for (Function<V, EnumMessage> additionalCheck : additionalChecks) {
EnumMessage validationError = additionalCheck.apply(fromMap);
if (validationError != null)
return Optional.of(validationError);
}
return empty();
}
@Override
public String ruleName() {
return getClass().getSimpleName() + "{" + fieldName + "}";
}
}

View file

@ -12,10 +12,12 @@ import ru.spcex.clearing.platform.messaging.domain.cud.company.ClearingMemberCat
import ru.spcex.clearing.platform.messaging.domain.cud.company.ClearingMemberCategoryUpdateRequest; import ru.spcex.clearing.platform.messaging.domain.cud.company.ClearingMemberCategoryUpdateRequest;
import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule; import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule;
import ru.spcex.clearing.validation.common.rules.IdPresentRule; import ru.spcex.clearing.validation.common.rules.IdPresentRule;
import ru.spcex.clearing.validation.common.rules.specific.IdPresentSpecificRule;
import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.enumeration.WorkflowStatus;
import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.validation.ImdgValidationContext; import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.validation.IValidator; import ru.spcex.platform.utils.validation.IValidator;
import ru.spcex.platform.utils.validation.ValidatorImpl; import ru.spcex.platform.utils.validation.ValidatorImpl;
@ -37,7 +39,7 @@ public class ClearingMemberCategoryValidationConfig {
addImdg.accept(IMDGDistributedNames.Map_Company); addImdg.accept(IMDGDistributedNames.Map_Company);
addImdg.accept(IMDGDistributedNames.Map_ClearingCategoryDictionary); addImdg.accept(IMDGDistributedNames.Map_ClearingCategoryDictionary);
return new ValidatorImpl<>(context, return new ValidatorImpl<>(context,
IdPresentRule.instance("companyId", IdPresentSpecificRule.instance("companyId",
ClearingMemberCategoryNewRequest::getCompanyId, ClearingMemberCategoryNewRequest::getCompanyId,
IMDGDistributedNames.Map_Company, IMDGDistributedNames.Map_Company,
Company.class, Company.class,
@ -64,7 +66,7 @@ public class ClearingMemberCategoryValidationConfig {
addImdg.accept(IMDGDistributedNames.Map_ClearingCategoryDictionary); addImdg.accept(IMDGDistributedNames.Map_ClearingCategoryDictionary);
addImdg.accept(IMDGDistributedNames.Map_ClearingMemberCategory); addImdg.accept(IMDGDistributedNames.Map_ClearingMemberCategory);
return new ValidatorImpl<>(context, return new ValidatorImpl<>(context,
IdPresentRule.instance("id", IdPresentSpecificRule.instance("id",
ClearingMemberCategoryUpdateRequest::getId, ClearingMemberCategoryUpdateRequest::getId,
IMDGDistributedNames.Map_ClearingMemberCategory, IMDGDistributedNames.Map_ClearingMemberCategory,
ClearingMemberCategory.class, ClearingMemberCategory.class,
@ -73,9 +75,9 @@ public class ClearingMemberCategoryValidationConfig {
clearingMemberCategory -> { clearingMemberCategory -> {
Imdg<Company> companyImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class); Imdg<Company> companyImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class);
Company company = companyImdg.getSingleObjectByID(clearingMemberCategory.getCompanyId()); Company company = companyImdg.getSingleObjectByID(clearingMemberCategory.getCompanyId());
if (company == null) return CompanyErrors.CompanyNotFound; if (company == null) return new EnumMessage(CompanyErrors.CompanyNotFound, company.getShortName());
if (!WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus())) if (!WorkflowStatus.Active.getKey().equals(company.getWorkflowStatus()))
return CompanyErrors.CompanyDisabled; return new EnumMessage(CompanyErrors.CompanyDisabled, company.getShortName());
return null; return null;
}), }),
DictionaryPresentRule.instance("clearingMemberCategory", DictionaryPresentRule.instance("clearingMemberCategory",

View file

@ -11,8 +11,8 @@ import ru.spcex.clearing.platform.messaging.domain.cud.securitites.ListingNewReq
import ru.spcex.clearing.platform.messaging.domain.cud.securitites.ListingUpdateRequest; import ru.spcex.clearing.platform.messaging.domain.cud.securitites.ListingUpdateRequest;
import ru.spcex.clearing.securities.errors.SecuritiesError; import ru.spcex.clearing.securities.errors.SecuritiesError;
import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule; import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule;
import ru.spcex.clearing.validation.common.rules.IdPresentRule;
import ru.spcex.clearing.validation.common.rules.SpecialIdPresentRule; import ru.spcex.clearing.validation.common.rules.SpecialIdPresentRule;
import ru.spcex.clearing.validation.common.rules.specific.IdPresentSpecificRule;
import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.enumeration.InstrumentType; import ru.spcex.platform.enumeration.InstrumentType;
import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.enumeration.WorkflowStatus;
@ -115,7 +115,7 @@ public class ListingValidationProvider {
context.setValidatedObject(listingRequest); context.setValidatedObject(listingRequest);
context.addImdg(IMDGDistributedNames.Map_Listing, listingImdg); context.addImdg(IMDGDistributedNames.Map_Listing, listingImdg);
return new ValidatorImpl<>(context, return new ValidatorImpl<>(context,
IdPresentRule.instance("id", IdPresentSpecificRule.instance("id",
CommonDeleteRequest::getId, CommonDeleteRequest::getId,
IMDGDistributedNames.Map_Listing, IMDGDistributedNames.Map_Listing,
Listing.class, Listing.class,
@ -124,14 +124,14 @@ public class ListingValidationProvider {
true, true,
(Listing listing) -> { (Listing listing) -> {
if (WorkflowStatus.Blocked.equalsByKey(listing.getWorkflowStatus())) { if (WorkflowStatus.Blocked.equalsByKey(listing.getWorkflowStatus())) {
return SecuritiesError.InstrumentNotActive; return new EnumMessage(SecuritiesError.InstrumentNotActive, listing.getSymbolCode());
} }
if (listing.getSecurityId() == null) if (listing.getSecurityId() == null)
return null; return null;
Security security = securitySelector.selectSecurityById(listing.getSecurityId()); Security security = securitySelector.selectSecurityById(listing.getSecurityId());
if (security != null) { if (security != null) {
if (InstrumentType.RATE.equalsByKey(security.getInstrumentType())) if (InstrumentType.RATE.equalsByKey(security.getInstrumentType()))
return SecuritiesError.ListingOnMMSDeletedBySystem; new EnumMessage(SecuritiesError.ListingOnMMSDeletedBySystem);
} }
return null; return null;
} }