account-service company-service securities-service поправил валидацию словарей DictionaryPresentRule

This commit is contained in:
AKurakin 2023-09-21 12:22:13 +03:00
parent 3ba0611852
commit 06efab761d
16 changed files with 96 additions and 53 deletions

View file

@ -18,7 +18,6 @@ import ru.spcex.clearing.validation.common.rules.specific.IdPresentSpecificRule;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.enumeration.AccountStatus;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.ServiceStatus;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
@ -79,7 +78,7 @@ public class AccountValidationConfig {
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue,
AccountError.DictionaryNotFound,
false
// , statusValue -> {
// if (ServiceStatus.Active.equalsByKey(statusValue.getCode())) return null;
@ -91,10 +90,15 @@ public class AccountValidationConfig {
IMDGDistributedNames.Map_AccountTypeDictionary,
AccountTypeDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue,
AccountError.DictionaryNotFound,
accountType -> {
if (AccountType.Corr.equalsByKey(accountType.getCode())) return null;
return AccountError.WrongFieldValue;
}).withMessageDecorator((causeEmpty, errorCode, fieldName, fieldValue) -> {
if (errorCode == AccountError.WrongFieldValue)
return DictionaryPresentRule.FIELD_NOT_FOUND_DECORATOR_1.decorator(causeEmpty, errorCode, fieldName, fieldValue);
else
return DictionaryPresentRule.DICTIONARY_NOT_FOUND_DECORATOR_2.decorator(causeEmpty, errorCode, fieldName, fieldValue);
}),
new SameAccountValidationRule<>(AccountType.Corr, CorrespondentAccountNewRequest::getAccount)
);
@ -137,14 +141,14 @@ public class AccountValidationConfig {
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue,
AccountError.DictionaryNotFound,
false),
DictionaryPresentRule.instance("accountType",
CorrespondentAccountUpdateRequest::getAccountType,
IMDGDistributedNames.Map_AccountTypeDictionary,
AccountTypeDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue,
AccountError.DictionaryNotFound,
false
// accountType -> {
// if (AccountType.Corr.equalsByKey(accountType.getCode())) return null;

View file

@ -66,7 +66,7 @@ public class BankAccountValidationConfig {
IMDGDistributedNames.Map_CurrencyCodeDictionary,
CurrencyCodeDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue),
AccountError.DictionaryNotFound),
FieldRequiredRule.instance("bankIdentificationCode",
BankAccountNewRequest::getBankIdentificationCode,
AccountError.RequiredFieldEmpty),
@ -78,7 +78,7 @@ public class BankAccountValidationConfig {
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue,
AccountError.DictionaryNotFound,
false)
);
};
@ -118,7 +118,7 @@ public class BankAccountValidationConfig {
IMDGDistributedNames.Map_CurrencyCodeDictionary,
CurrencyCodeDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue,
AccountError.DictionaryNotFound,
false)
);
};

View file

@ -64,13 +64,13 @@ public class ClearingAccountValidationConfig {
IMDGDistributedNames.Map_ClearingAccountTypeDictionary,
ClearingAccountTypeDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue),
AccountError.DictionaryNotFound),
DictionaryPresentRule.instance("status",
ClearingAccountNewRequest::getStatus,
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue,
AccountError.DictionaryNotFound,
false)
);
};

View file

@ -61,7 +61,7 @@ public class DepoAccountValidationConfig {
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue,
AccountError.DictionaryNotFound,
false)
);
};

View file

@ -124,7 +124,7 @@ public class TradingClearingRegistryValidationConfig {
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue,
AccountError.DictionaryNotFound,
false),
new newTCRDuplicateCheck()
);
@ -189,7 +189,7 @@ public class TradingClearingRegistryValidationConfig {
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
AccountError.RequiredFieldEmpty,
AccountError.WrongFieldValue,
AccountError.DictionaryNotFound,
false)
);
};

View file

@ -1,6 +1,7 @@
package ru.spcex.clearing.validation.common.rules;
import ru.clearing.platform.dictionary.AbstractDictionary;
import ru.spcex.clearing.validation.common.rules.specific.IMessageDecorator;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
@ -20,15 +21,31 @@ import java.util.function.Function;
* @param <R> Класс проверяемого объекта
* @param <D> Класс словаря
*/
public record DictionaryPresentRule<R, D extends AbstractDictionary>(String fieldName,
Function<R, String> getter,
String dictionaryName,
Class<D> dictionaryClass,
IErrorEnumId errorEmptyRequiredValue,
IErrorEnumId errorWrongDictionaryValue,
boolean required,
Function<D, IErrorEnumId>[] additionalChecks) implements IValidationRule<ImdgValidationContext<R>> {
public class DictionaryPresentRule<R, D extends AbstractDictionary> implements IValidationRule<ImdgValidationContext<R>> {
public static final IMessageDecorator FIELD_NOT_FOUND_DECORATOR_1 = (isEmpty, errorCode, dictionaryName, fieldValue) -> new EnumMessage(errorCode, dictionaryName);
public static final IMessageDecorator DICTIONARY_NOT_FOUND_DECORATOR_2 = (isEmpty, errorCode, dictionaryName, fieldValue) -> new EnumMessage(errorCode, fieldValue, dictionaryName);
public final String fieldName;
public final Function<R, String> getter;
public final String dictionaryName;
public final Class<D> dictionaryClass;
public final IErrorEnumId errorEmptyRequiredValue;
public final IErrorEnumId errorWrongDictionaryValue;
public final boolean required;
public final Function<D, IErrorEnumId>[] additionalChecks;
protected IMessageDecorator decorator;
public DictionaryPresentRule(String fieldName, Function<R, String> getter, String dictionaryName, Class<D> dictionaryClass, IErrorEnumId errorEmptyRequiredValue, IErrorEnumId errorWrongDictionaryValue, boolean required, Function<D, IErrorEnumId>[] additionalChecks) {
this.fieldName = fieldName;
this.getter = getter;
this.dictionaryName = dictionaryName;
this.dictionaryClass = dictionaryClass;
this.errorEmptyRequiredValue = errorEmptyRequiredValue;
this.errorWrongDictionaryValue = errorWrongDictionaryValue;
this.required = required;
this.additionalChecks = additionalChecks;
this.decorator = DICTIONARY_NOT_FOUND_DECORATOR_2;
}
/**
* @param fieldName Название поля
@ -99,7 +116,7 @@ public record DictionaryPresentRule<R, D extends AbstractDictionary>(String fiel
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
R validatedObject = context.getValidatedObject();
String enumCode = getter.apply(validatedObject);
if (enumCode == null) return required ? of(errorEmptyRequiredValue, fieldName) : empty();
if (enumCode == null) return required ? decorator.of(true, errorEmptyRequiredValue, fieldName, null) : empty();
Imdg<D> dictImdg = context.obtainMap(
dictionaryName,
dictionaryClass
@ -108,11 +125,11 @@ public record DictionaryPresentRule<R, D extends AbstractDictionary>(String fiel
ImdgPredicate imdgPredicate = imdgPredicateBuilder.equals("code", enumCode);
Collection<D> fromMap = dictImdg.getCollectionObjectsByPredicate(imdgPredicate);
if (fromMap.isEmpty()) {
return of(errorWrongDictionaryValue, enumCode, dictionaryClass.getSimpleName());
return decorator.of(false, errorWrongDictionaryValue, dictionaryClass.getSimpleName(), enumCode);
}
D dictionaryFromMap = fromMap.iterator().next();
if (dictionaryFromMap == null) {
return of(errorWrongDictionaryValue, enumCode, dictionaryClass.getSimpleName());
if (dictionaryFromMap == null) { // never
return decorator.of(false, errorWrongDictionaryValue, dictionaryClass.getSimpleName(), enumCode);
}
for (Function<D, IErrorEnumId> additionalCheck : additionalChecks) {
IErrorEnumId validationError = additionalCheck.apply(dictionaryFromMap);
@ -122,6 +139,11 @@ public record DictionaryPresentRule<R, D extends AbstractDictionary>(String fiel
return empty();
}
public DictionaryPresentRule<R, D> withMessageDecorator(IMessageDecorator decorator) {
this.decorator = Objects.requireNonNull(decorator);
return this;
}
@Override
public String ruleName() {
return getClass().getSimpleName() + "{" + fieldName + " - " + dictionaryName + "}";

View file

@ -0,0 +1,14 @@
package ru.spcex.clearing.validation.common.rules.specific;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IErrorEnumId;
import java.util.Optional;
public interface IMessageDecorator {
EnumMessage decorator(boolean causeEmpty, IErrorEnumId errorCode, String fieldName, String fieldValue);
default Optional<EnumMessage> of(boolean causeEmpty, IErrorEnumId errorCode, String fieldName, String fieldValue) {
return Optional.ofNullable(decorator(causeEmpty, errorCode, fieldName, fieldValue));
}
}

View file

@ -50,7 +50,8 @@ public class ClearingMemberCategoryValidationConfig {
IMDGDistributedNames.Map_ClearingCategoryDictionary,
ClearingCategoryDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.CategoryNotFound));
CompanyErrors.CategoryNotFound).withMessageDecorator(DictionaryPresentRule.FIELD_NOT_FOUND_DECORATOR_1)
);
};
}
@ -85,8 +86,9 @@ public class ClearingMemberCategoryValidationConfig {
IMDGDistributedNames.Map_ClearingCategoryDictionary,
ClearingCategoryDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue,
false));
CompanyErrors.DictionaryNotFound,
false)
);
};
}

View file

@ -55,14 +55,14 @@ public class CompanyRoleSetValidationConfig {
IMDGDistributedNames.Map_CompanyRoleDictionary,
CompanyRoleDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue,
CompanyErrors.DictionaryNotFound,
false),
DictionaryPresentRule.instance("workflowStatus",
CompanyRoleSetNewRequest::getWorkflowStatus,
IMDGDistributedNames.Map_WorkflowStatusDictionary,
WorkflowStatusDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue,
CompanyErrors.DictionaryNotFound,
false)
);
};

View file

@ -51,7 +51,7 @@ public class CompanySymbolValidationConfig {
IMDGDistributedNames.Map_CompanySymbolDictionary,
CompanySymbolDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue,
CompanyErrors.DictionaryNotFound,
false),
new CompanySymbolOfSymbolNewRequestNotExistRule()
);
@ -98,7 +98,7 @@ public class CompanySymbolValidationConfig {
IMDGDistributedNames.Map_CompanySymbolDictionary,
CompanySymbolDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue,
CompanyErrors.DictionaryNotFound,
false)
);
};

View file

@ -51,13 +51,13 @@ public class CompanyValidationConfig {
IMDGDistributedNames.Map_WorkflowStatusDictionary,
WorkflowStatusDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue),
CompanyErrors.DictionaryNotFound),
DictionaryPresentRule.instance("companySymbol",
CompanyNewRequest::getCompanySymbol,
IMDGDistributedNames.Map_CompanySymbolDictionary,
CompanySymbolDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue),
CompanyErrors.DictionaryNotFound),
new CompanySymbolNotExistRule()
);
};
@ -86,13 +86,13 @@ public class CompanyValidationConfig {
IMDGDistributedNames.Map_WorkflowStatusDictionary,
WorkflowStatusDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue)
CompanyErrors.DictionaryNotFound)
// DictionaryPresentRule.instance("companySymbol",
// CompanyNewRequest::getCompanySymbol,
// IMDGDistributedNames.Map_CompanySymbolDictionary,
// CompanySymbolDictionary.class,
// CompanyErrors.RequiredFieldEmpty,
// CompanyErrors.WrongFieldValue)
// CompanyErrors.DictionaryNotFound)
);
};
}
@ -151,41 +151,41 @@ public class CompanyValidationConfig {
IMDGDistributedNames.Map_CorporationSoleTypeDictionary,
CorporationSoleTypeDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue, false),
CompanyErrors.DictionaryNotFound, false),
DictionaryPresentRule.instance("CountryCode",
CompanyInfoUpdateRequest::getCountryCode,
IMDGDistributedNames.Map_CountryCodeDictionary,
CountryCodeDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue,
CompanyErrors.DictionaryNotFound,
false),
DictionaryPresentRule.instance("ProfessionalSign",
CompanyInfoUpdateRequest::getProfessionalSign,
IMDGDistributedNames.Map_AllowedDictionary,
AllowedDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue,
CompanyErrors.DictionaryNotFound,
false),
DictionaryPresentRule.instance("legalKind",
CompanyInfoUpdateRequest::getLegalKind,
IMDGDistributedNames.Map_LegalKindDictionary,
LegalKindDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue,
CompanyErrors.DictionaryNotFound,
false),
DictionaryPresentRule.instance("organizationType",
CompanyInfoUpdateRequest::getOrganizationType,
IMDGDistributedNames.Map_OrganizationTypeDictionary,
OrganizationTypeDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue,
CompanyErrors.DictionaryNotFound,
false),
DictionaryPresentRule.instance("residence",
CompanyInfoUpdateRequest::getResidence,
IMDGDistributedNames.Map_CountryCodeDictionary,
CountryCodeDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue,
CompanyErrors.DictionaryNotFound,
false)
);

View file

@ -48,7 +48,7 @@ public class ContactValidationConfig {
IMDGDistributedNames.Map_ContactTypeDictionary,
ContactTypeDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue),
CompanyErrors.DictionaryNotFound),
FieldRequiredRule.instance("contactValue",
ContactNewRequest::getContactValue,
CompanyErrors.RequiredFieldEmpty)
@ -85,7 +85,7 @@ public class ContactValidationConfig {
IMDGDistributedNames.Map_ContactTypeDictionary,
ContactTypeDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue,
CompanyErrors.DictionaryNotFound,
false)
);
};

View file

@ -49,7 +49,7 @@ public class ProfileDocumentValidationConfig {
IMDGDistributedNames.Map_DocumentTypeDictionary,
DocumentTypeDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue),
CompanyErrors.DictionaryNotFound),
FieldRequiredRule.instance("issueDate",
ProfileDocumentNewRequest::getIssueDate,
CompanyErrors.RequiredFieldEmpty),
@ -104,7 +104,7 @@ public class ProfileDocumentValidationConfig {
IMDGDistributedNames.Map_DocumentTypeDictionary,
DocumentTypeDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue,
CompanyErrors.DictionaryNotFound,
false),
EndDtAfterStartDtRule.instance("validFromDate", "validToDate",
ProfileDocumentUpdateRequest::getValidFromDate,

View file

@ -50,14 +50,14 @@ public class RelationValidationConfig {
IMDGDistributedNames.Map_ClearingCategoryDictionary,
ClearingCategoryDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue,
CompanyErrors.DictionaryNotFound,
false),
DictionaryPresentRule.instance("serviceStatus",
RelationNewRequest::getServiceStatus,
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue)
CompanyErrors.DictionaryNotFound)
);
};
}
@ -109,7 +109,7 @@ public class RelationValidationConfig {
IMDGDistributedNames.Map_ServiceStatusDictionary,
ServiceStatusDictionary.class,
CompanyErrors.RequiredFieldEmpty,
CompanyErrors.WrongFieldValue)
CompanyErrors.DictionaryNotFound)
);
};
}

View file

@ -6,6 +6,7 @@ public enum SecuritiesError implements IErrorEnumId {
GeneralError(1000L),
UserVerifyDenial(1001L), // 'Нет прав на проведение данной операции
RequiredFieldIsEmpty(1002L),
DictionaryNotFound(1003L),
WrongFieldValue(1004L),
InstrumentAlreadyExists(1010L),
InstrumentNotFound(1011L),

View file

@ -69,12 +69,12 @@ public class ListingValidationProvider {
),
DictionaryPresentRule.instance("tradingCurrency", ListingNewRequest::getTradingCurrency,
IMDGDistributedNames.Map_CurrencyCodeDictionary, CurrencyCodeDictionary.class,
SecuritiesError.RequiredFieldIsEmpty, SecuritiesError.WrongFieldValue,
SecuritiesError.RequiredFieldIsEmpty, SecuritiesError.DictionaryNotFound,
false
),
DictionaryPresentRule.instance("workflowStatus", ListingNewRequest::getWorkflowStatus,
IMDGDistributedNames.Map_WorkflowStatusDictionary, WorkflowStatusDictionary.class,
SecuritiesError.RequiredFieldIsEmpty, SecuritiesError.WrongFieldValue,
SecuritiesError.RequiredFieldIsEmpty, SecuritiesError.DictionaryNotFound,
false
),
new NotSameActiveListing<>(ListingNewRequest::getSecurityId, ListingNewRequest::getMarket)
@ -97,12 +97,12 @@ public class ListingValidationProvider {
),
DictionaryPresentRule.instance("tradingCurrency", ListingUpdateRequest::getTradingCurrency,
IMDGDistributedNames.Map_CurrencyCodeDictionary, CurrencyCodeDictionary.class,
SecuritiesError.RequiredFieldIsEmpty, SecuritiesError.WrongFieldValue,
SecuritiesError.RequiredFieldIsEmpty, SecuritiesError.DictionaryNotFound,
false
),
DictionaryPresentRule.instance("workflowStatus", ListingUpdateRequest::getWorkflowStatus,
IMDGDistributedNames.Map_WorkflowStatusDictionary, WorkflowStatusDictionary.class,
SecuritiesError.RequiredFieldIsEmpty, SecuritiesError.WrongFieldValue,
SecuritiesError.RequiredFieldIsEmpty, SecuritiesError.DictionaryNotFound,
false
)
);