clearing-service http://jira.mfd.msk:8088/browse/CLS-307 SPLT рефакторинг

This commit is contained in:
AKurakin 2023-08-29 11:39:46 +03:00
parent 99e83b8bf9
commit f720d2a945
9 changed files with 116 additions and 52 deletions

View file

@ -36,6 +36,9 @@ public class RSplitDepositActionNew implements IAction<RegistrySplitDepositActio
@ApiModelProperty(value = "Договор для разделения", example = "ABCD")
@JsonProperty
public String contract;
@ApiModelProperty(value = "Направление", example = "OUT")
@JsonProperty
public String direction;
@Override
@ -45,6 +48,7 @@ public class RSplitDepositActionNew implements IAction<RegistrySplitDepositActio
req.setOutboundAmount(this.outboundAmount);
req.setRefundDate(this.refundDate);
req.setContract(this.contract);
req.setDirection(this.direction);
return req;
}
@ -85,4 +89,12 @@ public class RSplitDepositActionNew implements IAction<RegistrySplitDepositActio
public void setContract(String contract) {
this.contract = contract;
}
public String getDirection() {
return direction;
}
public void setDirection(String direction) {
this.direction = direction;
}
}

View file

@ -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"
}
]
}

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--?xml-stylesheet type="text/xsl" href="\..\corp-reports\src\data\meta\meta.server.xslt"?-->
<meta version="3.7.0.44">
<meta version="3.7.0.45">
<!-- _xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" _xsi:noNamespaceSchemaLocation="file:///E:/d/projects/meta/from/meta.xsd" -->
<!--Здесь словари-->
<enums>
@ -937,7 +937,7 @@
<outboundAmount type="10" name="Сумма изъятия" shortname="Сумма" required="true"/>
<refundDate type="6" name="Дата возврата" shortname="Дата" required="true"/>
<comment type="2" length="255" name="Основание для вывода" shortname="Основание"/>
<direction type="1" name="Направление" shortname="Направление" link="inOutDirection"/>
<direction type="12" name="Направление" shortname="Направление" link="inOutDirection"/>
</post>
<post name="Отметить средства на возврат депозита" destination="registries/returnDeposit" class="ru.spcex.clearing.backendapi.controller.request.cud.registry.ReturnDepositActionNew">
<id type="1" name="Регистр требований" shortname="Регистр требований" required="true" enabled="false" visible="false"/>

View file

@ -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"
}
]
}

View file

@ -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
);
};
}

View file

@ -295,6 +295,7 @@ public class RegistryService {
if (roleCheck != null) {
return roleCheck;
}
Registry baseRegistry;
{
IValidator validator = splitDepositActionVal.apply(requestPayload);
Optional<EnumMessage> 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<EnumMessage> 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<Registry> 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<EnumMessage> 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();
}
}

View file

@ -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<ImdgValidationContext<RegistrySplitDepositActionRequest>> {
CrossvalidateByRegistry() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<RegistrySplitDepositActionRequest> context) {
RegistrySplitDepositActionRequest request = context.getValidatedObject();
Imdg<Registry> 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();
}
}

View file

@ -26,5 +26,7 @@ public enum ValidationStored {
Sdf20Account, Sdf20Company, Sdf20Tcr, Sdf20Dst, Sdf20Ast, Sdf20Security,
SecurityBySecurityCode
SecurityBySecurityCode,
RegistryByContract
}

View file

@ -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;
}
}