diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/registry/RSplitDepositActionNew.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/registry/RSplitDepositActionNew.java index 9dc27ad99..62ec95e7b 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/registry/RSplitDepositActionNew.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/registry/RSplitDepositActionNew.java @@ -36,6 +36,9 @@ public class RSplitDepositActionNew implements IAction - + @@ -937,7 +937,7 @@ - + diff --git a/clearing-parent/backend-api/src/test/resources/meta.json b/clearing-parent/backend-api/src/test/resources/meta.json index e3312e1da..d2cde42d2 100644 --- a/clearing-parent/backend-api/src/test/resources/meta.json +++ b/clearing-parent/backend-api/src/test/resources/meta.json @@ -1,6 +1,6 @@ { - "version": "3.7.0.44", + "version": "3.7.0.45", "enums": { @@ -4040,7 +4040,7 @@ } , {"code": "direction", - "type": 1,"name": "Направление","shortname": "Направление","link": "inOutDirection" + "type": 12,"name": "Направление","shortname": "Направление","link": "inOutDirection" } ] } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/ValidationConfig.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/ValidationConfig.java index 01be1971a..592d0c12c 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/ValidationConfig.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/config/ValidationConfig.java @@ -19,6 +19,7 @@ import ru.clearing.classes.statics.data.sdf.*; import ru.clearing.classes.statics.data.security.MoneyMarketSecurity; import ru.clearing.classes.statics.data.security.Security; import ru.clearing.classes.statics.data.statement.Statement; +import ru.clearing.platform.dictionary.InOutDirectionDictionary; import ru.clearing.platform.dictionary.SectionDictionary; import ru.spcex.clearing.error.ClearingError; import ru.spcex.clearing.imdg.IMDGDistributedNames; @@ -28,6 +29,7 @@ import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryReturnDe import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistrySplitDepositActionRequest; import ru.spcex.clearing.service.validation.*; import ru.spcex.clearing.util.security.UserRoleVerification; +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.platform.enumeration.ClearingCategory; @@ -347,7 +349,14 @@ public class ValidationConfig { context.setLogPrefix(r -> "contract=%d refundDate=%s".formatted(r.getContract(), r.getRefundDate())); return new ValidatorImpl<>(context, FieldRequiredRule.instance("contract", RegistrySplitDepositActionRequest::getContract, ClearingError.RequiredFieldEmpty), - FieldRequiredRule.instance("refundDate", RegistrySplitDepositActionRequest::getRefundDate, ClearingError.RequiredFieldEmpty) + FieldRequiredRule.instance("refundDate", RegistrySplitDepositActionRequest::getRefundDate, ClearingError.RequiredFieldEmpty), +// IdPresentRule.instance("direction", RegistrySplitDepositActionRequest::getDirection, +// IMDGDistributedNames.Map_InOutDirectionDictionary, InOutDirectionDictionary.class, +// ClearingError.RequiredFieldEmpty, ClearingError.DictionaryNotFound, false), + DictionaryPresentRule.instance("direction", RegistrySplitDepositActionRequest::getDirection, + IMDGDistributedNames.Map_InOutDirectionDictionary, InOutDirectionDictionary.class, + ClearingError.RequiredFieldEmpty, ClearingError.DictionaryNotFound, false), + SplitDepositRequestValidationRule.CrossvalidateByRegistry ); }; } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/RegistryService.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/RegistryService.java index be0d41112..040e70dab 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/RegistryService.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/RegistryService.java @@ -295,6 +295,7 @@ public class RegistryService { if (roleCheck != null) { return roleCheck; } + Registry baseRegistry; { IValidator validator = splitDepositActionVal.apply(requestPayload); Optional err = validator.tillFirstError(); @@ -304,32 +305,7 @@ public class RegistryService { msgResolver.resolve(err.get())); return new RequestInfoUpdate(req.getId(), Status.Error, msgResolver.resolve(err.get())); } - } - - Registry baseRegistry; - { - ImdgPredicateBuilder prdBldr = registryImdg.predicateBuilder(); - ImdgPredicate query = prdBldr.and( - RegistryCodeSqlBuilder.getInstance(RegistryTradingParams.OM_T).buildPredicate(prdBldr), - prdBldr.equals("contract", requestPayload.getContract())); - baseRegistry = registryImdg.getSingleObjectByPredicate(query); - if (baseRegistry == null) { - String errMsg = msgResolver.resolve(new EnumMessage(ClearingError.TCRegistryNotFound, requestPayload.getContract())); - log.info("RegistrySplitDepositActionRequest request id={}, registry query \"{}\": {}", - req.getId(), query, errMsg); - return new RequestInfoUpdate(req.getId(), Status.Error, errMsg); - } else { - log.debug("Registry.id={} found by query \"{}\"", - baseRegistry.getId(), query); - } - } - { - Optional err = validateSplitDepositRegister(baseRegistry, requestPayload); - if (err.isPresent()) { - log.info("RegistrySplitDepositActionRequest request id={} cross validation with registry.id={} error: {}", - req.getId(), baseRegistry.getId(), msgResolver.resolve(err.get())); - return new RequestInfoUpdate(req.getId(), Status.Error, msgResolver.resolve(err.get())); - } + baseRegistry = validator.getStored(ValidationStored.RegistryByContract); } ImdgTransaction txCtx = imdgProvider.newTransaction(); @@ -338,7 +314,7 @@ public class RegistryService { try { Imdg registryTMap = txCtx.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); Instant now = Instant.now(); - InOutDirection direction = InOutDirection.out; // todo откуда брать направление? + InOutDirection direction = IEnumKey.getEnumByKey(InOutDirection.class, requestPayload.getDirection()); // 1. Первая группа Registry firstRegistry = baseRegistry.clone(); firstRegistry.setId(null); @@ -388,21 +364,4 @@ public class RegistryService { return new RequestInfoUpdate(req.getId(), Status.Success, null); } - private Optional validateSplitDepositRegister(Registry registry, RegistrySplitDepositActionRequest request) { - if (!RegistryStatus.PROC.equalsByKey(registry.getRegistryStatus())) { - log.trace("Registry[{}].RegistryStatus={} - error", registry.getId(), registry.getRegistryStatus()); - return Optional.of(new EnumMessage(ClearingError.TCRegistryNotFound, request.getContract())); - } - BigDecimal regBalance = registry.getBalance(); - if (regBalance == null || regBalance.compareTo(request.getOutboundAmount()) < 0) { - log.trace("Registry[{}] balance={} < OutboundAmount {}", registry.getId(), regBalance, request.getOutboundAmount()); - return Optional.of(new EnumMessage(ClearingError.BalanceInsufficient, request.getContract())); - } - if (!registry.getRefundDate().isAfter(request.getRefundDate())) { - log.trace("Registry[{}].RefundDate={} but request RefundDate={}", registry.getId(), registry.getRefundDate(), request.getRefundDate()); - return Optional.of(new EnumMessage(ClearingError.WrongFieldValue, "RefundDate")); - } - return Optional.empty(); - } - } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/SplitDepositRequestValidationRule.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/SplitDepositRequestValidationRule.java new file mode 100644 index 000000000..90d1346cd --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/SplitDepositRequestValidationRule.java @@ -0,0 +1,72 @@ +package ru.spcex.clearing.service.validation; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.clearing.classes.statics.data.registry.Registry; +import ru.spcex.clearing.error.ClearingError; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistrySplitDepositActionRequest; +import ru.spcex.platform.enumeration.RegistryStatus; +import ru.spcex.platform.enumeration.RegistryTradingParams; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; +import ru.spcex.platform.imdg.api.predicate.specific.RegistryCodeSqlBuilder; +import ru.spcex.platform.imdg.validation.ImdgValidationContext; +import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.validation.IValidationRule; + +import java.math.BigDecimal; +import java.util.Optional; + +public enum SplitDepositRequestValidationRule implements IValidationRule> { + CrossvalidateByRegistry() { + @Override + public Optional validate(ImdgValidationContext context) { + RegistrySplitDepositActionRequest request = context.getValidatedObject(); + + Imdg registryImdg = context.obtainMap(IMDGDistributedNames.Map_Registry, Registry.class); + + // Поиск регистра + ImdgPredicateBuilder prdBldr = registryImdg.predicateBuilder(); + ImdgPredicate query = prdBldr.and( + RegistryCodeSqlBuilder.getInstance(RegistryTradingParams.OM_T).buildPredicate(prdBldr), + prdBldr.equals("contract", request.getContract())); + Registry registry = registryImdg.getSingleObjectByPredicate(query); + if (registry == null) { + log.debug("Registry not found by query \"{}\"", query); + return of(ClearingError.TCRegistryNotFound, request.getContract()); + } else { + log.trace("Registry.id={} found by query \"{}\"", registry.getId(), query); + } + context.storeObject(ValidationStored.RegistryByContract, registry); + + // кросс-валидация + if (!RegistryStatus.PROC.equalsByKey(registry.getRegistryStatus())) { + log.debug("Registry[{}].RegistryStatus={} - error", + registry.getId(), registry.getRegistryStatus()); + return Optional.of(new EnumMessage(ClearingError.TCRegistryNotFound, request.getContract())); + } + BigDecimal regBalance = registry.getBalance(); + if (regBalance == null || regBalance.compareTo(request.getOutboundAmount()) < 0) { + log.trace("Registry[{}] balance={} < OutboundAmount {}", + registry.getId(), regBalance, request.getOutboundAmount()); + return Optional.of(new EnumMessage(ClearingError.BalanceInsufficient, request.getContract())); + } + if (!registry.getRefundDate().isAfter(request.getRefundDate())) { + log.trace("Registry[{}].RefundDate={} but request RefundDate={}", + registry.getId(), registry.getRefundDate(), request.getRefundDate()); + return Optional.of(new EnumMessage(ClearingError.WrongFieldValue, "RefundDate")); + } + + return empty(); + } + }; + + private final static Logger log = LoggerFactory.getLogger(SplitDepositRequestValidationRule.class); + + @Override + public String ruleName() { + return getClass().getSimpleName() + "." + name(); + } +} diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/ValidationStored.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/ValidationStored.java index c5a0efe7c..a4faa986a 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/ValidationStored.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/ValidationStored.java @@ -26,5 +26,7 @@ public enum ValidationStored { Sdf20Account, Sdf20Company, Sdf20Tcr, Sdf20Dst, Sdf20Ast, Sdf20Security, - SecurityBySecurityCode + SecurityBySecurityCode, + + RegistryByContract } diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/registry/RegistrySplitDepositActionRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/registry/RegistrySplitDepositActionRequest.java index 231d82d69..c3a6d39ee 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/registry/RegistrySplitDepositActionRequest.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/registry/RegistrySplitDepositActionRequest.java @@ -21,6 +21,8 @@ public class RegistrySplitDepositActionRequest { private LocalDate refundDate; @JsonProperty private String contract; + @JsonProperty + private String direction; public String getComment() { return comment; @@ -53,4 +55,12 @@ public class RegistrySplitDepositActionRequest { public void setContract(String contract) { this.contract = contract; } + + public String getDirection() { + return direction; + } + + public void setDirection(String direction) { + this.direction = direction; + } }