This commit is contained in:
AKurakin 2023-08-29 16:37:34 +03:00
parent 6237f534f2
commit 5cdf12a323
4 changed files with 89 additions and 76 deletions

View file

@ -64,6 +64,7 @@ public class ValidationConfig {
Imdg<Session> imdgSession;
Imdg<SectionDictionary> imdgSectionDictionary;
Imdg<Statement> imdgStatement;
Imdg<InOutDirectionDictionary> imdgInOutDirection;
ImdgProvider imdgProvider;
public ValidationConfig(ImdgProvider imdgProvider) {
@ -82,6 +83,7 @@ public class ValidationConfig {
this.equitySecurityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_EquitySecurity, EquitySecurity.class);
this.imdgStatement = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class);
this.imdgDepoAccount = imdgProvider.getImdg(IMDGDistributedNames.Map_DepoAccount, DepoAccount.class);
this.imdgInOutDirection = imdgProvider.getImdg(IMDGDistributedNames.Map_InOutDirectionDictionary, InOutDirectionDictionary.class);
this.imdgProvider = imdgProvider;
}
@ -346,7 +348,8 @@ public class ValidationConfig {
ImdgValidationContext<RegistrySplitDepositActionRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(refundDateRequest);
context.addImdg(IMDGDistributedNames.Map_Registry, imdgRegistry);
context.setLogPrefix(r -> "contract=%d refundDate=%s".formatted(r.getContract(), r.getRefundDate()));
context.addImdg(IMDGDistributedNames.Map_InOutDirectionDictionary, imdgInOutDirection);
context.setLogPrefix(r -> "contract=%s 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),

View file

@ -6,7 +6,6 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.registry.Registry;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.spcex.clearing.error.ClearingError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.CreateRegistryRequest;
@ -66,6 +65,7 @@ public class RegistryService {
this.splitDepositActionVal = splitDepositActionVal;
this.msgResolver = msgResolver;
this.rights = rights;
rights.setRoleForVerification(UserRole.Admin);
}
public void createRegistry(CreateRegistryRequest createRegistryRequest) {
@ -213,24 +213,15 @@ public class RegistryService {
RegistryTradingParams registryInfo = null;
//todo спросить про дубль C и T
switch (registryType) {
case Owner_A ->
registryInfo = new RegistryTradingParams(RegistryDesignation.A, RegistryInstrumentType.M, RegistryCapacity.A, RegistryUnit.T);
case Client_B ->
registryInfo = new RegistryTradingParams(RegistryDesignation.A, RegistryInstrumentType.M, RegistryCapacity.B, RegistryUnit.T);
case Trustee_C, DepoOfShares_T ->
registryInfo = new RegistryTradingParams(RegistryDesignation.A, RegistryInstrumentType.S, RegistryCapacity.A, RegistryUnit.T);
case TrusteeManager_D ->
registryInfo = new RegistryTradingParams(RegistryDesignation.A, RegistryInstrumentType.S, RegistryCapacity.A, RegistryUnit.A);
case Issuer_E ->
registryInfo = new RegistryTradingParams(RegistryDesignation.A, RegistryInstrumentType.S, RegistryCapacity.E, RegistryUnit.R);
case ToThePlacementOrRedeem_Z ->
registryInfo = new RegistryTradingParams(RegistryDesignation.A, RegistryInstrumentType.S, RegistryCapacity.Z, RegistryUnit.R);
case DepoBond_H ->
registryInfo = new RegistryTradingParams(RegistryDesignation.A, RegistryInstrumentType.S, RegistryCapacity.A, RegistryUnit.R);
case DepoOfTrustedBond_N ->
registryInfo = new RegistryTradingParams(RegistryDesignation.A, RegistryInstrumentType.S, RegistryCapacity.C, RegistryUnit.R);
case DepoOfTrustedShares_S ->
registryInfo = new RegistryTradingParams(RegistryDesignation.A, RegistryInstrumentType.S, RegistryCapacity.C, RegistryUnit.T);
case Owner_A -> registryInfo = new RegistryTradingParams(RegistryDesignation.A, RegistryInstrumentType.M, RegistryCapacity.A, RegistryUnit.T);
case Client_B -> registryInfo = new RegistryTradingParams(RegistryDesignation.A, RegistryInstrumentType.M, RegistryCapacity.B, RegistryUnit.T);
case Trustee_C, DepoOfShares_T -> registryInfo = new RegistryTradingParams(RegistryDesignation.A, RegistryInstrumentType.S, RegistryCapacity.A, RegistryUnit.T);
case TrusteeManager_D -> registryInfo = new RegistryTradingParams(RegistryDesignation.A, RegistryInstrumentType.S, RegistryCapacity.A, RegistryUnit.A);
case Issuer_E -> registryInfo = new RegistryTradingParams(RegistryDesignation.A, RegistryInstrumentType.S, RegistryCapacity.E, RegistryUnit.R);
case ToThePlacementOrRedeem_Z -> registryInfo = new RegistryTradingParams(RegistryDesignation.A, RegistryInstrumentType.S, RegistryCapacity.Z, RegistryUnit.R);
case DepoBond_H -> registryInfo = new RegistryTradingParams(RegistryDesignation.A, RegistryInstrumentType.S, RegistryCapacity.A, RegistryUnit.R);
case DepoOfTrustedBond_N -> registryInfo = new RegistryTradingParams(RegistryDesignation.A, RegistryInstrumentType.S, RegistryCapacity.C, RegistryUnit.R);
case DepoOfTrustedShares_S -> registryInfo = new RegistryTradingParams(RegistryDesignation.A, RegistryInstrumentType.S, RegistryCapacity.C, RegistryUnit.T);
}
return registryInfo;
}
@ -295,7 +286,7 @@ public class RegistryService {
if (roleCheck != null) {
return roleCheck;
}
Registry baseRegistry;
Collection<Registry> baseRegistrys;
{
IValidator validator = splitDepositActionVal.apply(requestPayload);
Optional<EnumMessage> err = validator.tillFirstError();
@ -305,7 +296,7 @@ public class RegistryService {
msgResolver.resolve(err.get()));
return new RequestInfoUpdate(req.getId(), Status.Error, msgResolver.resolve(err.get()));
}
baseRegistry = validator.getStored(ValidationStored.RegistryByContract);
baseRegistrys = validator.getStored(ValidationStored.RegistrysByContract);
}
ImdgTransaction txCtx = imdgProvider.newTransaction();
@ -319,43 +310,56 @@ public class RegistryService {
direction = InOutDirection.out;
log.debug("Direction not set. Use default: {}", direction);
}
// 1. Первая группа
Registry firstRegistry = baseRegistry.clone();
firstRegistry.setId(null);
firstRegistry.setCreated(now);
firstRegistry.setUpdated(null);
if (InOutDirection.out == direction) {
firstRegistry.setBalance(baseRegistry.getBalance().subtract(requestPayload.getOutboundAmount()));
} else if (InOutDirection.in == direction) {
firstRegistry.setBalance(baseRegistry.getBalance().add(requestPayload.getOutboundAmount()));
} else {
log.warn("Direction not set, do not change Balance");
}
firstRegistry.setContract(baseRegistry.getContract() + "~1");
registryTMap.insert(firstRegistry);
log.debug("Process {} for {} registry", direction, baseRegistrys.size());
Long groupId = null;
for (Registry baseRegistry : baseRegistrys) {
log.trace("Registry[{}], groupId={}, ClearingCode={}", baseRegistry.getId(), baseRegistry.getGroupId(), baseRegistry.getClearingCode());
if (groupId == null)
groupId = baseRegistry.getGroupId();
else if (!groupId.equals(baseRegistry.getGroupId())) {
log.warn("Group id different: groupId={}; registry[{}].groupId={}", groupId, baseRegistry.getId(), baseRegistry.getGroupId());
}
// 1. Первая группа
Registry firstRegistry = baseRegistry.clone();
firstRegistry.setId(null);
firstRegistry.setCreated(now);
firstRegistry.setUpdated(null);
if (InOutDirection.out == direction) {
firstRegistry.setBalance(baseRegistry.getBalance().subtract(requestPayload.getOutboundAmount()));
} else if (InOutDirection.in == direction) {
firstRegistry.setBalance(baseRegistry.getBalance().add(requestPayload.getOutboundAmount()));
} else {
log.warn("Direction not set, do not change Balance");
}
firstRegistry.setContract(baseRegistry.getContract() + "~1");
registryTMap.insert(firstRegistry);
// 2. Вторая группа
Registry secondRegistry = null;
if (InOutDirection.out == direction) {
secondRegistry.setId(null);
secondRegistry.setCreated(now);
secondRegistry.setUpdated(null);
secondRegistry.setBalance(requestPayload.getOutboundAmount());
secondRegistry.setContract(baseRegistry.getContract() + "~2");
registryTMap.insert(secondRegistry);
}
// 2. Вторая группа
Registry secondRegistry = null;
if (InOutDirection.out == direction) {
secondRegistry = baseRegistry.clone();
secondRegistry.setId(null);
secondRegistry.setCreated(now);
secondRegistry.setUpdated(null);
secondRegistry.setBalance(requestPayload.getOutboundAmount());
secondRegistry.setContract(baseRegistry.getContract() + "~2");
secondRegistry.setRefundDate(requestPayload.getRefundDate());
secondRegistry.setSettlementDate(requestPayload.getRefundDate());
registryTMap.insert(secondRegistry);
}
// 3. Текущим обязательствам установить статус SPLT
baseRegistry.setRegistryStatus(RegistryStatus.SPLT.getKey());
baseRegistry.setUpdated(Instant.now());
registryTMap.update(baseRegistry);
// 3. Текущим обязательствам установить статус SPLT
baseRegistry.setRegistryStatus(RegistryStatus.SPLT.getKey());
baseRegistry.setUpdated(Instant.now());
registryTMap.update(baseRegistry);
log.debug("Registry[{}] groupId={} split to: id1={} {}, id2={} {}",
baseRegistry.getId(), baseRegistry.getGroupId(),
firstRegistry == null ? null : firstRegistry.getId(), firstRegistry == null ? null : firstRegistry.getContract(),
secondRegistry == null ? null : secondRegistry.getId(), secondRegistry == null ? null : secondRegistry.getContract()
);
}
txOk = true;
log.debug("Registry[{}] groupId={} split to: id1={} {}, id2={} {}",
baseRegistry.getId(), baseRegistry.getGroupId(),
firstRegistry == null ? null : firstRegistry.getId(), firstRegistry == null ? null : firstRegistry.getContract(),
secondRegistry == null ? null : secondRegistry.getId(), secondRegistry == null ? null : secondRegistry.getContract()
);
} finally {
if (txOk) {
txCtx.commitTransaction();

View file

@ -6,18 +6,20 @@ 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.RegistryDesignation;
import ru.spcex.platform.enumeration.RegistryStatus;
import ru.spcex.platform.enumeration.RegistryTradingParams;
import ru.spcex.platform.enumeration.RegistryUnit;
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.Collection;
import java.util.Optional;
import java.util.stream.Collectors;
public enum SplitDepositRequestValidationRule implements IValidationRule<ImdgValidationContext<RegistrySplitDepositActionRequest>> {
CrossvalidateByRegistry() {
@ -30,32 +32,36 @@ public enum SplitDepositRequestValidationRule implements IValidationRule<ImdgVal
// Поиск регистра
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);
prdBldr.or(prdBldr.equals("registryStatus", RegistryStatus.PROC.getKey()), prdBldr.equals("registryStatus", RegistryStatus.MNG.getKey())),
prdBldr.or(prdBldr.equals("registryDesignation", RegistryDesignation.O.getKey()), prdBldr.equals("registryDesignation", RegistryDesignation.T.getKey())),
prdBldr.equals("registryUnit", RegistryUnit.T.getKey()),
prdBldr.equals("contract", request.getContract())
);
Collection<Registry> registrys = registryImdg.getCollectionObjectsByPredicate(query);
registrys = registrys.stream()
.filter(r->r.getValueDate()!=null && r.getSettlementDate()!=null && r.getValueDate().isBefore(r.getSettlementDate()))
.collect(Collectors.toList());
Registry registryO = registrys.stream()
.filter(r -> RegistryDesignation.O.equalsByKey(r.getRegistryDesignation()))
.findAny().orElse(null);
log.trace("Found registry {}. Crossvalidate for {}", registrys, registryO);
if (registryO == null) {
log.debug("Registry not found by query \"{}\" and valueDate < settlementDate", query);
return of(ClearingError.TCRegistryNotFound, request.getContract());
} else {
log.trace("Registry.id={} found by query \"{}\"", registry.getId(), query);
}
context.storeObject(ValidationStored.RegistryByContract, registry);
context.storeObject(ValidationStored.RegistrysByContract, registrys);
// кросс-валидация
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) {
BigDecimal regBalance = registryO.getBalance();
if (regBalance == null || regBalance.compareTo(request.getOutboundAmount()) <= 0) {
log.trace("Registry[{}] balance={} < OutboundAmount {}",
registry.getId(), regBalance, request.getOutboundAmount());
registryO.getId(), regBalance, request.getOutboundAmount());
return Optional.of(new EnumMessage(ClearingError.BalanceInsufficient, request.getContract()));
}
if (!registry.getRefundDate().isAfter(request.getRefundDate())) {
if (registryO.getRefundDate().isBefore(request.getRefundDate())) { // дате в регистре >= refundDate
log.trace("Registry[{}].RefundDate={} but request RefundDate={}",
registry.getId(), registry.getRefundDate(), request.getRefundDate());
registryO.getId(), registryO.getRefundDate(), request.getRefundDate());
return Optional.of(new EnumMessage(ClearingError.WrongFieldValue, "RefundDate"));
}

View file

@ -28,5 +28,5 @@ public enum ValidationStored {
SecurityBySecurityCode,
RegistryByContract
RegistrysByContract
}