SDF57 поиск счета по comment (в случае ANLT)

This commit is contained in:
ialbert 2023-07-09 12:23:24 +03:00
parent c4c12ccad7
commit a82ab9b0ca
2 changed files with 146 additions and 84 deletions

View file

@ -0,0 +1,130 @@
package ru.spcex.clearing.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import ru.clearing.classes.statics.data.account.Account;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
import ru.spcex.clearing.error.ClearingError;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.enumeration.AccountType;
import ru.spcex.platform.enumeration.ServiceStatus;
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.EnumMessage;
import ru.spcex.platform.utils.enumeration.IEnumId;
@Component
public class AnltSearcher {
private Logger log = LoggerFactory.getLogger(getClass());
private final Imdg<TradingClearingRegistry> tradingClearingRegistryImdg;
private final Imdg<Company> companyImdg;
private final Imdg<Account> accountImdg;
public AnltSearcher(ImdgProvider imdgProvider) {
this.tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class);
this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
}
@FunctionalInterface
public interface AnltLogger {
void log(IEnumId subject, Object... args);
}
public AnltSearch loadByAnlt(String comment) {
String commentTcrStripped = getTkrCodeFromComment(comment);
// AnltLogger localLogger = (subject, args) -> log.debug("stmt.id={} comment='{}' error: {}", statementId, commentTcrStripped, messageResolver.resolve(new EnumMessage(subject, args)));
if (commentTcrStripped == null) {
return new AnltSearch(ClearingError.AccountNotFound, "comment not contain TCR");
}
ImdgPredicateBuilder pb = tradingClearingRegistryImdg.predicateBuilder();
ImdgPredicate tcrPredicate = pb.and(
pb.equals("code", commentTcrStripped),
pb.equals("status", ServiceStatus.Active.getKey())
);
TradingClearingRegistry tcr = tradingClearingRegistryImdg.getSingleObjectByPredicate(tcrPredicate);
if (tcr == null) {
return new AnltSearch(ClearingError.TCRegistryNotFound, commentTcrStripped);
}
if (tcr.getMoneyAccountId() == null) {
return new AnltSearch(ClearingError.WrongField, "moneyAccountId");
}
Account infoAcc = accountImdg.getSingleObjectByID(tcr.getMoneyAccountId());
if (infoAcc == null) {
return new AnltSearch(ClearingError.AccountNotFound, "moneyAccountId");
}
if (!infoAcc.getAccountType().equals(AccountType.Info.getKey())) {
return new AnltSearch(ClearingError.AccountNotFound, "accountType");
}
Company company = companyImdg.getSingleObjectByID(tcr.getCompanyId());
if (company == null) {
return new AnltSearch(ClearingError.CompanyNotFoundB, tcr.getCompanyId());
}
return new AnltSearch(infoAcc, company);
}
private static String getTkrCodeFromComment(String comment) {
if (comment == null) {
return null;
}
comment = comment.toUpperCase();
int tcrIndex = comment.indexOf("ТКР");
if (tcrIndex == -1) {
return null;
}
comment = comment.substring(tcrIndex + 3);
return comment.replaceAll("\\s+", "");
}
public static class AnltSearch {
private EnumMessage error;
private Account account;
private Company company;
public AnltSearch(IEnumId errSubject, Object... args) {
this.error = new EnumMessage(errSubject, args);
}
public AnltSearch(Account account, Company company) {
this.account = account;
this.company = company;
}
public boolean isFound() {
return error == null && account != null && company != null;
}
public EnumMessage getError() {
return error;
}
public void setError(EnumMessage error) {
this.error = error;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
public Company getCompany() {
return company;
}
public void setCompany(Company company) {
this.company = company;
}
}
}

View file

@ -22,6 +22,7 @@ import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.balance.StatementRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.clearing.ContinueSessionBnRequest;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.service.AnltSearcher;
import ru.spcex.clearing.service.LoggingService;
import ru.spcex.clearing.service.builder.RegistryBuilder;
import ru.spcex.clearing.service.model.Result;
@ -34,9 +35,7 @@ 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.collection.Pair;
import ru.spcex.platform.utils.enumeration.EnumMessage;
import ru.spcex.platform.utils.enumeration.IEnumId;
import ru.spcex.platform.utils.enumeration.IEnumKey;
import ru.spcex.platform.utils.enumeration.IMessageResolver;
import ru.spcex.platform.utils.text.TextUtil;
@ -72,13 +71,14 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
private final Imdg<Company> companyImdg;
private final Imdg<Security> securityImdg;
private final Imdg<Currency> currencyImdg;
private final AnltSearcher anltSearcher;
private final IMessageResolver messageResolver;
private final Pattern pattern = Pattern.compile("№.*");
public Sdf57Executor(@Qualifier("sdf57Validator") Function<SDf57, IValidator> sDf57Validator,
LoggingService errorLogger,
ImdgProvider imdgProvider,
IMessageResolver errorResolver, IMessageResolver messageResolver) {
IMessageResolver errorResolver, AnltSearcher anltSearcher, IMessageResolver messageResolver) {
this.statementImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class);
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
this.sdf02Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf02, SDf02.class);
@ -92,6 +92,7 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
this.errorLogger = errorLogger;
this.imdgProvider = imdgProvider;
this.errorResolver = errorResolver;
this.anltSearcher = anltSearcher;
this.messageResolver = messageResolver;
this.securityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Security, Security.class);
}
@ -310,16 +311,19 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
Account acc = stmtCmpAcc.account();
createRegistryIfNeeded.accept(stmtCmpAcc);
if (accountIsAnlt(acc)) {
Optional<Pair<Company, Account>> anltLink = loadByAnlt(stmt.getId(), stmt.getComment());
//счет оказался биржевым, и удалось найти счет агента по комментарию
anltLink.ifPresent(pair -> {
AnltSearcher.AnltSearch searchResult = anltSearcher.loadByAnlt(stmt.getComment());
if (searchResult.isFound()) {
log.debug("stmt.id={} comment={} is anlt, loaded account.id={}/companyId={}",
stmt.getId(), stmt.getComment(), pair.getSecond().getId(), pair.getFirst().getId());
createRegistryIfNeeded.accept(new StmtCmpAcc(stmt, anltLink.get().getFirst(), anltLink.get().getSecond()));
});
//счет оказался биржевым, но не знаем кто адресат, заполняем DMAU
if (anltLink.isEmpty()) {
log.debug("stmt.id={} comment={} account not found. Create DMAU registry", stmt.getId(), stmt.getComment());
stmt.getId(),
stmt.getComment(),
searchResult.getAccount().getId(),
searchResult.getCompany().getId());
createRegistryIfNeeded.accept(new StmtCmpAcc(stmt, searchResult.getCompany(), searchResult.getAccount()));
} else {
log.debug("stmt.id={} comment='{}' error: {}. Creating DMAU registry",
stmt.getId(),
stmt.getComment(),
messageResolver.resolve(searchResult.getError()));
Optional<Registry> dmau = RegistrySearch.builder(registryImdg)
.rgsCode(RegistryTradingParams.DMAU)
.companyId(cmp.getId())
@ -359,54 +363,6 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
return anlt;
}
@FunctionalInterface
private interface AnltLogger {
void log(IEnumId subject, Object... args);
}
private Optional<Pair<Company, Account>> loadByAnlt(Long statementId, String comment) {
String commentTcrStripped = getTkrCodeFromComment(comment);
AnltLogger localLogger = (subject, args) -> log.debug("stmt.id={} comment='{}' error: {}", statementId, commentTcrStripped, messageResolver.resolve(new EnumMessage(subject, args)));
if (commentTcrStripped == null) {
localLogger.log(ClearingError.AccountNotFound, "comment not contain TCR");
return Optional.empty();
}
ImdgPredicateBuilder pb = tradingClearingRegistryImdg.predicateBuilder();
ImdgPredicate tcrPredicate = pb.and(
pb.equals("code", commentTcrStripped),
pb.equals("status", ServiceStatus.Active.getKey())
);
TradingClearingRegistry tcr = tradingClearingRegistryImdg.getSingleObjectByPredicate(tcrPredicate);
if (tcr == null) {
localLogger.log(ClearingError.TCRegistryNotFound, commentTcrStripped);
return Optional.empty();
}
if (tcr.getMoneyAccountId() == null) {
localLogger.log(ClearingError.WrongField, "moneyAccountId");
return Optional.empty();
}
Account infoAcc = accountImdg.getSingleObjectByID(tcr.getMoneyAccountId());
if (infoAcc == null) {
localLogger.log(ClearingError.AccountNotFound, "moneyAccountId");
return Optional.empty();
}
if (!infoAcc.getAccountType().equals(AccountType.Info.getKey())) {
localLogger.log(ClearingError.AccountNotFound, "accountType");
return Optional.empty();
}
Company company = companyImdg.getSingleObjectByID(tcr.getCompanyId());
if (company == null) {
localLogger.log(ClearingError.CompanyNotFoundB, tcr.getCompanyId());
return Optional.empty();
}
return Optional.of(new Pair<>(company, infoAcc));
}
private Registry copyRegB(Registry rgs) {
Registry rgsB = rgs.clone();
rgsB.setRegistryUnit(RegistryUnit.B.getKey());
@ -539,30 +495,6 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
r.setUpdated(Instant.now());
}
private Optional<Registry> findRegByDesignation(Statement stmt,
RegistryTradingParams rgsCode,
boolean contractCondition,
boolean statusCondition) {
String sql = RegistryCodeSqlBuilder.getInstance(rgsCode).build();
ImdgPredicateBuilder pb = registryImdg.predicateBuilder();
ImdgPredicate rgstrPredicate = pb.and(pb.sql(sql),
pb.sql(sql),
pb.equals("companyId", stmt.getAddresseeId()),
pb.equals("accountId", stmt.getAccountId())
);
if (contractCondition) {
rgstrPredicate = pb.and(rgstrPredicate, pb.equals("contract", stmt.getContract()));
}
if (statusCondition) {
rgstrPredicate = pb.and(rgstrPredicate, pb.or(
pb.equals("registryStatus", RegistryStatus.PROC.getKey()),
pb.equals("registryStatus", RegistryStatus.MNG.getKey())
));
}
return Optional.ofNullable(registryImdg.getSingleObjectByPredicate(rgstrPredicate));
}
private static class RegistrySearch {
private final ImdgPredicateBuilder pb;
private final Imdg<Registry> registryImdg;