diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/AccountService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/AccountService.java index 66819ecaa..85d82a532 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/AccountService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/AccountService.java @@ -100,9 +100,6 @@ public class AccountService extends QueueConsumer implements InitializingBean { @Override public void afterPropertiesSet() { - callback(AccountSdf01Request.class) - .setFunction(this::accountNewSdf01) - .forDestination(Consts.ACCOUNT_NEW_SDF01, callbacks::put); callback(CorrespondentAccountNewRequest.class) .setFunction(this::accountCorrespondentNew) .forDestination(Consts.DESTINATION_CORRESPONDENT_ACCOUNT_NEW, callbacks::put); @@ -234,50 +231,6 @@ public class AccountService extends QueueConsumer implements InitializingBean { return null; } - @Deprecated - public RequestInfoUpdate accountNewSdf01(BaseRequest userRequest) { - log.debug("AccountSdf01Request received"); - - AccountSdf01Request req = userRequest.getRequestPayload(); - List accountToStatement = new ArrayList<>(); - for (AccountSdfRequestPart accountReq : req.getAccounts()) { - Account account = new Account(); - account.setAccount(accountReq.getAccount()); - account.setCompanyId(accountReq.getCompanyId()); - account.setAccountType(accountReq.getAccountType()); - account.setStatus(WorkflowStatus.Active.getKey()); - account.setCreated(Instant.now()); - account.setUpdated(account.getCreated()); - accountMap.insert(account); - AccountSdfToStatementRequestPart responsePart = responsePart(accountReq.getSdfId()); - accountToStatement.add(responsePart); - } - sendStatementRequestBack(req.getGroupingSdf01Id(), accountToStatement); - log.debug("successfully processed, grouping id={}, processed number={}", req.getGroupingSdf01Id(), accountToStatement.size()); - - return null; - } - - public void accountUpdateWithBrake(BaseRequest userRequest) { - - } - - public AccountSdfToStatementRequestPart responsePart(Long sdf01Id) { - AccountSdfToStatementRequestPart responsePart = new AccountSdfToStatementRequestPart(); - responsePart.setSdfId(sdf01Id); - responsePart.setErrorCode(null); - responsePart.setErrorText(null); - return responsePart; - } - - @Deprecated - public void sendStatementRequestBack(Long groupingSdf01Id, List results) { - StatementRequest request = new StatementRequest(); - request.setGroupId(groupingSdf01Id); - request.setAccountCreationResults(results); - log.debug("Send message to kafka \"{}\": {}", Consts.STATEMENT_PROCESS, LogFormatter.toStringWrapper(request)); - kafkaSender.sendRequestToQueue(Consts.STATEMENT_PROCESS, request); - } /** * Заполняет поля relationId и companyId из соответствующей записи Relation diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/ClearingAccountService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/ClearingAccountService.java index 1ccdc5243..9d28ae3f3 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/ClearingAccountService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/ClearingAccountService.java @@ -16,6 +16,10 @@ import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.account.ClearingAccountNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.account.ClearingAccountUpdateRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdf01Request; +import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdfRequestPart; +import ru.spcex.clearing.platform.messaging.domain.cud.balance.AccountSdfToStatementRequestPart; +import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest; import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryNewRequest; import ru.spcex.clearing.platform.messaging.serialization.LogFormatter; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; @@ -24,7 +28,9 @@ import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; import ru.spcex.clearing.util.services.RequestHelper; import ru.spcex.clearing.validation.common.ValidationHelper; import ru.spcex.platform.enumeration.AccountType; +import ru.spcex.platform.enumeration.SdfTable; import ru.spcex.platform.enumeration.ServiceStatus; +import ru.spcex.platform.enumeration.WorkflowStatus; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.imdg.api.ImdgTransaction; @@ -34,6 +40,8 @@ import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.validation.IValidator; import java.time.Instant; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.function.Function; @@ -61,9 +69,9 @@ public class ClearingAccountService extends QueueConsumer implements Initializin IMessageResolver messageResolver, RequestHelper requestHelper, @Qualifier("clearingAccountNewRequestValidator") - Function clearingAccountNewRequestValidator, + Function clearingAccountNewRequestValidator, @Qualifier("clearingAccountUpdateRequestValidator") - Function clearingAccountUpdateRequestValidator) { + Function clearingAccountUpdateRequestValidator) { super(kafkaQueue, kafkaResponseQueue); this.kafkaSender = kafkaSender; this.accountService = accountService; @@ -85,6 +93,10 @@ public class ClearingAccountService extends QueueConsumer implements Initializin callback(ClearingAccountUpdateRequest.class) .setFunction(this::clearingAccountUpdate) .forDestination(Consts.DESTINATION_CLEARING_ACCOUNT_UPDATE, callbacks::put); + callback(AccountSdf01Request.class) + .setFunction(this::accountNewSdf01) + .forDestination(Consts.ACCOUNT_NEW_SDF01, callbacks::put); + init(); } @@ -174,4 +186,101 @@ public class ClearingAccountService extends QueueConsumer implements Initializin return null; } + + + public RequestInfoUpdate accountNewSdf01(BaseRequest userRequest) { + log.debug("AccountSdf01Request received, id={}", userRequest.getId()); + + AccountSdf01Request req = userRequest.getRequestPayload(); + List accountToStatement = new ArrayList<>(); + + ImdgTransaction imdgTransaction = imdgProvider.newTransaction(); + List toTCRRequests = new ArrayList<>(); + boolean txOk = false; + imdgTransaction.beginTransaction(); + try { + accountsLoop: + for (AccountSdfRequestPart accountReq : req.getAccounts()) { + Instant now = Instant.now(); + Account account = new Account(); + account.setAccount(accountReq.getAccount()); + account.setAccountType(AccountType.Clrn.getKey()); + account.setStatus(ServiceStatus.Active.getKey()); + account.setCompanyId(accountReq.getCompanyId()); + account.setCreated(now); + account.setUpdated(now); + RequestInfoUpdate requestInfoUpdate = accountService.fillAccountFromRelation(account, userRequest.getId(), true); + if (requestInfoUpdate != null) { + log.warn("Error fill new account from relation. {}", /*account.getId(),*/ requestInfoUpdate.getMessage()); + { + AccountSdfToStatementRequestPart responsePart = new AccountSdfToStatementRequestPart(); + responsePart.setSdfId(accountReq.getSdfId()); + responsePart.setErrorCode(AccountError.ClearingCategoryNotFound.getId()); // see accountService.fillAccountFromRelation + responsePart.setErrorText(requestInfoUpdate.getMessage()); + accountToStatement.add(responsePart); + continue accountsLoop; + } + } + + Long clearingAccountId = -1L; + Long accountId = -1L; + ClearingAccount clearingAccount = null; + accountId = accountImdg.insert(account); + + clearingAccount = new ClearingAccount(); + clearingAccount.setCompanyId(accountReq.getCompanyId()); + clearingAccount.setAccountId(accountId); + clearingAccount.setClearingAccountType(accountReq.getAccountType()); + clearingAccountId = clearingAccountImdg.insert(clearingAccount); + log.trace("New account {}, clearingAccount {} was created.", accountId, clearingAccountId); + + { + TradingClearingRegistryNewRequest request = new TradingClearingRegistryNewRequest(); + request.setMoneyAccountId(accountId); + request.setCompanyId(clearingAccount.getCompanyId()); + toTCRRequests.add(request); + } + { + AccountSdfToStatementRequestPart responsePart = new AccountSdfToStatementRequestPart(); + responsePart.setSdfId(accountReq.getSdfId()); + responsePart.setErrorCode(null); + responsePart.setErrorText(null); + accountToStatement.add(responsePart); + } + } + txOk = true; + } finally { + if (txOk) { + imdgTransaction.commitTransaction(); + } else { + log.debug("failed insert, new clearing accounts. Request id={}", userRequest.getId()); + imdgTransaction.rollbackTransaction(); + } + } + + if (txOk) { + log.debug("Sending {} messages of TradingClearingRegistryNewRequest", toTCRRequests.size()); + for (TradingClearingRegistryNewRequest tcrReq : toTCRRequests) { + log.debug("Send message to kafka \"{}\": {}", Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, + LogFormatter.toStringWrapper(tcrReq)); + Long kafkaId = kafkaSender.sendRequestToQueue(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, tcrReq); + log.trace("successfully send request {} to kafka: new clearing account MoneyAccountId {}, DepoAccountId {}", + kafkaId, tcrReq.getMoneyAccountId(), tcrReq.getDepoAccountId()); + } + } + + sendStatementRequestBack(req.getGroupingSdf01Id(), accountToStatement); + log.debug("successfully processed, grouping id={}, processed number={}", req.getGroupingSdf01Id(), accountToStatement.size()); + + return null; + } + + public void sendStatementRequestBack(Long groupingSdf01Id, List results) { + StatementRequest request = new StatementRequest(); + request.setGroupId(groupingSdf01Id); + request.setAccountCreationResults(results); + request.setTable(SdfTable.SDF_01); // по нему запрос получили + log.debug("Send message to kafka \"{}\": {}", Consts.STATEMENT_PROCESS, LogFormatter.toStringWrapper(request)); + kafkaSender.sendRequestToQueue(Consts.STATEMENT_PROCESS, request); + } } diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java index d77b05871..5c0774a12 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/TradingClearingRegistryService.java @@ -20,10 +20,11 @@ import ru.spcex.clearing.platform.messaging.domain.ActionType; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeNewRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.clearing.CreateRegistryRequest; import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonIdRequest; import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.registry.TradingClearingRegistryUpdateRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.reports.ReportRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.reports.NotificationRequest; import ru.spcex.clearing.platform.messaging.serialization.LogFormatter; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; @@ -34,8 +35,6 @@ import ru.spcex.clearing.validation.common.ValidationHelper; 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.ImdgPredicate; -import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.validation.IValidator; @@ -64,6 +63,7 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini private final Function tradingClearingRegistryUpdateRequestValidator; private final RequestHelper requestHelper; private final Function tradingClearingRegistryNewRequestValidator; + private final Function tradingClearingRegistryAutoNewRequestValidator; private final Function tradingClearingRegistryBlockRequestValidator; private final IMessageResolver messageResolver; @@ -90,7 +90,6 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini this.validationHelper = validationHelper; this.userRoleVerification = userRoleVerification; this.requestHelper = requestHelper; - this.tradingClearingRegistryNewRequestValidator = tradingClearingRegistryNewRequestValidator; this.tradingClearingRegistryImdg = imdgProvider.getImdg( IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class ); @@ -100,6 +99,8 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class); this.relationImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); + this.tradingClearingRegistryNewRequestValidator = tradingClearingRegistryNewRequestValidator; + this.tradingClearingRegistryAutoNewRequestValidator = tradingClearingRegistryNewRequestValidator; // без relation. this.tradingClearingRegistryUpdateRequestValidator = tradingClearingRegistryUpdateRequestValidator; this.tradingClearingRegistryBlockRequestValidator = tradingClearingRegistryBlockRequestValidator; this.messageResolver = messageResolver; @@ -127,7 +128,7 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); if (requestInfoUpdate != null) return requestInfoUpdate; - requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, tradingClearingRegistryNewRequestValidator); + requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, tradingClearingRegistryAutoNewRequestValidator); if (requestInfoUpdate != null) return requestInfoUpdate; TradingClearingRegistryNewRequest req = userRequest.getRequestPayload(); @@ -162,64 +163,6 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini req.getCompanyId()); } } - Relation relation = relationImdg.getSingleObjectByFieldValues(Map.of("consumerId", req.getCompanyId())); - if (ru.spcex.platform.enumeration.Service.MKR.equalsByKey(relation.getService())) { - TradingClearingRegistry registry = tradingClearingRegistryImdg.getSingleObjectByFieldValues(Map.of("companyId", req.getCompanyId())); - if (registry != null) { - return requestHelper.makeErrorResponse(userRequest, - AccountError.TradingClearingRegistryAlreadyExist, - req.getCompanyId(), - registry.getId()); - } - DepoAccount depoAccountForCheck = depoAccountImdg.getSingleObjectByFieldValues(Map.of("companyId", req.getCompanyId())); - if (depoAccountForCheck == null) - return requestHelper.makeErrorResponse(userRequest, AccountError.DepoAccountNotFound, req.getCompanyId()); - } else if (ru.spcex.platform.enumeration.Service.FOND.equalsByKey(relation.getService())) { - if (AccountType.Info.equalsByKey(accountMain.getStatus())) { - TradingClearingRegistry registry = tradingClearingRegistryImdg.getSingleObjectByFieldValues(Map.of( - "companyId", req.getCompanyId(), - "tradingClearingRegistryType", TradingClearingRegistryPurpose.M.getKey() - )); - if (registry != null) { - return requestHelper.makeErrorResponse(userRequest, - AccountError.TradingClearingRegistryAlreadyExist, - req.getCompanyId(), - registry.getId()); - } - DepoAccount depoAccountForCheck = depoAccountImdg.getSingleObjectByFieldValues(Map.of("companyId", req.getCompanyId())); - if (depoAccountForCheck == null) - return requestHelper.makeErrorResponse(userRequest, AccountError.DepoAccountNotFound, req.getCompanyId()); - } else if (AccountType.Clrn.equalsByKey(accountMain.getStatus())) { - ImdgPredicateBuilder imdgPredicateBuilder = tradingClearingRegistryImdg.predicateBuilder(); - ImdgPredicate predicate = imdgPredicateBuilder.and( - imdgPredicateBuilder.equals("companyId", req.getCompanyId()), - imdgPredicateBuilder.or( - imdgPredicateBuilder.equals("tradingClearingRegistryPurpose", TradingClearingRegistryPurpose.M.getKey()), - imdgPredicateBuilder.equals("tradingClearingRegistryPurpose", TradingClearingRegistryPurpose.C.getKey()) - ) - ); - Collection registry = tradingClearingRegistryImdg.getCollectionObjectsByPredicate(predicate); - if (!registry.isEmpty()) { - return requestHelper.makeErrorResponse(userRequest, - AccountError.TradingClearingRegistryAlreadyExist, - req.getCompanyId(), - registry.iterator().next().getId()); - } - DepoAccount depoAccountForCheck = depoAccountImdg.getSingleObjectByFieldValues(Map.of("companyId", req.getCompanyId())); - if (depoAccountForCheck == null) { - return requestHelper.makeErrorResponse(userRequest, AccountError.DepoAccountNotFound, req.getCompanyId()); - } - } else if (AccountType.Depo.equalsByKey(accountMain.getStatus())) { - InformationAccount infoAccountForCheck = informationAccountImdg.getSingleObjectByFieldValues( - Map.of("companyId", req.getCompanyId()) - ); - ClearingAccount clearingAccountForCheck = clearingAccountImdg.getSingleObjectByFieldValues( - Map.of("companyId", req.getCompanyId()) - ); - if (infoAccountForCheck == null && clearingAccountForCheck == null) - return requestHelper.makeErrorResponse(userRequest, AccountError.MoneyAccountNotFound, req.getCompanyId()); - } - } List activeStatuses = Arrays.asList(ServiceStatus.Active.getKey(), ServiceStatus.Reopened.getKey()); String status = null; @@ -425,24 +368,18 @@ public class TradingClearingRegistryService extends QueueConsumer implements Ini * clearing-service сообщение на открытие клиринговых регистров; */ protected void sendNotificationToClearingSvc(TradingClearingRegistry tradingClearingRegistry) { - TradingClearingRegistryNewRequest request = new TradingClearingRegistryNewRequest(); - request.setTradingClearingRegistryType(tradingClearingRegistry.getTradingClearingRegistryType()); + CreateRegistryRequest request = new CreateRegistryRequest(); request.setCompanyId(tradingClearingRegistry.getCompanyId()); - request.setMoneyAccountId(tradingClearingRegistry.getMoneyAccountId()); - request.setDepoAccountId(tradingClearingRegistry.getDepoAccountId()); - request.setStatus(tradingClearingRegistry.getStatus()); - log.debug("Send message to kafka \"{}\": {}", Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, LogFormatter.toStringWrapper(request)); - kafkaSender.sendRequestToQueue(Consts.DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW, request); + log.debug("Send message to kafka \"{}\": {}", Consts.REGISTRY_NEW, LogFormatter.toStringWrapper(request)); + kafkaSender.sendRequestToQueue(Consts.REGISTRY_NEW, request); } /** - * todo report-service сообщение на формирование уведомления о создании нового ТКР + * report-service сообщение на формирование уведомления о создании нового ТКР */ protected void sendNotificationToReportSvc(TradingClearingRegistry tradingClearingRegistry) { - log.debug("Todo report destination: new TCR (не реализовано)"); -// ReportRequest request = new ReportRequest(); -// request.setReportId(ReportType.NEW_TRADING_CLEARING_REGISTRY); -// request.setTradingClearingRegistryId(tradingClearingRegistry.getId()); -// log.debug("Send message to kafka \"{}\": {}", Consts.CREATE_REPORT_FOR_TCR, LogFormatter.toStringWrapper(request)); -// kafkaSender.sendRequestToQueue(Consts.CREATE_REPORT_FOR_TCR, request); + NotificationRequest request = new NotificationRequest(); + request.setConsumerId(tradingClearingRegistry.getCompanyId()); + log.debug("Send message to kafka \"{}\": {}", Consts.CREATE_NOTIFICATION_NTCR, LogFormatter.toStringWrapper(request)); + kafkaSender.sendRequestToQueue(Consts.CREATE_NOTIFICATION_NTCR, request); } } diff --git a/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/AccountServiceTest.java b/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/AccountServiceTest.java index 3df591562..e7e4afae9 100644 --- a/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/AccountServiceTest.java +++ b/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/AccountServiceTest.java @@ -70,7 +70,6 @@ class AccountServiceTest { public static final MatcherFactory.Matcher ACCOUNT_MATCHER = usingIgnoringFieldsComparator(); public static final MatcherFactory.Matcher REQUEST_INFO_MATCHER_MATCHER = usingIgnoringFieldsComparator("created"); private static final int PARTITION = 0; - private static final String TOPIC_ACCOUNT_NEW = Consts.ACCOUNT_NEW_SDF01; private static final String account = "123456789123"; private static final Long companyId = 0L; private static final Long relationId = 0L; @@ -247,76 +246,4 @@ class AccountServiceTest { accountImdg.delete(resultBlock); } - /** - * {@link AccountService#accountNewSdf01(BaseRequest)}
- * Тест проверяет создание сущности {@link BaseRequest} в Hazelcast при передаче из Apache Kafka.
- * Входной запрос {@link AccountSdf01Request}:
- * {@link AccountSdfRequestPart#setSdfId} - текущий Id
- * {@link AccountSdfRequestPart#setAccount} - 123456789123
- * {@link AccountSdfRequestPart#setCompanyId} - текущий Id
- * {@link AccountSdf01Request#setGroupingSdf01Id} - текущий Id
- * {@link AccountSdf01Request#setAccounts} - Collections.singletonList(AccountSdfRequestPart)
- */ - @Test - void accountSdf01New() throws InterruptedException { - //ARRANGE - Long firstID = currentID.getAndIncrement(); - Long secondID = currentID.getAndIncrement(); - AccountSdfRequestPart accountSdfRequestPart = new AccountSdfRequestPart(); - accountSdfRequestPart.setSdfId(firstID); - accountSdfRequestPart.setAccount(account); - accountSdfRequestPart.setCompanyId(firstID); - AccountSdf01Request accountSdf01Request = new AccountSdf01Request(); - accountSdf01Request.setGroupingSdf01Id(firstID); - accountSdf01Request.setAccounts(Collections.singletonList(accountSdfRequestPart)); - BaseRequest baseNewRequest = new BaseRequest<>(); - baseNewRequest.setRequestPayload(accountSdf01Request); - baseNewRequest.setId(firstID); - baseNewRequest.setActionType(ActionType.NEW); - String jsonBaseNewRequest; - ObjectMapper objectMapper = new ObjectMapper(); - try { - jsonBaseNewRequest = objectMapper.writeValueAsString(baseNewRequest); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - - AccountSdfToStatementRequestPart responsePart = new AccountSdfToStatementRequestPart(); - responsePart.setSdfId(firstID); - responsePart.setErrorCode(null); - responsePart.setErrorText(null); - List accountToStatement = Collections.singletonList(responsePart); - StatementRequest statementRequest = new StatementRequest(); - statementRequest.setGroupId(firstID); - statementRequest.setAccountCreationResults(accountToStatement); - - BaseRequest baseRequest = new BaseRequest<>(); - baseRequest.setId(secondID); - baseRequest.setActionType(ActionType.SYSTEM); - baseRequest.setRequestPayload(statementRequest); - - Account predictableAccount = new Account(); - predictableAccount.setAccount(account); - predictableAccount.setCompanyId(firstID); - - RequestInfo predictableRequestInfo = new RequestInfo(); - predictableRequestInfo.setId(secondID); - predictableRequestInfo.setStatus(Status.Processing); - - //KAFKA - addRecordToKafka((MockConsumer) accountService.getConsumer(), TOPIC_ACCOUNT_NEW, PARTITION, 0, jsonBaseNewRequest); - - //waiting for kafka producer send message (finale event) - verify(producer, timeout(30_000L).times(2)) - .send(producerRecord.capture()); - //todo переписать валидацию ожидания на новые waitingSendAndCheckRecord / waitingWhenTryAddRecordAndCheckError - - ImdgHazelcast accountImdg = (ImdgHazelcast) hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Account, Account.class); - - //ASSERT - Account accountResult = accountImdg.getSingleObjectBySQL(String.format("account = %s", account)); - predictableAccount.setId(accountResult.getId()); - ACCOUNT_MATCHER.assertMatch(accountResult, predictableAccount); - accountImdg.delete(accountResult); - } } \ No newline at end of file diff --git a/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/ClearingAccountServiceTest.java b/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/ClearingAccountServiceTest.java index 9bd20e597..f29961c9a 100644 --- a/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/ClearingAccountServiceTest.java +++ b/clearing-parent/account-service/src/test/java/ru/spcex/clearing/account/service/ClearingAccountServiceTest.java @@ -1,5 +1,7 @@ package ru.spcex.clearing.account.service; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.kafka.clients.consumer.MockConsumer; import org.apache.kafka.clients.producer.MockProducer; import org.apache.kafka.clients.producer.Producer; @@ -26,23 +28,35 @@ import ru.spcex.clearing.account.config.validation.ClearingAccountValidationConf import ru.spcex.clearing.account.config.validation.ValidationConfig; import ru.spcex.clearing.account.utils.MatcherFactory; import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.ActionType; +import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.account.ClearingAccountNewRequest; import ru.spcex.clearing.platform.messaging.domain.cud.account.ClearingAccountUpdateRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdf01Request; +import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountSdfRequestPart; +import ru.spcex.clearing.platform.messaging.domain.cud.balance.AccountSdfToStatementRequestPart; +import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest; +import ru.spcex.clearing.platform.messaging.service.RequestInfo; +import ru.spcex.clearing.platform.messaging.service.Status; import ru.spcex.clearing.test.TestObjectCreator; import ru.spcex.clearing.test.config.ImdgTestConfig; import ru.spcex.clearing.test.config.KafkaTestConfig; import ru.spcex.platform.enumeration.*; import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.iml.hazelcast.adapter.ImdgHazelcast; import ru.spcex.platform.imdg.iml.hazelcast.service.HazelcastService; import javax.annotation.PostConstruct; +import java.util.Collections; +import java.util.List; import java.util.Map; import static org.mockito.Mockito.timeout; import static org.mockito.Mockito.verify; import static ru.spcex.clearing.account.utils.MatcherFactory.usingIgnoringFieldsComparator; import static ru.spcex.clearing.test.TestUtils.*; +import static ru.spcex.clearing.test.config.ImdgTestConfig.currentID; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { @@ -224,4 +238,77 @@ class ClearingAccountServiceTest { ACCOUNT_MATCHER.assertMatch(accountResult, predictableAccount); } +// /** +// * {@link ClearingAccountService#accountNewSdf01(BaseRequest)}
+// * Тест проверяет создание сущности {@link BaseRequest} в Hazelcast при передаче из Apache Kafka.
+// * Входной запрос {@link AccountSdf01Request}:
+// * {@link AccountSdfRequestPart#setSdfId} - текущий Id
+// * {@link AccountSdfRequestPart#setAccount} - 123456789123
+// * {@link AccountSdfRequestPart#setCompanyId} - текущий Id
+// * {@link AccountSdf01Request#setGroupingSdf01Id} - текущий Id
+// * {@link AccountSdf01Request#setAccounts} - Collections.singletonList(AccountSdfRequestPart)
+// */ +// @Test +// void accountSdf01New() throws InterruptedException { +// //ARRANGE +// Long firstID = currentID.getAndIncrement(); +// Long secondID = currentID.getAndIncrement(); +// AccountSdfRequestPart accountSdfRequestPart = new AccountSdfRequestPart(); +// accountSdfRequestPart.setSdfId(firstID); +// accountSdfRequestPart.setAccount(account); +// accountSdfRequestPart.setCompanyId(firstID); +// AccountSdf01Request accountSdf01Request = new AccountSdf01Request(); +// accountSdf01Request.setGroupingSdf01Id(firstID); +// accountSdf01Request.setAccounts(Collections.singletonList(accountSdfRequestPart)); +// BaseRequest baseNewRequest = new BaseRequest<>(); +// baseNewRequest.setRequestPayload(accountSdf01Request); +// baseNewRequest.setId(firstID); +// baseNewRequest.setActionType(ActionType.NEW); +// String jsonBaseNewRequest; +// ObjectMapper objectMapper = new ObjectMapper(); +// try { +// jsonBaseNewRequest = objectMapper.writeValueAsString(baseNewRequest); +// } catch (JsonProcessingException e) { +// throw new RuntimeException(e); +// } +// +// AccountSdfToStatementRequestPart responsePart = new AccountSdfToStatementRequestPart(); +// responsePart.setSdfId(firstID); +// responsePart.setErrorCode(null); +// responsePart.setErrorText(null); +// List accountToStatement = Collections.singletonList(responsePart); +// StatementRequest statementRequest = new StatementRequest(); +// statementRequest.setGroupId(firstID); +// statementRequest.setAccountCreationResults(accountToStatement); +// +// BaseRequest baseRequest = new BaseRequest<>(); +// baseRequest.setId(secondID); +// baseRequest.setActionType(ActionType.SYSTEM); +// baseRequest.setRequestPayload(statementRequest); +// +// Account predictableAccount = new Account(); +// predictableAccount.setAccount(account); +// predictableAccount.setCompanyId(firstID); +// +// RequestInfo predictableRequestInfo = new RequestInfo(); +// predictableRequestInfo.setId(secondID); +// predictableRequestInfo.setStatus(Status.Processing); +// +// //KAFKA +// final String TOPIC_ACCOUNT_NEW = Consts.ACCOUNT_NEW_SDF01; +// addRecordToKafka((MockConsumer) accountService.getConsumer(), TOPIC_ACCOUNT_NEW, PARTITION, 0, jsonBaseNewRequest); +// +// //waiting for kafka producer send message (finale event) +// verify(producer, timeout(30_000L).times(2)) +// .send(producerRecord.capture()); +// //todo переписать валидацию ожидания на новые waitingSendAndCheckRecord / waitingWhenTryAddRecordAndCheckError +// +// ImdgHazelcast accountImdg = (ImdgHazelcast) hazelcastServiceTest.getImdg(IMDGDistributedNames.Map_Account, Account.class); +// +// //ASSERT +// Account accountResult = accountImdg.getSingleObjectBySQL(String.format("account = %s", account)); +// predictableAccount.setId(accountResult.getId()); +// ACCOUNT_MATCHER.assertMatch(accountResult, predictableAccount); +// accountImdg.delete(accountResult); +// } } \ No newline at end of file diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/SpecifUtil.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/SpecifUtil.java index 79ac236da..f40573d5a 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/SpecifUtil.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/SpecifUtil.java @@ -1,15 +1,15 @@ package ru.spcex.clearing.service; public class SpecifUtil { - public static String[] splitPaymentPurpose(String paymentPurpose) { - if (paymentPurpose == null || paymentPurpose.length() < 1) return new String[0]; - int specifSize = divisionRoundUp(paymentPurpose.length(), 35); - specifSize = Math.min(specifSize, 6); - String[] res = new String[specifSize]; + public static String[] split5SegmentsBy35Symbols(String str) { + if (str == null || str.length() < 1) return new String[0]; + int size = divisionRoundUp(str.length(), 35); + size = Math.min(size, 6); + String[] res = new String[size]; for (int i = 0; i < res.length; i++) { int startIndex = i * 35; - int endIndex = Math.min(35 * (i + 1), paymentPurpose.length()); - res[i] = paymentPurpose.substring(startIndex, endIndex); + int endIndex = Math.min(35 * (i + 1), str.length()); + res[i] = str.substring(startIndex, endIndex); } return res; } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/StatementService.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/StatementService.java index 3fef674bc..106e78c81 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/StatementService.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/StatementService.java @@ -68,11 +68,13 @@ public class StatementService extends QueueConsumer implements InitializingBean } private void process(BaseRequest systemRequest) { + log.debug("Receiving StatementRequest id={}", systemRequest.getId()); StatementRequest statementRequest = systemRequest.getRequestPayload(); SdfTable table = statementRequest.getTable(); Optional completePairKey = saveRequest(statementRequest); if (completePairKey.isPresent()) { + boolean doSomeone = false; if (List.of(SdfTable.SDF_01, SdfTable.SDF_57).contains(table)) { { //всегда сначала обработаем sdf57 @@ -86,6 +88,7 @@ public class StatementService extends QueueConsumer implements InitializingBean ContinueSessionBnRequest continueSessionBn = new ContinueSessionBnRequest(); kafkaSender.sendRequestToQueue(Consts.CONTINUE_SESSION_BN_FIRST_PART, continueSessionBn); pairOfSdfRequest.remove(key); + doSomeone = true; } } else if (List.of(SdfTable.SDF_08, SdfTable.SDF_04).contains(table)) { if (table == SdfTable.SDF_08) { @@ -94,6 +97,7 @@ public class StatementService extends QueueConsumer implements InitializingBean Pair pair = pairOfSdfRequest.get(key); processSdf08(pair.getFirst()); pairOfSdfRequest.remove(key); + doSomeone = true; } } else if (table == SdfTable.SDF_04) { { @@ -101,9 +105,14 @@ public class StatementService extends QueueConsumer implements InitializingBean Pair pair = pairOfSdfRequest.get(key); processSdf04(pair.getFirst()); pairOfSdfRequest.remove(key); + doSomeone = true; } } } + if (!doSomeone) { + log.warn("No operation for request.id={}; statementRequest GroupId={}, table={}", + systemRequest.getId(), statementRequest.getGroupId(), statementRequest.getTable()); + } } } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilderFinalMkr.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilderFinalMkrDeals.java similarity index 74% rename from clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilderFinalMkr.java rename to clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilderFinalMkrDeals.java index 1cec2ecee..0279ac510 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilderFinalMkr.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilderFinalMkrDeals.java @@ -22,8 +22,11 @@ import java.time.format.DateTimeFormatter; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; -public class PaymentInstructionBuilderFinalMkr { - private final static Logger log = LoggerFactory.getLogger(PaymentInstructionBuilderFinalMkr.class); +/** + * Builder для кейса итоговой сессии МКР, 7 шаг, кейс - по сделкам + */ +public class PaymentInstructionBuilderFinalMkrDeals { + private final static Logger log = LoggerFactory.getLogger(PaymentInstructionBuilderFinalMkrDeals.class); private Registry cm_t; @@ -40,38 +43,38 @@ public class PaymentInstructionBuilderFinalMkr { protected AtomicLong documentNumberId = new AtomicLong(0L); // порядковый номер (сквозной по всем компаниям за день private static final DateTimeFormatter DATE_FORMATTER_ddMMyy = DateTimeFormatter.ofPattern("ddMMyy"); - public static PaymentInstructionBuilderFinalMkr builder(ImdgProvider imdgProvider) { - return new PaymentInstructionBuilderFinalMkr(imdgProvider); + public static PaymentInstructionBuilderFinalMkrDeals builder(ImdgProvider imdgProvider) { + return new PaymentInstructionBuilderFinalMkrDeals(imdgProvider); } - private PaymentInstructionBuilderFinalMkr(ImdgProvider imdgProvider) { + private PaymentInstructionBuilderFinalMkrDeals(ImdgProvider imdgProvider) { this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class); this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); this.companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); this.securityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Security, Security.class); } - public PaymentInstructionBuilderFinalMkr lm_t(Registry lm_t) { + public PaymentInstructionBuilderFinalMkrDeals lm_t(Registry lm_t) { this.lm_t = lm_t; return this; } - public PaymentInstructionBuilderFinalMkr cm_t(Registry cm_t) { + public PaymentInstructionBuilderFinalMkrDeals cm_t(Registry cm_t) { this.cm_t = cm_t; return this; } - public PaymentInstructionBuilderFinalMkr tranAcc(Account account) { + public PaymentInstructionBuilderFinalMkrDeals tranAcc(Account account) { this.tranAccount = account; return this; } - public PaymentInstructionBuilderFinalMkr sessionId(Long sessionId) { + public PaymentInstructionBuilderFinalMkrDeals sessionId(Long sessionId) { this.sessionId = sessionId; return this; } - public PaymentInstructionBuilderFinalMkr amount(BigDecimal amount) { + public PaymentInstructionBuilderFinalMkrDeals amount(BigDecimal amount) { this.amount = amount; return this; } @@ -83,30 +86,38 @@ public class PaymentInstructionBuilderFinalMkr { Instant now = Instant.now(); String symbolPRC = selectSymbolValue(Sender.Prc.getId(), CompanySymbol.BIC); // 2 "НКО АО ПРЦ" + String tranBic; { // record 1 payment1 = new PaymentInstruction(); payment1.setCreated(now); payment1.setClearingDate(TimeUtil.toLocalDate(now)); payment1.setSenderId(lm_t.getCompanyId()); payment1.setAddresseeId(Sender.One.getId()); - String symbol1 = selectSymbolValue(payment1.getAddresseeId(), CompanySymbol.BIC); - if (symbol1 == null) { - log.warn("CompanySymbols BIC not found for companyId={}", payment1.getAddresseeId()); - } else { - payment1.setAdresseeBic(symbol1); + { + tranBic = selectSymbolValue(payment1.getAddresseeId(), CompanySymbol.BIC); + if (tranBic == null) { + log.warn("CompanySymbols BIC not found for companyId={}", payment1.getAddresseeId()); + } else { + payment1.setAdresseeBic(tranBic); + } } - - Company companyPRC = companyImdg.getSingleObjectByID(Sender.Prc.getId()); // 2 "НКО АО ПРЦ" - String companyPRCName = null; - if (companyPRC == null) { - log.warn("Company.id={} not found", Sender.Prc.getId()); - } else { - companyPRCName = companyPRC.getShortName(); + { + Company companyPRC = companyImdg.getSingleObjectByID(Sender.Prc.getId()); // 2 "НКО АО ПРЦ" + if (companyPRC == null) { + log.warn("Company.id={} not found", Sender.Prc.getId()); + } else { + payment1.setPayeeBankName(companyPRC.getShortName()); + payment1.setAddresseeBankName(companyPRC.getShortName()); + } + } + { + String payeeBic = selectSymbolValue(payment1.getSenderId(), CompanySymbol.BIC); + if (payeeBic == null) { + log.warn("payeeBic by senderId={} not found", payment1.getSenderId()); + } else { + payment1.setPayeeBic(payeeBic); + } } - payment1.setPayeeBankName(companyPRCName); - payment1.setPayeeBic(symbolPRC); - - payment1.setAddresseeBankName(companyPRCName); payment1.setPaymentDate(TimeUtil.localDateToInstant(lm_t.getSettlementDate())); @@ -132,11 +143,8 @@ public class PaymentInstructionBuilderFinalMkr { payment1.setCredit_csAccount(null); { - Account acc1 = selectAccount(payment1.getAddresseeId(), AccountType.Corr, Status.Active, Allowed.ALLOWED); - if (acc1 != null) { - payment1.setDebitLeg_accountId(acc1.getId()); - payment1.setDebitLeg_account(acc1.getAccount()); - } + payment1.setDebitLeg_accountId(tranAccount.getId()); + payment1.setDebitLeg_account(tranAccount.getAccount()); } payment1.setDebit_csAccount(null); @@ -144,6 +152,11 @@ public class PaymentInstructionBuilderFinalMkr { payment1.setDebitLeg_currencyCode(CurrencyCode.RUB.getKey()); payment1.setTransactionStatus(TransactionStatus.stld.getKey()); payment1.setDocumentNumber(nextDocumentNumber(lm_t, payment1)); + payment1.setCreditLeg_direction(InOutDirection.out.getKey()); + payment1.setDebitLeg_direction(InOutDirection.in.getKey()); + payment1.setCreditLeg_securityId(lm_t.getSecurityId()); + payment1.setDebitLeg_securityId(lm_t.getSecurityId()); + payment1.setSessionId(sessionId); } //**************** @@ -152,7 +165,7 @@ public class PaymentInstructionBuilderFinalMkr { payment2.setCreated(now); payment2.setClearingDate(TimeUtil.toLocalDate(now)); payment2.setSenderId(Sender.One.getId()); // СПВБ - payment2.setAddresseeId(lm_t.getCompanyId()); + payment2.setAddresseeId(cm_t.getCompanyId()); String symbol2 = selectSymbolValue(payment2.getAddresseeId(), CompanySymbol.BIC); if (symbol2 == null) { log.warn("CompanySymbols BIC not found for companyId={}", payment2.getAddresseeId()); @@ -166,7 +179,7 @@ public class PaymentInstructionBuilderFinalMkr { payment2.setPayeeBankName(companyPRC.getShortName()); payment2.setAddresseeBankName(companyPRC.getShortName()); } - payment2.setPayeeBic(symbolPRC); + payment2.setAdresseeBic(tranBic); payment2.setPaymentDate(TimeUtil.localDateToInstant(lm_t.getSettlementDate())); payment2.setPaymentPurpose("Размещение депозита " + lm_t.getContract()); payment2.setSettlementDate(lm_t.getSettlementDate()); @@ -189,6 +202,13 @@ public class PaymentInstructionBuilderFinalMkr { payment2.setDebit_csAccount(null); payment2.setTransactionStatus(TransactionStatus.stld.getKey()); payment2.setDocumentNumber(nextDocumentNumber(cm_t, payment2)); + payment2.setCreditLeg_direction(InOutDirection.out.getKey()); + payment2.setDebitLeg_direction(InOutDirection.in.getKey()); + payment2.setCreditLeg_currencyCode(CurrencyCode.RUB.getKey()); + payment2.setDebitLeg_currencyCode(CurrencyCode.RUB.getKey()); + payment2.setCreditLeg_securityId(lm_t.getSecurityId()); + payment2.setDebitLeg_securityId(lm_t.getSecurityId()); + payment2.setSessionId(sessionId); } return new Pair<>(payment1, payment2); } @@ -234,7 +254,7 @@ public class PaymentInstructionBuilderFinalMkr { Account account = accountImdg.getSingleObjectByFieldValues(Map.of( "companyId", companyId, "accountType", accountType.getKey(), - "accountStatus", accountStatus.getKey(), + "status", accountStatus.getKey(), "processingSign", processingSign.getKey() )); if (account == null) { diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/Sdf03Builder.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/Sdf03Builder.java index f02fd0477..00ee57f12 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/Sdf03Builder.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/Sdf03Builder.java @@ -77,7 +77,7 @@ public class Sdf03Builder { sDf03.setPay_val("RUR"); sDf03.setSum_deb(paymentInstruction.getDebitLeg_amount() != null ? paymentInstruction.getDebitLeg_amount().toString() : null); //37 sp_code varchar(2) Код назначения платежа - String[] splitPaymentPurpose = SpecifUtil.splitPaymentPurpose(paymentInstruction.getPaymentPurpose()); + String[] splitPaymentPurpose = SpecifUtil.split5SegmentsBy35Symbols(paymentInstruction.getPaymentPurpose()); for (int i = 0; i < splitPaymentPurpose.length; i++) { String specif = splitPaymentPurpose[i]; if (i == 0) { diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf01Executor.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf01Executor.java index 94132651c..caea3e120 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf01Executor.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf01Executor.java @@ -111,8 +111,12 @@ public class Sdf01Executor extends AbstractExecutor { //на данном шаге company существует -> getId ok //формируем пакетный запрос на добавление account //ответ придет в этот же метод, process - result.getAccountRequests().add(createAccountRequestPart(sdf01.getId(), sdf01.getAccount(), company.getId())); - log.info("account {} for sdf01.id={} not found - send request for creation", sdf01.getAccount(), sdf01.getId()); + if (company == null) { + log.warn("account {} for sdf01.id={} not found. Can not send request for creation, cause company not found too", sdf01.getAccount(), sdf01.getId()); + } else { + result.getAccountRequests().add(createAccountRequestPart(sdf01.getId(), sdf01.getAccount(), sdf01.getAcc_type(), company.getId())); + log.info("account {} for sdf01.id={} not found - send request for creation", sdf01.getAccount(), sdf01.getId()); + } continue; } else if (ClearingErrorInternal.AccountNotPresent.equals(error.map(EnumMessage::getSubject).orElse(null))) { log.error("fatal error: resumed processing after generating accounts, but no account found for sdf01.id={}", sdf01.getId()); @@ -182,11 +186,11 @@ public class Sdf01Executor extends AbstractExecutor { return stmt; } - private AccountSdfRequestPart createAccountRequestPart(Long sdf01Id, String account, Long companyId) { + private AccountSdfRequestPart createAccountRequestPart(Long sdf01Id, String account, String accountType, Long companyId) { AccountSdfRequestPart req = new AccountSdfRequestPart(); req.setAccount(account); req.setCompanyId(companyId); - req.setAccountType(AccountType.Clrn.getKey()); + req.setAccountType(accountType); req.setSdfId(sdf01Id); return req; } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf08Executor.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf08Executor.java index c1a76eb0a..79a92f754 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf08Executor.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf08Executor.java @@ -99,8 +99,14 @@ public class Sdf08Executor extends AbstractExecutor { Account account = validator.getStored(ValidationStored.Sdf08Account); if (statementRequest.getAccountCreationResults().size() == 0 && ClearingErrorInternal.AccountNotPresent.equals(error.map(EnumMessage::getSubject).orElse(null))) { - result.getAccountRequests().add(createAccountRequestPart(sdf08.getId(), sdf08.getDepoCode(), account.getCompanyId())); - log.info("account {} for sdf08.id={} not found - send request for creation", sdf08.getDepoCode(), sdf08.getId()); + Company company = validator.getStored(ValidationStored.Sdf08Company); + Long companyId = company == null ? null : company.getId(); // account == null сегда, т.к. кейс AccountNotPresent + if (companyId == null) { + log.warn("account {} for sdf08.id={} not found. Can not send request for creation, cause company not found too", sdf08.getDepoCode(), sdf08.getId()); + } else { + result.getAccountRequests().add(createAccountRequestPart(sdf08.getId(), sdf08.getDepoCode(), companyId)); + log.info("account {} for sdf08.id={} not found - send request for creation", sdf08.getDepoCode(), sdf08.getId()); + } continue; } else if (ClearingErrorInternal.AccountNotPresent.equals(error.map(EnumMessage::getSubject).orElse(null))) { log.error("fatal error: resumed processing after generating accounts, but no account found for sdf01.id={}", sdf08.getId()); diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/SdfLegacyExecutor.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/SdfLegacyExecutor.java index c8a5ce1a3..01292d12e 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/SdfLegacyExecutor.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/SdfLegacyExecutor.java @@ -94,8 +94,12 @@ public class SdfLegacyExecutor extends AbstractExecutor { //на данном шаге company существует -> getId ok //формируем пакетный запрос на добавление account //ответ придет в этот же метод, process - result.getAccountRequests().add(createAccountRequestPart(sdf01.getId(), sdf01.getAccount(), company.getId())); - log.info("account {} for sdf01.id={} not found - send request for creation", sdf01.getAccount(), sdf01.getId()); + if (company == null) { + log.warn("account {} for sdf01.id={} not found. Can not send request for creation, cause company not found too", sdf01.getAccount(), sdf01.getId()); + } else { + result.getAccountRequests().add(createAccountRequestPart(sdf01.getId(), sdf01.getAccount(), company.getId())); + log.info("account {} for sdf01.id={} not found - send request for creation", sdf01.getAccount(), sdf01.getId()); + } continue; } else if (ClearingError.AccountNotPresent.equals(error.map(EnumMessage::getSubject).orElse(null))) { log.error("fatal error: resumed processing after generating accounts, but no account found for sdf01.id={}", sdf01.getId()); diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/FinalMkrSession.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/FinalMkrSession.java index 39da49f47..3dd5b038a 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/FinalMkrSession.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/FinalMkrSession.java @@ -40,7 +40,8 @@ public class FinalMkrSession extends AbstractSession implements InitializingBean private final InclusionObligations inclusionObligations; private final InspectionObligations inspectionObligations; private final FormingRegistersOnOS formingRegistersOnOS; - private final FormingPaymentInstructionDealsFinalMkr formingPaymentInstruction; + private final FormingPaymentInstructionReturnMkr formingPaymentInstructionReturn; + private final FormingPaymentInstructionDealsFinalMkr formingPaymentInstructionDeals; private final UnlockResources unlockResources; private final FinishingSession finishingSession; private final EndStageNotification endStageNotification; @@ -58,7 +59,7 @@ public class FinalMkrSession extends AbstractSession implements InitializingBean ObligationAdmission obligationsAdmission, InclusionObligations inclusionObligations, FormingRegistersOnOS formingRegistersOnOS, - FormingPaymentInstructionDealsFinalMkr formingPaymentInstruction, + FormingPaymentInstructionReturnMkr formingPaymentInstructionReturn, FormingPaymentInstructionDealsFinalMkr formingPaymentInstructionDeals, UnlockResources unlockResources, FinishingSession finishingSession, EndStageNotification endStageNotification, @@ -72,7 +73,8 @@ public class FinalMkrSession extends AbstractSession implements InitializingBean this.obligationsAdmission = obligationsAdmission; this.inclusionObligations = inclusionObligations; this.formingRegistersOnOS = formingRegistersOnOS; - this.formingPaymentInstruction = formingPaymentInstruction; + this.formingPaymentInstructionReturn = formingPaymentInstructionReturn; + this.formingPaymentInstructionDeals = formingPaymentInstructionDeals; this.unlockResources = unlockResources; this.finishingSession = finishingSession; this.endStageNotification = endStageNotification; @@ -170,12 +172,22 @@ public class FinalMkrSession extends AbstractSession implements InitializingBean //stage 6 runStage(TaskType.FormingRegistersOnOS, formingRegistersOnOS); //returns Collection //stage 7 - StageResult> paymentResult = null; + + StageResult> returnsPayment = null; { FormingPaymentInstructionPayload payload = new FormingPaymentInstructionPayload(); payload.setSessionId(currSession.getId()); //stage 7 - paymentResult = runStage(TaskType.FormingPaymentInstruction, payload, formingPaymentInstruction); + returnsPayment = runStage(TaskType.FormingPaymentInstruction, payload, formingPaymentInstructionReturn); + } + + StageResult> paymentResult = null; + { + FormingPaymentInstructionDealsMkrPayload payload = new FormingPaymentInstructionDealsMkrPayload(); + payload.setSessionId(currSession.getId()); + payload.setPaymentInstructionReturns(returnsPayment.getStageResult()); + //stage 7 + paymentResult = runStage(TaskType.FormingPaymentInstruction, payload, formingPaymentInstructionDeals); } if (paymentResult != null && paymentResult.getStageResult().isEmpty()) { runStage(TaskType.FormingPaymentInstruction, balanceRevise); diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionDealsFinalMkr.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionDealsFinalMkr.java index ae010368e..3a07e1021 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionDealsFinalMkr.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionDealsFinalMkr.java @@ -17,13 +17,13 @@ import ru.spcex.clearing.error.ClearingError; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.balance.ExportToFileRequest; -import ru.spcex.clearing.platform.messaging.domain.cud.importexport.SwtExporterRequest; import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; -import ru.spcex.clearing.service.builder.PaymentInstructionBuilderFinalMkr; +import ru.spcex.clearing.service.SpecifUtil; +import ru.spcex.clearing.service.builder.PaymentInstructionBuilderFinalMkrDeals; 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.FormingPaymentInstructionPayload; +import ru.spcex.clearing.session.stage.task.FormingPaymentInstructionDealsMkrPayload; import ru.spcex.platform.enumeration.*; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; @@ -43,9 +43,10 @@ import java.time.format.DateTimeFormatter; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; +import java.util.stream.Stream; -import static ru.spcex.platform.enumeration.RegistryTradingParams.CM_T; -import static ru.spcex.platform.enumeration.RegistryTradingParams.LM_T; +import static ru.spcex.platform.enumeration.RegistryTradingParams.*; +import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD; @Service @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) @@ -81,10 +82,10 @@ public class FormingPaymentInstructionDealsFinalMkr implements ISessionStage { @Override public StageResult submit(Task task) { - FormingPaymentInstructionPayload payload = (FormingPaymentInstructionPayload) task.getData(); + FormingPaymentInstructionDealsMkrPayload payload = (FormingPaymentInstructionDealsMkrPayload) task.getData(); switch (task.getTaskType()) { case FormingPaymentInstruction -> { - return formingPaymentInstructions(payload.getSessionId()); + return formingPaymentInstructions(payload.getSessionId(), payload.getPaymentInstructionReturns()); } default -> { throw new IllegalStateException("Unknown task type: " + task.getTaskType()); @@ -112,9 +113,10 @@ public class FormingPaymentInstructionDealsFinalMkr implements ISessionStage { * регистр LMAT кто переводит деньги (registry.account)
* в итоге создается 2 PaymentInstruction: LMAT -> TRAN счет -> CMAT счет */ - private StageResult formingPaymentInstructions(Long sessionId) { + private StageResult formingPaymentInstructions(Long sessionId, Collection paymentInstructionReturns) { Collection registries = selectRegistries(); log.debug("found registries.size() = {}", registries.size()); + //клиринговый счет, через который будут проводиться сделки Account tranAcc = accountImdg.getSingleObjectBySQL("accountType = '%s' and status = '%s' and processingSign = '%s'" .formatted(AccountType.Tran.getKey(), AccountStatus.ACTIVE.getKey(), Allowed.ALLOWED.getKey())); if (tranAcc == null) { @@ -123,6 +125,7 @@ public class FormingPaymentInstructionDealsFinalMkr implements ISessionStage { false); } log.debug("found tranAcc.id = {}", tranAcc.getId()); + //группируем регистры по groupId Map> groups = registries .stream() .collect(Collectors.groupingBy(Registry::getGroupId)); @@ -135,20 +138,54 @@ public class FormingPaymentInstructionDealsFinalMkr implements ISessionStage { .filter(rgs -> equalsByRegistry(rgsCode, rgs)) .findFirst() .orElse(null); - Registry rgsCmt = findByCode.apply(CM_T); - Registry rgsLmt = findByCode.apply(LM_T); - if (rgsCmt == null || rgsLmt == null) { - log.error("groupId {} cmt_t {} lm_t {} - both must be present", groupId, rgsCmt, rgsLmt); + //интересуют обязательства и требования по деньгам + Registry cm_t = findByCode.apply(CM_T); + Registry lm_t = findByCode.apply(LM_T); + if (cm_t == null || lm_t == null) { + log.error("groupId {} cmt_t {} lm_t {} - both must be present", groupId, cm_t, lm_t); continue; } - log.debug("generating payment instruction for groupId {} cmt_t {} lm_t {}", + { + //изменение активов - блокируем средства беред отправкой sdf'ов + Optional amfO = findRelatedAsset(lm_t.getTradingClearingRegistryId(), lm_t.getCompanyId(), AM_F); + Optional payerAmtO = findRelatedAsset(lm_t.getTradingClearingRegistryId(), lm_t.getCompanyId(), AM_T); + Optional ambO = findRelatedAsset(lm_t.getTradingClearingRegistryId(), lm_t.getCompanyId(), AM_B); + Optional receiverAmtO = findRelatedAsset(cm_t.getTradingClearingRegistryId(), cm_t.getCompanyId(), AM_B); + log.debug("changing A* registers based on LM_T {} and CM_T {} found AM*F.id={}, AM*T.id={}, AM*B.id={}, AM*B.id={}", + lm_t.getId(), + cm_t.getId(), + amfO.map(Registry::getId).orElse(null), + payerAmtO.map(Registry::getId).orElse(null), + ambO.map(Registry::getId).orElse(null), + receiverAmtO.map(Registry::getId).orElse(null) + ); + Instant now = Instant.now(); + amfO.ifPresent(amf -> { + amf.setBalance(safeBD(amf.getBalance()).subtract(safeBD(lm_t.getBalance()))); + setUpdatedStoreInImdg(amf, now); + }); + payerAmtO.ifPresent(amt -> { + amt.setSettledDebit(safeBD(amt.getSettledDebit()).add(safeBD(lm_t.getBalance()))); + setUpdatedStoreInImdg(amt, now); + }); + ambO.ifPresent(amb -> { + amb.setBalance(safeBD(amb.getBalance()).add(safeBD(lm_t.getBalance()))); + setUpdatedStoreInImdg(amb, now); + }); + receiverAmtO.ifPresent(amt -> { + // у отправителя и получателя одинаково, см. в FormingPaymentInstruction + amt.setSettledDebit(safeBD(amt.getSettledDebit()).add(safeBD(lm_t.getBalance()))); + setUpdatedStoreInImdg(amt, now); + }); + } + log.trace("generating payment instruction for groupId {} cmt_t {} lm_t {}", groupId, - rgsCmt.getId(), - rgsLmt.getId()); - Pair pmtInstrs = PaymentInstructionBuilderFinalMkr + cm_t.getId(), + lm_t.getId()); + Pair pmtInstrs = PaymentInstructionBuilderFinalMkrDeals .builder(imdgProvider) - .cm_t(rgsCmt) - .lm_t(rgsLmt) + .cm_t(cm_t) + .lm_t(lm_t) .tranAcc(tranAcc) .sessionId(sessionId) .build(); @@ -156,29 +193,46 @@ public class FormingPaymentInstructionDealsFinalMkr implements ISessionStage { paymentInstructionImdg.insert(pmtInstr); allPaymentInstructions.add(pmtInstr); }); - log.debug("generated PaymentInstructions for groupId {}: pmtInstr1.id={} pmtInstr2.id={}", + log.trace("generated PaymentInstructions for groupId {}: pmtInstr1.id={} pmtInstr2.id={}", groupId, pmtInstrs.getFirst().getId(), pmtInstrs.getSecond().getId()); } - sendSdfs(allPaymentInstructions); + + log.debug("PaymentInstructions return size {}, PaymentInstructions deals size {}. sending SDF03", + paymentInstructionReturns.size(), + allPaymentInstructions.size()); + List returnsAndDeals = Stream.concat(paymentInstructionReturns.stream(), allPaymentInstructions.stream()).toList(); + sendSdfs(returnsAndDeals); StageResult> stageResult = new StageResult<>(null, true); - stageResult.setStageResult(allPaymentInstructions); + stageResult.setStageResult(returnsAndDeals); return stageResult; } + + private void setUpdatedStoreInImdg(Registry rgs, Instant now) { + rgs.setUpdated(now); + registryImdg.update(rgs); + } + + private Optional findRelatedAsset(Long tradingClearingRegistryId, Long companyId, RegistryTradingParams rgsCode) { + ImdgPredicateBuilder rgsPrdBldr = registryImdg.predicateBuilder(); + RegistryCodeSqlBuilder codeSql = RegistryCodeSqlBuilder.getInstance(rgsCode); + ImdgPredicate assetCondition = rgsPrdBldr.and( + rgsPrdBldr.equals("tradingClearingRegistryId", tradingClearingRegistryId), + rgsPrdBldr.equals("companyId", companyId), + rgsPrdBldr.sql(codeSql.build()) + ); + return Optional.ofNullable(registryImdg.getSingleObjectByPredicate(assetCondition)); + } + private void sendSdfs(List formedPaymentInstructions) { List sDf03Created = new ArrayList<>(); - List sDf12Created = new ArrayList<>(); for (PaymentInstruction paymentInstruction : formedPaymentInstructions) { - Security security = securityImdg.getSingleObjectByID(paymentInstruction.getCreditLeg_securityId()); Account account = accountImdg.getSingleObjectByID(paymentInstruction.getCreditLeg_accountId()); - if (InstrumentType.CRNC.equalsByKey(security.getInstrumentType()) && - List.of(AccountType.Corr, AccountType.Clrn).contains(IEnumKey.getEnumByKey(AccountType.class, account.getAccountType()))) { + if (List.of(AccountType.Corr, AccountType.Clrn, AccountType.Tran, AccountType.Anlt) + .contains(IEnumKey.getEnumByKey(AccountType.class, account.getAccountType()))) { sDf03Created.add(newSDf03(paymentInstruction)); - } else if (!InstrumentType.CRNC.equalsByKey(security.getInstrumentType()) && - AccountType.Depo.equalsByKey(account.getAccountType())) { - sDf12Created.add(newSDf12(paymentInstruction)); } } @@ -194,31 +248,6 @@ public class FormingPaymentInstructionDealsFinalMkr implements ISessionStage { exportToFileRequest.setSdfGroupId(sdf03GroupId); kafkaSender.sendRequestToQueue(Consts.EXPORT_PROCESS, exportToFileRequest); } - - Long sdf12GroupId = null; - Long maxTxNumber = 1L; - if (!sDf12Created.isEmpty()) { - sdf12GroupId = imdgProvider.getImdgIdGenerator().nextId(); - ImdgPredicateBuilder predicateBuilder = sDf12Imdg.predicateBuilder(); - ImdgPredicate notEmptyTransactionNum = predicateBuilder.not(predicateBuilder.equals("transaction_number", "")); - Long maxId = sDf12Imdg.aggregateLongMax("id", notEmptyTransactionNum); - if (maxId != null) { - SDf12 sDf12 = sDf12Imdg.getSingleObjectByID(maxId); - maxTxNumber = Long.parseLong(sDf12.getTransactionNumber()) + 1; - } - } - for (SDf12 sDf12 : sDf12Created) { - sDf12.setGenerationId(sdf03GroupId); - sDf12.setTransactionNumber(maxTxNumber.toString()); - sDf12.setTransactionQuantity(String.valueOf(sDf12Created.size())); - sDf12Imdg.insert(sDf12); - } - - if (sdf12GroupId != null) { - SwtExporterRequest swtExporterRequest = new SwtExporterRequest(); - swtExporterRequest.setType("SDF_12"); - kafkaSender.sendRequestToQueue(Consts.SWT_EXPORTER, swtExporterRequest); - } } private SDf03 newSDf03(PaymentInstruction paymentInstruction) { @@ -241,11 +270,24 @@ public class FormingPaymentInstructionDealsFinalMkr implements ISessionStage { senderSbankName = company.getShortName(); } } - sDf03.setSbanknam1(senderSbankName); - sDf03.setSbanknam2(senderSbankName); - sDf03.setSbanknam3(senderSbankName); - sDf03.setSbanknam4(senderSbankName); - sDf03.setSbanknam5(senderSbankName); + String[] bnkNmeParts = SpecifUtil.split5SegmentsBy35Symbols(senderSbankName); + for (int i = 0; i < bnkNmeParts.length; i++) { + if (i == 0) { + sDf03.setSbanknam1(bnkNmeParts[i]); + } + if (i == 1) { + sDf03.setSbanknam2(bnkNmeParts[i]); + } + if (i == 2) { + sDf03.setSbanknam3(bnkNmeParts[i]); + } + if (i == 3) { + sDf03.setSbanknam4(bnkNmeParts[i]); + } + if (i == 4) { + sDf03.setSbanknam5(bnkNmeParts[i]); + } + } sDf03.setC_acc_cred(paymentInstruction.getDebitLeg_account()); diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionReturnMkr.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionReturnMkr.java new file mode 100644 index 000000000..0d7721270 --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionReturnMkr.java @@ -0,0 +1,343 @@ +package ru.spcex.clearing.session.stage.impl; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Service; +import ru.clearing.classes.statics.data.account.Account; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.payment.PaymentInstruction; +import ru.clearing.classes.statics.data.registry.Registry; +import ru.clearing.classes.statics.data.sdf.SDf03; +import ru.clearing.classes.statics.data.sdf.SDf12; +import ru.clearing.classes.statics.data.security.Security; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.platform.messaging.domain.Consts; +import ru.spcex.clearing.platform.messaging.domain.cud.balance.ExportToFileRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.importexport.SwtExporterRequest; +import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; +import ru.spcex.clearing.service.builder.PaymentInstructionBuilder; +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.FormingPaymentInstructionPayload; +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.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.utils.enumeration.IEnumKey; +import ru.spcex.platform.utils.time.TimeUtil; + +import java.math.BigDecimal; +import java.time.Instant; +import java.time.format.DateTimeFormatter; +import java.util.*; + +import static ru.spcex.platform.enumeration.RegistryTradingParams.*; + +@Service +@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class FormingPaymentInstructionReturnMkr implements ISessionStage { + private final Logger log = LoggerFactory.getLogger(getClass()); + //todo remove (set all in single method setImdg(provider -> setImdg1();setIdGenerator();...) + private ImdgProvider imdgProvider; + private ImdgId idGenerator; + private Imdg registryImdg; + private Imdg paymentInstructionImdg; + private Imdg securityImdg; + private Imdg accountImdg; + private Imdg companyImdg; + private Imdg sDf03Imdg; + private Imdg sDf12Imdg; + private KafkaSender kafkaSender; + + @Autowired + public FormingPaymentInstructionReturnMkr(ImdgProvider imdgProvider, + KafkaSender kafkaSender) { + this.kafkaSender = kafkaSender; + this.imdgProvider = imdgProvider; + this.idGenerator = imdgProvider.getImdgIdGenerator(); + this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); + this.securityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Security, Security.class); + this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class); + this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + this.sDf03Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf03, SDf03.class); + this.sDf12Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf12, SDf12.class); + this.paymentInstructionImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PaymentInstruction, PaymentInstruction.class); + } + + @Override + public StageResult submit(Task task) { + FormingPaymentInstructionPayload payload = (FormingPaymentInstructionPayload) task.getData(); + switch (task.getTaskType()) { + case FormingPaymentInstruction -> { + return formingPaymentInstruction(payload.getSessionId()); + } + default -> { + throw new IllegalStateException("Unknown task type: " + task.getTaskType()); + } + } + } + + + private StageResult formingPaymentInstruction(Long sessionId) { + RegistryCodeSqlBuilder registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(LM_T, CM_T); + String registryCodeCondition = registryCodeSqlBuilder.build(); + + Collection rgsAll = registryImdg.getCollectionObjectsBySQL(registryCodeCondition) + .stream() + .filter(rgs -> rgs.getValueDate() != null) + .filter(rgs -> rgs.getSettlementDate() != null) + .filter(rgs -> rgs.getSettlementDate().isAfter(rgs.getValueDate())) + .toList(); + log.debug("LM*T and CM*T size = {}", rgsAll.size()); + + List obligationsByMoney = rgsAll.stream() + .filter(registry -> equalsByRegistry(LM_T, registry)) + .toList(); + + log.debug("changing assets by LM*T"); + //изменяем активы по обязательствам по деньгам (LM_T) + for (Registry obligationByMoney : obligationsByMoney) { + String sql = String.format("tradingClearingRegistryId = %s and companyId = %s", + obligationByMoney.getTradingClearingRegistryId(), obligationByMoney.getCompanyId()); + Collection relatedRegistries = registryImdg.getCollectionObjectsBySQL(sql); + + for (Registry relatedRegistry : relatedRegistries) { + if (equalsByRegistry(AM_F, relatedRegistry)) { + relatedRegistry.setBalance(safeBD(relatedRegistry.getBalance()).subtract(safeBD(obligationByMoney.getBalance()))); + } else if (equalsByRegistry(AM_T, relatedRegistry)) { + relatedRegistry.setSettledDebit(safeBD(relatedRegistry.getSettledDebit()).add(safeBD(obligationByMoney.getBalance()))); + } else if (equalsByRegistry(AM_B, relatedRegistry)) { + relatedRegistry.setBalance(safeBD(relatedRegistry.getBalance()).add(safeBD(obligationByMoney.getBalance()))); + } + registryImdg.update(relatedRegistry); + } + } + log.debug("changing assets by CM*T"); + List requirementsByMoney = rgsAll.stream() + .filter(registry -> equalsByRegistry(CM_T, registry)) + .toList(); + //изменяем активы по требованиям по деньгам CM_T + for (Registry requirementByMoney : requirementsByMoney) { + String sql = String.format("tradingClearingRegistryId = %s and companyId = %s", + requirementByMoney.getTradingClearingRegistryId(), requirementByMoney.getCompanyId()); + Collection relatedRegistries = registryImdg.getCollectionObjectsBySQL(sql); + + for (Registry relatedRegistry : relatedRegistries) { + if (equalsByRegistry(AM_T, relatedRegistry)) { + relatedRegistry.setSettledDebit(safeBD(relatedRegistry.getSettledDebit()).add(safeBD(requirementByMoney.getBalance()))); + } + registryImdg.update(relatedRegistry); + } + } + + List formedPaymentInstructions = new ArrayList<>(); + + List allLiabilities = rgsAll + .stream() + .filter(registry -> RegistryDesignation.L.equalsByKey(registry.getRegistryDesignation())) + .toList(); + //todo сортировка if needed + for (int i = 0; i < allLiabilities.size(); i++) { + Registry lm_t = allLiabilities.get(i); + if (lm_t == null) continue; + LinkedList relatedRegistries = new LinkedList<>(); + relatedRegistries.add(lm_t); + for (int j = i + 1; j < allLiabilities.size(); j++) { + Registry related = allLiabilities.get(j); + if (related == null) continue; + if (registriesOfTheSameAgents(lm_t, related)) { + relatedRegistries.add(related); + allLiabilities.set(j, null); + } + } + log.trace("LM*T.id={} return group size {}", lm_t.getId(), relatedRegistries.size()); + BigDecimal sumBalance = relatedRegistries.stream().map(Registry::getBalance).reduce(BigDecimal.ZERO, BigDecimal::add); + log.trace("LM*T.id={} sumBalance={}", lm_t.getId(), sumBalance); + List builderList = new ArrayList<>(); + builderList.add(lm_t); + rgsAll.stream() + .filter(rgs -> rgs.getGroupId().equals(lm_t.getGroupId())) + .filter(rgs -> RegistryDesignation.C.equalsByKey(rgs.getRegistryDesignation())) + .findFirst() + .ifPresent(builderList::add); + + PaymentInstruction paymentInstruction = createPaymentInstruction(builderList, sumBalance, sessionId); + formedPaymentInstructions.add(paymentInstruction); + paymentInstructionImdg.insert(paymentInstruction); + log.trace("LM*T.id={} created paymentInstruction.id={}", lm_t.getId(), paymentInstruction.getId()); + builderList.forEach(registry -> { + registry.setPaymentId(paymentInstruction.getId()); + registry.setUpdated(Instant.now()); + registryImdg.update(registry); + }); + } + + //sdf отправляют + //sendSdfs(formedPaymentInstructions); + + StageResult> stageResult = new StageResult(null, true); + stageResult.setStageResult(formedPaymentInstructions); + return stageResult; + } + + private void sendSdfs(List formedPaymentInstructions) { + List sDf03Created = new ArrayList<>(); + List sDf12Created = new ArrayList<>(); + for (PaymentInstruction paymentInstruction : formedPaymentInstructions) { + Security security = securityImdg.getSingleObjectByID(paymentInstruction.getCreditLeg_securityId()); + Account account = accountImdg.getSingleObjectByID(paymentInstruction.getCreditLeg_accountId()); + if (InstrumentType.CRNC.equalsByKey(security.getInstrumentType()) && + List.of(AccountType.Corr, AccountType.Clrn).contains(IEnumKey.getEnumByKey(AccountType.class, account.getAccountType()))) { + sDf03Created.add(newSDf03(paymentInstruction)); + } else if (!InstrumentType.CRNC.equalsByKey(security.getInstrumentType()) && + AccountType.Depo.equalsByKey(account.getAccountType())) { + sDf12Created.add(newSDf12(paymentInstruction)); + } + } + + Long sdf03GroupId = !sDf03Created.isEmpty() ? imdgProvider.getImdgIdGenerator().nextId() : null; + for (SDf03 sDf03 : sDf03Created) { + sDf03.setGenerationId(sdf03GroupId); + sDf03Imdg.insert(sDf03); + } + + if (sdf03GroupId != null) { + ExportToFileRequest exportToFileRequest = new ExportToFileRequest(); + exportToFileRequest.setNameOfTable("DF-03"); + exportToFileRequest.setSdfGroupId(sdf03GroupId); + kafkaSender.sendRequestToQueue(Consts.EXPORT_PROCESS, exportToFileRequest); + } + + Long sdf12GroupId = null; + Long maxTxNumber = 1L; + if (!sDf12Created.isEmpty()) { + sdf12GroupId = imdgProvider.getImdgIdGenerator().nextId(); + ImdgPredicateBuilder predicateBuilder = sDf12Imdg.predicateBuilder(); + ImdgPredicate notEmptyTransactionNum = predicateBuilder.not(predicateBuilder.equals("transaction_number", "")); + Long maxId = sDf12Imdg.aggregateLongMax("id", notEmptyTransactionNum); + if (maxId != null) { + SDf12 sDf12 = sDf12Imdg.getSingleObjectByID(maxId); + maxTxNumber = Long.parseLong(sDf12.getTransactionNumber()) + 1; + } + } + for (SDf12 sDf12 : sDf12Created) { + sDf12.setGenerationId(sdf03GroupId); + sDf12.setTransactionNumber(maxTxNumber.toString()); + sDf12.setTransactionQuantity(String.valueOf(sDf12Created.size())); + sDf12Imdg.insert(sDf12); + } + + if (sdf12GroupId != null) { + SwtExporterRequest swtExporterRequest = new SwtExporterRequest(); + swtExporterRequest.setType("SDF_12"); + kafkaSender.sendRequestToQueue(Consts.SWT_EXPORTER, swtExporterRequest); + } + } + + private PaymentInstruction createPaymentInstruction(List registries, BigDecimal balance, Long sessionId) { + PaymentInstructionBuilder paymentInstructionBuilder = PaymentInstructionBuilder.builder(imdgProvider, registries) + .sessionId(sessionId) + .amount(balance); + return paymentInstructionBuilder.build(); + } + + private SDf03 newSDf03(PaymentInstruction paymentInstruction) { + log.debug("creating sdf03"); + SDf03 sDf03 = new SDf03(); + sDf03.setId(idGenerator.nextId()); + sDf03.setSeg_type("S"); + sDf03.setDoc_type("002"); + String strId = paymentInstruction.getId().toString(); + String strIdCut = strId.length() > 16 ? strId.substring(strId.length() - 16) : strId; + sDf03.setDocnm_ref(strIdCut); + sDf03.setC_acc_deb(paymentInstruction.getCreditLeg_account()); + + String senderSbankName = ""; + if (paymentInstruction.getSenderId().equals(1L)) { + senderSbankName = paymentInstruction.getPayeeBankName(); + } else { + Company company = companyImdg.getSingleObjectByID(paymentInstruction.getSenderId()); + if (company != null) { + senderSbankName = company.getShortName(); + } + } + sDf03.setSbanknam1(senderSbankName); + sDf03.setSbanknam2(senderSbankName); + sDf03.setSbanknam3(senderSbankName); + sDf03.setSbanknam4(senderSbankName); + sDf03.setSbanknam5(senderSbankName); + + sDf03.setC_acc_cred(paymentInstruction.getDebitLeg_account()); + + String addresseeSbankName = ""; + if (paymentInstruction.getAddresseeId().equals(1L)) { + addresseeSbankName = paymentInstruction.getAddresseeBankName(); + } else { + Company company = companyImdg.getSingleObjectByID(paymentInstruction.getAddresseeId()); + if (company != null) { + addresseeSbankName = company.getShortName(); + } + } + sDf03.setRbanknam1(addresseeSbankName); + sDf03.setRbanknam2(addresseeSbankName); + sDf03.setRbanknam3(addresseeSbankName); + sDf03.setRbanknam4(addresseeSbankName); + sDf03.setRbanknam5(addresseeSbankName); + + sDf03.setPay_date(payDateFormatter.format(TimeUtil.toLocalDate(paymentInstruction.getPaymentDate()))); + sDf03.setPay_val("RUR"); + sDf03.setSum_deb(paymentInstruction.getDebitLeg_amount() != null ? paymentInstruction.getDebitLeg_amount().toString() : ""); + sDf03.setSpecif_1(paymentInstruction.getPaymentPurpose()); + sDf03.setGenerationTime(Instant.now()); + sDf03.setPaymentInstructionId(paymentInstruction.getId()); + log.debug("successfully processed, new id {}", sDf03.getId()); + return sDf03; + } + + private SDf12 newSDf12(PaymentInstruction paymentInstruction) { + log.debug("creating sdf12"); + SDf12 sDf12 = new SDf12(); + sDf12.setId(idGenerator.nextId()); + sDf12.setOutDocument(sDf12.getId().toString()); + sDf12.setDirection("DELFREE"); + sDf12.setQuantity(paymentInstruction.getCreditLeg_amount().toString()); + sDf12.setSecurityCode(paymentInstruction.getCreditLeg_securityId().toString()); + sDf12.setDepoCodeSender(paymentInstruction.getCreditLeg_account()); + sDf12.setDepoCodeAdressee(paymentInstruction.getDebitLeg_account()); +// sDf12.setTransactionNumber(); + sDf12.setGenerationTime(Instant.now()); + return sDf12; + } + + private BigDecimal safeBD(BigDecimal value) { + return value != null ? value : BigDecimal.ZERO; + } + + DateTimeFormatter payDateFormatter = DateTimeFormatter.ofPattern("dd.MM.yy"); + + + + private boolean registriesOfTheSameAgents(Registry rgs1, Registry rgs2) { + return Objects.equals(rgs1.getSecurityId(), rgs2.getSecurityId()) + && Objects.equals(rgs1.getTradingClearingRegistryId(), rgs2.getTradingClearingRegistryId()) + && Objects.equals(rgs1.getCompanyId(), rgs2.getCompanyId()) + && Objects.equals(rgs1.getCounterPartyId(), rgs2.getCounterPartyId()); + } + + private static boolean equalsByRegistry(RegistryTradingParams code, Registry rgs) { + return code.equalByRegistry( + IEnumKey.getEnumByKey(RegistryDesignation.class, rgs.getRegistryDesignation()), + IEnumKey.getEnumByKey(RegistryInstrumentType.class, rgs.getRegistryInstrumentType()), + IEnumKey.getEnumByKey(RegistryCapacity.class, rgs.getRegistryCapacity()), + IEnumKey.getEnumByKey(RegistryUnit.class, rgs.getRegistryUnit()) + ); + + } +} diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/task/FormingPaymentInstructionDealsMkrPayload.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/task/FormingPaymentInstructionDealsMkrPayload.java new file mode 100644 index 000000000..51fd741d6 --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/task/FormingPaymentInstructionDealsMkrPayload.java @@ -0,0 +1,29 @@ +package ru.spcex.clearing.session.stage.task; + +import ru.clearing.classes.statics.data.payment.PaymentInstruction; + +import java.util.Collection; + +public class FormingPaymentInstructionDealsMkrPayload { + private Long sessionId; + /** + * для МКР итоговой сессии SDF будет отправляться по 1. возвратам 2. сделкам + * соотв. поле нужно чтобы передать сделанные пейменты из пункта 1 в 2 + */ + private Collection paymentInstructionReturns; + public Long getSessionId() { + return sessionId; + } + + public void setSessionId(Long sessionId) { + this.sessionId = sessionId; + } + + public Collection getPaymentInstructionReturns() { + return paymentInstructionReturns; + } + + public void setPaymentInstructionReturns(Collection paymentInstructionReturns) { + this.paymentInstructionReturns = paymentInstructionReturns; + } +} diff --git a/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/service/SpecifUtilTest.java b/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/service/SpecifUtilTest.java index a53305668..254e32488 100644 --- a/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/service/SpecifUtilTest.java +++ b/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/service/SpecifUtilTest.java @@ -15,7 +15,7 @@ class SpecifUtilTest { public void testSplit() { { //40 symbols - String[] splitted = SpecifUtil.splitPaymentPurpose("0123456789012345678901234567890123456789"); + String[] splitted = SpecifUtil.split5SegmentsBy35Symbols("0123456789012345678901234567890123456789"); Assertions.assertEquals(2, splitted.length); Assertions.assertEquals("01234567890123456789012345678901234", splitted[0]); Assertions.assertEquals("56789", splitted[1]); @@ -23,27 +23,27 @@ class SpecifUtilTest { { //40 symbols - String[] splitted = SpecifUtil.splitPaymentPurpose("01234567890123456789012345678901234"); + String[] splitted = SpecifUtil.split5SegmentsBy35Symbols("01234567890123456789012345678901234"); Assertions.assertEquals(1, splitted.length); Assertions.assertEquals("01234567890123456789012345678901234", splitted[0]); } { //10 symbols - String[] splitted = SpecifUtil.splitPaymentPurpose("0123456789"); + String[] splitted = SpecifUtil.split5SegmentsBy35Symbols("0123456789"); Assertions.assertEquals(1, splitted.length); Assertions.assertEquals("0123456789", splitted[0]); } { //0 symbols - String[] splitted = SpecifUtil.splitPaymentPurpose(""); + String[] splitted = SpecifUtil.split5SegmentsBy35Symbols(""); Assertions.assertEquals(0, splitted.length); } { //80 symbols - String[] splitted = SpecifUtil.splitPaymentPurpose("0123456789012345678901234567890123456789" + + String[] splitted = SpecifUtil.split5SegmentsBy35Symbols("0123456789012345678901234567890123456789" + "0123456789012345678901234567890123456789"); Assertions.assertEquals(3, splitted.length); Assertions.assertEquals("01234567890123456789012345678901234", splitted[0]); @@ -53,7 +53,7 @@ class SpecifUtilTest { { //maximum symbols - String[] splitted = SpecifUtil.splitPaymentPurpose("01234567890123456789012345678912345" + + String[] splitted = SpecifUtil.split5SegmentsBy35Symbols("01234567890123456789012345678912345" + "01234567890123456789012345678912345" + "01234567890123456789012345678912345" + "01234567890123456789012345678912345" + diff --git a/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/session/stage/util/RegistryUtilTest.java b/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/session/stage/util/RegistryUtilTest.java index d423313bd..f6ffb8249 100644 --- a/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/session/stage/util/RegistryUtilTest.java +++ b/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/session/stage/util/RegistryUtilTest.java @@ -3,7 +3,7 @@ package ru.spcex.clearing.session.stage.util; import org.junit.jupiter.api.Test; import ru.clearing.classes.statics.data.registry.Registry; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; class RegistryUtilTest { diff --git a/clearing-parent/dbf-importer/src/main/java/ru/spcex/clearing/dbf/importer/logic/data/tables/SDf52Table.java b/clearing-parent/dbf-importer/src/main/java/ru/spcex/clearing/dbf/importer/logic/data/tables/SDf52Table.java index 730c518a8..f0a6f994a 100644 --- a/clearing-parent/dbf-importer/src/main/java/ru/spcex/clearing/dbf/importer/logic/data/tables/SDf52Table.java +++ b/clearing-parent/dbf-importer/src/main/java/ru/spcex/clearing/dbf/importer/logic/data/tables/SDf52Table.java @@ -4,13 +4,14 @@ import ru.clearing.classes.statics.data.sdf.SDf52; import ru.spcex.clearing.dbf.importer.logic.data.enums.ETable; import ru.spcex.clearing.imdg.IMDGDistributedNames; +import java.math.BigDecimal; import java.time.Instant; public class SDf52Table extends AbstractTable { private static final String PREFIX = ETable.DF_52.name(); private static final Class CLAZZ = SDf52.class; - private static final String NAME_OF_HZ_MAP = IMDGDistributedNames.Map_SDf57; + private static final String NAME_OF_HZ_MAP = IMDGDistributedNames.Map_SDf52; public SDf52Table() { super(PREFIX, CLAZZ, NAME_OF_HZ_MAP); @@ -23,7 +24,8 @@ public class SDf52Table extends AbstractTable { result.setAcc_name((String) entity[1]); result.setDeal((String) entity[2]); result.setDate((String) entity[3]); - result.setStatus((Long) entity[4]); + BigDecimal status = (BigDecimal) entity[4]; + result.setStatus(status != null ? status.longValue() : null); result.setFileName(filename); result.setGenerationTime(Instant.now()); result.setGenerationId(fileId); diff --git a/clearing-parent/dbf-importer/src/main/java/ru/spcex/clearing/dbf/importer/logic/data/tables/SDf55Table.java b/clearing-parent/dbf-importer/src/main/java/ru/spcex/clearing/dbf/importer/logic/data/tables/SDf55Table.java index daed9eafb..d1e11037b 100644 --- a/clearing-parent/dbf-importer/src/main/java/ru/spcex/clearing/dbf/importer/logic/data/tables/SDf55Table.java +++ b/clearing-parent/dbf-importer/src/main/java/ru/spcex/clearing/dbf/importer/logic/data/tables/SDf55Table.java @@ -10,7 +10,7 @@ public class SDf55Table extends AbstractTable { private static final String PREFIX = ETable.DF_55.name(); private static final Class CLAZZ = SDf55.class; - private static final String NAME_OF_HZ_MAP = IMDGDistributedNames.Map_SDf57; + private static final String NAME_OF_HZ_MAP = IMDGDistributedNames.Map_SDf55; public SDf55Table() { super(PREFIX, CLAZZ, NAME_OF_HZ_MAP); @@ -22,41 +22,43 @@ public class SDf55Table extends AbstractTable { result.setSeg_type((String) entity[0]); result.setDoc_type((String) entity[1]); result.setDocnm_ref((String) entity[2]); - result.setDocnmprev((String) entity[4]); - result.setSbankcode((String) entity[5]); - result.setC_acc_deb((String) entity[6]); - result.setSbanknam1((String) entity[7]); - result.setSbanknam2((String) entity[8]); - result.setSbanknam3((String) entity[9]); - result.setSbanknam4((String) entity[10]); - result.setSbanknam5((String) entity[11]); - result.setRbankcode((String) entity[12]); - result.setC_acc_cred((String) entity[13]); - result.setRbanknam1((String) entity[14]); - result.setRbanknam2((String) entity[15]); - result.setRbanknam3((String) entity[16]); - result.setRbanknam4((String) entity[17]); - result.setRbanknam5((String) entity[18]); - result.setOp_type((String) entity[19]); + result.setDocnmprev((String) entity[3]); + result.setSbankcode((String) entity[4]); + result.setC_acc_deb((String) entity[5]); + result.setSbanknam1((String) entity[6]); + result.setSbanknam2((String) entity[7]); + result.setSbanknam3((String) entity[8]); + result.setSbanknam4((String) entity[9]); + result.setSbanknam5((String) entity[10]); + result.setRbankcode((String) entity[11]); + result.setC_acc_cred((String) entity[12]); + result.setRbanknam1((String) entity[13]); + result.setRbanknam2((String) entity[14]); + result.setRbanknam3((String) entity[15]); + result.setRbanknam4((String) entity[16]); + result.setRbanknam5((String) entity[17]); + result.setOp_type((String) entity[18]); + result.setOp_order((String) entity[19]); result.setPay_date((String) entity[20]); -// result.setExt_date((String) entity[21]); - result.setPay_val((String) entity[22]); - result.setSum_deb((String) entity[23]); - result.setSclientn1((String) entity[24]); - result.setSclientn2((String) entity[25]); - result.setSclientn3((String) entity[26]); - result.setSclientn4((String) entity[27]); - result.setInn_deb((String) entity[28]); - result.setKpp_deb((String) entity[29]); - result.setAcc_deb((String) entity[30]); - result.setRclientn1((String) entity[31]); - result.setRclientn2((String) entity[32]); - result.setRclientn3((String) entity[33]); - result.setRclientn4((String) entity[34]); -// result.setInn_cred((String) entity[]); -// result.setKpp_cred((String) entity[]); -// result.setAcc_kr((String) entity[]); -// result.setSpecif((String) entity[36]); + result.setPay_val((String) entity[21]); + result.setSum_deb((String) entity[22]); + result.setSclientn1((String) entity[23]); + result.setSclientn2((String) entity[24]); + result.setSclientn3((String) entity[25]); + result.setSclientn4((String) entity[26]); + result.setInn_deb((String) entity[27]); + result.setKpp_deb((String) entity[28]); + result.setAcc_deb((String) entity[29]); + result.setRclientn1((String) entity[30]); + result.setRclientn2((String) entity[31]); + result.setRclientn3((String) entity[32]); + result.setRclientn4((String) entity[33]); + result.setInn_cred((String) entity[34]); + result.setKpp_cred((String) entity[35]); + result.setAcc_kr_1((String) entity[36]); + result.setSpecif_1((String) entity[37]); + result.setSend_type((String) entity[38]); + result.setDoc_result((String) entity[39]); result.setFileName(filename); result.setGenerationTime(Instant.now()); result.setGenerationId(fileId); diff --git a/clearing-parent/gateway-api/src/main/java/ru/spcex/clearing/gatewayapi/request/InboundRequest.java b/clearing-parent/gateway-api/src/main/java/ru/spcex/clearing/gatewayapi/request/InboundRequest.java index 56d4801bf..008e0919d 100644 --- a/clearing-parent/gateway-api/src/main/java/ru/spcex/clearing/gatewayapi/request/InboundRequest.java +++ b/clearing-parent/gateway-api/src/main/java/ru/spcex/clearing/gatewayapi/request/InboundRequest.java @@ -8,6 +8,7 @@ import ru.spcex.clearing.gatewayapi.config.deserializers.InstantDeserializer; import ru.spcex.clearing.gatewayapi.config.serializers.InstantSerializer; import java.time.Instant; +import java.util.Map; import java.util.UUID; public class InboundRequest { @@ -52,7 +53,7 @@ public class InboundRequest { @ApiModelProperty( value = "Контент", example = "null" ) - private String content = null; + private Map content = null; public UUID getId() { @@ -86,4 +87,12 @@ public class InboundRequest { public void setSection(String section) { this.section = section; } + + public Map getContent() { + return content; + } + + public void setContent(Map content) { + this.content = content; + } } diff --git a/clearing-parent/gateway-api/src/main/java/ru/spcex/clearing/gatewayapi/service/GatewayService.java b/clearing-parent/gateway-api/src/main/java/ru/spcex/clearing/gatewayapi/service/GatewayService.java index 360545a3f..b9fdc8a3e 100644 --- a/clearing-parent/gateway-api/src/main/java/ru/spcex/clearing/gatewayapi/service/GatewayService.java +++ b/clearing-parent/gateway-api/src/main/java/ru/spcex/clearing/gatewayapi/service/GatewayService.java @@ -14,7 +14,9 @@ import ru.spcex.clearing.gatewayapi.config.GatewayApiSettings; import ru.spcex.clearing.gatewayapi.config.InboundServerSettings; import ru.spcex.clearing.gatewayapi.request.InboundRequest; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; +import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.gateway.GatewayTaskRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.utilities.LimExportedRequest; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.util.security.UserRoleVerification; @@ -23,6 +25,7 @@ import ru.spcex.platform.enumeration.Task; import java.time.Instant; import java.util.Collections; +import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -48,19 +51,22 @@ public class GatewayService extends QueueConsumer implements InitializingBean { @Override public void afterPropertiesSet() throws Exception { callback(GatewayTaskRequest.class) - .setFunction(this::requestOnDemandCompany) + .setConsumer(this::requestOnDemandCompany) .forDestination(Task.loadParty_LOCM.topic(), callbacks::put); callback(GatewayTaskRequest.class) - .setFunction(this::requestOnDemandSecurity) + .setConsumer(this::requestOnDemandSecurity) .forDestination(Task.loadIssue_LOSC.topic(), callbacks::put); + callback(LimExportedRequest.class) + .setConsumer(this::requestOnLimit) + .forDestination(Consts.LIM_EXPORTED, callbacks::put); init(); } - public RequestInfoUpdate requestOnDemandCompany(BaseRequest userRequest) { + public void requestOnDemandCompany(BaseRequest userRequest) { log.debug("LOCM task received"); RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); - if (requestInfoUpdate != null) return requestInfoUpdate; + if (requestInfoUpdate != null) return; logUnknownProperties(userRequest); @@ -77,14 +83,35 @@ public class GatewayService extends QueueConsumer implements InitializingBean { String response = restTemplate.postForObject(url, request, String.class); log.debug("LOCM task complete, response: {}", response); - return null; } - public RequestInfoUpdate requestOnDemandSecurity(BaseRequest userRequest) { + public void requestOnLimit(BaseRequest userRequest) { + LimExportedRequest exportedRequest = userRequest.getRequestPayload(); + String url = formingInboundUrl(inboundServerSettings.getPathLOCM()); + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setContentType(MediaType.APPLICATION_JSON); + httpHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); + InboundRequest inboundRequest = new InboundRequest(); + inboundRequest.setId(UUID.randomUUID()); + inboundRequest.setType("FILL_LIMITS"); + inboundRequest.setSection(Section.FOND.getKey()); + inboundRequest.setDatetime(Instant.now()); + + Map content = new HashMap<>(); + content.put("file", exportedRequest.getLimFileName()); + inboundRequest.setContent(content); + HttpEntity request = new HttpEntity<>(inboundRequest, httpHeaders); + + String response = restTemplate.postForObject(url, request, String.class); + + log.debug("LOCM task complete, response: {}", response); + } + + public void requestOnDemandSecurity(BaseRequest userRequest) { log.debug("LOSC task received"); RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(userRequest); - if (requestInfoUpdate != null) return requestInfoUpdate; + if (requestInfoUpdate != null) return; logUnknownProperties(userRequest); @@ -107,7 +134,7 @@ public class GatewayService extends QueueConsumer implements InitializingBean { response = restTemplate.postForObject(url, request, String.class); log.debug("LOCM task 2/2 complete (MKR section), response: {}", response); - return null; +// return null; } private String formingInboundUrl(String path) { diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java index b71bf93c3..49e1f3772 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java @@ -85,7 +85,6 @@ public interface Consts { String CREATE_REPORT_FOR_PERIOD = "create-report-for-period"; String CREATE_REPORT_FOR_REGISTRY = "create-report-for-registry"; - @Deprecated String ACCOUNT_NEW_SDF01 = "account-new-sdf01"; String DESTINATION_RELATION_NEW = "relation-new"; @@ -100,7 +99,7 @@ public interface Consts { String DESTINATION_CLIENT_CODE_UPDATE = "client-code-update"; String DESTINATION_CLIENT_CODE_DELETE = "client-code-delete"; - String DESTINATION_TRADING_CLEARING_REGISTRY_NEW = "trading-clearing-registry-new"; // todo check buplicate REGISTRY_NEW? + String DESTINATION_TRADING_CLEARING_REGISTRY_NEW = "trading-clearing-registry-new"; // не путать с REGISTRY_NEW String DESTINATION_TRADING_CLEARING_REGISTRY_AUTO_NEW = "trading-clearing-registry-auto-new"; String DESTINATION_TRADING_CLEARING_REGISTRY_UPDATE = "trading-clearing-registry-update"; String DESTINATION_TRADING_CLEARING_REGISTRY_BLOCK = "trading-clearing-registry-block"; diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/sdf01/AccountSdf01Request.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/sdf01/AccountSdf01Request.java index ac51a7e37..2e9cb13a2 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/sdf01/AccountSdf01Request.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/sdf01/AccountSdf01Request.java @@ -4,7 +4,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; -@Deprecated public class AccountSdf01Request { private Long groupingSdf01Id; diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/sdf01/AccountSdfRequestPart.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/sdf01/AccountSdfRequestPart.java index 987235af7..863d1a974 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/sdf01/AccountSdfRequestPart.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/account/sdf01/AccountSdfRequestPart.java @@ -2,7 +2,6 @@ package ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01; import com.fasterxml.jackson.annotation.JsonProperty; -@Deprecated public class AccountSdfRequestPart { @JsonProperty private Long sdfId;