etreschenkov 2026-05-26 10:32:04 +03:00
parent 3f95a5b3c2
commit 5149014098
5 changed files with 74 additions and 55 deletions

View file

@ -155,6 +155,7 @@ public class ClientCodeValidationConfig {
GatewayEksClientCodeValidationRule.RubAccountPresent, GatewayEksClientCodeValidationRule.RubAccountPresent,
GatewayEksClientCodeValidationRule.CompanyPresent, GatewayEksClientCodeValidationRule.CompanyPresent,
GatewayEksClientCodeValidationRule.DepoAccountsPresent, GatewayEksClientCodeValidationRule.DepoAccountsPresent,
GatewayEksClientCodeValidationRule.ClsAccountsPresent,
GatewayEksClientCodeValidationRule.TcrIsNotPresent GatewayEksClientCodeValidationRule.TcrIsNotPresent
// GatewayClientCodeValidationRule.TcrIsNotPresent, // GatewayClientCodeValidationRule.TcrIsNotPresent,
// GatewayClientCodeValidationRule.TcrListIsNotPresent // GatewayClientCodeValidationRule.TcrListIsNotPresent

View file

@ -3,11 +3,9 @@ package ru.spcex.clearing.account.service.v2.facade;
import java.time.Instant; import java.time.Instant;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; 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.Account;
import ru.clearing.classes.statics.data.account.ClearingAccount; import ru.clearing.classes.statics.data.account.ClearingAccount;
import ru.clearing.classes.statics.data.account.InformationAccount; import ru.clearing.classes.statics.data.account.InformationAccount;
@ -60,20 +58,15 @@ public class AccountFacade implements IClearingFacade {
this.tradingClearingRegistryListFacade = tradingClearingRegistryListFacade; this.tradingClearingRegistryListFacade = tradingClearingRegistryListFacade;
} }
public Optional<Pair<Long, String>> createAccountWithSpecificType(MoneyAccountMsgRequest moneyAccountMsgRequest, Company company) { public Pair<Long, String> createAccountInfo(MoneyAccountMsgRequest moneyAccountMsgRequest, Company company) {
String currencyCode = moneyAccountMsgRequest.getCurrCode() == null ? CurrencyCode.RUB.getKey() : moneyAccountMsgRequest.getCurrCode(); String currencyCode = moneyAccountMsgRequest.getCurrCode() == null ? CurrencyCode.RUB.getKey() : moneyAccountMsgRequest.getCurrCode();
Instant now = Instant.now(); 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 account = new Account();
account.setCompanyId(company.getId()); account.setCompanyId(company.getId());
account.setAccount(accountValue); account.setAccount(accountValue);
account.setAccountType(accountType.getKey()); account.setAccountType(AccountType.Info.getKey());
account.setCurrency(currencyCode); account.setCurrency(currencyCode);
account.setStatus(WorkflowStatus.Active.getKey()); account.setStatus(WorkflowStatus.Active.getKey());
account.setCreated(now); account.setCreated(now);
@ -81,45 +74,34 @@ public class AccountFacade implements IClearingFacade {
accountHelper.fillAccountFromRelation(account, null, false); accountHelper.fillAccountFromRelation(account, null, false);
accountImdg.insert(account); accountImdg.insert(account);
Long specificAccId; Long specificAccId = makeInfoPart(account).getAccountId();
switch (accountType) { return new Pair<>(specificAccId, currencyCode);
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));
} }
private String defineAccountValByType(AccountType accountType, MoneyAccountMsgRequest moneyAccountMsgRequest, private String defineAccountValForInfo(String currencyCode) {
String currencyCode) { ImdgPredicateBuilder predicateBuilder = currencyImdg.predicateBuilder();
if (AccountType.Clrn == accountType) { Currency currency = currencyImdg.getFirstObjectByPredicate(
return moneyAccountMsgRequest.getAccount(); predicateBuilder.equals("currencyCode", currencyCode)
} else if (AccountType.Info == accountType) { );
ImdgPredicateBuilder predicateBuilder = currencyImdg.predicateBuilder(); Long currencyCodeId = CurrencyCode.RUB.getKey().equals(currencyCode) ? 810 : currency.getId();
Currency currency = currencyImdg.getFirstObjectByPredicate(
predicateBuilder.equals("currencyCode", currencyCode)
);
Long currencyCodeId = CurrencyCode.RUB.getKey().equals(currencyCode) ? 810 : currency.getId();
ImdgPredicateBuilder pb = accountImdg.predicateBuilder(); ImdgPredicateBuilder pb = accountImdg.predicateBuilder();
ImdgPredicate andPredicate = pb.and( ImdgPredicate andPredicate = pb.and(
pb.equals("accountType", AccountType.Anlt.getKey()), pb.equals("accountType", AccountType.Anlt.getKey()),
pb.equals("currency", currencyCode) pb.equals("currency", currencyCode)
); );
Collection<Account> accountsAnlt = accountImdg.getCollectionObjectsByPredicate(andPredicate); Collection<Account> accountsAnlt = accountImdg.getCollectionObjectsByPredicate(andPredicate);
if (accountsAnlt.isEmpty()) { if (accountsAnlt.isEmpty()) {
log.warn("Account with {} not exist.", andPredicate); log.warn("Account with {} not exist.", andPredicate);
} else if (accountsAnlt.size() > 1) { } else if (accountsAnlt.size() > 1) {
log.warn("Account for companyId 1 and accountType=ANLT contains multiply elements, use first"); 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;
} }
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) { 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); log.debug("For account id={} make ClearingAccount id={}", account.getId(), clrnId);
return clnrAcc; return clnrAcc;
} }
public void lock() { public void lock() {
// tradingClearingRegistryFacade.lock() // tradingClearingRegistryFacade.lock()
// tradingClearingRegistryListFacade.lock() // tradingClearingRegistryListFacade.lock()

View file

@ -12,6 +12,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service; 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.Account;
import ru.clearing.classes.statics.data.account.DepoAccount; import ru.clearing.classes.statics.data.account.DepoAccount;
import ru.clearing.classes.statics.data.company.Company; 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); Long depoAccountId = depoAccount.map(DepoAccount::getAccountId).orElse(null);
List<Pair<Long, String>> accountIds = new ArrayList<>(); List<Pair<Long, String>> accountIds = new ArrayList<>();
for (MoneyAccountMsgRequest account : tkrAccount.getMoneyAccounts()) { for (MoneyAccountMsgRequest account : tkrAccount.getMoneyAccounts()) {
Optional<Pair<Long, String>> accId = accountFacade.createAccountWithSpecificType(account, company); if (StringUtils.hasText(account.getEks_account())) {
if (accId.isPresent()) { log.debug("eks_account is filled, creating info account: {}", account.getEks_account());
accountIds.add(accId.get()); Pair<Long, String> accId = accountFacade.createAccountInfo(account, company);
accountIds.add(accId);
} else { } else {
log.error("Can't create info account for account: {}", tkrAccount.getClientCode()); List<Account> clrnAccs = validator.getStored(ClientCodeStoreObjects.CLRN_ACCS);
clrnAccs.forEach(acc -> accountIds.add(new Pair<>(acc.getId(), acc.getCurrency())));
} }
} }
Optional<Long> rubMoneyAcc = accountIds.stream() Long rubMoneyAcc = accountIds.stream()
.filter(pair -> CurrencyCode.RUB.equalsByKey(pair.getSecond())) .filter(pair -> CurrencyCode.RUB.equalsByKey(pair.getSecond()))
.findFirst() .findFirst()
.map(Pair::getFirst); .map(Pair::getFirst)
.orElse(null);
List<Long> accIds = accountIds.stream() List<Long> accIds = accountIds.stream()
.filter(pair -> !CurrencyCode.RUB.equalsByKey(pair.getSecond())) .filter(pair -> !CurrencyCode.RUB.equalsByKey(pair.getSecond()))
@ -207,7 +211,7 @@ public class ClientCodeMessageListener extends QueueConsumer implements Initiali
clientCodeNewRequest.setCompanyId(company.getId()); clientCodeNewRequest.setCompanyId(company.getId());
clientCodeNewRequest.setCode(tkrAccount.getClientCode()); clientCodeNewRequest.setCode(tkrAccount.getClientCode());
clientCodeNewRequest.setMoneyAccountId(rubMoneyAcc.get()); clientCodeNewRequest.setMoneyAccountId(rubMoneyAcc);
clientCodeNewRequest.setDepoAccountId(depoAccountId); clientCodeNewRequest.setDepoAccountId(depoAccountId);
clientCodeNewRequest.setCurrencyAccountList(accIds); clientCodeNewRequest.setCurrencyAccountList(accIds);
clientCodeFacade.createClientCodeWithTkr(clientCodeNewRequest, validator, false); clientCodeFacade.createClientCodeWithTkr(clientCodeNewRequest, validator, false);

View file

@ -4,6 +4,7 @@ public enum ClientCodeStoreObjects {
COMPANY, COMPANY,
MONEY_ACCOUNT, MONEY_ACCOUNT,
DEPO_ACCOUNT, DEPO_ACCOUNT,
CLRN_ACCS,
MAPPED_TO_CURRENCY_ACCOUNTS, MAPPED_TO_CURRENCY_ACCOUNTS,
TRADING_CLEARING_REGISTRY TRADING_CLEARING_REGISTRY
} }

View file

@ -1,11 +1,13 @@
package ru.spcex.clearing.account.validation; package ru.spcex.clearing.account.validation;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils; 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.AccountSymbols;
import ru.clearing.classes.statics.data.account.DepoAccount; import ru.clearing.classes.statics.data.account.DepoAccount;
import ru.clearing.classes.statics.data.company.Company; 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.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.cud.account.TkrAccount; import ru.spcex.clearing.platform.messaging.domain.cud.account.TkrAccount;
import ru.spcex.clearing.platform.messaging.domain.cud.gateway.MoneyAccountMsgRequest; 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.CurrencyCode;
import ru.spcex.platform.enumeration.Status; import ru.spcex.platform.enumeration.Status;
import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.Imdg;
@ -91,10 +94,35 @@ public enum GatewayEksClientCodeValidationRule implements IValidationRule<ImdgVa
return Optional.empty(); return Optional.empty();
} }
}, },
ClsAccountsPresent() {
@Override
public Optional<EnumMessage> validate(ImdgValidationContext<TkrAccount> context) {
TkrAccount validatedObject = context.getValidatedObject();
List<MoneyAccountMsgRequest> moneyAccounts = validatedObject.getMoneyAccounts().stream()
.filter(account -> StringUtils.hasText(account.getAccount()))
.toList();
Imdg<Account> accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
List<Account> 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() { TcrIsNotPresent() {
@Override @Override
public Optional<EnumMessage> validate(ImdgValidationContext<TkrAccount> context) { public Optional<EnumMessage> validate (ImdgValidationContext < TkrAccount > context) {
Optional<DepoAccount> depoAccountOpt = context.getStoredObject(ClientCodeStoreObjects.DEPO_ACCOUNT); Optional<DepoAccount> depoAccountOpt = context.getStoredObject(ClientCodeStoreObjects.DEPO_ACCOUNT);
if (depoAccountOpt.isEmpty()) { if (depoAccountOpt.isEmpty()) {
return empty(); return empty();
@ -113,7 +141,9 @@ public enum GatewayEksClientCodeValidationRule implements IValidationRule<ImdgVa
} }
return Optional.empty(); return Optional.empty();
} }
}; }
;
private static final Logger log = LoggerFactory.getLogger(GatewayEksClientCodeValidationRule.class); private static final Logger log = LoggerFactory.getLogger(GatewayEksClientCodeValidationRule.class);
} }