clearing-service http://jira.mfd.msk:8088/browse/CLS-307 SPLT рефакторинг
This commit is contained in:
parent
99e83b8bf9
commit
f720d2a945
9 changed files with 116 additions and 52 deletions
|
|
@ -36,6 +36,9 @@ public class RSplitDepositActionNew implements IAction<RegistrySplitDepositActio
|
||||||
@ApiModelProperty(value = "Договор для разделения", example = "ABCD")
|
@ApiModelProperty(value = "Договор для разделения", example = "ABCD")
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
public String contract;
|
public String contract;
|
||||||
|
@ApiModelProperty(value = "Направление", example = "OUT")
|
||||||
|
@JsonProperty
|
||||||
|
public String direction;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -45,6 +48,7 @@ public class RSplitDepositActionNew implements IAction<RegistrySplitDepositActio
|
||||||
req.setOutboundAmount(this.outboundAmount);
|
req.setOutboundAmount(this.outboundAmount);
|
||||||
req.setRefundDate(this.refundDate);
|
req.setRefundDate(this.refundDate);
|
||||||
req.setContract(this.contract);
|
req.setContract(this.contract);
|
||||||
|
req.setDirection(this.direction);
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -85,4 +89,12 @@ public class RSplitDepositActionNew implements IAction<RegistrySplitDepositActio
|
||||||
public void setContract(String contract) {
|
public void setContract(String contract) {
|
||||||
this.contract = contract;
|
this.contract = contract;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDirection() {
|
||||||
|
return direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDirection(String direction) {
|
||||||
|
this.direction = direction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
"version": "3.7.0.44",
|
"version": "3.7.0.45",
|
||||||
|
|
||||||
"enums": {
|
"enums": {
|
||||||
|
|
||||||
|
|
@ -4040,7 +4040,7 @@
|
||||||
}
|
}
|
||||||
,
|
,
|
||||||
{"code": "direction",
|
{"code": "direction",
|
||||||
"type": 1,"name": "Направление","shortname": "Направление","link": "inOutDirection"
|
"type": 12,"name": "Направление","shortname": "Направление","link": "inOutDirection"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--?xml-stylesheet type="text/xsl" href="\..\corp-reports\src\data\meta\meta.server.xslt"?-->
|
<!--?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" -->
|
<!-- _xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" _xsi:noNamespaceSchemaLocation="file:///E:/d/projects/meta/from/meta.xsd" -->
|
||||||
<!--Здесь словари-->
|
<!--Здесь словари-->
|
||||||
<enums>
|
<enums>
|
||||||
|
|
@ -937,7 +937,7 @@
|
||||||
<outboundAmount type="10" name="Сумма изъятия" shortname="Сумма" required="true"/>
|
<outboundAmount type="10" name="Сумма изъятия" shortname="Сумма" required="true"/>
|
||||||
<refundDate type="6" name="Дата возврата" shortname="Дата" required="true"/>
|
<refundDate type="6" name="Дата возврата" shortname="Дата" required="true"/>
|
||||||
<comment type="2" length="255" name="Основание для вывода" shortname="Основание"/>
|
<comment type="2" length="255" name="Основание для вывода" shortname="Основание"/>
|
||||||
<direction type="1" name="Направление" shortname="Направление" link="inOutDirection"/>
|
<direction type="12" name="Направление" shortname="Направление" link="inOutDirection"/>
|
||||||
</post>
|
</post>
|
||||||
<post name="Отметить средства на возврат депозита" destination="registries/returnDeposit" class="ru.spcex.clearing.backendapi.controller.request.cud.registry.ReturnDepositActionNew">
|
<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"/>
|
<id type="1" name="Регистр требований" shortname="Регистр требований" required="true" enabled="false" visible="false"/>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
"version": "3.7.0.44",
|
"version": "3.7.0.45",
|
||||||
|
|
||||||
"enums": {
|
"enums": {
|
||||||
|
|
||||||
|
|
@ -4040,7 +4040,7 @@
|
||||||
}
|
}
|
||||||
,
|
,
|
||||||
{"code": "direction",
|
{"code": "direction",
|
||||||
"type": 1,"name": "Направление","shortname": "Направление","link": "inOutDirection"
|
"type": 12,"name": "Направление","shortname": "Направление","link": "inOutDirection"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.MoneyMarketSecurity;
|
||||||
import ru.clearing.classes.statics.data.security.Security;
|
import ru.clearing.classes.statics.data.security.Security;
|
||||||
import ru.clearing.classes.statics.data.statement.Statement;
|
import ru.clearing.classes.statics.data.statement.Statement;
|
||||||
|
import ru.clearing.platform.dictionary.InOutDirectionDictionary;
|
||||||
import ru.clearing.platform.dictionary.SectionDictionary;
|
import ru.clearing.platform.dictionary.SectionDictionary;
|
||||||
import ru.spcex.clearing.error.ClearingError;
|
import ru.spcex.clearing.error.ClearingError;
|
||||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
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.platform.messaging.domain.cud.registry.RegistrySplitDepositActionRequest;
|
||||||
import ru.spcex.clearing.service.validation.*;
|
import ru.spcex.clearing.service.validation.*;
|
||||||
import ru.spcex.clearing.util.security.UserRoleVerification;
|
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.FieldRequiredRule;
|
||||||
import ru.spcex.clearing.validation.common.rules.IdPresentRule;
|
import ru.spcex.clearing.validation.common.rules.IdPresentRule;
|
||||||
import ru.spcex.platform.enumeration.ClearingCategory;
|
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()));
|
context.setLogPrefix(r -> "contract=%d refundDate=%s".formatted(r.getContract(), r.getRefundDate()));
|
||||||
return new ValidatorImpl<>(context,
|
return new ValidatorImpl<>(context,
|
||||||
FieldRequiredRule.instance("contract", RegistrySplitDepositActionRequest::getContract, ClearingError.RequiredFieldEmpty),
|
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
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -295,6 +295,7 @@ public class RegistryService {
|
||||||
if (roleCheck != null) {
|
if (roleCheck != null) {
|
||||||
return roleCheck;
|
return roleCheck;
|
||||||
}
|
}
|
||||||
|
Registry baseRegistry;
|
||||||
{
|
{
|
||||||
IValidator validator = splitDepositActionVal.apply(requestPayload);
|
IValidator validator = splitDepositActionVal.apply(requestPayload);
|
||||||
Optional<EnumMessage> err = validator.tillFirstError();
|
Optional<EnumMessage> err = validator.tillFirstError();
|
||||||
|
|
@ -304,32 +305,7 @@ public class RegistryService {
|
||||||
msgResolver.resolve(err.get()));
|
msgResolver.resolve(err.get()));
|
||||||
return new RequestInfoUpdate(req.getId(), Status.Error, msgResolver.resolve(err.get()));
|
return new RequestInfoUpdate(req.getId(), Status.Error, msgResolver.resolve(err.get()));
|
||||||
}
|
}
|
||||||
}
|
baseRegistry = validator.getStored(ValidationStored.RegistryByContract);
|
||||||
|
|
||||||
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()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImdgTransaction txCtx = imdgProvider.newTransaction();
|
ImdgTransaction txCtx = imdgProvider.newTransaction();
|
||||||
|
|
@ -338,7 +314,7 @@ public class RegistryService {
|
||||||
try {
|
try {
|
||||||
Imdg<Registry> registryTMap = txCtx.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
|
Imdg<Registry> registryTMap = txCtx.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
|
||||||
Instant now = Instant.now();
|
Instant now = Instant.now();
|
||||||
InOutDirection direction = InOutDirection.out; // todo откуда брать направление?
|
InOutDirection direction = IEnumKey.getEnumByKey(InOutDirection.class, requestPayload.getDirection());
|
||||||
// 1. Первая группа
|
// 1. Первая группа
|
||||||
Registry firstRegistry = baseRegistry.clone();
|
Registry firstRegistry = baseRegistry.clone();
|
||||||
firstRegistry.setId(null);
|
firstRegistry.setId(null);
|
||||||
|
|
@ -388,21 +364,4 @@ public class RegistryService {
|
||||||
return new RequestInfoUpdate(req.getId(), Status.Success, null);
|
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -26,5 +26,7 @@ public enum ValidationStored {
|
||||||
|
|
||||||
Sdf20Account, Sdf20Company, Sdf20Tcr, Sdf20Dst, Sdf20Ast, Sdf20Security,
|
Sdf20Account, Sdf20Company, Sdf20Tcr, Sdf20Dst, Sdf20Ast, Sdf20Security,
|
||||||
|
|
||||||
SecurityBySecurityCode
|
SecurityBySecurityCode,
|
||||||
|
|
||||||
|
RegistryByContract
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ public class RegistrySplitDepositActionRequest {
|
||||||
private LocalDate refundDate;
|
private LocalDate refundDate;
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
private String contract;
|
private String contract;
|
||||||
|
@JsonProperty
|
||||||
|
private String direction;
|
||||||
|
|
||||||
public String getComment() {
|
public String getComment() {
|
||||||
return comment;
|
return comment;
|
||||||
|
|
@ -53,4 +55,12 @@ public class RegistrySplitDepositActionRequest {
|
||||||
public void setContract(String contract) {
|
public void setContract(String contract) {
|
||||||
this.contract = contract;
|
this.contract = contract;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDirection() {
|
||||||
|
return direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDirection(String direction) {
|
||||||
|
this.direction = direction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue