From 514901409801d9f0d0f664945d6c041fb047bf1c Mon Sep 17 00:00:00 2001 From: etreschenkov Date: Tue, 26 May 2026 10:32:04 +0300 Subject: [PATCH] http://jira.mfd.msk:8088/browse/CLS-1023#comment-74874 --- .../ClientCodeValidationConfig.java | 1 + .../service/v2/facade/AccountFacade.java | 73 +++++++------------ .../listeners/ClientCodeMessageListener.java | 18 +++-- .../validation/ClientCodeStoreObjects.java | 1 + .../GatewayEksClientCodeValidationRule.java | 36 ++++++++- 5 files changed, 74 insertions(+), 55 deletions(-) diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/ClientCodeValidationConfig.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/ClientCodeValidationConfig.java index cbd9899d5..335377771 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/ClientCodeValidationConfig.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/config/validation/ClientCodeValidationConfig.java @@ -155,6 +155,7 @@ public class ClientCodeValidationConfig { GatewayEksClientCodeValidationRule.RubAccountPresent, GatewayEksClientCodeValidationRule.CompanyPresent, GatewayEksClientCodeValidationRule.DepoAccountsPresent, + GatewayEksClientCodeValidationRule.ClsAccountsPresent, GatewayEksClientCodeValidationRule.TcrIsNotPresent // GatewayClientCodeValidationRule.TcrIsNotPresent, // GatewayClientCodeValidationRule.TcrListIsNotPresent diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/v2/facade/AccountFacade.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/v2/facade/AccountFacade.java index 7b9182e77..7d4719d09 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/v2/facade/AccountFacade.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/v2/facade/AccountFacade.java @@ -3,11 +3,9 @@ package ru.spcex.clearing.account.service.v2.facade; import java.time.Instant; import java.util.Collection; import java.util.Map; -import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; import ru.clearing.classes.statics.data.account.Account; import ru.clearing.classes.statics.data.account.ClearingAccount; import ru.clearing.classes.statics.data.account.InformationAccount; @@ -60,20 +58,15 @@ public class AccountFacade implements IClearingFacade { this.tradingClearingRegistryListFacade = tradingClearingRegistryListFacade; } - public Optional> createAccountWithSpecificType(MoneyAccountMsgRequest moneyAccountMsgRequest, Company company) { + public Pair createAccountInfo(MoneyAccountMsgRequest moneyAccountMsgRequest, Company company) { String currencyCode = moneyAccountMsgRequest.getCurrCode() == null ? CurrencyCode.RUB.getKey() : moneyAccountMsgRequest.getCurrCode(); Instant now = Instant.now(); - AccountType accountType = StringUtils.hasText(moneyAccountMsgRequest.getAccount()) ? AccountType.Clrn : - StringUtils.hasText(moneyAccountMsgRequest.getEks_account()) ? AccountType.Info : null; - if (accountType == null) { - return Optional.empty(); - } - String accountValue = defineAccountValByType(accountType, moneyAccountMsgRequest, currencyCode); + String accountValue = defineAccountValForInfo(currencyCode); Account account = new Account(); account.setCompanyId(company.getId()); account.setAccount(accountValue); - account.setAccountType(accountType.getKey()); + account.setAccountType(AccountType.Info.getKey()); account.setCurrency(currencyCode); account.setStatus(WorkflowStatus.Active.getKey()); account.setCreated(now); @@ -81,45 +74,34 @@ public class AccountFacade implements IClearingFacade { accountHelper.fillAccountFromRelation(account, null, false); accountImdg.insert(account); - Long specificAccId; - switch (accountType) { - case Clrn -> specificAccId = makeClrnPart(account).getAccountId(); - case Info -> specificAccId = makeInfoPart(account).getAccountId(); - default -> throw new IllegalArgumentException("Unknown accountType: " + accountType); - } - return Optional.of(new Pair<>(specificAccId, currencyCode)); + Long specificAccId = makeInfoPart(account).getAccountId(); + return new Pair<>(specificAccId, currencyCode); } - private String defineAccountValByType(AccountType accountType, MoneyAccountMsgRequest moneyAccountMsgRequest, - String currencyCode) { - if (AccountType.Clrn == accountType) { - return moneyAccountMsgRequest.getAccount(); - } else if (AccountType.Info == accountType) { - ImdgPredicateBuilder predicateBuilder = currencyImdg.predicateBuilder(); - Currency currency = currencyImdg.getFirstObjectByPredicate( - predicateBuilder.equals("currencyCode", currencyCode) - ); - Long currencyCodeId = CurrencyCode.RUB.getKey().equals(currencyCode) ? 810 : currency.getId(); + private String defineAccountValForInfo(String currencyCode) { + ImdgPredicateBuilder predicateBuilder = currencyImdg.predicateBuilder(); + Currency currency = currencyImdg.getFirstObjectByPredicate( + predicateBuilder.equals("currencyCode", currencyCode) + ); + Long currencyCodeId = CurrencyCode.RUB.getKey().equals(currencyCode) ? 810 : currency.getId(); - ImdgPredicateBuilder pb = accountImdg.predicateBuilder(); - ImdgPredicate andPredicate = pb.and( - pb.equals("accountType", AccountType.Anlt.getKey()), - pb.equals("currency", currencyCode) - ); - Collection accountsAnlt = accountImdg.getCollectionObjectsByPredicate(andPredicate); - if (accountsAnlt.isEmpty()) { - log.warn("Account with {} not exist.", andPredicate); - } else if (accountsAnlt.size() > 1) { - log.warn("Account for companyId 1 and accountType=ANLT contains multiply elements, use first"); - } - Account anltAccount = accountsAnlt.iterator().next(); - String specialAnltAccId = anltAccount.getAccount().substring(anltAccount.getAccount().length() - 4); - Long infoSequenceId = informationAccountService.accountNextId(currencyCode, currencyCodeId); - String accountValue = informationAccountService.generateInfoAccount(currencyCodeId, infoSequenceId, specialAnltAccId); - log.trace("New info-account SequenceId={} account={}", infoSequenceId, accountValue); - return accountValue; + ImdgPredicateBuilder pb = accountImdg.predicateBuilder(); + ImdgPredicate andPredicate = pb.and( + pb.equals("accountType", AccountType.Anlt.getKey()), + pb.equals("currency", currencyCode) + ); + Collection accountsAnlt = accountImdg.getCollectionObjectsByPredicate(andPredicate); + if (accountsAnlt.isEmpty()) { + log.warn("Account with {} not exist.", andPredicate); + } else if (accountsAnlt.size() > 1) { + log.warn("Account for companyId 1 and accountType=ANLT contains multiply elements, use first"); } - return null; + Account anltAccount = accountsAnlt.iterator().next(); + String specialAnltAccId = anltAccount.getAccount().substring(anltAccount.getAccount().length() - 4); + Long infoSequenceId = informationAccountService.accountNextId(currencyCode, currencyCodeId); + String accountValue = informationAccountService.generateInfoAccount(currencyCodeId, infoSequenceId, specialAnltAccId); + log.trace("New info-account SequenceId={} account={}", infoSequenceId, accountValue); + return accountValue; } private InformationAccount makeInfoPart(Account account) { @@ -149,6 +131,7 @@ public class AccountFacade implements IClearingFacade { log.debug("For account id={} make ClearingAccount id={}", account.getId(), clrnId); return clnrAcc; } + public void lock() { // tradingClearingRegistryFacade.lock() // tradingClearingRegistryListFacade.lock() diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/v2/listeners/ClientCodeMessageListener.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/v2/listeners/ClientCodeMessageListener.java index b6b4019ce..16ad89dde 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/v2/listeners/ClientCodeMessageListener.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/service/v2/listeners/ClientCodeMessageListener.java @@ -12,6 +12,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; import ru.clearing.classes.statics.data.account.Account; import ru.clearing.classes.statics.data.account.DepoAccount; import ru.clearing.classes.statics.data.company.Company; @@ -185,18 +186,21 @@ public class ClientCodeMessageListener extends QueueConsumer implements Initiali Long depoAccountId = depoAccount.map(DepoAccount::getAccountId).orElse(null); List> accountIds = new ArrayList<>(); for (MoneyAccountMsgRequest account : tkrAccount.getMoneyAccounts()) { - Optional> accId = accountFacade.createAccountWithSpecificType(account, company); - if (accId.isPresent()) { - accountIds.add(accId.get()); + if (StringUtils.hasText(account.getEks_account())) { + log.debug("eks_account is filled, creating info account: {}", account.getEks_account()); + Pair accId = accountFacade.createAccountInfo(account, company); + accountIds.add(accId); } else { - log.error("Can't create info account for account: {}", tkrAccount.getClientCode()); + List clrnAccs = validator.getStored(ClientCodeStoreObjects.CLRN_ACCS); + clrnAccs.forEach(acc -> accountIds.add(new Pair<>(acc.getId(), acc.getCurrency()))); } } - Optional rubMoneyAcc = accountIds.stream() + Long rubMoneyAcc = accountIds.stream() .filter(pair -> CurrencyCode.RUB.equalsByKey(pair.getSecond())) .findFirst() - .map(Pair::getFirst); + .map(Pair::getFirst) + .orElse(null); List accIds = accountIds.stream() .filter(pair -> !CurrencyCode.RUB.equalsByKey(pair.getSecond())) @@ -207,7 +211,7 @@ public class ClientCodeMessageListener extends QueueConsumer implements Initiali clientCodeNewRequest.setCompanyId(company.getId()); clientCodeNewRequest.setCode(tkrAccount.getClientCode()); - clientCodeNewRequest.setMoneyAccountId(rubMoneyAcc.get()); + clientCodeNewRequest.setMoneyAccountId(rubMoneyAcc); clientCodeNewRequest.setDepoAccountId(depoAccountId); clientCodeNewRequest.setCurrencyAccountList(accIds); clientCodeFacade.createClientCodeWithTkr(clientCodeNewRequest, validator, false); diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/validation/ClientCodeStoreObjects.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/validation/ClientCodeStoreObjects.java index b4d600f08..5a048c642 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/validation/ClientCodeStoreObjects.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/validation/ClientCodeStoreObjects.java @@ -4,6 +4,7 @@ public enum ClientCodeStoreObjects { COMPANY, MONEY_ACCOUNT, DEPO_ACCOUNT, + CLRN_ACCS, MAPPED_TO_CURRENCY_ACCOUNTS, TRADING_CLEARING_REGISTRY } diff --git a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/validation/GatewayEksClientCodeValidationRule.java b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/validation/GatewayEksClientCodeValidationRule.java index d0e0db98e..11bf79e03 100644 --- a/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/validation/GatewayEksClientCodeValidationRule.java +++ b/clearing-parent/account-service/src/main/java/ru/spcex/clearing/account/validation/GatewayEksClientCodeValidationRule.java @@ -1,11 +1,13 @@ package ru.spcex.clearing.account.validation; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.StringUtils; +import ru.clearing.classes.statics.data.account.Account; import ru.clearing.classes.statics.data.account.AccountSymbols; import ru.clearing.classes.statics.data.account.DepoAccount; import ru.clearing.classes.statics.data.company.Company; @@ -14,6 +16,7 @@ import ru.spcex.clearing.account.errors.AccountError; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.cud.account.TkrAccount; import ru.spcex.clearing.platform.messaging.domain.cud.gateway.MoneyAccountMsgRequest; +import ru.spcex.platform.enumeration.AccountType; import ru.spcex.platform.enumeration.CurrencyCode; import ru.spcex.platform.enumeration.Status; import ru.spcex.platform.imdg.api.Imdg; @@ -91,10 +94,35 @@ public enum GatewayEksClientCodeValidationRule implements IValidationRule validate(ImdgValidationContext context) { + TkrAccount validatedObject = context.getValidatedObject(); + List moneyAccounts = validatedObject.getMoneyAccounts().stream() + .filter(account -> StringUtils.hasText(account.getAccount())) + .toList(); + Imdg accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class); + List validClrnAccs = new ArrayList<>(); + for (MoneyAccountMsgRequest moneyAccount : moneyAccounts) { + ImdgPredicateBuilder predicateBuilder = accountImdg.predicateBuilder(); + Account clrnAcc = accountImdg.getFirstObjectByPredicate( + predicateBuilder.and( + predicateBuilder.equals("account", moneyAccount.getAccount()), + predicateBuilder.equals("accountType", AccountType.Clrn.getKey()) + )); + if (clrnAcc == null) { + return of(AccountError.AccountNotFound, moneyAccount.getAccount()); + } + validClrnAccs.add(clrnAcc); + } + context.storeObject(ClientCodeStoreObjects.CLRN_ACCS, validClrnAccs); + return Optional.empty(); + } + }, TcrIsNotPresent() { @Override - public Optional validate(ImdgValidationContext context) { + public Optional validate (ImdgValidationContext < TkrAccount > context) { Optional depoAccountOpt = context.getStoredObject(ClientCodeStoreObjects.DEPO_ACCOUNT); if (depoAccountOpt.isEmpty()) { return empty(); @@ -113,7 +141,9 @@ public enum GatewayEksClientCodeValidationRule implements IValidationRule