From eeb8e4dc5f4605e37f14f13d8a50d3acf4dc8d09 Mon Sep 17 00:00:00 2001 From: ialbert Date: Tue, 15 Aug 2023 19:33:03 +0300 Subject: [PATCH] =?UTF-8?q?ExecutionDeposit=20=D0=B7=D0=B0=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=BE=D0=BB=D1=8F?= =?UTF-8?q?=20CounterPartyTradingClearingRegistryId=20SDF10?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../clearing/config/ValidationConfig.java | 7 +- .../execution/ExecutionDepositComponent.java | 22 ++ .../service/executors/Sdf10Executor.java | 340 +++++++++--------- .../service/executors/Sdf21Executor.java | 2 +- ...> CompanyByTradingCodeValidationRule.java} | 18 +- .../validation/Sdf10ValidationRule.java | 81 ++++- .../service/validation/ValidationStored.java | 4 +- .../enumeration/RegistryTradingParams.java | 5 + 8 files changed, 284 insertions(+), 195 deletions(-) rename clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/{CompanyByDepoCodeValidationRule.java => CompanyByTradingCodeValidationRule.java} (63%) 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 2da2f572e..f1bea5dae 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 @@ -202,7 +202,7 @@ public class ValidationConfig { context.addImdg(IMDGDistributedNames.Map_EquitySecurity, equitySecurityImdg); context.setLogPrefix(LogPrefixId.INSTANCE); return new ValidatorImpl<>(context, - CompanyByDepoCodeValidationRule.instance(SDf21::getDepoCodeCl), + CompanyByTradingCodeValidationRule.instance(SDf21::getDepoCodeCl), Sdf21ValidationRule.AccountPresent, SecurityBySecurityCodeValidationRule.instance(SDf21::getSecurityCode) ); @@ -279,9 +279,10 @@ public class ValidationConfig { context.setLogPrefix(LogPrefixId.INSTANCE); return new ValidatorImpl<>(context, Sdf10ValidationRule.DepoAccountPresent, - CompanyByDepoCodeValidationRule.instance(SDf10::getDepoCode), + CompanyByTradingCodeValidationRule.instance(SDf10::getDepoCode), Sdf10ValidationRule.CompanyStatus, - SecurityBySecurityCodeValidationRule.instance(SDf10::getSecurityCode) + SecurityBySecurityCodeValidationRule.instance(SDf10::getSecurityCode), + Sdf10ValidationRule.Balance ); }; } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/execution/ExecutionDepositComponent.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/execution/ExecutionDepositComponent.java index 0d18779ef..621133502 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/execution/ExecutionDepositComponent.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/execution/ExecutionDepositComponent.java @@ -25,6 +25,7 @@ import ru.spcex.clearing.service.validation.ValidationStored; import ru.spcex.platform.enumeration.*; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.enumeration.IEnumId; import ru.spcex.platform.utils.enumeration.IEnumKey; @@ -239,6 +240,17 @@ public class ExecutionDepositComponent { eDeposit.setContract(contract); eDeposit.setCounterPartyId(counterCompany.getId()); eDeposit.setSecurityCode(sTrades.getSecCode()); + { + ImdgPredicateBuilder strPb = sTradeImdg.predicateBuilder(); + STrades counterSTrades = sTradeImdg.getFirstObjectByPredicate(strPb.and( + strPb.equals("tradeNum", sTrades.getTradeNum()), + strPb.equals("section", sTrades.getSection()), + strPb.not(strPb.equals("section", sTrades.getSection())))); + if (counterSTrades != null) { + searchTcrByStrades(counterSTrades) + .ifPresent(tcr -> eDeposit.setCounterPartyTradingClearingRegistryId(tcr.getId())); + } + } return eDeposit; } @@ -265,4 +277,14 @@ public class ExecutionDepositComponent { private void logError(Long sTradeId, EnumMessage msg) { log.warn("sTrade id={} {}", sTradeId, msgResolver.resolve(msg)); } + + private Optional searchTcrByStrades(STrades sTrades) { + IValidator counterValidator = stradesValidator.apply(sTrades); + Optional err = counterValidator.tillFirstError(); + if (err.isPresent()) { + log.error("couldn't extract setCounterPartyTradingClearingRegistryId from strades.id={}", sTrades.getId()); + return Optional.empty(); + } + return counterValidator.getStored(ValidationStored.STradesTradingClearingRegistry); + } } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf10Executor.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf10Executor.java index 397734da4..0027eacf2 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf10Executor.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf10Executor.java @@ -12,22 +12,26 @@ import ru.clearing.classes.statics.data.instrument.issue.EquitySecurity; import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeSecurity; import ru.clearing.classes.statics.data.registry.Registry; import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; -import ru.clearing.classes.statics.data.sdf.SDf06; -import ru.clearing.classes.statics.data.sdf.SDf07; import ru.clearing.classes.statics.data.sdf.SDf10; import ru.clearing.classes.statics.data.sdf.SDf11; import ru.clearing.classes.statics.data.statement.Statement; +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.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.clearing.AssetOperationListRequest; import ru.spcex.clearing.platform.messaging.domain.cud.clearing.AssetOperationRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.gateway.AssetOperationApprovalRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.gateway.SingleAssetResponse; import ru.spcex.clearing.platform.messaging.domain.cud.importexport.SwtExporterRequest; import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; +import ru.spcex.clearing.service.validation.ValidationStored; import ru.spcex.platform.enumeration.*; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.number.BigDecimalUtil; import ru.spcex.platform.utils.validation.IValidator; @@ -35,8 +39,10 @@ import ru.spcex.platform.utils.validation.IValidator; import java.math.BigDecimal; import java.time.Instant; import java.time.LocalDate; +import java.util.ArrayList; import java.util.Collection; import java.util.Map; +import java.util.Optional; import java.util.function.Function; @Service @@ -51,11 +57,11 @@ public class Sdf10Executor { private final Imdg depoAccountImdg; private final Imdg tradingClearingRegistryImdg; private final Imdg companyImdg; - private final Imdg sdf06Imdg; - private final Imdg sdf07Imdg; + private final Imdg sdf10Imdg; + private final Imdg sdf11Imdg; private final ImdgId idGenerator; private final IMessageResolver messageResolver; - private final Function sDf06Validator; + private final Function sDf10Validator; private final KafkaSender kafkaSender; private final static BigDecimal successResult = BigDecimal.ZERO; @@ -65,14 +71,15 @@ public class Sdf10Executor { private final static BigDecimal errorResult1 = new BigDecimal("1"); //отказ от gateway private final static BigDecimal errorResult3 = new BigDecimal("3"); + private final static String DEFAULT_11_RES = "result"; private Long sdf10GroupId; - private Long sdf07GroupId; + private Long sdf11GroupId; @Autowired public Sdf10Executor(ImdgProvider imdgProvider, IMessageResolver messageResolver, - @Qualifier("sdf06ValidatorNew") Function sDf06Validator, + @Qualifier("sdf10Validator") Function sDf10Validator, KafkaSender kafkaSender) { this.imdgProvider = imdgProvider; this.statementImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class); @@ -84,15 +91,14 @@ public class Sdf10Executor { this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); this.idGenerator = imdgProvider.getImdgIdGenerator(); this.messageResolver = messageResolver; - this.sDf06Validator = sDf06Validator; + this.sDf10Validator = sDf10Validator; this.kafkaSender = kafkaSender; - this.sdf06Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf06, SDf06.class); - this.sdf07Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf07, SDf07.class); + this.sdf10Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf10, SDf10.class); + this.sdf11Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf11, SDf11.class); } public void execute(BaseRequest systemRequest) { Imdg sdf10Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf10, SDf10.class); - Imdg sdf11Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf11, SDf11.class); Long groupId = systemRequest.getRequestPayload().getGroupId(); Collection sdfs = sdf10Imdg.getCollectionObjectsByFieldValues(Map.of( "generationId", groupId @@ -100,157 +106,142 @@ public class Sdf10Executor { Instant now = Instant.now(); Long sdf11GroupId = idGenerator.nextId(); log.info("processing SDF10 groupId: {} sdf10s: {}", groupId, sdfs.size()); - for (SDf10 sdf10 : sdfs) { - SDf11 sdf11 = createSdf11(sdf10, now); - sdf11.setGenerationId(sdf11GroupId); - sdf11.setResult(SdfResult.OK.getKey()); - sdf11Imdg.insert(sdf11); - log.debug("sdf10.id={} created sdf11.id={}", sdf10.getId(), sdf11.getId()); + if (sdf10GroupId != null) { + log.warn("currently awaiting gateway response for groupId: {}. skipping groupId {}", sdf10GroupId, groupId); + sdfs.forEach(sdf10 -> { + SDf11 errorSdf11 = createSdf11(sdf10, now, DEFAULT_11_RES); + errorSdf11.setGenerationId(sdf11GroupId); + this.sdf11Imdg.insert(errorSdf11); + }); + sendToExporter(sdf11GroupId); + return; + } + Collection requests = new ArrayList<>(); + boolean sdf11WasCreated = false; + for (SDf10 sDf10 : sdfs) { + IValidator validator = sDf10Validator.apply(sDf10); + Optional err = validator.tillFirstError(); + if (err.isPresent()) { + log.debug("sdf10.id={} validation error: {}", sDf10.getId(), messageResolver.resolve(err.get())); + SDf11 errorSdf11; + String errorResult; + Statement stmt = null; + if (needToCreateStatement(err.get())) { + errorResult = DEFAULT_11_RES; + stmt = createStatementBySdf10(sDf10, + ((Company) validator.getStored(ValidationStored.CompanyByTradingCode)).getId(), + validator.getStored(ValidationStored.Sdf10Account)); + } else { + errorResult = DEFAULT_11_RES; + } + errorSdf11 = createSdf11(sDf10, now, errorResult); + errorSdf11.setGenerationId(sdf11GroupId); + this.sdf11Imdg.insert(errorSdf11); + sdf11WasCreated = true; + if (stmt != null) { + stmt.setOutSDfId(errorSdf11.getId()); + statementImdg.insert(stmt); + log.debug("Statement created: {}", stmt.getId()); + } + continue; + } + Company company = validator.getStored(ValidationStored.CompanyByTradingCode); + Account account = validator.getStored(ValidationStored.Sdf10Account); + TradingClearingRegistry tcr = validator.getStored(ValidationStored.Sdf10Tcr); + Statement stmt = createStatementBySdf10(sDf10, company.getId(), account); + statementImdg.insert(stmt); + log.debug("Statement created: {}", stmt.getId()); + if (InOutDirection.in.getKey().equals(stmt.getInOutDirection())) { + processedApproved(stmt, sDf10, now, sdf11GroupId); + sdf11WasCreated = true; + } else { + requests.add(requestFromStatement(stmt, company.getTradingCode(), tcr.getCode())); + } + } + if (requests.size() > 0) { + this.sdf10GroupId = groupId; + this.sdf11GroupId = sdf11GroupId; + AssetOperationListRequest assetOperationListRequest = new AssetOperationListRequest(); + assetOperationListRequest.setAssetOperationRequests(requests); + kafkaSender.sendRequestToQueue(Consts.ASSET_OPERATION, assetOperationListRequest); + } else if (sdf11WasCreated) { + sendToExporter(sdf11GroupId); } - sendToExporter(sdf11GroupId); -// if (sdf10GroupId != null) { -// log.warn("currently awaiting gateway response for groupId: {}. skipping groupId {}", sdf10GroupId, groupId); -// sdfs.forEach(sdf10 -> { -// SDf11 errorSdf11 = createSdf11(sdf10, now, errorResult2); -// errorSdf11.setGenerationId(sdf11GroupId); -// sdf07Imdg.insert(errorSdf11); -// }); -// sendToExporter(sdf11GroupId); -// return; -// } -// Collection requests = new ArrayList<>(); -// boolean sdf07WasCreated = false; -// for (SDf06 sDf06 : sdfs) { -// IValidator validator = sDf06Validator.apply(sDf06); -// Optional err = validator.tillFirstError(); -// if (err.isPresent()) { -// log.debug("sdf06.id={} validation error: {}", sDf06.getId(), messageResolver.resolve(err.get())); -// SDf07 errorSdf07; -// BigDecimal errorResult; -// Statement stmt = null; -// if (needToCreateStatement(err.get())) { -// errorResult = errorResult1; -// stmt = createStatementBySdf06(sDf06, -// ((Company) validator.getStored(ValidationStored.Sdf06Company)).getId(), -// validator.getStored(ValidationStored.Sdf06Account)); -// } else { -// errorResult = errorResult2; -// } -// errorSdf07 = createSdf11(sDf06, now, errorResult); -// errorSdf07.setGenerationId(sdf11GroupId); -// sdf07Imdg.insert(errorSdf07); -// sdf07WasCreated = true; -// if (stmt != null) { -// stmt.setOutSDfId(errorSdf07.getId()); -// statementImdg.insert(stmt); -// log.debug("Statement created: {}", stmt.getId()); -// } -// continue; -// } -// Company company = validator.getStored(ValidationStored.Sdf06Company); -// Account account = validator.getStored(ValidationStored.Sdf06Account); -// TradingClearingRegistry tcr = tradingClearingRegistryImdg.getFirstObjectByFieldValues( -// Map.of("moneyAccountId", account.getId()) -// ); -// //проверка существует ли statement пока убрал -// Statement stmt = createStatementBySdf06(sDf06, company.getId(), account); -// statementImdg.insert(stmt); -// log.debug("Statement created: {}", stmt.getId()); -// if (InOutDirection.in.getKey().equals(stmt.getInOutDirection())) { -// processedApproved(stmt, sDf06, now, sdf11GroupId); -// sdf07WasCreated = true; -// } else { -// requests.add(requestFromStatement(stmt, company.getTradingCode(), tcr.getCode())); -// } -// } -// if (requests.size() > 0) { -// this.sdf10GroupId = groupId; -// this.sdf07GroupId = sdf11GroupId; -// AssetOperationListRequest assetOperationListRequest = new AssetOperationListRequest(); -// assetOperationListRequest.setAssetOperationRequests(requests); -// kafkaSender.sendRequestToQueue(Consts.ASSET_OPERATION, assetOperationListRequest); -// } else if (sdf07WasCreated) { -// sendToExporter(sdf11GroupId); -// } } -// private void processedApproved(Statement stmt, SDf06 sDf06, Instant time) { -// processedApproved(stmt, sDf06, time, sdf07GroupId); -// } -// -// private void processedApproved(Statement stmt, SDf06 sDf06, Instant time, Long sdf07GenerationId) { -// log.trace("statement.id={}, sdf07.id={}, sdf06.id={} executed", -// stmt.getId(), -// sDf06.getGenerationId(), -// sDf06.getId()); -// SDf07 sdf07 = createSdf11(sDf06, time, successResult); -// sdf07.setGenerationId(sdf07GenerationId); -// sdf07Imdg.insert(sdf07); -// stmt.setOperationStatus(OperationStatus.Executed.getKey()); -// stmt.setUpdated(time); -// stmt.setOutSDfId(sdf07.getId()); -// statementImdg.update(stmt); -// } + private void processedApproved(Statement stmt, SDf10 sDf10, Instant time) { + processedApproved(stmt, sDf10, time, sdf11GroupId); + } -// private boolean needToCreateStatement(EnumMessage err) { -// return ClearingError.ActiveSessionIsPresent.equals(err.getSubject()) || ClearingError.BalanceInsufficient.equals(err.getSubject()); -// } -// -// public void processGatewayResponse(BaseRequest req) { -// Instant now = Instant.now(); -// for (SingleAssetResponse gatewayMsg : req.getRequestPayload().getApprovals()) { -// //получаем запрос для текущей группы sdf06 -// //находим группу -// Long statementId = gatewayMsg.getStatementId(); -// Statement stmt = statementImdg.getSingleObjectByID(statementId); -// if (stmt == null) { -// log.error("Statement.id {} not found", statementId); -// return; -// } -// -// Long sdf06Id = stmt.getInSDfId(); -// SDf06 sdf06 = sdf06Imdg.getSingleObjectByID(sdf06Id); -// if (sdf06 == null) { -// log.error("Sdf06.id {} not found by statement.id {}", sdf06Id, statementId); -// return; -// } -// -// Long groupId = sdf06.getGenerationId(); -// //сверяем группу SDF06 пришедшего запроса с ожидаемой -// if (sdf10GroupId == null || !sdf10GroupId.equals(groupId)) { -// log.error("do not currently waiting for gateway response for statement.id {} sdf06 groupId {}; waiting for {}", -// statementId, -// groupId, -// sdf06Id); -// return; -// } -// -// Instant updatedTime = Instant.now(); -// if (gatewayMsg.isApproved()) { -// processedApproved(stmt, sdf06, updatedTime); -// } else { -// log.trace("statement.id={}, sdf07.id={}, sdf06.id={} rejected (by gateway answer)", -// statementId, -// sdf06.getGenerationId(), -// sdf06.getId()); -// SDf07 sdf07 = createSdf11(sdf06, now, errorResult3); -// sdf07.setGenerationId(sdf07GroupId); -// sdf07Imdg.insert(sdf07); -// stmt.setOperationStatus(OperationStatus.Rejected.getKey()); -// stmt.setUpdated(updatedTime); -// stmt.setOutSDfId(sdf07.getId()); -// statementImdg.update(stmt); -// } -// } -// sendToExporter(sdf07GroupId); -// log.debug("All gateway responses received for SDF06 groupId {}. SDF07 groupId {}", sdf10GroupId, sdf07GroupId); -// clearContext(); -// } -// -// private void clearContext() { -// this.sdf10GroupId = null; -// this.sdf07GroupId = null; -// } + private void processedApproved(Statement stmt, SDf10 sDf10, Instant time, Long sdf11GenerationId) { + log.trace("statement.id={}, sdf11.id={}, sdf10.id={} executed", + stmt.getId(), + sDf10.getGenerationId(), + sDf10.getId()); + SDf11 sdf11 = createSdf11(sDf10, time, DEFAULT_11_RES); + sdf11.setGenerationId(sdf11GenerationId); + sdf11Imdg.insert(sdf11); + stmt.setOperationStatus(OperationStatus.Executed.getKey()); + stmt.setUpdated(time); + stmt.setOutSDfId(sdf11.getId()); + statementImdg.update(stmt); + } + + public void processGatewayResponse(BaseRequest req) { + Instant now = Instant.now(); + for (SingleAssetResponse gatewayMsg : req.getRequestPayload().getApprovals()) { + //получаем запрос для текущей группы sdf10 + //находим группу + Long statementId = gatewayMsg.getStatementId(); + Statement stmt = statementImdg.getSingleObjectByID(statementId); + if (stmt == null) { + log.error("Statement.id {} not found", statementId); + return; + } + + Long sdf10Id = stmt.getInSDfId(); + SDf10 sdf10 = sdf10Imdg.getSingleObjectByID(sdf10Id); + if (sdf10 == null) { + log.error("Sdf10.id {} not found by statement.id {}", sdf10Id, statementId); + return; + } + + Long groupId = sdf10.getGenerationId(); + //сверяем группу SDF10 пришедшего запроса с ожидаемой + if (sdf10GroupId == null || !sdf10GroupId.equals(groupId)) { + log.error("do not currently waiting for gateway response for statement.id {} sdf10 groupId {}; waiting for {}", + statementId, + groupId, + sdf10Id); + return; + } + + Instant updatedTime = Instant.now(); + if (gatewayMsg.isApproved()) { + processedApproved(stmt, sdf10, updatedTime); + } else { + log.trace("statement.id={}, sdf11.id={}, sdf10.id={} rejected (by gateway answer)", + statementId, + sdf10.getGenerationId(), + sdf10.getId()); + SDf11 sdf11 = createSdf11(sdf10, now, DEFAULT_11_RES); + sdf11.setGenerationId(sdf11GroupId); + sdf11Imdg.insert(sdf11); + stmt.setOperationStatus(OperationStatus.Rejected.getKey()); + stmt.setUpdated(updatedTime); + stmt.setOutSDfId(sdf11.getId()); + statementImdg.update(stmt); + } + } + sendToExporter(sdf11GroupId); + log.debug("All gateway responses received for SDF10 groupId {}. SDF11 groupId {}", sdf10GroupId, sdf11GroupId); + clearContext(); + } + + private void clearContext() { + this.sdf10GroupId = null; + this.sdf11GroupId = null; + } private void sendToExporter(Long generationId) { SwtExporterRequest swtReq = new SwtExporterRequest(); @@ -259,42 +250,28 @@ public class Sdf10Executor { kafkaSender.sendRequestToQueue(Consts.SWT_EXPORTER, swtReq); } - private SDf11 createSdf11(SDf10 sdf10, Instant time) { -// SDf11 sDf07 = new SDf11(); -// sDf07.setInSDfId(sdf06.getId()); -// sDf07.setGenerationTime(time); -// sDf07.setAccount(sdf06.getAccount()); -// sDf07.setSum(sdf06.getSum()); -// sDf07.setMarket(sdf06.getMarket()); -// sDf07.setType(sdf06.getType()); -// sDf07.setDeal(sdf06.getDeal()); -// sDf07.setClientN(sdf06.getClientN()); -// sDf07.setInn(sdf06.getInn()); -// sDf07.setBic(sdf06.getBic()); -// sDf07.setNumber(sdf06.getNumber()); -// sDf07.setSpec(sdf06.getSpec()); -// sDf07.setResult(result); -// return sDf07; + private SDf11 createSdf11(SDf10 sdf10, Instant time, String result) { SDf11 sdf11 = new SDf11(); sdf11.setOutDocument(sdf10.getOutDocument()); +// sdf11.setInDocument(); sdf11.setDepoCode(sdf10.getDepoCode()); sdf11.setQuantity(sdf10.getQuantity()); sdf11.setSecurityCode(sdf10.getSecurityCode()); sdf11.setClientName(sdf10.getClientName()); sdf11.setGenerationTime(time); -// sdf11.setGenerationId(sdf10.getGenerationId()); + sdf11.setResult(result); return sdf11; } - private Statement createStatementBySdf06(SDf06 sdf06, Long companyId, Account account) { + private Statement createStatementBySdf10(SDf10 sdf10, Long companyId, Account account) { Statement stmt = new Statement(); stmt.setAddresseeId(companyId); stmt.setSenderId(Sender.Prc.getId()); stmt.setStatementType(StatementType.incr.getKey()); - stmt.setComment(sdf06.getSpec()); + //fixme stmt.setComment(sdf10.()); stmt.setAccountId(account.getId()); stmt.setAccount(account.getAccount()); - BigDecimal amount = BigDecimalUtil.safeBD(sdf06.getSum()); + BigDecimal amount = BigDecimalUtil.safeBD(new BigDecimal(sdf10.getQuantity())); //fixme safe new BigDecimal if (amount.compareTo(BigDecimal.ZERO) >= 0) { stmt.setInOutDirection(InOutDirection.in.getKey()); } else { @@ -302,7 +279,7 @@ public class Sdf10Executor { } stmt.setAmount(amount.abs()); stmt.setOperationStatus(OperationStatus.Pending.getKey()); - stmt.setInSDfId(sdf06.getId()); + stmt.setInSDfId(sdf10.getId()); stmt.setInOutSDfType(InOutSDfType.type6.getKey()); stmt.setClearingDate(LocalDate.now()); stmt.setCreated(Instant.now()); @@ -319,4 +296,9 @@ public class Sdf10Executor { req.setDirection(stmt.getInOutDirection()); return req; } + + private boolean needToCreateStatement(EnumMessage err) { + return ClearingError.ActiveSessionIsPresent.equals(err.getSubject()) || ClearingError.BalanceInsufficient.equals(err.getSubject()) + || ClearingError.TCRegistryNotFound.equals(err.getSubject()); + } } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf21Executor.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf21Executor.java index 9a1723ede..280109394 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf21Executor.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf21Executor.java @@ -145,7 +145,7 @@ public class Sdf21Executor extends AbstractExecutor { log.error("error while validating sdf21.id={} - {}", sdf21.getId(), messageResolver.resolve(error.get())); continue; } - Company company = validator.getStored(ValidationStored.CompanyByDepoCode); + Company company = validator.getStored(ValidationStored.CompanyByTradingCode); Account account = validator.getStored(ValidationStored.Sdf21Account); log.debug("company.id={}, account.id={}", company.getId(), account.getId()); //адресат CREDIT / владелец DEBIT diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/CompanyByDepoCodeValidationRule.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/CompanyByTradingCodeValidationRule.java similarity index 63% rename from clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/CompanyByDepoCodeValidationRule.java rename to clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/CompanyByTradingCodeValidationRule.java index 8254f72cb..363614094 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/CompanyByDepoCodeValidationRule.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/validation/CompanyByTradingCodeValidationRule.java @@ -14,24 +14,24 @@ import java.util.Objects; import java.util.Optional; import java.util.function.Function; -public class CompanyByDepoCodeValidationRule implements IValidationRule> { +public class CompanyByTradingCodeValidationRule implements IValidationRule> { - private final Function depoCodeExtractor; + private final Function tradingCodeExtractor; - private CompanyByDepoCodeValidationRule(Function depoCodeExtractor) { - Objects.requireNonNull(depoCodeExtractor, "cannot create CompanyByDepoCodeValidationRule: depoCodeExtractor is null"); - this.depoCodeExtractor = depoCodeExtractor; + private CompanyByTradingCodeValidationRule(Function tradingCodeExtractor) { + Objects.requireNonNull(tradingCodeExtractor, "cannot create CompanyByDepoCodeValidationRule: depoCodeExtractor is null"); + this.tradingCodeExtractor = tradingCodeExtractor; } - public static CompanyByDepoCodeValidationRule instance(Function depoCodeExtractor) { - return new CompanyByDepoCodeValidationRule<>(depoCodeExtractor); + public static CompanyByTradingCodeValidationRule instance(Function depoCodeExtractor) { + return new CompanyByTradingCodeValidationRule<>(depoCodeExtractor); } @Override public Optional validate(ImdgValidationContext context) { T validatedObject = context.getValidatedObject(); Imdg companyImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class); - String depoCode = depoCodeExtractor.apply(validatedObject); + String depoCode = tradingCodeExtractor.apply(validatedObject); if (TextUtil.isEmpty(depoCode) || depoCode.length() < 4) { return of(ClearingError.CompanyNotFoundB, depoCode); } @@ -41,7 +41,7 @@ public class CompanyByDepoCodeValidationRule implements IValidationRule> { DepoAccountPresent() { @@ -37,13 +47,15 @@ public enum Sdf10ValidationRule implements IValidationRule validate(ImdgValidationContext context) { - Company company = context.getStoredObject(ValidationStored.CompanyByDepoCode); + Company company = context.getStoredObject(ValidationStored.CompanyByTradingCode); if (company == null) { return of(ClearingError.CompanyNotActive, "null"); } @@ -53,6 +65,73 @@ public enum Sdf10ValidationRule implements IValidationRule validate(ImdgValidationContext context) { + DepoAccount account = context.getStoredObject(ValidationStored.Sdf10Account); + if (account == null) { + return of(ClearingError.TCRegistryNotFound, ""); + } + Imdg tcrImdg; + tcrImdg = context.obtainMap(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class); +// if (AccountType.Anlt.getKey().equals(account.getAccountType())) { +// log.debug("account.id={} is ANLT", account.getId()); +// if (TextUtil.isEmpty(sdf10.getSpec())) { +// return of(ClearingError.TCRegistryNotFound, ""); +// } +// Imdg companyImdg = context.obtainMap(IMDGDistributedNames.Map_Company, Company.class); +// Imdg accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class); +// AnltSearcher anltSearcher = new AnltSearcher(tcrImdg, companyImdg, accountImdg); +// AnltSearcher.AnltSearch anltSrch = anltSearcher.loadByAnlt(sdf10.getSpec()); +// if (!anltSrch.isFound()) { +// log.debug("account.id={} ANLT couldn't find account by spec {}", account.getId(), sdf10.getSpec()); +// return of(ClearingError.TCRegistryNotFound, sdf10.getSpec()); +// } else { +// account = anltSrch.getAccount(); +// log.debug("account.id={} ANLT found account.id={} by spec {}", account.getId(), account.getId(), sdf10.getSpec()); +// } +// } + TradingClearingRegistry tcr = tcrImdg.getFirstObjectByFieldValues( + Map.of("moneyAccountId", account.getId()) + ); + if (tcr == null) { + return of(ClearingError.TCRegistryNotFound, ""); + } + context.storeObject(ValidationStored.Sdf10Tcr, tcr); + return empty(); + } + }, + Balance() { + @Override + public Optional validate(ImdgValidationContext context) { + SDf10 sdf10 = context.getValidatedObject(); + if (BigDecimalUtil.safeBD(new BigDecimal(sdf10.getQuantity())).compareTo(BigDecimal.ZERO) >= 0) { //fixme safe new BigDecimal + return empty(); + } + Company company = context.getStoredObject(ValidationStored.CompanyByTradingCode); + Account account = context.getStoredObject(ValidationStored.Sdf10Account); + Imdg registryImdg = context.obtainMap(IMDGDistributedNames.Map_Registry, Registry.class); + ImdgPredicateBuilder prdctBldr = registryImdg.predicateBuilder(); + Function prdctByRegistryCode = code -> prdctBldr.and( + prdctBldr.equals("account", account.getAccount()), + prdctBldr.equals("companyId", company.getId()), + prdctBldr.sql(RegistryCodeSqlBuilder.getInstance(code).build())); + Registry rgsAsf = registryImdg.getSingleObjectByPredicate(prdctByRegistryCode.apply(RegistryTradingParams.AS_F)); + Registry rgsDst = registryImdg.getSingleObjectByPredicate(prdctByRegistryCode.apply(RegistryTradingParams.DS_T)); + log.trace("validating sdf10 id={} account={} companyId={} found registries: AS*F.id={} DS*T.id={}", + sdf10.getId(), account.getAccount(), company.getId(), + rgsAsf == null ? null : rgsAsf.getId(), + rgsDst == null ? null : rgsDst.getId() + ); + BigDecimal asfBalance = rgsAsf == null ? BigDecimal.ZERO : BigDecimalUtil.safeBD(rgsAsf.getBalance()); + BigDecimal dstBalance = rgsDst == null ? BigDecimal.ZERO : BigDecimalUtil.safeBD(rgsDst.getBalance()); + BigDecimal stmtAmount = BigDecimalUtil.safeBD(new BigDecimal(sdf10.getQuantity())); //fixme safe new BigDecimal + if (asfBalance.subtract(dstBalance).compareTo(stmtAmount.abs()) < 0) { + return of(ClearingError.BalanceInsufficient); + } + return empty(); + } + } ; private final static Logger log = LoggerFactory.getLogger(Sdf10ValidationRule.class); @Override 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 a87a424ee..03a28834f 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 @@ -10,7 +10,7 @@ public enum ValidationStored { Sdf08Company, Sdf08Account, - Sdf10Company, Sdf10Account, + Sdf10Company, Sdf10Account, Sdf10DepoAccount, Sdf10Tcr, Sdf21Account, @@ -18,5 +18,5 @@ public enum ValidationStored { ReturnDepositDmx, - CompanyByDepoCode + CompanyByTradingCode } diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/RegistryTradingParams.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/RegistryTradingParams.java index dd751417e..173b8e2d6 100644 --- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/RegistryTradingParams.java +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/RegistryTradingParams.java @@ -24,6 +24,7 @@ public record RegistryTradingParams(RegistryDesignation registryDesignation, public final static RegistryTradingParams AM_T; public final static RegistryTradingParams AM_B; public final static RegistryTradingParams AS_T; + public final static RegistryTradingParams DS_T; public final static RegistryTradingParams AS_B; public final static RegistryTradingParams AS_F; public final static RegistryTradingParams CM_T; @@ -132,6 +133,10 @@ public record RegistryTradingParams(RegistryDesignation registryDesignation, RegistryInstrumentType.M, RegistryCapacity.A, RegistryUnit.U); + DS_T = new RegistryTradingParams(RegistryDesignation.D, + RegistryInstrumentType.S, + null, + RegistryUnit.T); } }