diff --git a/clearing-parent/balance-service/pom.xml b/clearing-parent/balance-service/pom.xml
index 60e35a567..1abc9c32c 100644
--- a/clearing-parent/balance-service/pom.xml
+++ b/clearing-parent/balance-service/pom.xml
@@ -36,6 +36,10 @@
com.fasterxml.jackson.core
jackson-databind
+
+ ru.spcex.platform
+ platform-enum
+
diff --git a/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/config/ImdgValidationContext.java b/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/config/ImdgValidationContext.java
new file mode 100644
index 000000000..40a5f805e
--- /dev/null
+++ b/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/config/ImdgValidationContext.java
@@ -0,0 +1,51 @@
+package ru.spcex.clearing.balance.config;
+
+import ru.spcex.platform.classes.base.SpcexObjectBase;
+import ru.spcex.platform.imdg.api.Imdg;
+import ru.spcex.platform.utils.validation.IValidatorContext;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ImdgValidationContext implements IValidatorContext {
+ private final Map> imdgs;
+ private final Map, Object> storedObjects;
+ private T validatedObject;
+
+ public ImdgValidationContext() {
+ this.imdgs = new HashMap<>();
+ this.storedObjects = new HashMap<>();
+ }
+
+ void addImdg(String key, Imdg> imdg) {
+ imdgs.put(key, imdg);
+ }
+
+ void setValidatedObject(T validatedObject) {
+ this.validatedObject = validatedObject;
+ }
+
+ public T getValidatedObject() {
+ return validatedObject;
+ }
+
+ public void storeObject(Enum> storedObject, Object anyObject) {
+ storedObjects.put(storedObject, anyObject);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public S getStoredObject(Enum> storedObject) {
+ Object o = storedObjects.get(storedObject);
+ return (S) o;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Imdg obtainMap(String mapName, Class clazz) {
+ Imdg> imdg = imdgs.get(mapName);
+ if (imdg == null) {
+ throw new IllegalStateException(mapName + " imdg wasn't added to validation context");
+ }
+ return (Imdg) imdg;
+ }
+}
diff --git a/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/config/MessagesConfig.java b/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/config/MessagesConfig.java
new file mode 100644
index 000000000..1b8fea101
--- /dev/null
+++ b/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/config/MessagesConfig.java
@@ -0,0 +1,30 @@
+package ru.spcex.clearing.balance.config;
+
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.support.ResourceBundleMessageSource;
+import ru.spcex.platform.utils.enumeration.IMessageResolver;
+import ru.spcex.platform.utils.enumeration.SpringPropertiesMessageResolver;
+
+import java.util.Locale;
+
+@Configuration
+public class MessagesConfig {
+ @Bean("validation-error-messages")
+ public ResourceBundleMessageSource messages() {
+ ResourceBundleMessageSource source = new ResourceBundleMessageSource();
+ source.setBasenames("messages/error");
+ source.setUseCodeAsDefaultMessage(true);
+ source.setDefaultEncoding("utf8");
+ source.setDefaultLocale(Locale.ROOT);
+ return source;
+ }
+
+ @Bean
+ public IMessageResolver errorResolver(@Qualifier("validation-error-messages") ResourceBundleMessageSource messageBundle) {
+ SpringPropertiesMessageResolver resolver = new SpringPropertiesMessageResolver(messageBundle);
+ resolver.setLocale("ru");
+ return resolver;
+ }
+}
diff --git a/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/config/ValidationConfig.java b/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/config/ValidationConfig.java
new file mode 100644
index 000000000..d8ec3a972
--- /dev/null
+++ b/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/config/ValidationConfig.java
@@ -0,0 +1,38 @@
+package ru.spcex.clearing.balance.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import ru.clearing.classes.statics.data.account.Account;
+import ru.clearing.classes.statics.data.sdf.SDf01;
+import ru.spcex.clearing.balance.validation.Sdf01ValidationRule;
+import ru.spcex.clearing.imdg.IMDGDistributedNames;
+import ru.spcex.platform.classes.base.SpcexObjectBase;
+import ru.spcex.platform.imdg.api.ImdgProvider;
+import ru.spcex.platform.utils.validation.IValidator;
+import ru.spcex.platform.utils.validation.ValidatorImpl;
+
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+
+@Configuration
+public class ValidationConfig {
+
+ @Autowired
+ @Bean("sdf01Validator")
+ public Function sdf01Validator(ImdgProvider imdgProvider) {
+ return sDf01 -> {
+ ImdgValidationContext context = new ImdgValidationContext<>();
+ context.setValidatedObject(sDf01);
+ BiConsumer> addImdg = (s, aClass) -> context.addImdg(s, imdgProvider.getImdg(s, aClass));
+ addImdg.accept(IMDGDistributedNames.Map_Account, Account.class);
+ return new ValidatorImpl<>(context,
+ Sdf01ValidationRule.AccountPresent,
+ Sdf01ValidationRule.CurrencyCode,
+ Sdf01ValidationRule.CurrentDateOnly,
+ Sdf01ValidationRule.Market,
+ Sdf01ValidationRule.accountType);
+ };
+ }
+
+}
diff --git a/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/errors/BalanceError.java b/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/errors/BalanceError.java
new file mode 100644
index 000000000..6b9cad972
--- /dev/null
+++ b/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/errors/BalanceError.java
@@ -0,0 +1,23 @@
+package ru.spcex.clearing.balance.errors;
+
+import ru.spcex.platform.utils.enumeration.IEnumId;
+
+public enum BalanceError implements IEnumId {
+ CompanyNotFound(5211L),
+ CurrencyNotFound(5213L),
+ CurrentDateOnly(5214L),
+ WrongMarket(5215L),
+ WrongAccount(5215L),
+ AccountNotPresent(-1L);
+ ;
+ private final Long id;
+
+ BalanceError(Long id) {
+ this.id = id;
+ }
+
+ @Override
+ public Long getId() {
+ return id;
+ }
+}
diff --git a/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/service/LoggingService.java b/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/service/LoggingService.java
new file mode 100644
index 000000000..14b8762c7
--- /dev/null
+++ b/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/service/LoggingService.java
@@ -0,0 +1,28 @@
+package ru.spcex.clearing.balance.service;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Component;
+import ru.spcex.platform.utils.enumeration.EnumMessage;
+import ru.spcex.platform.utils.enumeration.IMessageResolver;
+
+@Component
+public class LoggingService {
+ private final Logger log = LoggerFactory.getLogger(getClass());
+ private final IMessageResolver errorResolver;
+
+ @Autowired
+ public LoggingService(@Qualifier("errorResolver") IMessageResolver errorResolver) {
+ this.errorResolver = errorResolver;
+ }
+
+ public void logError(String message, EnumMessage error, Object... args) {
+ log.error(message + " {}", args, errorResolver.resolve(error));
+ }
+
+ public void logError(EnumMessage error) {
+ log.error("{}", errorResolver.resolve(error));
+ }
+}
diff --git a/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/service/StatementService.java b/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/service/StatementService.java
new file mode 100644
index 000000000..afc945838
--- /dev/null
+++ b/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/service/StatementService.java
@@ -0,0 +1,105 @@
+package ru.spcex.clearing.balance.service;
+
+import org.apache.kafka.clients.consumer.Consumer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+import ru.clearing.classes.statics.data.account.Account;
+import ru.clearing.classes.statics.data.company.Company;
+import ru.clearing.classes.statics.data.sdf.SDf01;
+import ru.clearing.classes.statics.data.statement.Statement;
+import ru.spcex.clearing.balance.errors.BalanceError;
+import ru.spcex.clearing.balance.validation.ValidationStored;
+import ru.spcex.clearing.imdg.IMDGDistributedNames;
+import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
+import ru.spcex.clearing.platform.messaging.domain.Consts;
+import ru.spcex.clearing.platform.messaging.domain.cud.account.AccountNewRequest;
+import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest;
+import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
+import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
+import ru.spcex.platform.imdg.api.Imdg;
+import ru.spcex.platform.imdg.api.ImdgProvider;
+import ru.spcex.platform.utils.enumeration.EnumMessage;
+import ru.spcex.platform.utils.validation.IValidator;
+
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Function;
+
+@Service
+public class StatementService extends QueueConsumer implements InitializingBean {
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ private final ImdgProvider imdgProvider;
+ private final KafkaSender kafkaReqProducer;
+ private final LoggingService errorLogger;
+ private final Imdg sdf01Imdg;
+ private final Imdg companyImdg;
+ private final Imdg accountImdg;
+ private final Imdg statementImdg;
+ private final Function sDf01Validator;
+
+ @Autowired
+ public StatementService(Consumer kafkaQueue, ImdgProvider imdgProvider, KafkaSender kafkaReqProducer, LoggingService errorLogger,
+ @Qualifier("sdf01Validator") Function sDf01Validator) {
+ super(kafkaQueue);
+ this.imdgProvider = imdgProvider;
+ this.sdf01Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf01, SDf01.class);
+ this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
+ this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
+ this.statementImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class);
+ this.kafkaReqProducer = kafkaReqProducer;
+ this.errorLogger = errorLogger;
+ this.sDf01Validator = sDf01Validator;
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ callback(StatementRequest.class)
+ .setConsumer(this::process)
+ .forDestination(Consts.DESTINATION_SDF02_NEW, callbacks::put);
+ init();
+ }
+
+ private void process(BaseRequest systemRequest) {
+ StatementRequest sdfInfo = systemRequest.getRequestPayload();
+ SDf01 sdf01 = sdf01Imdg.getSingleObjectByID(sdfInfo.getSdf01Id());
+ Company company = companyImdg.getSingleObjectByFieldValues(Map.of("tradingCode", sdf01.getDeal()));
+ if (company == null) {
+ errorLogger.logError("sdf01.id={}", new EnumMessage(BalanceError.CompanyNotFound), sdfInfo.getSdf01Id());
+ return;
+ }
+ IValidator validator = sDf01Validator.apply(sdf01);
+ Optional error = validator.tillFirstError();
+ if (BalanceError.AccountNotPresent.equals(error.map(EnumMessage::getSubject).orElse(null))) {
+ kafkaReqProducer.sendRequestToQueue(Consts.ACCOUNT_NEW, createAccountRequest(sdf01.getAccount()));
+ log.info("account not found - send request for creation");
+ return;
+ }
+ if (error.isPresent()) {
+ errorLogger.logError("sdf01.id={}", error.get(), sdf01.getId());
+ return;
+ }
+ Statement statement = statementImdg.getSingleObjectByFieldValues(Map.of("account", sdf01.getAccount()));
+
+ if (statement == null) {
+ createFlow(sdfInfo, validator.getStored(ValidationStored.Sdf01Account));
+ } else {
+// updateFlow(statement);
+ }
+
+ }
+
+ private void createFlow(StatementRequest sdfInfo, Account storedObject) {
+
+ }
+
+ private AccountNewRequest createAccountRequest(String account) {
+ AccountNewRequest req = new AccountNewRequest();
+ req.setAccount(account);
+ return req;
+ }
+}
diff --git a/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/validation/Sdf01ValidationRule.java b/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/validation/Sdf01ValidationRule.java
new file mode 100644
index 000000000..b5ed4842f
--- /dev/null
+++ b/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/validation/Sdf01ValidationRule.java
@@ -0,0 +1,77 @@
+package ru.spcex.clearing.balance.validation;
+
+import ru.clearing.classes.statics.data.account.Account;
+import ru.clearing.classes.statics.data.sdf.SDf01;
+import ru.spcex.clearing.balance.config.ImdgValidationContext;
+import ru.spcex.clearing.balance.errors.BalanceError;
+import ru.spcex.clearing.imdg.IMDGDistributedNames;
+import ru.spcex.platform.enumeration.AccountType;
+import ru.spcex.platform.imdg.api.Imdg;
+import ru.spcex.platform.utils.enumeration.EnumMessage;
+import ru.spcex.platform.utils.validation.IValidationRule;
+
+import java.time.LocalDate;
+import java.util.Map;
+import java.util.Optional;
+
+public enum Sdf01ValidationRule implements IValidationRule> {
+ AccountPresent() {
+ @Override
+ public Optional validate(ImdgValidationContext context) {
+ SDf01 sdf01 = context.getValidatedObject();
+ Imdg accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
+ Account account = accountImdg.getSingleObjectByFieldValues(Map.of("account", sdf01.getAccount(),
+ "accountType", AccountType.Clrn.getKey()));
+ if (account == null) {
+ return of(BalanceError.AccountNotPresent);
+ }
+ context.storeObject(ValidationStored.Sdf01Account, account);
+ return empty();
+ }
+ },
+ CurrencyCode() {
+ @Override
+ public Optional validate(ImdgValidationContext context) {
+ SDf01 sdf01 = context.getValidatedObject();
+ if (!"RUR".equals(sdf01.getCurr_code())) {
+ return of(BalanceError.CurrencyNotFound);
+ }
+ return empty();
+ }
+ },
+ CurrentDateOnly() {
+ @Override
+ public Optional validate(ImdgValidationContext context) {
+ SDf01 sdf01 = context.getValidatedObject();
+ //fixme string format???
+ if (!LocalDate.now().toString().equals(sdf01.getDat())) {
+ return of(BalanceError.CurrentDateOnly);
+ }
+ return empty();
+ }
+ },
+ Market() {
+ @Override
+ public Optional validate(ImdgValidationContext context) {
+ SDf01 sdf01 = context.getValidatedObject();
+ if (!"U".equals(sdf01.getMarket())) {
+ return of(BalanceError.WrongMarket);
+ }
+ return empty();
+ }
+ },
+ accountType() {
+ @Override
+ public Optional validate(ImdgValidationContext context) {
+ SDf01 sdf01 = context.getValidatedObject();
+ if (!"A".equals(sdf01.getAcc_type())) {
+ return of(BalanceError.WrongAccount);
+ }
+ return empty();
+ }
+ };
+ @Override
+ public String ruleName() {
+ return "Sdf01ValidationRule." + name();
+ }
+}
diff --git a/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/validation/ValidationStored.java b/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/validation/ValidationStored.java
new file mode 100644
index 000000000..2170a8d40
--- /dev/null
+++ b/clearing-parent/balance-service/src/main/java/ru/spcex/clearing/balance/validation/ValidationStored.java
@@ -0,0 +1,5 @@
+package ru.spcex.clearing.balance.validation;
+
+public enum ValidationStored {
+ Sdf01Account;
+}
diff --git a/clearing-parent/balance-service/src/main/resources/application.properties b/clearing-parent/balance-service/src/main/resources/application.properties
index 2e1bbbab3..509e8cd92 100644
--- a/clearing-parent/balance-service/src/main/resources/application.properties
+++ b/clearing-parent/balance-service/src/main/resources/application.properties
@@ -3,10 +3,17 @@ balance-service.hazelcast.cluster-members=127.0.0.1
balance-service.hazelcast.login=dev
balance-service.hazelcast.password=dev-pass
-balance-service.kafka.bootstrap-servers=localhost:9092
-balance-service.kafka.group-id=dev-group
-balance-service.kafka.enable-auto-commit=false
-balance-service.kafka.session-timeout-ms=30000
-balance-service.kafka.auto-offset-reset=latest
-balance-service.kafka.linger-ms=1
-balance-service.kafka.buffer-memory=33554432
\ No newline at end of file
+balance-service.kafka-consumer.bootstrap-servers=localhost:9092
+balance-service.kafka-consumer.group-id=dev-group
+balance-service.kafka-consumer.enable-auto-commit=false
+balance-service.kafka-consumer.session-timeout-ms=30000
+balance-service.kafka-consumer.auto-offset-reset=latest
+balance-service.kafka-consumer.linger-ms=1
+balance-service.kafka-consumer.buffer-memory=33554432
+
+balance-service.kafka-producer.bootstrap-servers=localhost:9092
+balance-service.kafka-producer.acks=all
+balance-service.kafka-producer.retries=0
+balance-service.kafka-producer.batch-size=16384
+balance-service.kafka-producer.linger-ms=1
+balance-service.kafka-producer.buffer-memory=33554432
\ No newline at end of file
diff --git a/clearing-parent/balance-service/src/main/resources/messages/error.properties b/clearing-parent/balance-service/src/main/resources/messages/error.properties
new file mode 100644
index 000000000..3f2dc2393
--- /dev/null
+++ b/clearing-parent/balance-service/src/main/resources/messages/error.properties
@@ -0,0 +1,2 @@
+5211=Company not found
+5213=Currency not found
diff --git a/clearing-parent/balance-service/src/main/resources/messages/error_ru.properties b/clearing-parent/balance-service/src/main/resources/messages/error_ru.properties
new file mode 100644
index 000000000..1820f1d6e
--- /dev/null
+++ b/clearing-parent/balance-service/src/main/resources/messages/error_ru.properties
@@ -0,0 +1,2 @@
+5211=Компания не найдена
+5213=Валюта не найдена
\ No newline at end of file
diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/AccountType.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/AccountType.java
new file mode 100644
index 000000000..71385a733
--- /dev/null
+++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/AccountType.java
@@ -0,0 +1,18 @@
+package ru.spcex.platform.enumeration;
+
+import ru.spcex.platform.utils.enumeration.IEnumKey;
+
+public enum AccountType implements IEnumKey {
+ Clrn("CLRN");
+
+ private final String key;
+
+ AccountType(String key) {
+ this.key = key;
+ }
+
+ @Override
+ public String getKey() {
+ return key;
+ }
+}
diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java
index cc94a5fd5..d9d4fc0c8 100644
--- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java
+++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java
@@ -25,4 +25,9 @@ public interface Consts {
String USER_AUTH_SUCCESS = "user-auth-success";
String USER_LOGOUT_SUCCESS = "user-logout-success";
+
+ //todo
+ String STATEMENT_NEW = "statement-action";
+ String ACCOUNT_NEW = "account-new";
+
}
diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/AccountNewRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/AccountNewRequest.java
new file mode 100644
index 000000000..2241fcbc2
--- /dev/null
+++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/AccountNewRequest.java
@@ -0,0 +1,14 @@
+package ru.spcex.clearing.platform.messaging.domain.cud.account;
+
+public class AccountNewRequest {
+
+ private String account;
+
+ public String getAccount() {
+ return account;
+ }
+
+ public void setAccount(String account) {
+ this.account = account;
+ }
+}
diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/balance/StatementRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/balance/StatementRequest.java
new file mode 100644
index 000000000..d1a98147a
--- /dev/null
+++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/balance/StatementRequest.java
@@ -0,0 +1,16 @@
+package ru.spcex.clearing.platform.messaging.domain.cud.balance;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class StatementRequest {
+ @JsonProperty
+ private Long sdf01Id;
+
+ public Long getSdf01Id() {
+ return sdf01Id;
+ }
+
+ public void setSdf01Id(Long sdf01Id) {
+ this.sdf01Id = sdf01Id;
+ }
+}
\ No newline at end of file
diff --git a/platform-parent/platform-utils/pom.xml b/platform-parent/platform-utils/pom.xml
index 94591fe86..e74e3410a 100644
--- a/platform-parent/platform-utils/pom.xml
+++ b/platform-parent/platform-utils/pom.xml
@@ -35,6 +35,16 @@
slf4j-api
provided
+
+ org.junit.jupiter
+ junit-jupiter
+ test
+
+
+ org.assertj
+ assertj-core
+ test
+
\ No newline at end of file
diff --git a/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/validation/IValidator.java b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/validation/IValidator.java
index a9d688c70..36f9b3608 100644
--- a/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/validation/IValidator.java
+++ b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/validation/IValidator.java
@@ -38,4 +38,8 @@ public interface IValidator {
* валидирует все, возвращает первую ошибку - для совместимости
*/
Optional validateAllReturnFirst();
+
+ default S getStored(Enum> storedObject) {
+ throw new UnsupportedOperationException("not implemented");
+ }
}
diff --git a/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/validation/IValidatorContext.java b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/validation/IValidatorContext.java
index 0a4d8d365..7d8ff27c2 100644
--- a/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/validation/IValidatorContext.java
+++ b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/validation/IValidatorContext.java
@@ -1,3 +1,7 @@
package ru.spcex.platform.utils.validation;
-public interface IValidatorContext {}
+public interface IValidatorContext {
+ default S getStoredObject(Enum> storedObject) {
+ throw new UnsupportedOperationException("not implemented");
+ }
+}
diff --git a/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/validation/ValidatorImpl.java b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/validation/ValidatorImpl.java
index 7cc384b55..7271a72af 100644
--- a/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/validation/ValidatorImpl.java
+++ b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/validation/ValidatorImpl.java
@@ -100,6 +100,11 @@ public class ValidatorImpl implements IValidator {
return Optional.empty();
}
+ @Override
+ public S getStored(Enum> storedObject) {
+ return context.getStoredObject(storedObject);
+ }
+
public C getContext() {
return context;
}
diff --git a/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/validation/DatePrimitiveValidation.java b/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/validation/DatePrimitiveValidation.java
new file mode 100644
index 000000000..8c1d59349
--- /dev/null
+++ b/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/validation/DatePrimitiveValidation.java
@@ -0,0 +1,6 @@
+package ru.spcex.platform.utils.validation;
+
+public enum DatePrimitiveValidation {
+ MonthValue
+ ;
+}
diff --git a/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/validation/DateValidation.java b/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/validation/DateValidation.java
new file mode 100644
index 000000000..3a53091e9
--- /dev/null
+++ b/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/validation/DateValidation.java
@@ -0,0 +1,6 @@
+package ru.spcex.platform.utils.validation;
+
+public enum DateValidation {
+ LocalDate, Midnight
+ ;
+}
diff --git a/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/validation/TestEnumWithId.java b/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/validation/TestEnumWithId.java
new file mode 100644
index 000000000..f357d0c12
--- /dev/null
+++ b/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/validation/TestEnumWithId.java
@@ -0,0 +1,20 @@
+package ru.spcex.platform.utils.validation;
+
+import ru.spcex.platform.utils.enumeration.IEnumId;
+
+public enum TestEnumWithId implements IEnumId {
+ Message1(1L),
+ Message2(2L),
+ Message3(3L),
+ Message4(4L);
+ private final Long id;
+
+ TestEnumWithId(Long id) {
+ this.id = id;
+ }
+
+ @Override
+ public Long getId() {
+ return id;
+ }
+}
diff --git a/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/validation/TestValidationContext.java b/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/validation/TestValidationContext.java
new file mode 100644
index 000000000..44bff84a5
--- /dev/null
+++ b/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/validation/TestValidationContext.java
@@ -0,0 +1,32 @@
+package ru.spcex.platform.utils.validation;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class TestValidationContext implements IValidatorContext {
+ private Map, Object> storedObjects;
+ private T validatedObject;
+
+ public TestValidationContext() {
+ this.storedObjects = new HashMap<>();
+ }
+
+ void setValidatedObject(T validatedObject) {
+ this.validatedObject = validatedObject;
+ }
+
+ public T getValidatedObject() {
+ return validatedObject;
+ }
+
+ public void storeObject(Enum> storedObject, Object anyObject) {
+ storedObjects.put(storedObject, anyObject);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public S getStoredObject(Enum> storedObject) {
+ Object o = storedObjects.get(storedObject);
+ return (S) o;
+ }
+}
diff --git a/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/validation/TestValidationRule.java b/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/validation/TestValidationRule.java
new file mode 100644
index 000000000..fdc89b64c
--- /dev/null
+++ b/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/validation/TestValidationRule.java
@@ -0,0 +1,52 @@
+package ru.spcex.platform.utils.validation;
+
+import ru.spcex.platform.utils.enumeration.EnumMessage;
+import ru.spcex.platform.utils.time.TimeUtil;
+
+import java.time.Instant;
+import java.time.LocalDate;
+import java.util.Optional;
+
+public enum TestValidationRule implements IValidationRule> {
+ isToday() {
+ @Override
+ public Optional validate(TestValidationContext context) {
+ Instant validatedObject = context.getValidatedObject();
+ LocalDate localDate = validatedObject.atZone(TimeUtil.zone).toLocalDate();
+ if (!LocalDate.now().equals(localDate)) {
+ return of(TestEnumWithId.Message1);
+ }
+ context.storeObject(DateValidation.LocalDate, localDate);
+ return Optional.empty();
+ }
+ },
+ isAfterMidnight() {
+ @Override
+ public Optional validate(TestValidationContext context) {
+ Instant validatedObject = context.getValidatedObject();
+ Instant midnight = TimeUtil.localDateToInstant(LocalDate.now());
+ if (!validatedObject.isAfter(midnight)) {
+ return of(TestEnumWithId.Message2);
+ }
+ context.storeObject(DateValidation.Midnight, midnight);
+ return empty();
+ }
+ },
+ isMonthValid() {
+ @Override
+ public Optional validate(TestValidationContext context) {
+ Instant validatedObject = context.getValidatedObject();
+ LocalDate localDate = validatedObject.atZone(TimeUtil.zone).toLocalDate();
+ int monthValue = localDate.getMonthValue();
+ if (!(monthValue >= 1 && monthValue <= 12)) {
+ return of(TestEnumWithId.Message3);
+ }
+ context.storeObject(DatePrimitiveValidation.MonthValue, monthValue);
+ return empty();
+ }
+ };
+ @Override
+ public String ruleName() {
+ return "TestValidationRule" + name();
+ }
+}
diff --git a/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/validation/ValidatorImplTest.java b/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/validation/ValidatorImplTest.java
new file mode 100644
index 000000000..d8f9b35c4
--- /dev/null
+++ b/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/validation/ValidatorImplTest.java
@@ -0,0 +1,41 @@
+package ru.spcex.platform.utils.validation;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import ru.spcex.platform.utils.enumeration.EnumMessage;
+import ru.spcex.platform.utils.time.TimeUtil;
+
+import java.time.Instant;
+import java.time.LocalDate;
+import java.util.Optional;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class ValidatorImplTest {
+ private IValidator validator;
+ @BeforeEach
+ public void initiateValidator() {
+ TestValidationContext context = new TestValidationContext<>();
+ context.setValidatedObject(Instant.now());
+ this.validator = new ValidatorImpl<>(context,
+ TestValidationRule.isToday,
+ TestValidationRule.isAfterMidnight,
+ TestValidationRule.isMonthValid
+ );
+ }
+
+ @Test
+ public void testStoredObjects() {
+ Optional enumMessage = validator.tillFirstError();
+ assertTrue(enumMessage.isEmpty());
+ LocalDate localDate = validator.getStored(DateValidation.LocalDate);
+ assertNotNull(localDate);
+ assertEquals(LocalDate.now(), localDate);
+ Instant midnight = validator.getStored(DateValidation.Midnight);
+ assertNotNull(midnight);
+ assertEquals(LocalDate.now().atStartOfDay().atZone(TimeUtil.zone).toInstant(), midnight);
+ Integer month = validator.getStored(DatePrimitiveValidation.MonthValue);
+ assertNotNull(month);
+ assertEquals(LocalDate.now().getMonthValue(), month);
+ }
+}
\ No newline at end of file