This commit is contained in:
ialbert 2023-09-14 19:35:09 +03:00
parent 2db5bbc7c0
commit 5b82083596
9 changed files with 206 additions and 54 deletions

View file

@ -0,0 +1,15 @@
package ru.spcex.clearing.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ru.spcex.clearing.error.ClearingError;
import ru.spcex.clearing.util.services.RequestHelper;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
@Configuration
public class RequestHelperConfiguration {
@Bean
public RequestHelper reqHelper(IMessageResolver msgRslv) {
return new RequestHelper(msgRslv, ClearingError.GeneralError);
}
}

View file

@ -25,6 +25,7 @@ import ru.spcex.clearing.error.ClearingError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.payment.PIClearingOutbondActionNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryChangeRefundDateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryChangeStatusExtractRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryReturnDepositRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistrySplitDepositActionRequest;
import ru.spcex.clearing.service.validation.*;
@ -343,6 +344,22 @@ public class ValidationConfig {
};
}
@Bean("statusExtractValidator")
public Function<RegistryChangeStatusExtractRequest, IValidator> statusExtractValidator() {
return statusExtractRequest -> {
ImdgValidationContext<RegistryChangeStatusExtractRequest> context = new ImdgValidationContext<>();
context.setValidatedObject(statusExtractRequest);
context.addImdg(IMDGDistributedNames.Map_Registry, imdgRegistry);
context.setLogPrefix(LogPrefixId.INSTANCE);
return new ValidatorImpl<>(context,
StatusExtractValidationRule.Fields,
new PresentById(IMDGDistributedNames.Map_Registry, ClearingError.RecordNotFound, true),
StatusExtractValidationRule.ContractCheck,
StatusExtractValidationRule.RegistryStatusValid
);
};
}
@Bean("splitDepositValidator")
public Function<RegistrySplitDepositActionRequest, IValidator> splitDepositValidator() {
return refundDateRequest -> {

View file

@ -6,10 +6,12 @@ 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;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryChangeRefundDateRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryChangeStatusExtractRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistryReturnDepositRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.RegistrySplitDepositActionRequest;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
@ -17,6 +19,7 @@ import ru.spcex.clearing.platform.messaging.service.Status;
import ru.spcex.clearing.service.validation.ValidationStored;
import ru.spcex.clearing.session.stage.util.RegistryUtil;
import ru.spcex.clearing.util.security.UserRoleVerification;
import ru.spcex.clearing.util.services.RequestHelper;
import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
@ -46,24 +49,29 @@ public class RegistryService {
private final Imdg<Registry> registryImdg;
private final Function<RegistryReturnDepositRequest, IValidator> returnDepositVal;
private final Function<RegistryChangeRefundDateRequest, IValidator> refundDateVal;
private final Function<RegistryChangeStatusExtractRequest, IValidator> statusExtractVal;
private final Function<RegistrySplitDepositActionRequest, IValidator> splitDepositActionVal;
private final IMessageResolver msgResolver;
private final RequestHelper reqHelp;
private final UserRoleVerification rights;
public RegistryService(ImdgProvider imdgProvider,
@Qualifier("returnDepositValidator") Function<RegistryReturnDepositRequest, IValidator> returnDepositVal,
@Qualifier("refundDateValidator") Function<RegistryChangeRefundDateRequest, IValidator> refundDateVal,
@Qualifier("splitDepositValidator") Function<RegistrySplitDepositActionRequest, IValidator> splitDepositActionVal,
@Qualifier("statusExtractValidator") Function<RegistryChangeStatusExtractRequest, IValidator> statusExtractVal,
IMessageResolver msgResolver,
UserRoleVerification rights) {
RequestHelper reqHelp, UserRoleVerification rights) {
this.imdgProvider = imdgProvider;
this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
this.returnDepositVal = returnDepositVal;
this.refundDateVal = refundDateVal;
this.splitDepositActionVal = splitDepositActionVal;
this.statusExtractVal = statusExtractVal;
this.msgResolver = msgResolver;
this.reqHelp = reqHelp;
this.rights = rights;
rights.setRoleForVerification(UserRole.Admin);
}
@ -156,6 +164,26 @@ public class RegistryService {
return new RequestInfoUpdate(req.getId(), Status.Success, null);
}
public RequestInfoUpdate changeStatusExtract(BaseRequest<RegistryChangeStatusExtractRequest> req) {
if (!rights.userHasRole(req.getUserId(), UserRole.Admin)) {
return reqHelp.error(req.getId(), ClearingError.UserVerifyDenial);
}
RegistryChangeStatusExtractRequest payload = req.getRequestPayload();
IValidator validator = statusExtractVal.apply(payload);
Optional<EnumMessage> err = validator.tillFirstError();
if (err.isPresent()) {
log.error("RegistryChangeStatusExtractRequest.id={} validation error: {}",
req.getId(),
msgResolver.resolve(err.get()));
return reqHelp.error(req.getId(), err.get());
}
Registry registry = validator.getStored(Stored.PresentById);
registry.setRegistryStatus(payload.getRegistryStatus());
log.debug("changing registry.id={} status to {}", registry.getId(), payload.getRegistryStatus());
registryImdg.update(registry);
return reqHelp.success(req.getId());
}
public RequestInfoUpdate changeRefundDate(BaseRequest<RegistryChangeRefundDateRequest> req) {
RegistryChangeRefundDateRequest requestPayload = req.getRequestPayload();
IValidator validator = refundDateVal.apply(requestPayload);

View file

@ -155,6 +155,18 @@ public class AssetTBFProcessing {
return new AssetTrio(asf, asb, ast);
}
public Optional<Registry> searchByTcrCompanyAccount(Registry rgs,
RegistryTradingParams params) {
ImdgPredicateBuilder pb = rgsImdg.predicateBuilder();
ImdgPredicate prdct = pb.and(
pb.sql(RegistryCodeSqlBuilder.getInstance(params).build()),
pb.equals("tradingClearingRegistryId", rgs.getTradingClearingRegistryId()),
pb.equals("companyId", rgs.getCompanyId()),
pb.equals("accountId", rgs.getAccountId())
);
return Optional.ofNullable(rgsImdg.getFirstObjectByPredicate(prdct));
}
public Optional<AssetTrio> searchMoneyByAccAndCompany(Long companyId, Long accountId) {
ImdgPredicateBuilder pb = rgsImdg.predicateBuilder();
Function<RegistryTradingParams, ImdgPredicate> prdct = rgsCode -> pb.and(

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.platform.messaging.domain.cud.registry.RegistryChangeStatusExtractRequest;
import ru.spcex.platform.enumeration.RegistryStatus;
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
import ru.spcex.platform.imdg.validation.Stored;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IEnumKey;
import ru.spcex.platform.utils.text.TextUtil;
import ru.spcex.platform.utils.validation.IValidationRule;
import java.util.Objects;
import java.util.Optional;
public enum StatusExtractValidationRule implements IValidationRule<ImdgValidationContext<RegistryChangeStatusExtractRequest>> {
Fields() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<RegistryChangeStatusExtractRequest> context) {
RegistryChangeStatusExtractRequest validatedObject = context.getValidatedObject();
if (validatedObject.getId() == null) {
return of(ClearingError.WrongField, "id");
}
if (TextUtil.isEmpty(validatedObject.getRegistryStatus())) {
return of(ClearingError.WrongField, "registryStatus");
}
return empty();
}
},
ContractCheck() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<RegistryChangeStatusExtractRequest> context) {
RegistryChangeStatusExtractRequest validatedObject = context.getValidatedObject();
if (TextUtil.isEmpty(validatedObject.getContract())) {
return empty();
}
Registry rgs = context.getStoredObject(Stored.PresentById);
if (rgs == null) {
log.error("PresentById check passed, yet not Stored.PresentById is present");
return of(ClearingError.WrongField, "id");
}
if (!Objects.equals(rgs.getContract(), validatedObject.getContract())) {
return of(ClearingError.WrongField, "contract");
}
return empty();
}
},
RegistryStatusValid() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<RegistryChangeStatusExtractRequest> context) {
RegistryChangeStatusExtractRequest validatedObject = context.getValidatedObject();
if (TextUtil.isEmpty(validatedObject.getRegistryStatus())) {
return empty();
}
RegistryStatus rgsStatus = IEnumKey.getEnumByKey(RegistryStatus.class, validatedObject.getRegistryStatus());
if (rgsStatus == null) {
return of(ClearingError.WrongField, "registryStatus");
}
return empty();
}
}
;
private final static Logger log = LoggerFactory.getLogger(StatusExtractValidationRule.class);
@Override
public String ruleName() {
return "StatusExtractValidationRule." + name();
}
}

View file

@ -18,6 +18,7 @@ import ru.spcex.clearing.session.stage.ISessionStage;
import ru.spcex.clearing.session.stage.StageResult;
import ru.spcex.clearing.session.stage.Task;
import ru.spcex.clearing.session.stage.task.InspectionPoolPayload;
import ru.spcex.clearing.session.stage.util.RegistryUtil;
import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
@ -145,38 +146,29 @@ public class InspectionObligations implements ISessionStage {
Instant now = Instant.now();
//по каждому регистру OM*T, TM*T, OS*T, TS*T из одной группы
for (Registry registry : group) {//TODO CLRNWORM проверка на пустой blockedRegistry
Registry blockedRegistry = null;
if (IEnumKey.getEnumByKey(RegistryInstrumentType.class, registry.getRegistryInstrumentType()) == RegistryInstrumentType.M) {
String moneyBAssetSql = searchMoneyBAssetsSql(registry);
log.debug("search money asset by registry.id={} sql {}", registry.getId(), moneyBAssetSql);
blockedRegistry = registryImdg.getFirstObjectBySQL(moneyBAssetSql);
if (IEnumKey.getEnumByKey(RegistryDesignation.class, registry.getRegistryDesignation()) == RegistryDesignation.O) {
blockedRegistry.setBalance(blockedRegistry.getBalance().add(registry.getBalance()));
} else if (IEnumKey.getEnumByKey(RegistryDesignation.class, registry.getRegistryDesignation()) == RegistryDesignation.T) {
blockedRegistry.setBalance(blockedRegistry.getBalance().subtract(registry.getBalance()));
}
blockedRegistry.setSessionId(sessionId);
blockedRegistry.setUpdated(now);
registryImdg.update(blockedRegistry);
} else if (section != null && section == Section.FOND &&
IEnumKey.getEnumByKey(RegistryInstrumentType.class, registry.getRegistryInstrumentType()) == RegistryInstrumentType.S) {
String securityBAssetSql = searchSecurityBAssetsSql(registry);
log.debug("search security asset by registry.id={} sql {}", registry.getId(), securityBAssetSql);
blockedRegistry = registryImdg.getFirstObjectBySQL(securityBAssetSql);
if (IEnumKey.getEnumByKey(RegistryDesignation.class, registry.getRegistryDesignation()) == RegistryDesignation.O) {
blockedRegistry.setBalance(blockedRegistry.getBalance().add(registry.getBalance()));
} else if (IEnumKey.getEnumByKey(RegistryDesignation.class, registry.getRegistryDesignation()) == RegistryDesignation.T) {
blockedRegistry.setBalance(blockedRegistry.getBalance().subtract(registry.getBalance()));
}
blockedRegistry.setSessionId(sessionId);
blockedRegistry.setUpdated(now);
registryImdg.update(blockedRegistry);
}
if (blockedRegistry != null) {
Optional<Registry> registryUnitF = registryManager.findRegByUnit(registry.getCompanyId(), registry.getAccountId(), registry.getContract(), blockedRegistry, RegistryUnit.F);
Optional<Registry> registryUnitT = registryManager.findRegByUnit(registry.getCompanyId(), registry.getAccountId(), registry.getContract(), blockedRegistry, RegistryUnit.T);
if (registryUnitF.isPresent() && registryUnitT.isPresent()) {
assets.process(blockedRegistry, registryUnitT.get(), registryUnitF.get(), BigDecimal.ZERO);
{
RegistryInstrumentType mOrS = IEnumKey.getEnumByKey(RegistryInstrumentType.class, registry.getRegistryInstrumentType());
if (mOrS == null) continue;
Optional<Registry> a__t = assets.searchByTcrCompanyAccount(registry, A__T.type(mOrS));
Optional<Registry> a__b = a__t.map(a__tFound -> assets
.searchByTcrCompanyAccount(a__tFound, A__B.type(mOrS))
.orElse(copyB(a__tFound)));
Optional<Registry> a__f = a__t.map(a__tFound -> assets
.searchByTcrCompanyAccount(a__tFound, A__F.type(mOrS))
.orElse(copyF(a__tFound)));
log.debug("registry {}.id={}: {}", registry.getRegistryCode(), registry.getId(),
a__t.map(r -> "A**T.id=%d/A**B.id=%d/A**F.id=%d"
.formatted(a__t.get().getId(), a__b.get().getId(), a__f.get().getId()))
.orElse("not found"));
if (a__t.isPresent()) {
BigDecimal amount = safeBD(registry.getBalance());
if (IEnumKey.getEnumByKey(RegistryDesignation.class, registry.getRegistryDesignation()) == RegistryDesignation.O) {
amount = amount.negate();
} else if (IEnumKey.getEnumByKey(RegistryDesignation.class, registry.getRegistryDesignation()) == RegistryDesignation.T) {
amount = amount;
}
a__b.get().setSessionId(sessionId);
assets.process(a__b.get(), a__t.get(), a__f.get(), amount);
}
}
}
@ -253,28 +245,24 @@ foreach( at: rgsAT)
obligation.getCompanyId());
}
private String searchMoneyBAssetsSql(Registry obligation) {
return String.format("%s and " +
"tradingClearingRegistryId = '%s' and " +
"companyId = '%s' and " +
"accountId = %s",
RegistryCodeSqlBuilder.getInstance(AM_B).build(),
obligation.getTradingClearingRegistryId(),
obligation.getCompanyId(),
obligation.getAccountId());
private Registry copyF(Registry rgs) {
Registry rgsF = rgs.clone();
RegistryManager.zeroState(rgsF);
rgsF.setRegistryUnit(RegistryUnit.F.getKey());
rgsF.setRegistryCode(RegistryUtil.clearingCode(rgsF));
registryImdg.insert(rgsF);
log.debug("created {}.id={} by {}.id={}", rgsF.getRegistryCode(), rgsF.getId(), rgs.getRegistryCode(), rgs.getId());
return rgsF;
}
private String searchSecurityBAssetsSql(Registry registry) {
return String.format("%s and " +
"tradingClearingRegistryId = '%s' and " +
"companyId = '%s' and " +
"securitySymbol = '%s' and " +
"accountId = %s",
RegistryCodeSqlBuilder.getInstance(AS_B).build(),
registry.getTradingClearingRegistryId(),
registry.getCompanyId(),
registry.getSecuritySymbol(),
registry.getAccountId());
private Registry copyB(Registry rgs) {
Registry rgsB = rgs.clone();
RegistryManager.zeroState(rgsB);
rgsB.setRegistryUnit(RegistryUnit.B.getKey());
rgsB.setRegistryCode(RegistryUtil.clearingCode(rgsB));
registryImdg.insert(rgsB);
log.debug("created {}.id={} by {}.id={}", rgsB.getRegistryCode(), rgsB.getId(), rgs.getRegistryCode(), rgs.getId());
return rgsB;
}
private void defineStatusAndUpdateRegistry(List<CheckResult> checkResults, List<Registry> registries) {

View file

@ -6,6 +6,7 @@ import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
import ru.spcex.clearing.platform.messaging.service.Status;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IEnumId;
import ru.spcex.platform.utils.enumeration.IErrorEnumId;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.error.ClearingBaseException;
@ -102,4 +103,17 @@ public class RequestHelper {
this.log = log;
return this;
}
public RequestInfoUpdate success(Long id) {
return new RequestInfoUpdate(id, Status.Success, null);
}
public RequestInfoUpdate error(Long id, EnumMessage err) {
return new RequestInfoUpdate(id, Status.Error, messageResolver.resolve(err));
}
public RequestInfoUpdate error(Long id, IEnumId sbj, Object... args) {
EnumMessage error = new EnumMessage(sbj, args);
return new RequestInfoUpdate(id, Status.Error, messageResolver.resolve(error));
}
}

View file

@ -88,6 +88,7 @@ public record RegistryTradingParams(RegistryDesignation registryDesignation,
public final static RegistryTradingParams AM_T;
public final static RegistryTradingParams AM_B;
public final static RegistryTradingParams A__B;
public final static RegistryTradingParams A__F;
public final static RegistryTradingParams A__T;
public final static RegistryTradingParams AS_T;
public final static RegistryTradingParams DS_I;
@ -153,6 +154,10 @@ public record RegistryTradingParams(RegistryDesignation registryDesignation,
null,
null,
RegistryUnit.B);
A__F = new RegistryTradingParams(RegistryDesignation.A,
null,
null,
RegistryUnit.F);
A__T = new RegistryTradingParams(RegistryDesignation.A,
null,
null,

View file

@ -1,10 +1,11 @@
package ru.spcex.clearing.platform.messaging.domain.cud.registry;
import com.fasterxml.jackson.annotation.JsonProperty;
import ru.spcex.platform.classes.base.interfaces.WithId;
import java.math.BigDecimal;
public class RegistryChangeStatusExtractRequest {
public class RegistryChangeStatusExtractRequest implements WithId {
@JsonProperty
public Long id;
@JsonProperty