Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
2f2d99e7ce
61 changed files with 4421 additions and 2959 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -2079,7 +2079,7 @@
|
|||
|
||||
"fields": [
|
||||
{"code": "companyId",
|
||||
"type": 1,"name": "Наименование компании","shortname": "Компании","link": "company","linkCode": "shortName","required": true,"enabled": false
|
||||
"type": 1,"name": "Наименование компании","shortname": "Компания","link": "company","linkCode": "shortName","required": true,"enabled": false
|
||||
}
|
||||
,
|
||||
{"code": "documentType",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -2079,7 +2079,7 @@
|
|||
|
||||
"fields": [
|
||||
{"code": "companyId",
|
||||
"type": 1,"name": "Наименование компании","shortname": "Компании","link": "company","linkCode": "shortName","required": true,"enabled": false
|
||||
"type": 1,"name": "Наименование компании","shortname": "Компания","link": "company","linkCode": "shortName","required": true,"enabled": false
|
||||
}
|
||||
,
|
||||
{"code": "documentType",
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@ public class Sdf16Executor extends AbstractExecutor<SDf16> {
|
|||
LoggingService errorLogger,
|
||||
ImdgProvider imdgProvider,
|
||||
AccountBalanceService accountBalanceService,
|
||||
IMessageResolver errorResolver, KafkaSender kafaSender) {
|
||||
IMessageResolver errorResolver,
|
||||
KafkaSender kafaSender) {
|
||||
this.statementImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class);
|
||||
this.sdf17Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf17, SDf17.class);
|
||||
this.accountBalanceImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_AccountBalance, AccountBalance.class);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,252 @@
|
|||
package ru.spcex.clearing.service.builder;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import ru.clearing.classes.statics.data.account.Account;
|
||||
import ru.clearing.classes.statics.data.company.Company;
|
||||
import ru.clearing.classes.statics.data.company.CompanySymbols;
|
||||
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
|
||||
import ru.clearing.classes.statics.data.registry.Registry;
|
||||
import ru.clearing.classes.statics.data.security.Security;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.platform.enumeration.*;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.utils.collection.Pair;
|
||||
import ru.spcex.platform.utils.time.TimeUtil;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
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);
|
||||
|
||||
|
||||
private Registry cm_t;
|
||||
private Registry lm_t;
|
||||
private Account tranAccount;
|
||||
|
||||
private Imdg<Account> accountImdg;
|
||||
private Imdg<Company> companyImdg;
|
||||
private Imdg<CompanySymbols> companySymbolsImdg;
|
||||
private Imdg<Security> securityImdg;
|
||||
private Long sessionId;
|
||||
private BigDecimal amount;
|
||||
protected LocalDate documentNumberResetAt;
|
||||
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);
|
||||
}
|
||||
|
||||
private PaymentInstructionBuilderFinalMkr(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) {
|
||||
this.lm_t = lm_t;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PaymentInstructionBuilderFinalMkr cm_t(Registry cm_t) {
|
||||
this.cm_t = cm_t;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PaymentInstructionBuilderFinalMkr tranAcc(Account account) {
|
||||
this.tranAccount = account;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PaymentInstructionBuilderFinalMkr sessionId(Long sessionId) {
|
||||
this.sessionId = sessionId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PaymentInstructionBuilderFinalMkr amount(BigDecimal amount) {
|
||||
this.amount = amount;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Pair<PaymentInstruction, PaymentInstruction> build() {
|
||||
|
||||
PaymentInstruction payment1;
|
||||
PaymentInstruction payment2;
|
||||
|
||||
Instant now = Instant.now();
|
||||
String symbolPRC = selectSymbolValue(Sender.Prc.getId(), CompanySymbol.BIC); // 2 "НКО АО ПРЦ"
|
||||
{ // 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);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
payment1.setPayeeBankName(companyPRCName);
|
||||
payment1.setPayeeBic(symbolPRC);
|
||||
|
||||
payment1.setAddresseeBankName(companyPRCName);
|
||||
|
||||
payment1.setPaymentDate(TimeUtil.localDateToInstant(lm_t.getSettlementDate()));
|
||||
|
||||
payment1.setPaymentPurpose("Размещение депозита " + lm_t.getContract());
|
||||
|
||||
payment1.setSettlementDate(lm_t.getSettlementDate());
|
||||
|
||||
BigDecimal amount = lm_t.getBalance() == null ? null : lm_t.getBalance().abs();
|
||||
payment1.setCreditLeg_amount(amount);
|
||||
payment1.setDebitLeg_amount(amount);
|
||||
|
||||
{
|
||||
Long accountId = lm_t.getAccountId();
|
||||
Account acc1 = accountImdg.getSingleObjectByID(accountId);
|
||||
if (acc1 == null) {
|
||||
log.warn("Account not found: {}", accountId);
|
||||
} else {
|
||||
payment1.setCreditLeg_accountId(acc1.getId());
|
||||
payment1.setCreditLeg_account(acc1.getAccount());
|
||||
}
|
||||
}
|
||||
|
||||
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.setDebit_csAccount(null);
|
||||
payment1.setCreditLeg_currencyCode(CurrencyCode.RUB.getKey());
|
||||
payment1.setDebitLeg_currencyCode(CurrencyCode.RUB.getKey());
|
||||
payment1.setTransactionStatus(TransactionStatus.stld.getKey());
|
||||
payment1.setDocumentNumber(nextDocumentNumber(lm_t, payment1));
|
||||
}
|
||||
|
||||
//****************
|
||||
{ // record 2
|
||||
payment2 = new PaymentInstruction();
|
||||
payment2.setCreated(now);
|
||||
payment2.setClearingDate(TimeUtil.toLocalDate(now));
|
||||
payment2.setSenderId(Sender.One.getId()); // СПВБ
|
||||
payment2.setAddresseeId(lm_t.getCompanyId());
|
||||
String symbol2 = selectSymbolValue(payment2.getAddresseeId(), CompanySymbol.BIC);
|
||||
if (symbol2 == null) {
|
||||
log.warn("CompanySymbols BIC not found for companyId={}", payment2.getAddresseeId());
|
||||
} else {
|
||||
payment2.setAdresseeBic(symbol2);
|
||||
}
|
||||
Company companyPRC = companyImdg.getSingleObjectByID(Sender.Prc.getId());
|
||||
if (companyPRC == null) {
|
||||
log.warn("Company.id={} not found", Sender.Prc.getId());
|
||||
} else {
|
||||
payment2.setPayeeBankName(companyPRC.getShortName());
|
||||
payment2.setAddresseeBankName(companyPRC.getShortName());
|
||||
}
|
||||
payment2.setPayeeBic(symbolPRC);
|
||||
payment2.setPaymentDate(TimeUtil.localDateToInstant(lm_t.getSettlementDate()));
|
||||
payment2.setPaymentPurpose("Размещение депозита " + lm_t.getContract());
|
||||
payment2.setSettlementDate(lm_t.getSettlementDate());
|
||||
BigDecimal amount = lm_t.getBalance() == null ? null : lm_t.getBalance().abs();
|
||||
payment2.setCreditLeg_amount(amount);
|
||||
payment2.setDebitLeg_amount(amount);
|
||||
{
|
||||
payment2.setCreditLeg_accountId(tranAccount.getId());
|
||||
payment2.setCreditLeg_account(tranAccount.getAccount());
|
||||
}
|
||||
payment2.setCredit_csAccount(null);
|
||||
|
||||
{
|
||||
Account acc2 = accountImdg.getSingleObjectByID(cm_t.getAccountId());
|
||||
if (acc2 != null) {
|
||||
payment2.setDebitLeg_accountId(acc2.getId());
|
||||
payment2.setDebitLeg_account(acc2.getAccount());
|
||||
}
|
||||
}
|
||||
payment2.setDebit_csAccount(null);
|
||||
payment2.setTransactionStatus(TransactionStatus.stld.getKey());
|
||||
payment2.setDocumentNumber(nextDocumentNumber(cm_t, payment2));
|
||||
}
|
||||
return new Pair<>(payment1, payment2);
|
||||
}
|
||||
|
||||
protected String nextDocumentNumber(Registry rgs, PaymentInstruction paymentInstruction) {
|
||||
LocalDate nowD = LocalDate.now();
|
||||
if (documentNumberResetAt == null || documentNumberResetAt.isBefore(nowD)) synchronized (this) {
|
||||
long oldNum = documentNumberId.get(); // reset optimistic
|
||||
if (oldNum > 0) {
|
||||
while (!documentNumberId.compareAndSet(oldNum, 0)) {
|
||||
oldNum = documentNumberId.get();
|
||||
if (oldNum < 2) break;
|
||||
}
|
||||
}
|
||||
documentNumberResetAt = nowD;
|
||||
}
|
||||
String paymentDate = DATE_FORMATTER_ddMMyy.format(TimeUtil.toLocalDate(paymentInstruction.getPaymentDate()));
|
||||
String num = String.format("%s/%s/%s/%s",
|
||||
rgs.getContract(), paymentDate,
|
||||
paymentInstruction.getSenderId(), documentNumberId.incrementAndGet()
|
||||
);
|
||||
return num;
|
||||
}
|
||||
|
||||
protected String selectSymbolValue(Long companyId, CompanySymbol symbol) {
|
||||
if (companyId == null) {
|
||||
return null;
|
||||
}
|
||||
CompanySymbols cSymbol = companySymbolsImdg.getSingleObjectByFieldValues(Map.of(
|
||||
"companyId", companyId,
|
||||
"companySymbol", symbol.getKey()));
|
||||
if (cSymbol == null) {
|
||||
return null;
|
||||
} else {
|
||||
return cSymbol.getCompanySymbolValue();
|
||||
}
|
||||
}
|
||||
|
||||
protected Account selectAccount(Long companyId, AccountType accountType, Status accountStatus, Allowed processingSign) {
|
||||
if (companyId == null) {
|
||||
return null;
|
||||
}
|
||||
Account account = accountImdg.getSingleObjectByFieldValues(Map.of(
|
||||
"companyId", companyId,
|
||||
"accountType", accountType.getKey(),
|
||||
"accountStatus", accountStatus.getKey(),
|
||||
"processingSign", processingSign.getKey()
|
||||
));
|
||||
if (account == null) {
|
||||
log.trace("Account not found by: companyId={} accountType={} accountStatus={} processingSign={}",
|
||||
companyId, accountType.getKey(), accountStatus.getKey(), processingSign.getKey()
|
||||
);
|
||||
} else {
|
||||
log.trace("Found Account.id={} by: companyId={} accountType={} accountStatus={} processingSign={}", account.getId(),
|
||||
companyId, accountType.getKey(), accountStatus.getKey(), processingSign.getKey()
|
||||
);
|
||||
}
|
||||
return account;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -61,7 +61,7 @@ public class ExecutionDepositComponent {
|
|||
private final IMessageResolver msgResolver;
|
||||
private final Function<STrades, IValidator> stradesValidator;
|
||||
private final KafkaSender kafkaSender;
|
||||
private static final DateTimeFormatter contractFormatter = DateTimeFormatter.ofPattern("ddMMyyyy");
|
||||
private static final DateTimeFormatter contractFormatter = DateTimeFormatter.ofPattern("ddMMyy");
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ import java.util.Map;
|
|||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Service
|
||||
public class Sdf57Executor extends AbstractExecutor<SDf57> {
|
||||
|
|
@ -66,7 +67,7 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
|
|||
private final Imdg<Security> securityImdg;
|
||||
private final Imdg<Currency> currencyImdg;
|
||||
private final IMessageResolver messageResolver;
|
||||
// private final Pair<>
|
||||
private final Pattern pattern = Pattern.compile("№\\w*/\\d{6}/\\d*/\\d*");
|
||||
|
||||
public Sdf57Executor(@Qualifier("sdf57Validator") Function<SDf57, IValidator> sDf57Validator,
|
||||
LoggingService errorLogger,
|
||||
|
|
@ -182,7 +183,7 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
|
|||
}
|
||||
registryImdg.update(rgs);
|
||||
};
|
||||
Consumer<RegistryDesignation> create = (dsgn) -> {
|
||||
Consumer<RegistryDesignation> createRegA = (dsgn) -> {
|
||||
Registry registry = createRegistryByStatement(stmt, company, account, dsgn);
|
||||
Registry registryB = copyRegB(registry);
|
||||
Registry registryF = copyRegF(registry, registryB.getBalance());
|
||||
|
|
@ -192,11 +193,19 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
|
|||
registryImdg.insert(registryB);
|
||||
};
|
||||
|
||||
//todo понять что происходит со инициатором/контрагентом, особенно если у нас только один Statement
|
||||
findRegByDesignation(stmt, RegistryDesignation.A).ifPresentOrElse(update, () -> create.accept(RegistryDesignation.A));
|
||||
if (!StringUtils.isEmpty(sdf57.getSpecif()) && sdf57.getSpecif().contains("№")) {
|
||||
findRegByDesignation(stmt, RegistryDesignation.A).ifPresentOrElse(update, () -> createRegA.accept(RegistryDesignation.A));
|
||||
InOutDirection direction = IEnumKey.getEnumByKey(InOutDirection.class, stmt.getInOutDirection());
|
||||
if (!StringUtils.isEmpty(sdf57.getSpecif()) && pattern.matcher(sdf57.getSpecif()).find() && InOutDirection.in.equals(direction)) {
|
||||
//todo доделать 11. Идентификация средств УК на клиринговом счете
|
||||
findRegByDesignation(stmt, RegistryDesignation.D).ifPresentOrElse(update, () -> create.accept(RegistryDesignation.D));
|
||||
findRegByDesignation(stmt, RegistryDesignation.D).ifPresentOrElse(rgs -> {
|
||||
rgs.setBalance(safeBD(rgs.getBalance()).add(safeBD(stmt.getAmount())));
|
||||
rgs.setUpdated(Instant.now());
|
||||
registryImdg.update(rgs);
|
||||
},
|
||||
() -> findRegByDesignation(stmt, RegistryDesignation.O).ifPresent(rgs -> {
|
||||
Registry registryD = copyRegD(rgs);
|
||||
registryImdg.insert(registryD);
|
||||
}));
|
||||
}
|
||||
stmt.setOperationStatus(OperationStatus.Executed.getKey());
|
||||
} else {
|
||||
|
|
@ -230,6 +239,13 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
|
|||
return rgsF;
|
||||
}
|
||||
|
||||
private Registry copyRegD(Registry rgs) {
|
||||
Registry rgsB = rgs.clone();
|
||||
rgsB.setRegistryDesignation(RegistryDesignation.D.getKey());
|
||||
rgsB.setRegistryCode(RegistryUtil.clearingCode(rgsB));
|
||||
return rgsB;
|
||||
}
|
||||
|
||||
private record StmtCmpAcc(Statement statement, Company company, Account account) {
|
||||
}
|
||||
|
||||
|
|
@ -363,7 +379,7 @@ public class Sdf57Executor extends AbstractExecutor<SDf57> {
|
|||
pb.equals("companyId", s.getAddresseeId()),
|
||||
pb.equals("accountId", s.getAccountId())
|
||||
);
|
||||
if (des.equals(RegistryDesignation.D) && !TextUtil.isEmpty(s.getContract())) {
|
||||
if (des.equals(RegistryDesignation.D) || des.equals(RegistryDesignation.O) && !TextUtil.isEmpty(s.getContract())) {
|
||||
rgstrPredicate = pb.and(rgstrPredicate, pb.equals("contract", s.getContract()));
|
||||
}
|
||||
return Optional.ofNullable(registryImdg.getSingleObjectByPredicate(rgstrPredicate));
|
||||
|
|
|
|||
|
|
@ -61,9 +61,8 @@ public enum RegistryStep3ValidationRule implements IValidationRule<ImdgValidatio
|
|||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<Registry> context) {
|
||||
Registry validatedObject = context.getValidatedObject();
|
||||
Relation relation = context.getStoredObject(RegistryValidationStored.Relation);
|
||||
Imdg<Account> accountImdg = context.obtainMap(IMDGDistributedNames.Map_Account, Account.class);
|
||||
Account account = accountImdg.getSingleObjectBySQL("id = %d and relationId = %d".formatted(validatedObject.getAccountId(), relation.getId()));
|
||||
Account account = accountImdg.getSingleObjectBySQL("id = %d".formatted(validatedObject.getAccountId()));
|
||||
if (account == null || (!IEnumKey.contains(account.getStatus(), ServiceStatus.Active, ServiceStatus.Reopened))) {
|
||||
return of(ClearingError.AccountNotActive, validatedObject.getAccountId());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,16 +9,19 @@ import ru.clearing.classes.statics.data.execution.ExecutionCommon;
|
|||
import ru.clearing.classes.statics.data.execution.ExecutionDeposit;
|
||||
import ru.clearing.classes.statics.data.misc.Session;
|
||||
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
|
||||
import ru.clearing.classes.statics.data.registry.Registry;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
|
||||
import ru.spcex.clearing.session.stage.impl.*;
|
||||
import ru.spcex.clearing.session.stage.task.*;
|
||||
import ru.spcex.platform.classes.base.interfaces.ExecutionType;
|
||||
import ru.spcex.platform.enumeration.RegistryStatus;
|
||||
import ru.spcex.platform.enumeration.Section;
|
||||
import ru.spcex.platform.enumeration.SessionStatus;
|
||||
import ru.spcex.platform.enumeration.SessionType;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
||||
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
|
@ -37,13 +40,14 @@ public class FinalMkrSession extends AbstractSession implements InitializingBean
|
|||
private final InclusionObligations inclusionObligations;
|
||||
private final InspectionObligations inspectionObligations;
|
||||
private final FormingRegistersOnOS formingRegistersOnOS;
|
||||
private final FormingPaymentInstruction formingPaymentInstruction;
|
||||
private final FormingPaymentInstructionDealsFinalMkr formingPaymentInstruction;
|
||||
private final UnlockResources unlockResources;
|
||||
private final FinishingSession finishingSession;
|
||||
private final EndStageNotification endStageNotification;
|
||||
|
||||
private final Imdg<ExecutionDeposit> executionDepositImdg;
|
||||
private final Supplier<List<String>> marketCodes;
|
||||
private final Imdg<Registry> registryImdg;
|
||||
|
||||
|
||||
public FinalMkrSession(
|
||||
|
|
@ -54,7 +58,7 @@ public class FinalMkrSession extends AbstractSession implements InitializingBean
|
|||
ObligationAdmission obligationsAdmission,
|
||||
InclusionObligations inclusionObligations,
|
||||
FormingRegistersOnOS formingRegistersOnOS,
|
||||
FormingPaymentInstruction formingPaymentInstruction,
|
||||
FormingPaymentInstructionDealsFinalMkr formingPaymentInstruction,
|
||||
UnlockResources unlockResources,
|
||||
FinishingSession finishingSession,
|
||||
EndStageNotification endStageNotification,
|
||||
|
|
@ -75,11 +79,22 @@ public class FinalMkrSession extends AbstractSession implements InitializingBean
|
|||
this.executionDepositImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionDeposit, ExecutionDeposit.class);
|
||||
this.inspectionObligations = inspectionObligations;
|
||||
this.marketCodes = marketCodes;
|
||||
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
dealsPrepare.searchForExecutions(ExecutionType.ExecutionDeposit);
|
||||
//fixme спросить у Кости нужны ли эти поправки
|
||||
ImdgPredicateBuilder rgsPrctBuilder = registryImdg.predicateBuilder();
|
||||
inclusionObligations.addRegistryCondition(
|
||||
rgsPrctBuilder.or(rgsPrctBuilder.equals("registryStatus", RegistryStatus.PROC.getKey()),
|
||||
rgsPrctBuilder.equals("registryStatus", RegistryStatus.MNG.getKey()))
|
||||
);
|
||||
inclusionObligations.addRegistryCondition(
|
||||
rgsPrctBuilder.less("valueDate", LocalDate.now())
|
||||
);
|
||||
inspectionObligations.setSessionType(sectionType());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -187,6 +202,7 @@ public class FinalMkrSession extends AbstractSession implements InitializingBean
|
|||
payload.setSection(currSession.getSection());
|
||||
payload.setSessionId(currSession.getId());
|
||||
runStage(TaskType.EndStageNotification, payload, endStageNotification);
|
||||
endSession();
|
||||
}
|
||||
} catch (StageException e) {
|
||||
//already logged
|
||||
|
|
|
|||
|
|
@ -192,6 +192,7 @@ public class IntermediateMkrSession extends AbstractSession implements Initializ
|
|||
payload.setSection(currSession.getSection());
|
||||
payload.setSessionId(currSession.getId());
|
||||
runStage(TaskType.EndStageNotification, payload, endStageNotification);
|
||||
endSession();
|
||||
}
|
||||
} catch (StageException e) {
|
||||
//already logged
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@ public class PrimaryAuctionB0Session extends AbstractSession implements Initiali
|
|||
payload.setSection(currSession.getSection());
|
||||
payload.setSessionId(currSession.getId());
|
||||
runStage(TaskType.EndStageNotification, payload, endStageNotification);
|
||||
endSession();
|
||||
}
|
||||
} catch (StageException e) {
|
||||
//already logged
|
||||
|
|
|
|||
|
|
@ -178,6 +178,7 @@ public class PrimaryAuctionBnSession extends AbstractSession implements Initiali
|
|||
payload.setSection(currSession.getSection());
|
||||
payload.setSessionId(currSession.getId());
|
||||
runStage(TaskType.EndStageNotification, payload, endStageNotification);
|
||||
endSession();
|
||||
}
|
||||
} catch (StageException e) {
|
||||
//already logged
|
||||
|
|
|
|||
|
|
@ -179,6 +179,7 @@ public class PrimaryAuctionT0Session extends AbstractSession implements Initiali
|
|||
payload.setSection(currSession.getSection());
|
||||
payload.setSessionId(currSession.getId());
|
||||
runStage(TaskType.EndStageNotification, payload, endStageNotification);
|
||||
endSession();
|
||||
}
|
||||
} catch (StageException e) {
|
||||
//already logged
|
||||
|
|
|
|||
|
|
@ -166,6 +166,7 @@ public class ReturnDepositSession extends AbstractSession implements Initializin
|
|||
payload.setSection(currSession.getSection());
|
||||
payload.setSessionId(currSession.getId());
|
||||
runStage(TaskType.EndStageNotification, payload, endStageNotification);
|
||||
endSession();
|
||||
}
|
||||
} catch (StageException e) {
|
||||
//already logged
|
||||
|
|
|
|||
|
|
@ -179,6 +179,7 @@ public class SecondaryAuctionT0Session extends AbstractSession implements Initia
|
|||
payload.setSection(currSession.getSection());
|
||||
payload.setSessionId(currSession.getId());
|
||||
runStage(TaskType.EndStageNotification, payload, endStageNotification);
|
||||
endSession();
|
||||
}
|
||||
} catch (StageException e) {
|
||||
//already logged
|
||||
|
|
|
|||
|
|
@ -0,0 +1,303 @@
|
|||
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.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.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.collection.Pair;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
||||
import ru.spcex.platform.utils.enumeration.SimpleMessageResolver;
|
||||
import ru.spcex.platform.utils.time.TimeUtil;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static ru.spcex.platform.enumeration.RegistryTradingParams.CM_T;
|
||||
import static ru.spcex.platform.enumeration.RegistryTradingParams.LM_T;
|
||||
|
||||
@Service
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public class FormingPaymentInstructionDealsFinalMkr 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<Registry> registryImdg;
|
||||
private Imdg<PaymentInstruction> paymentInstructionImdg;
|
||||
private Imdg<Security> securityImdg;
|
||||
private Imdg<Account> accountImdg;
|
||||
private Imdg<Company> companyImdg;
|
||||
private Imdg<SDf03> sDf03Imdg;
|
||||
private Imdg<SDf12> sDf12Imdg;
|
||||
private KafkaSender kafkaSender;
|
||||
private final IMessageResolver msgResolver = new SimpleMessageResolver();
|
||||
|
||||
@Autowired
|
||||
public FormingPaymentInstructionDealsFinalMkr(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 formingPaymentInstructions(payload.getSessionId());
|
||||
}
|
||||
default -> {
|
||||
throw new IllegalStateException("Unknown task type: " + task.getTaskType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Collection<Registry> selectRegistries() {
|
||||
ImdgPredicateBuilder rgsPb = registryImdg.predicateBuilder();
|
||||
RegistryCodeSqlBuilder registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(
|
||||
LM_T, CM_T
|
||||
);
|
||||
ImdgPredicate rgsCodePrdct = rgsPb.sql(registryCodeSqlBuilder.build());
|
||||
Collection<Registry> registries = registryImdg.getCollectionObjectsByPredicate(rgsCodePrdct);
|
||||
return registries.stream()
|
||||
.filter(rgs -> Objects.equals(rgs.getValueDate(), rgs.getSettlementDate()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
/**
|
||||
* аккаунт-счет с accountType='TRAN' - это счет СПВБ который принадлежит самой бирже<br>
|
||||
* хранят деньги разных участников<br>
|
||||
* в сделке: <br>
|
||||
* регистр CMAT кому переводить (registry.account)<br>
|
||||
* регистр LMAT кто переводит деньги (registry.account)<br>
|
||||
* в итоге создается 2 PaymentInstruction: LMAT -> TRAN счет -> CMAT счет
|
||||
*/
|
||||
private StageResult<?> formingPaymentInstructions(Long sessionId) {
|
||||
Collection<Registry> 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) {
|
||||
return new StageResult<>(
|
||||
new EnumMessage(ClearingError.AccountNotPresent, "accountType = " + AccountType.Tran.getKey()),
|
||||
false);
|
||||
}
|
||||
log.debug("found tranAcc.id = {}", tranAcc.getId());
|
||||
Map<Long, List<Registry>> groups = registries
|
||||
.stream()
|
||||
.collect(Collectors.groupingBy(Registry::getGroupId));
|
||||
log.debug("groups.size = {}", groups.size());
|
||||
List<PaymentInstruction> allPaymentInstructions = new ArrayList<>();
|
||||
for (Map.Entry<Long, List<Registry>> group : groups.entrySet()) {
|
||||
Long groupId = group.getKey();
|
||||
Function<RegistryTradingParams, Registry> findByCode = rgsCode -> group.getValue()
|
||||
.stream()
|
||||
.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);
|
||||
continue;
|
||||
}
|
||||
log.debug("generating payment instruction for groupId {} cmt_t {} lm_t {}",
|
||||
groupId,
|
||||
rgsCmt.getId(),
|
||||
rgsLmt.getId());
|
||||
Pair<PaymentInstruction, PaymentInstruction> pmtInstrs = PaymentInstructionBuilderFinalMkr
|
||||
.builder(imdgProvider)
|
||||
.cm_t(rgsCmt)
|
||||
.lm_t(rgsLmt)
|
||||
.tranAcc(tranAcc)
|
||||
.sessionId(sessionId)
|
||||
.build();
|
||||
Pair.forEach(pmtInstrs, pmtInstr -> {
|
||||
paymentInstructionImdg.insert(pmtInstr);
|
||||
allPaymentInstructions.add(pmtInstr);
|
||||
});
|
||||
log.debug("generated PaymentInstructions for groupId {}: pmtInstr1.id={} pmtInstr2.id={}",
|
||||
groupId,
|
||||
pmtInstrs.getFirst().getId(),
|
||||
pmtInstrs.getSecond().getId());
|
||||
}
|
||||
sendSdfs(allPaymentInstructions);
|
||||
StageResult<Collection<PaymentInstruction>> stageResult = new StageResult<>(null, true);
|
||||
stageResult.setStageResult(allPaymentInstructions);
|
||||
return stageResult;
|
||||
}
|
||||
|
||||
private void sendSdfs(List<PaymentInstruction> formedPaymentInstructions) {
|
||||
List<SDf03> sDf03Created = new ArrayList<>();
|
||||
List<SDf12> 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 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;
|
||||
}
|
||||
|
||||
DateTimeFormatter payDateFormatter = DateTimeFormatter.ofPattern("dd.MM.yy");
|
||||
|
||||
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())
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -13,13 +13,16 @@ import ru.spcex.clearing.session.stage.Task;
|
|||
import ru.spcex.platform.enumeration.*;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
||||
import ru.spcex.platform.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.IEnumKey;
|
||||
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
||||
import ru.spcex.platform.utils.enumeration.SimpleMessageResolver;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
|
@ -30,6 +33,7 @@ public class InspectionObligations implements ISessionStage {
|
|||
private ImdgProvider imdgProvider;
|
||||
private Imdg<Registry> registryImdg;
|
||||
private final IMessageResolver msgResolver = new SimpleMessageResolver();
|
||||
private SessionType sessionType;
|
||||
|
||||
private final static RegistryTradingParams OS_T;
|
||||
private final static RegistryTradingParams OM_T;
|
||||
|
|
@ -65,6 +69,10 @@ public class InspectionObligations implements ISessionStage {
|
|||
this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
|
||||
}
|
||||
|
||||
public void setSessionType(SessionType sessionType) {
|
||||
this.sessionType = sessionType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StageResult submit(Task<?> task) {
|
||||
switch (task.getTaskType()) {
|
||||
|
|
@ -95,6 +103,10 @@ public class InspectionObligations implements ISessionStage {
|
|||
boolean isUncovered = false;
|
||||
List<CheckResult> checkResults = new ArrayList<>();
|
||||
for (Registry obligation : obligationsInGroup) {
|
||||
if (SessionType.FINL.equals(sessionType) && RegistryInstrumentType.S.equalsByKey(obligation.getRegistryInstrumentType())) {
|
||||
checkResults.add(new CheckResult(obligation, false));
|
||||
continue;
|
||||
}
|
||||
String sqlAssetRegistryCondition = searchAssetsByObligationSql(obligation);
|
||||
log.debug("search asset by registry.id={} sql {}", sqlAssetRegistryCondition, obligation.getId());
|
||||
Registry asset = registryImdg.getSingleObjectBySQL(sqlAssetRegistryCondition);
|
||||
|
|
@ -154,6 +166,24 @@ public class InspectionObligations implements ISessionStage {
|
|||
tRegistryWithSameCompany.ifPresent(registry -> updateRegistryStatus(registry, RegistryStatus.FAIL));
|
||||
}
|
||||
}
|
||||
//проверяем есть ли второй день для сделки (он не входит в пул, поэтому ищем отдельно)
|
||||
if (registries.stream().anyMatch(rgs -> rgs.getRefundDate() != null)) {
|
||||
Optional<Pair<Long, LocalDate>> groupIdAndSettleDate = registries.stream()
|
||||
.map(rgs -> new Pair<>(rgs.getGroupId(), rgs.getSettlementDate()))
|
||||
.filter(pair -> pair.getFirst() != null)
|
||||
.filter(pair -> pair.getSecond() != null)
|
||||
.findFirst();
|
||||
if (groupIdAndSettleDate.isEmpty())
|
||||
return;
|
||||
ImdgPredicateBuilder pb = registryImdg.predicateBuilder();
|
||||
Collection<Registry> refundRgs = registryImdg.getCollectionObjectsByPredicate(
|
||||
pb.and(
|
||||
pb.equals("groupId", groupIdAndSettleDate.get().getFirst()),
|
||||
pb.not(pb.equals("settlementDate", groupIdAndSettleDate.get().getSecond()))
|
||||
)
|
||||
);
|
||||
refundRgs.forEach(rgs -> updateRegistryStatus(rgs, RegistryStatus.FAIL));
|
||||
}
|
||||
} else {
|
||||
registries.forEach(registry -> updateRegistryStatus(registry, RegistryStatus.OK));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ public class RegistryDepoBuilder implements IRegistryBuilder {
|
|||
boolean isTSelling = regDsgn.equals(RegistryDesignation.T) && side.isSell();
|
||||
boolean isTBuying = regDsgn.equals(RegistryDesignation.T) && side.isBuy();
|
||||
|
||||
if ((isOBuying || isTSelling) && !secondLeg || (isOSelling || isTBuying) && secondLeg) {
|
||||
if ((isOSelling || isTBuying) && !secondLeg || (isOBuying || isTSelling) && secondLeg) {
|
||||
reg.setRegistryInstrumentType(RegistryInstrumentType.M.getKey());
|
||||
reg.setBalanceDimension(BalanceDimension.MONY.getKey());
|
||||
Currency currency = currencyImdg.getSingleObjectByFieldValues(Map.of("currencyCode", exec.getSettlementCurrency()));
|
||||
|
|
@ -133,11 +133,11 @@ public class RegistryDepoBuilder implements IRegistryBuilder {
|
|||
reg.setSettledDebit((execDep).getFirstLegAmount());
|
||||
}
|
||||
if (secondLeg) {
|
||||
reg.setSettlementDate(execDep.getFirstLegSettlementDate());
|
||||
reg.setSettlementCode(execDep.getFirstLegSettlementCode());
|
||||
} else {
|
||||
reg.setSettlementDate(execDep.getSecondLegSettlementDate());
|
||||
reg.setSettlementCode(execDep.getSecondLegSettlementCode());
|
||||
} else {
|
||||
reg.setSettlementDate(execDep.getFirstLegSettlementDate());
|
||||
reg.setSettlementCode(execDep.getFirstLegSettlementCode());
|
||||
}
|
||||
reg.setRefundDate(execDep.getSecondLegSettlementDate());
|
||||
reg.setValueDate(execDep.getFirstLegSettlementDate());
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ public class ProfileDocumentValidationConfig {
|
|||
IMDGDistributedNames.Map_Company,
|
||||
Company.class,
|
||||
CompanyErrors.RequiredFieldEmpty,
|
||||
CompanyErrors.CompanyNotFound,
|
||||
company -> WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus()) ? null : CompanyErrors.CompanyDisabled),
|
||||
CompanyErrors.CompanyNotFound
|
||||
),
|
||||
DictionaryPresentRule.instance("documentType",
|
||||
ProfileDocumentNewRequest::getDocumentType,
|
||||
IMDGDistributedNames.Map_DocumentTypeDictionary,
|
||||
|
|
|
|||
|
|
@ -9,19 +9,15 @@ import ru.clearing.classes.statics.data.liabilities.LiabilitiesClaimsAssets;
|
|||
import ru.spcex.clearing.company.error.CompanyErrors;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.Consts;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.account.AccountNewRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeNewRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.account.InformationAccountNewRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.account.sdf01.AccountTerminationRequest;
|
||||
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
|
||||
import ru.spcex.platform.enumeration.AccountType;
|
||||
import ru.spcex.platform.enumeration.WorkflowStatus;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class AccountNotificationHelper {
|
||||
|
|
@ -96,4 +92,11 @@ public class AccountNotificationHelper {
|
|||
Long reqId = kafkaSender.sendRequestToQueue(Consts.INFORMATION_ACCOUNT_SYSTEM_NEW, r);
|
||||
log.debug("Send request id={}", reqId);
|
||||
}
|
||||
|
||||
public void clientCodeNew(ClientCodeNewRequest clientCodeNewRequest) {
|
||||
log.debug("Sending messages to account-service {} for company {}",
|
||||
Consts.DESTINATION_CLIENT_CODE_NEW_UM_COMPANY, clientCodeNewRequest.getCompanyId());
|
||||
Long reqId = kafkaSender.sendRequestToQueue(Consts.DESTINATION_CLIENT_CODE_NEW_UM_COMPANY, clientCodeNewRequest);
|
||||
log.debug("Send request id={}", reqId);
|
||||
}
|
||||
}
|
||||
|
|
@ -175,9 +175,9 @@ public class ClearingMemberCategoryService extends QueueConsumer implements Init
|
|||
transaction.beginTransaction();
|
||||
boolean txOk = false;
|
||||
try {
|
||||
companyService.relationService.cancelRelation(transaction, clearingMemberCategory.getCompanyId(), clearingMemberCategory);
|
||||
Imdg<ClearingMemberCategory> txClearingMemberCategoryMap = transaction.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class);
|
||||
txClearingMemberCategoryMap.delete(clearingMemberCategory);
|
||||
txClearingMemberCategoryMap.delete(clearingMemberCategory); // далить до cancelRelation внутри транзакции
|
||||
companyService.relationService.cancelRelation(transaction, clearingMemberCategory.getCompanyId(), clearingMemberCategory);
|
||||
txOk = true;
|
||||
} finally {
|
||||
if (txOk)
|
||||
|
|
|
|||
|
|
@ -379,6 +379,104 @@ public class CompanyService extends QueueConsumer implements InitializingBean {
|
|||
}
|
||||
|
||||
|
||||
public synchronized Company createOrUpdateCompany(BaseRequest<CompanyNewRequest> companyNewRequestBaseRequest, Long existCompanyId) throws ValidationException {
|
||||
CompanyNewRequest req = companyNewRequestBaseRequest.getRequestPayload();
|
||||
log.debug("company new or update, request {}, existCOmpanyId={}", companyNewRequestBaseRequest.getId(), existCompanyId);
|
||||
{ // Валидация
|
||||
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(companyNewRequestBaseRequest);
|
||||
if (requestInfoUpdate != null)
|
||||
throw new ValidationException(CompanyErrors.GeneralError, requestInfoUpdate.getMessage());
|
||||
// requestInfoUpdate = validationHelper.validateTillFirstError(companyNewRequestBaseRequest, companyNewRequestValidator);
|
||||
// if (requestInfoUpdate != null) throw new ValidationException(CompanyErrors.GeneralError, requestInfoUpdate.getMessage());
|
||||
}
|
||||
|
||||
Company company = null;
|
||||
if (existCompanyId != null) {
|
||||
company = companyIMap.getSingleObjectByID(existCompanyId);
|
||||
if (company == null) {
|
||||
throw new ValidationException(CompanyErrors.CompanyNotFound, String.valueOf(existCompanyId));
|
||||
}
|
||||
}
|
||||
|
||||
if (company == null) {
|
||||
// #createCompany
|
||||
company = new Company();
|
||||
company.setId(idSequence.nextId());
|
||||
Instant now = Instant.now();
|
||||
company.setCreated(now);
|
||||
company.setUpdated(now);
|
||||
log.debug("Create new company {}", company.getId());
|
||||
|
||||
company.setShortName(req.getShortName());
|
||||
company.setFullName(req.getFullName());
|
||||
|
||||
ImdgTransaction transaction = imdgProvider.newTransaction();
|
||||
transaction.beginTransaction();
|
||||
boolean txOk = false;
|
||||
try {
|
||||
if (req.getCompanySymbol() != null) {
|
||||
CompanySymbols newSymbol = companySymbolService.createCompanySymbol(transaction, company.getId(), req.getCompanySymbol(), req.getCompanySymbolValue());
|
||||
updateCompanyBySymbol(company, newSymbol, false);
|
||||
}
|
||||
|
||||
company.setWorkflowStatus(req.getWorkflowStatus());
|
||||
fillNewCompanyInfo(company, req);
|
||||
|
||||
Imdg<Company> companyMap = transaction.getImdg(IMDGDistributedNames.Map_Company, Company.class);
|
||||
companyMap.insert(company);
|
||||
log.debug("company-new request processed, BaseRequest.id = {}, company.id={}",
|
||||
companyNewRequestBaseRequest.getId(), company.getId());
|
||||
txOk = true;
|
||||
} finally {
|
||||
if (txOk)
|
||||
transaction.commitTransaction();
|
||||
else
|
||||
transaction.rollbackTransaction();
|
||||
}
|
||||
accountNotification.makeInfoAccount(company.getId());
|
||||
} else {
|
||||
log.debug("Update exist company {}", company.getId());
|
||||
company.setUpdated(Instant.now());
|
||||
// #updateCompany
|
||||
|
||||
company.setUpdated(Instant.now());
|
||||
company.setShortName(req.getShortName());
|
||||
company.setFullName(req.getFullName());
|
||||
|
||||
if (req.getCompanySymbol() != null || req.getCompanySymbolValue() != null) {
|
||||
log.trace("Request field CompanySymbol, CompanySymbolValue ignore for update company request.");
|
||||
}
|
||||
// CompanySymbols не обновляем
|
||||
ImdgTransaction transaction = imdgProvider.newTransaction();
|
||||
transaction.beginTransaction();
|
||||
boolean txOk = false;
|
||||
try {
|
||||
String prevStatus = company.getWorkflowStatus();
|
||||
if (req.getWorkflowStatus() != null) {
|
||||
company.setWorkflowStatus(req.getWorkflowStatus());
|
||||
if (!Objects.equals(prevStatus, company.getWorkflowStatus())) {
|
||||
relationService.onChangeWorkflowStatus(transaction, company, prevStatus, company.getWorkflowStatus());
|
||||
} else {
|
||||
log.trace("Status was not changed");
|
||||
}
|
||||
} else {
|
||||
log.trace("Null new WorkflowStatus");
|
||||
}
|
||||
Imdg<Company> companyMap = transaction.getImdg(IMDGDistributedNames.Map_Company, Company.class);
|
||||
companyMap.update(company);
|
||||
txOk = true;
|
||||
} finally {
|
||||
if (txOk)
|
||||
transaction.commitTransaction();
|
||||
else
|
||||
transaction.rollbackTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
return company;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Блокировка компании после блокировки счетов
|
||||
*
|
||||
|
|
|
|||
|
|
@ -154,9 +154,9 @@ public class CompanySymbolService extends QueueConsumer implements InitializingB
|
|||
if (companySymbols == null) {
|
||||
throw new ClearingBaseException(new EnumMessage(CompanyErrors.CompanyInfoNotFound, req.getId()));
|
||||
}
|
||||
if (!companySymbols.getCompanySymbol().equalsIgnoreCase(req.getCompanySymbolValue())) {
|
||||
throw new ClearingBaseException(new EnumMessage(CompanyErrors.EditCompanySymbols, req.getId()));
|
||||
}
|
||||
// if (!companySymbols.getCompanySymbol().equalsIgnoreCase(req.getCompanySymbolValue())) {
|
||||
// throw new ClearingBaseException(new EnumMessage(CompanyErrors.EditCompanySymbols, req.getId()));
|
||||
// }
|
||||
companySymbols.setCompanySymbolValue(req.getCompanySymbolValue());
|
||||
companySymbolsTMap.update(companySymbols);
|
||||
companyService.updateCompanyBySymbol(transaction, companySymbols, false);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,223 @@
|
|||
package ru.spcex.clearing.company.service;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.kafka.clients.consumer.Consumer;
|
||||
import org.apache.kafka.clients.producer.Producer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.clearing.classes.statics.data.company.Company;
|
||||
import ru.clearing.classes.statics.data.company.CompanySymbols;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.Consts;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeNewRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.company.*;
|
||||
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
|
||||
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
|
||||
import ru.spcex.clearing.util.security.UserRoleVerification;
|
||||
import ru.spcex.clearing.util.services.RequestHelper;
|
||||
import ru.spcex.clearing.validation.common.ValidationHelper;
|
||||
import ru.spcex.platform.enumeration.CompanySymbol;
|
||||
import ru.spcex.platform.enumeration.UserRole;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.utils.error.ValidationException;
|
||||
import ru.spcex.platform.utils.log.ExceptionUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Обрабатывает MultiCompanyRequest и распределяет сложный объект по...
|
||||
*/
|
||||
@Service
|
||||
public class MultiCompanyService
|
||||
extends QueueConsumer implements InitializingBean {
|
||||
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
private final RequestHelper requestHelper;
|
||||
|
||||
protected UserRoleVerification userRoleVerification;
|
||||
// private final ValidationHelper validationHelper;
|
||||
|
||||
final CompanyService companyService;
|
||||
final CompanyInfoService companyInfoService;
|
||||
final ProfileDocumentService profileDocumentService;
|
||||
final CompanySymbolService companySymbolService;
|
||||
final ContactService contactService;
|
||||
final AccountNotificationHelper accountNotification;
|
||||
final RelationService relationService;
|
||||
|
||||
final ImdgProvider imdgProvider;
|
||||
final Imdg<Company> companyIMap;
|
||||
final Imdg<CompanySymbols> companySymbolsImdg;
|
||||
|
||||
@Autowired
|
||||
public MultiCompanyService(Consumer<String, Object> kafkaQueue, Producer<String, Object> kafkaProducer,
|
||||
ImdgProvider imdgProvider,
|
||||
RequestHelper requestHelper,
|
||||
|
||||
CompanyService companyService,
|
||||
CompanyInfoService companyInfoService,
|
||||
ProfileDocumentService profileDocumentService,
|
||||
CompanySymbolService companySymbolService,
|
||||
ContactService contactService,
|
||||
AccountNotificationHelper accountNotification,
|
||||
RelationService relationService,
|
||||
ValidationHelper validationHelper
|
||||
) {
|
||||
super(kafkaQueue, kafkaProducer);
|
||||
this.imdgProvider = imdgProvider;
|
||||
this.requestHelper = requestHelper.setLogger(log);
|
||||
|
||||
// this.idSequence = imdgProvider.getImdgIdGenerator();
|
||||
// this.userRoleVerification = userRoleVerification;
|
||||
// userRoleVerification.setRoleForVerification(UserRole.Admin);
|
||||
// this.validationHelper = validationHelper;
|
||||
this.companyService = companyService;
|
||||
this.companyInfoService = companyInfoService;
|
||||
this.profileDocumentService = profileDocumentService;
|
||||
this.companySymbolService = companySymbolService;
|
||||
this.contactService = contactService;
|
||||
this.accountNotification = accountNotification;
|
||||
this.relationService = relationService;
|
||||
|
||||
companyIMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
|
||||
companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
callback(MultiCompanyRequest.class)
|
||||
.setFunction(request -> requestHelper.requestFunction(this::processMultiRequest, request))
|
||||
.forDestination(Consts.DESTINATION_COMPANY_MULTIREQUEST, callbacks::put);
|
||||
init();
|
||||
}
|
||||
|
||||
private synchronized RequestInfoUpdate processMultiRequest(BaseRequest<MultiCompanyRequest> baseRequest) {
|
||||
MultiCompanyRequest req = baseRequest.getRequestPayload();
|
||||
log.debug("company-batch-new request received, BaseRequest.id = {}", baseRequest.getId());
|
||||
{ // Валидация
|
||||
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(baseRequest);
|
||||
if (requestInfoUpdate != null) return requestInfoUpdate;
|
||||
|
||||
}
|
||||
/*
|
||||
todo:
|
||||
1) добавить апдейт кейсы
|
||||
2) сделать транзакции.
|
||||
|
||||
*/
|
||||
Long companyId = null;
|
||||
boolean txOk = false;
|
||||
synchronized (companyService) {
|
||||
try {
|
||||
companyId = getCompanyIdForCompanySymbols(req.getUuid(), req.getCompany());
|
||||
log.debug("For request {} (uuid {}) company {}.", baseRequest.getId(), req.getUuid(), companyId == null ? "not found" : ("found, id=" + companyId));
|
||||
|
||||
RequestInfoUpdate replyI;
|
||||
Company company = companyService.createOrUpdateCompany(wrapRequest(baseRequest, req.getCompany()), companyId);
|
||||
companyId = company.getId();
|
||||
log.debug("The companyId={}", companyId);
|
||||
fillCompanyId(req, companyId);
|
||||
|
||||
//todo update case:
|
||||
replyI = companyInfoService.companyInfoUpdate(wrapRequest(baseRequest, req.getCompanyInfo()));
|
||||
for (ProfileDocumentNewRequest partRequest : req.getProfileDocuments()) {
|
||||
replyI = profileDocumentService.profileDocumentNew(wrapRequest(baseRequest, partRequest));
|
||||
}
|
||||
for (CompanySymbolNewRequest partRequest : req.getCompanySymbols()) {
|
||||
replyI = companySymbolService.companySymbolNew(wrapRequest(baseRequest, partRequest));
|
||||
}
|
||||
for (ContactNewRequest partRequest : req.getContacts()) {
|
||||
replyI = contactService.contactNew(wrapRequest(baseRequest, partRequest));
|
||||
}
|
||||
txOk = true;
|
||||
} catch (ValidationException vex) {
|
||||
log.error("For companyId={} error: {}", companyId, ExceptionUtils.getStackTrace(vex));
|
||||
}
|
||||
}
|
||||
if (txOk) {
|
||||
log.debug("Create or update sendNewClientCode for company {}", companyId);
|
||||
for (ClientCodeNewRequest partRequest : req.getClientCodes()) {
|
||||
accountNotification.clientCodeNew(partRequest); // Consts.DESTINATION_CLIENT_CODE_NEW Consts.DESTINATION_CLIENT_CODE_UPDATE
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Long getCompanyIdForCompanySymbols(String uuid, CompanyNewRequest cnr) {
|
||||
CompanySymbols companySymbol = null;
|
||||
if (StringUtils.isNotEmpty(uuid)) {
|
||||
log.trace("Search company by companySymbol uuid={}", uuid);
|
||||
Collection<CompanySymbols> companySymbolsFromImdg = companySymbolsImdg.getCollectionObjectsByFieldValues(
|
||||
Map.of(
|
||||
"companySymbol", CompanySymbol.UUID.getKey(),
|
||||
"companySymbolValue", uuid
|
||||
)
|
||||
);
|
||||
if (!companySymbolsFromImdg.isEmpty()) {
|
||||
companySymbol = companySymbolsFromImdg.iterator().next();
|
||||
if (companySymbolsFromImdg.size() > 1) {
|
||||
log.warn("For UUID found > 1 company_symbols, use first (id = {})", companySymbol.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (companySymbol == null && StringUtils.isNotEmpty(cnr.getCompanySymbol())) {
|
||||
log.trace("Search company by companySymbol {}={}", cnr.getCompanySymbol(), cnr.getCompanySymbolValue());
|
||||
Collection<CompanySymbols> companySymbolsFromImdg = companySymbolsImdg.getCollectionObjectsByFieldValues(
|
||||
Map.of(
|
||||
"companySymbol", cnr.getCompanySymbol(),
|
||||
"companySymbolValue", cnr.getCompanySymbolValue()
|
||||
)
|
||||
);
|
||||
if (!companySymbolsFromImdg.isEmpty()) {
|
||||
companySymbol = companySymbolsFromImdg.iterator().next();
|
||||
if (companySymbolsFromImdg.size() > 1) {
|
||||
log.warn("For {} found > 1 company_symbols, use first (id = {})", cnr.getCompanySymbol(), cnr.getCompanySymbolValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (companySymbol != null)
|
||||
return companySymbol.getCompanyId();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
private <T> BaseRequest<T> wrapRequest(BaseRequest<?> template, T payload) {
|
||||
BaseRequest<T> r = new BaseRequest<>();
|
||||
r.setId(template.getId());
|
||||
r.setActionType(template.getActionType()); // todo?
|
||||
r.setUserId(template.getUserId());
|
||||
r.setCorrelationId(template.getCorrelationId());
|
||||
r.setRequestPayload(payload);
|
||||
return r;
|
||||
}
|
||||
|
||||
void fillCompanyId(MultiCompanyRequest req, Long companyId) {
|
||||
req.getCompany().setId(companyId);
|
||||
req.getCompanyInfo().setId(companyId);
|
||||
if (req.getCompanySymbols() == null) req.setCompanySymbols(new ArrayList<>());
|
||||
if (req.getClientCodes() == null) req.setClientCodes(new ArrayList<>());
|
||||
if (req.getProfileDocuments() == null) req.setProfileDocuments(new ArrayList<>());
|
||||
if (req.getContacts() == null) req.setContacts(new ArrayList<>());
|
||||
for (CompanySymbolNewRequest cs : req.getCompanySymbols()) {
|
||||
cs.setCompanyId(companyId);
|
||||
}
|
||||
for (ClientCodeNewRequest cc : req.getClientCodes()) {
|
||||
cc.setCompanyId(companyId);
|
||||
}
|
||||
for (ProfileDocumentNewRequest pd : req.getProfileDocuments()) {
|
||||
pd.setCompanyId(companyId);
|
||||
}
|
||||
for (ContactNewRequest c : req.getContacts()) {
|
||||
c.setCompanyId(companyId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -94,7 +94,7 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin
|
|||
}
|
||||
|
||||
@NonNull
|
||||
private RequestInfoUpdate profileDocumentNew(BaseRequest<ProfileDocumentNewRequest> profileDocumentNewRequestBaseRequest) {
|
||||
protected RequestInfoUpdate profileDocumentNew(BaseRequest<ProfileDocumentNewRequest> profileDocumentNewRequestBaseRequest) {
|
||||
log.trace("Start processing ProfileDocumentNewRequest!");
|
||||
|
||||
RequestInfoUpdate requestInfoUpdate = userRoleVerification.validateRoleAndGetResult(profileDocumentNewRequestBaseRequest);
|
||||
|
|
@ -146,10 +146,6 @@ public class ProfileDocumentService extends QueueConsumer implements Initializin
|
|||
log.warn("Company {} not found by profileDocument {}", profileDocument.getCompanyId(), profileDocument.getId());
|
||||
return requestHelper.makeErrorResponse(deleteRequest, CompanyErrors.CompanyNotFound, profileDocument.getCompanyId());
|
||||
}
|
||||
if (!WorkflowStatus.Active.equalsByKey(existCompany.getWorkflowStatus())) {
|
||||
log.debug("Company {} not active", profileDocument.getCompanyId());
|
||||
return requestHelper.makeErrorResponse(deleteRequest, CompanyErrors.CompanyNotFound, profileDocument.getCompanyId());
|
||||
}
|
||||
|
||||
ImdgTransaction transaction = imdgProvider.newTransaction();
|
||||
transaction.beginTransaction();
|
||||
|
|
|
|||
|
|
@ -272,8 +272,9 @@ public class RelationService extends QueueConsumer implements InitializingBean {
|
|||
return existRelation;
|
||||
}
|
||||
|
||||
Collection<String> selectCompanyClearingMemberCategory(Long companyId) {
|
||||
Collection<ClearingMemberCategory> companyCategory = clearingMemberCategoryImdg.getCollectionObjectsByFieldValues(
|
||||
Collection<String> selectCompanyClearingMemberCategory(ImdgTransaction tx, Long companyId) {
|
||||
Imdg<ClearingMemberCategory> cmcMap = tx == null ? clearingMemberCategoryImdg : tx.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class);
|
||||
Collection<ClearingMemberCategory> companyCategory = cmcMap.getCollectionObjectsByFieldValues(
|
||||
Map.of("companyId", companyId)
|
||||
);
|
||||
return companyCategory.stream()
|
||||
|
|
@ -325,7 +326,7 @@ public class RelationService extends QueueConsumer implements InitializingBean {
|
|||
|
||||
Relation relation = relationMap.getSingleObjectByID(req.getId());
|
||||
final Long companyId = relation.getConsumerId();
|
||||
Collection<String> companyCMC = selectCompanyClearingMemberCategory(companyId);
|
||||
Collection<String> companyCMC = selectCompanyClearingMemberCategory(null, companyId);
|
||||
boolean companyCMCisBIV = companyCMC.contains(ClearingCategory.B.getKey()) || companyCMC.contains(ClearingCategory.I.getKey())
|
||||
|| companyCMC.contains(ClearingCategory.V.getKey());
|
||||
boolean companyCMCisCF = companyCMC.contains(ClearingCategory.C.getKey()) || companyCMC.contains(ClearingCategory.F.getKey());
|
||||
|
|
@ -335,7 +336,7 @@ public class RelationService extends QueueConsumer implements InitializingBean {
|
|||
boolean txOk = false;
|
||||
try {
|
||||
tx.beginTransaction();
|
||||
relationUpdate0(tx, req, relation); // первоначальное ТЗ.
|
||||
//relationUpdate0(tx, req, relation); // первоначальное ТЗ.
|
||||
|
||||
boolean needAddNewRelation = false; // call relationNew0(req, companyId, firstCMC);
|
||||
if (ru.spcex.platform.enumeration.Service.MKR.equalsByKey(relation.getService())) { // relation B or I or V
|
||||
|
|
@ -467,6 +468,9 @@ public class RelationService extends QueueConsumer implements InitializingBean {
|
|||
log.debug("Relation {} already reopened(resumed)", relation.getId());
|
||||
return relation;
|
||||
}
|
||||
if (req.getComment() != null) {
|
||||
relation.setComment(req.getComment());
|
||||
}
|
||||
relation.setServiceStatus(ServiceStatus.Reopened.getKey());
|
||||
relation.setUpdated(Instant.now());
|
||||
|
||||
|
|
@ -505,18 +509,19 @@ public class RelationService extends QueueConsumer implements InitializingBean {
|
|||
Relation relation = relationMap.getSingleObjectByID(req.getId());
|
||||
Long companyId = relation.getConsumerId();
|
||||
|
||||
Collection<String> companyCMC = selectCompanyClearingMemberCategory(companyId);
|
||||
Collection<String> companyCMC = selectCompanyClearingMemberCategory(null, companyId);
|
||||
boolean companyCMCisBIV = companyCMC.contains(ClearingCategory.B.getKey()) || companyCMC.contains(ClearingCategory.I.getKey())
|
||||
|| companyCMC.contains(ClearingCategory.V.getKey());
|
||||
boolean companyCMCisCF = companyCMC.contains(ClearingCategory.C.getKey()) || companyCMC.contains(ClearingCategory.F.getKey());
|
||||
String firstCMC = companyCMC.isEmpty() ? null : companyCMC.iterator().next();
|
||||
|
||||
if (companyCMCisBIV) {
|
||||
if (companyCMCisBIV && MKR.equalsByKey(relation.getService())) {
|
||||
// relation не изменяем
|
||||
} else if (companyCMCisCF) {
|
||||
} else if (companyCMCisCF && FOND.equalsByKey(relation.getService())) {
|
||||
// relation не изменяем
|
||||
} else {
|
||||
// удалить.
|
||||
}
|
||||
// else ? todo bad logic! Проверить ТЗ.
|
||||
// else
|
||||
{
|
||||
ImdgTransaction tx = imdgProvider.newTransaction();
|
||||
boolean txOk = false;
|
||||
|
|
@ -588,28 +593,50 @@ public class RelationService extends QueueConsumer implements InitializingBean {
|
|||
relationMap.insert(relation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Приходит от ClearingMemberCategory
|
||||
*/
|
||||
protected void cancelRelation(ImdgTransaction transaction, Long companyId, ClearingMemberCategory clearingMemberCategory) {
|
||||
log.debug("Cancelling relations for companyId={} and clearingMemberCategory {}", companyId, clearingMemberCategory == null ? null : clearingMemberCategory.getClearingMemberCategory());
|
||||
Objects.requireNonNull(companyId, "companyId");
|
||||
Imdg<Relation> relationMap = transaction.getImdg(IMDGDistributedNames.Map_Relation, Relation.class);
|
||||
String serviceStatus = null;
|
||||
if (clearingMemberCategory == null) {
|
||||
log.warn("clearingMemberCategory not set for companyId={}", companyId);
|
||||
} else {
|
||||
ClearingCategory clearingCategory = getEnumByKey(ClearingCategory.class, clearingMemberCategory.getClearingMemberCategory());
|
||||
serviceStatus = serviceForCMC(clearingCategory).getKey();
|
||||
// String serviceStatus = null;
|
||||
// if (clearingMemberCategory == null) {
|
||||
// log.warn("clearingMemberCategory not set for companyId={}", companyId);
|
||||
// } else {
|
||||
// ClearingCategory clearingCategory = getEnumByKey(ClearingCategory.class, clearingMemberCategory.getClearingMemberCategory());
|
||||
// serviceStatus = serviceForCMC(clearingCategory).getKey();
|
||||
// }
|
||||
|
||||
Collection<String> companyCMC = selectCompanyClearingMemberCategory(null, companyId);
|
||||
if (companyCMC.contains(clearingMemberCategory.getClearingMemberCategory())) {
|
||||
// never
|
||||
log.warn("ClearingMemberCategory \"{}\" already exist in set for company {}.", clearingMemberCategory.getClearingMemberCategory(), companyId);
|
||||
}
|
||||
boolean companyCMCisBIV = companyCMC.contains(ClearingCategory.B.getKey()) || companyCMC.contains(ClearingCategory.I.getKey())
|
||||
|| companyCMC.contains(ClearingCategory.V.getKey());
|
||||
boolean companyCMCisCF = companyCMC.contains(ClearingCategory.C.getKey()) || companyCMC.contains(ClearingCategory.F.getKey());
|
||||
|
||||
|
||||
Relation relation = searchRelation(transaction, clearingMemberCategory.getClearingMemberCategory(), companyId);
|
||||
if (relation == null) {
|
||||
log.debug("Relation for clearingMemberCategory.id={} {} not found", clearingMemberCategory.getId(), clearingMemberCategory.getClearingMemberCategory());
|
||||
return;
|
||||
} else {
|
||||
relation.setUpdated(Instant.now());
|
||||
log.debug("Update exist relation.id={}", relation.getId());
|
||||
if (companyCMCisBIV && MKR.equalsByKey(relation.getService())) {
|
||||
// relation не изменяем
|
||||
log.debug("Relation {} {} lost for ClearingMemberCategory \"{}\".", relation.getId(), relation.getService(), clearingMemberCategory.getClearingMemberCategory());
|
||||
} else if (companyCMCisCF && FOND.equalsByKey(relation.getService())) {
|
||||
// relation не изменяем
|
||||
log.debug("Relation {} {} lost for ClearingMemberCategory \"{}\".", relation.getId(), relation.getService(), clearingMemberCategory.getClearingMemberCategory());
|
||||
} else {
|
||||
// удалить.
|
||||
log.debug("Block exist relation.id={}", relation.getId());
|
||||
relation.setUpdated(Instant.now());
|
||||
relation.setServiceStatus(Closed.getKey());
|
||||
relationMap.update(relation);
|
||||
log.debug("Relation[{}] updated (closed) by clearingMemberCategory[{}].", relation.getId(), clearingMemberCategory.getId());
|
||||
}
|
||||
}
|
||||
relation.setServiceStatus(Closed.getKey());
|
||||
log.debug("Relation[{}] updated (closed) by clearingMemberCategory[{}].", relation.getId(), clearingMemberCategory.getId());
|
||||
relationMap.insert(relation);
|
||||
}
|
||||
|
||||
protected void cancelAllRelationForCompany(ImdgTransaction transaction, Long companyId) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
-- DB version: 3.5.0.28
|
||||
-- DB version: 3.5.0.31
|
||||
-- DATA version: 3.5.0.8
|
||||
/* Dictionaries */
|
||||
|
||||
|
|
@ -652,11 +652,11 @@ INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (1019, 'SECR', 'Инс
|
|||
|
||||
INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (1020, 'SECR', 'Режим %s не найден.') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
|
||||
|
||||
INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (1021, 'SECR', 'Информиция об инструментах Денежного рынка на режимах добавляется автоматически.') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
|
||||
INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (1021, 'SECR', 'Информация об инструментах Денежного рынка на режимах добавляется автоматически.') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
|
||||
|
||||
INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (1022, 'SECR', 'Информиция об инструментах Денежного рынка на режимах изменяется автоматически.') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
|
||||
INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (1022, 'SECR', 'Информация об инструментах Денежного рынка на режимах изменяется автоматически.') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
|
||||
|
||||
INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (1023, 'SECR', 'Информиция об инструментах Денежного рынка на режимах блокируется автоматически.') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
|
||||
INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (1023, 'SECR', 'Информация об инструментах Денежного рынка на режимах блокируется автоматически.') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
|
||||
|
||||
INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (2000, 'UTIL', 'Общая ошибка модуля utility-service.') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
|
||||
|
||||
|
|
@ -864,7 +864,7 @@ INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (7010, 'SCHD', 'Нев
|
|||
|
||||
INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (7011, 'SCHD', 'Невозможно добавить задачу на прошедшее время.') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
|
||||
|
||||
INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (7012, 'SCHD', 'Указанный в задаче нструмент не найден.') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
|
||||
INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (7012, 'SCHD', 'Указанный в задаче инструмент не найден.') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
|
||||
|
||||
INSERT INTO ERROR_CODE_DICTIONARY(ID, CODE, NAME) values (7013, 'SCHD', 'Указанный инструмент неактивен.') ON CONFLICT (ID) DO UPDATE SET CODE = EXCLUDED.CODE, NAME = EXCLUDED.NAME;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
package ru.spcex.clearing.gatewayapi.config;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.http.client.ClientHttpRequestExecution;
|
||||
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
public class LoggingInterceptor implements ClientHttpRequestInterceptor {
|
||||
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@Override
|
||||
public ClientHttpResponse intercept(HttpRequest request,
|
||||
byte[] body,
|
||||
ClientHttpRequestExecution execution) throws IOException {
|
||||
|
||||
log.info("Request URI: " + request.getURI());
|
||||
log.info("Request method: " + request.getMethod());
|
||||
log.info("Request headers: " + request.getHeaders());
|
||||
log.info("Request body: " + new String(body, "UTF-8"));
|
||||
|
||||
ClientHttpResponse response = execution.execute(request, body);
|
||||
|
||||
log.info("Response status code: " + response.getStatusCode());
|
||||
log.info("Response body: " + StreamUtils.copyToString(response.getBody(), Charset.defaultCharset()));
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
|
@ -55,7 +55,7 @@ public class ProcessorConfiguration {
|
|||
pipeline.add(new PrepareMemberCompanies());
|
||||
pipeline.add(new ValidateMemberCompanies());
|
||||
pipeline.add(new CheckMemberCompanyExist(imdgProvider));
|
||||
pipeline.add(new SendMessageToCompanyServiceWithMemberCompanies(kafkaSender, imdgProvider));
|
||||
pipeline.add(new CompaniesKafkaMessenger(kafkaSender, imdgProvider));
|
||||
processor.setPipeline(pipeline);
|
||||
return processor;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import org.springframework.context.annotation.Configuration;
|
|||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
|
||||
@Configuration
|
||||
public class RestTemplateConfig {
|
||||
|
|
@ -19,9 +20,11 @@ public class RestTemplateConfig {
|
|||
|
||||
@Bean("rest-template")
|
||||
public RestTemplate restTemplate() {
|
||||
return builder
|
||||
RestTemplate restTemplate = builder
|
||||
.setConnectTimeout(Duration.ofMillis(10000))
|
||||
.setReadTimeout(Duration.ofMillis(40000))
|
||||
.build();
|
||||
restTemplate.setInterceptors(Collections.singletonList(new LoggingInterceptor()));
|
||||
return restTemplate;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
package ru.spcex.clearing.gatewayapi.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.filter.CommonsRequestLoggingFilter;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
|
|
@ -12,16 +10,6 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
|||
@EnableWebMvc
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
|
||||
@Bean
|
||||
public CommonsRequestLoggingFilter loggingFilter() {
|
||||
CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter();
|
||||
filter.setIncludePayload(true);
|
||||
filter.setIncludeQueryString(true);
|
||||
filter.setMaxPayloadLength(1000000000);
|
||||
filter.setAfterMessagePrefix("Income request data: ");
|
||||
return filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler("swagger-ui.html")
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import java.time.Instant;
|
|||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
public class InstantDeserializer extends JsonDeserializer<Instant> {
|
||||
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss:SSS");
|
||||
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss");
|
||||
|
||||
@Override
|
||||
public Instant deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
package ru.spcex.clearing.gatewayapi.config.filters;
|
||||
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
import java.io.*;
|
||||
|
||||
public class CachedHttpServletRequest extends HttpServletRequestWrapper {
|
||||
|
||||
private byte[] cachedPayload;
|
||||
|
||||
public CachedHttpServletRequest(HttpServletRequest request) throws IOException {
|
||||
super(request);
|
||||
InputStream requestInputStream = request.getInputStream();
|
||||
this.cachedPayload = StreamUtils.copyToByteArray(requestInputStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletInputStream getInputStream() {
|
||||
return new CachedServletInputStream(this.cachedPayload);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedReader getReader() {
|
||||
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(this.cachedPayload);
|
||||
return new BufferedReader(new InputStreamReader(byteArrayInputStream));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package ru.spcex.clearing.gatewayapi.config.filters;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.servlet.ReadListener;
|
||||
import javax.servlet.ServletInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class CachedServletInputStream extends ServletInputStream {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
private InputStream cachedInputStream;
|
||||
|
||||
public CachedServletInputStream(byte[] cachedBody) {
|
||||
this.cachedInputStream = new ByteArrayInputStream(cachedBody);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinished() {
|
||||
try {
|
||||
return cachedInputStream.available() == 0;
|
||||
} catch (IOException exp) {
|
||||
log.error(exp.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReadListener(ReadListener readListener) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return cachedInputStream.read();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package ru.spcex.clearing.gatewayapi.config.filters;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StreamUtils;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebFilter;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@Order(value = Ordered.HIGHEST_PRECEDENCE)
|
||||
@Component
|
||||
@WebFilter(filterName = "RequestCachingFilter", urlPatterns = "/*")
|
||||
public class RequestCachingFilter extends OncePerRequestFilter {
|
||||
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
|
||||
FilterChain filterChain) throws ServletException, IOException {
|
||||
CachedHttpServletRequest cachedHttpServletRequest = new CachedHttpServletRequest(request);
|
||||
log.info("REQUEST QUERY: " + request.getQueryString());
|
||||
log.info("REQUEST DATA: " + StreamUtils.copyToString(cachedHttpServletRequest.getInputStream(), StandardCharsets.UTF_8));
|
||||
filterChain.doFilter(cachedHttpServletRequest, response);
|
||||
}
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ import java.time.Instant;
|
|||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
public class InstantSerializer extends JsonSerializer<Instant> {
|
||||
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss:SSS");
|
||||
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss");
|
||||
|
||||
@Override
|
||||
public void serialize(Instant value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ public class GatewayController {
|
|||
)
|
||||
@ResponseBody
|
||||
public CommonResponse listingsFond(@RequestBody FondListingsRequest request) {
|
||||
request.validate(validTypes, List.of(Section.FOND));
|
||||
// request.validate(validTypes, List.of(Section.FOND));
|
||||
FondListingsRequestParam requestParam = new FondListingsRequestParam(request);
|
||||
ProcessResult processResult = fondListingsRequestProcessor.process(requestParam);
|
||||
if (processResult.getError() != null) throw new GatewayException(request, processResult.getError());
|
||||
|
|
@ -91,7 +91,7 @@ public class GatewayController {
|
|||
)
|
||||
@ResponseBody
|
||||
public CommonResponse listingsMM(@RequestBody MMListingsRequest request) {
|
||||
request.validate(validTypes, List.of(Section.MKR));
|
||||
// request.validate(validTypes, List.of(Section.MKR));
|
||||
MMListingsRequestParam requestParam = new MMListingsRequestParam(request);
|
||||
ProcessResult processResult = mmListingsRequestProcessor.process(requestParam);
|
||||
if (processResult.getError() != null) throw new GatewayException(request, processResult.getError());
|
||||
|
|
@ -112,7 +112,7 @@ public class GatewayController {
|
|||
)
|
||||
@ResponseBody
|
||||
public CommonResponse companies(@RequestBody CompaniesRequest request) {
|
||||
request.validate(validTypes, Collections.emptyList());
|
||||
// request.validate(validTypes, Collections.emptyList());
|
||||
CompaniesRequestParam requestParam = new CompaniesRequestParam(request);
|
||||
ProcessResult processResult = companiesRequestProcessor.process(requestParam);
|
||||
if (processResult.getError() != null) throw new GatewayException(request, processResult.getError());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,104 @@
|
|||
package ru.spcex.clearing.gatewayapi.logic.companies;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import ru.clearing.classes.statics.data.company.Company;
|
||||
import ru.spcex.clearing.gatewayapi.logic.ProcessResult;
|
||||
import ru.spcex.clearing.gatewayapi.logic.Stage;
|
||||
import ru.spcex.clearing.gatewayapi.request.objects.*;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
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.company.*;
|
||||
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
|
||||
import ru.spcex.platform.enumeration.CompanySymbol;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Отправка сообщения к company-service на создание/обновление company
|
||||
* todo Пока убрал совсем не рабочую логику с sendToQueueWaitForAnswer
|
||||
*/
|
||||
public class CompaniesKafkaMessenger extends Stage<CompaniesRequestParam> {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
private final KafkaSender kafkaSender;
|
||||
private final Imdg<Company> companyImdg;
|
||||
|
||||
public CompaniesKafkaMessenger(KafkaSender kafkaSender, ImdgProvider imdgProvider) {
|
||||
this.kafkaSender = kafkaSender;
|
||||
this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcessResult process(CompaniesRequestParam param) {
|
||||
List<MemberCompany> companyList = param.getMemberCompanyList();
|
||||
for (MemberCompany company : companyList) {
|
||||
if (company.isInvalidData()) continue;
|
||||
|
||||
MultiCompanyRequest multiCompanyRequest = new MultiCompanyRequest();
|
||||
|
||||
CompanyNewRequest companyNewRequest = new CompanyNewRequest();
|
||||
companyNewRequest.setShortName(company.getShortName());
|
||||
companyNewRequest.setFullName(company.getFullName());
|
||||
companyNewRequest.setCompanySymbol(CompanySymbol.UUID.getKey());
|
||||
companyNewRequest.setCompanySymbolValue(company.getId().toString());
|
||||
multiCompanyRequest.setCompany(companyNewRequest);
|
||||
|
||||
MemberCompanyInfo companyInfo = company.getCompanyInfo();
|
||||
CompanyInfoUpdateRequest companyInfoUpdateRequest = new CompanyInfoUpdateRequest();
|
||||
companyInfoUpdateRequest.setCountryCode("RUS"); // todo в текущей версии ТЗ присылается в цифровом обозначении
|
||||
companyInfoUpdateRequest.setProfessionalSign(companyInfo.getProfessionalSign());
|
||||
companyInfoUpdateRequest.setLegalKind(companyInfo.getLegalKind());
|
||||
companyInfoUpdateRequest.setOrganizationType(companyInfo.getOrganizationType());
|
||||
companyInfoUpdateRequest.setResidence(companyInfo.getResidence());
|
||||
multiCompanyRequest.setCompanyInfo(companyInfoUpdateRequest);
|
||||
|
||||
for (MemberCompanySymbols companySymbols : company.getMemberCompanySymbolsList()) {
|
||||
if (companySymbols.isInvalidData()) continue;
|
||||
CompanySymbolNewRequest companySymbolNewRequest = new CompanySymbolNewRequest();
|
||||
companySymbolNewRequest.setCompanySymbol(companySymbols.getCompanySymbol());
|
||||
companySymbolNewRequest.setCompanySymbolValue(companySymbols.getCompanySymbolValue());
|
||||
multiCompanyRequest.getCompanySymbols().add(companySymbolNewRequest);
|
||||
}
|
||||
|
||||
for (MemberContact contact : company.getContactList()) {
|
||||
if (contact.isInvalidData()) continue;
|
||||
ContactNewRequest contactNewRequest = new ContactNewRequest();
|
||||
contactNewRequest.setContactType(contact.getContactType());
|
||||
contactNewRequest.setContactValue(contact.getContactValue());
|
||||
multiCompanyRequest.getContacts().add(contactNewRequest);
|
||||
}
|
||||
|
||||
for (MemberProfileDocument profileDocument : company.getProfileDocumentList()) {
|
||||
if (profileDocument.isInvalidData()) continue;
|
||||
ProfileDocumentNewRequest profileDocumentNewRequest = new ProfileDocumentNewRequest();
|
||||
profileDocumentNewRequest.setDocumentType(profileDocument.getDocumentType());
|
||||
profileDocumentNewRequest.setIssueDate(profileDocument.getIssueDate());
|
||||
profileDocumentNewRequest.setIssuer(profileDocument.getIssuer());
|
||||
profileDocumentNewRequest.setNumber(profileDocument.getNumber());
|
||||
profileDocumentNewRequest.setValidToDate(profileDocument.getValidToDate());
|
||||
profileDocumentNewRequest.setLink(profileDocument.getLink());
|
||||
multiCompanyRequest.getProfileDocuments().add(profileDocumentNewRequest);
|
||||
}
|
||||
|
||||
for (MemberClient client : company.getClientList()) {
|
||||
if (client.isInvalidData()) continue;
|
||||
|
||||
if (!company.isAlreadyExist() || !client.isAlreadyExist()) {
|
||||
ClientCodeNewRequest clientCodeNewRequest = new ClientCodeNewRequest();
|
||||
clientCodeNewRequest.setCode(client.getClientCode());
|
||||
clientCodeNewRequest.setMoneyAccountId(client.getMoneyAccountId());
|
||||
clientCodeNewRequest.setDepoAccountId(client.getDepoAccountId());
|
||||
multiCompanyRequest.getClientCodes().add(clientCodeNewRequest);
|
||||
}
|
||||
}
|
||||
|
||||
kafkaSender.sendRequestToQueue(Consts.DESTINATION_COMPANY_MULTIREQUEST, multiCompanyRequest);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,179 +0,0 @@
|
|||
package ru.spcex.clearing.gatewayapi.logic.companies;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import ru.clearing.classes.statics.data.company.Company;
|
||||
import ru.spcex.clearing.gatewayapi.logic.ProcessResult;
|
||||
import ru.spcex.clearing.gatewayapi.logic.Stage;
|
||||
import ru.spcex.clearing.gatewayapi.request.objects.*;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
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.account.ClientCodeUpdateRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.company.*;
|
||||
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
|
||||
import ru.spcex.platform.enumeration.CompanySymbol;
|
||||
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.utils.enumeration.IEnumKey;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Отправка сообщения к company-service на создание/обновление company
|
||||
* todo Пока убрал совсем не рабочую логику с sendToQueueWaitForAnswer
|
||||
*/
|
||||
public class SendMessageToCompanyServiceWithMemberCompanies extends Stage<CompaniesRequestParam> {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
private final KafkaSender kafkaSender;
|
||||
private final Imdg<Company> companyImdg;
|
||||
|
||||
public SendMessageToCompanyServiceWithMemberCompanies(KafkaSender kafkaSender, ImdgProvider imdgProvider) {
|
||||
this.kafkaSender = kafkaSender;
|
||||
this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
|
||||
}
|
||||
@Override
|
||||
public ProcessResult process(CompaniesRequestParam param) {
|
||||
List<MemberCompany> companyList = param.getMemberCompanyList();
|
||||
for (MemberCompany company : companyList) {
|
||||
if (company.isInvalidData()) continue;
|
||||
|
||||
String companyWorkflowStatus = WorkflowStatus.Active.getKey();
|
||||
if (!company.getCompanyClearingCategoryList().isEmpty()) {
|
||||
MemberCompanyClearingCategory clearingCategory = company.getCompanyClearingCategoryList().get(0);
|
||||
ServiceStatus categoryStatus = IEnumKey.getEnumByKey(ServiceStatus.class, clearingCategory.getWorkflowStatus());
|
||||
if (categoryStatus == ServiceStatus.Active || categoryStatus == ServiceStatus.Appl || categoryStatus == ServiceStatus.Reopened) {
|
||||
companyWorkflowStatus = WorkflowStatus.Active.getKey();
|
||||
} else {
|
||||
companyWorkflowStatus = WorkflowStatus.Blocked.getKey();
|
||||
}
|
||||
}
|
||||
|
||||
CompanyNewRequest companyNewRequest = new CompanyNewRequest();
|
||||
if (company.isAlreadyExist()) companyNewRequest.setId(company.getMapId());
|
||||
companyNewRequest.setShortName(company.getShortName());
|
||||
companyNewRequest.setFullName(company.getFullName());
|
||||
companyNewRequest.setCompanySymbol(CompanySymbol.UUID.getKey());
|
||||
companyNewRequest.setCompanySymbolValue(company.getId().toString());
|
||||
|
||||
MemberCompanyInfo companyInfo = company.getCompanyInfo();
|
||||
|
||||
if (company.isAlreadyExist()) {
|
||||
kafkaSender.sendRequestToQueue(Consts.DESTINATION_COMPANY_UPDATE, companyNewRequest);
|
||||
} else {
|
||||
kafkaSender.sendRequestToQueue(Consts.DESTINATION_COMPANY_NEW, companyNewRequest);
|
||||
Company companyFromImdg = companyImdg.getSingleObjectByFieldValues(
|
||||
Map.of(
|
||||
"shortName", company.getShortName(),
|
||||
"fullName", company.getFullName(),
|
||||
"workflowStatus", companyWorkflowStatus
|
||||
)
|
||||
);
|
||||
if (companyFromImdg == null) {
|
||||
log.warn("Can't insert company (UUID {}), skipped", company.getId());
|
||||
company.setInvalidData(true);
|
||||
continue;
|
||||
}
|
||||
company.setAlreadyExist(true);
|
||||
company.setMapId(companyFromImdg.getId());
|
||||
}
|
||||
Long companyId = company.getMapId();
|
||||
|
||||
CompanyInfoUpdateRequest companyInfoUpdateRequest = new CompanyInfoUpdateRequest();
|
||||
companyInfoUpdateRequest.setId(companyId);
|
||||
companyInfoUpdateRequest.setCountryCode("RUS"); // todo в текущей версии ТЗ присылается в цифровом обозначении
|
||||
companyInfoUpdateRequest.setProfessionalSign(companyInfo.getProfessionalSign());
|
||||
companyInfoUpdateRequest.setLegalKind(companyInfo.getLegalKind());
|
||||
companyInfoUpdateRequest.setOrganizationType(companyInfo.getOrganizationType());
|
||||
companyInfoUpdateRequest.setResidence(companyInfo.getResidence());
|
||||
kafkaSender.sendRequestToQueue(Consts.DESTINATION_COMPANY_UPDATE, companyInfoUpdateRequest);
|
||||
|
||||
for (MemberCompanySymbols companySymbols : company.getMemberCompanySymbolsList()) {
|
||||
if (companySymbols.isInvalidData()) continue;
|
||||
if (!company.isAlreadyExist() || !companySymbols.isAlreadyExist()) {
|
||||
CompanySymbolNewRequest companySymbolNewRequest = new CompanySymbolNewRequest();
|
||||
companySymbolNewRequest.setCompanyId(companyId);
|
||||
companySymbolNewRequest.setCompanySymbol(companySymbols.getCompanySymbol());
|
||||
companySymbolNewRequest.setCompanySymbolValue(companySymbols.getCompanySymbolValue());
|
||||
kafkaSender.sendRequestToQueue(Consts.DESTINATION_COMPANY_SYMBOL_NEW, companySymbolNewRequest);
|
||||
} else {
|
||||
CompanySymbolUpdateRequest companySymbolUpdateRequest = new CompanySymbolUpdateRequest();
|
||||
companySymbolUpdateRequest.setId(companySymbols.getMapId());
|
||||
companySymbolUpdateRequest.setCompanyId(companyId);
|
||||
companySymbolUpdateRequest.setCompanySymbolValue(companySymbols.getCompanySymbolValue());
|
||||
kafkaSender.sendRequestToQueue(Consts.DESTINATION_COMPANY_SYMBOL_UPDATE, companySymbolUpdateRequest);
|
||||
}
|
||||
}
|
||||
|
||||
for (MemberContact contact : company.getContactList()) {
|
||||
if (contact.isInvalidData()) continue;
|
||||
if (!company.isAlreadyExist() || !contact.isAlreadyExist()) {
|
||||
ContactNewRequest contactNewRequest = new ContactNewRequest();
|
||||
contactNewRequest.setCompanyId(companyId);
|
||||
contactNewRequest.setContactType(contact.getContactType());
|
||||
contactNewRequest.setContactValue(contact.getContactValue());
|
||||
kafkaSender.sendRequestToQueue(Consts.DESTINATION_CONTACT_NEW, contactNewRequest);
|
||||
} else {
|
||||
ContactUpdateRequest contactUpdateRequest = new ContactUpdateRequest();
|
||||
contactUpdateRequest.setId(contact.getMapId());
|
||||
contactUpdateRequest.setContactType(contact.getContactType());
|
||||
contactUpdateRequest.setContactValue(contact.getContactValue());
|
||||
kafkaSender.sendRequestToQueue(Consts.DESTINATION_CONTACT_UPDATE, contactUpdateRequest);
|
||||
}
|
||||
}
|
||||
|
||||
for (MemberProfileDocument profileDocument : company.getProfileDocumentList()) {
|
||||
if (profileDocument.isInvalidData()) continue;
|
||||
if (!company.isAlreadyExist() || !profileDocument.isAlreadyExist()) {
|
||||
ProfileDocumentNewRequest profileDocumentNewRequest = new ProfileDocumentNewRequest();
|
||||
profileDocumentNewRequest.setCompanyId(companyId);
|
||||
profileDocumentNewRequest.setDocumentType(profileDocument.getDocumentType());
|
||||
profileDocumentNewRequest.setIssueDate(profileDocument.getIssueDate());
|
||||
profileDocumentNewRequest.setIssuer(profileDocument.getIssuer());
|
||||
profileDocumentNewRequest.setNumber(profileDocument.getNumber());
|
||||
profileDocumentNewRequest.setValidToDate(profileDocument.getValidToDate());
|
||||
profileDocumentNewRequest.setLink(profileDocument.getLink());
|
||||
kafkaSender.sendRequestToQueue(Consts.DESTINATION_PROFILE_DOCUMENT_NEW, profileDocumentNewRequest);
|
||||
} else {
|
||||
ProfileDocumentUpdateRequest profileDocumentUpdateRequest = new ProfileDocumentUpdateRequest();
|
||||
profileDocumentUpdateRequest.setId(profileDocument.getMapId());
|
||||
profileDocumentUpdateRequest.setCompanyId(companyId);
|
||||
profileDocumentUpdateRequest.setDocumentType(profileDocument.getDocumentType());
|
||||
profileDocumentUpdateRequest.setIssueDate(profileDocument.getIssueDate());
|
||||
profileDocumentUpdateRequest.setIssuer(profileDocument.getIssuer());
|
||||
profileDocumentUpdateRequest.setNumber(profileDocument.getNumber());
|
||||
profileDocumentUpdateRequest.setValidToDate(profileDocument.getValidToDate());
|
||||
profileDocumentUpdateRequest.setLink(profileDocument.getLink());
|
||||
kafkaSender.sendRequestToQueue(Consts.DESTINATION_PROFILE_DOCUMENT_NEW, profileDocumentUpdateRequest);
|
||||
}
|
||||
}
|
||||
|
||||
for (MemberClient client : company.getClientList()) {
|
||||
if (client.isInvalidData()) continue;
|
||||
|
||||
if (!company.isAlreadyExist() || !client.isAlreadyExist()) {
|
||||
ClientCodeNewRequest clientCodeNewRequest = new ClientCodeNewRequest();
|
||||
clientCodeNewRequest.setCompanyId(companyId);
|
||||
clientCodeNewRequest.setCode(client.getClientCode());
|
||||
clientCodeNewRequest.setMoneyAccountId(client.getMoneyAccountId());
|
||||
clientCodeNewRequest.setDepoAccountId(client.getDepoAccountId());
|
||||
kafkaSender.sendRequestToQueue(Consts.DESTINATION_CLIENT_CODE_NEW, clientCodeNewRequest);
|
||||
} else {
|
||||
ClientCodeUpdateRequest clientCodeUpdateRequest = new ClientCodeUpdateRequest();
|
||||
clientCodeUpdateRequest.setId(client.getMapId());
|
||||
clientCodeUpdateRequest.setCompanyId(companyId);
|
||||
clientCodeUpdateRequest.setCode(client.getClientCode());
|
||||
clientCodeUpdateRequest.setMoneyAccountId(client.getMoneyAccountId());
|
||||
clientCodeUpdateRequest.setDepoAccountId(client.getDepoAccountId());
|
||||
kafkaSender.sendRequestToQueue(Consts.DESTINATION_CLIENT_CODE_NEW, clientCodeUpdateRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -94,7 +94,7 @@ public class SendMessageToSecurityServiceWithFondSecurities extends Stage<FondLi
|
|||
fixedIncomeSecurityNewRequest.setNominalValue(security.getNominalValue());
|
||||
fixedIncomeSecurityNewRequest.setNominalCurrency(security.getNominalCurrency());
|
||||
fixedIncomeSecurityNewRequest.setMaturityDate(security.getMaturityDate());
|
||||
fixedIncomeSecurityNewRequest.setCouponFrequency(security.getCouponFrequency());
|
||||
fixedIncomeSecurityNewRequest.setCouponFrequency(security.getCouponFrequency().longValue());
|
||||
fixedIncomeSecurityNewRequest.setIssuerId(companyId);
|
||||
fixedIncomeSecurityNewRequest.setShortNameEng(security.getShortNameEng());
|
||||
fixedIncomeSecurityNewRequest.setFullNameEng(security.getFullNameEng());
|
||||
|
|
@ -112,7 +112,7 @@ public class SendMessageToSecurityServiceWithFondSecurities extends Stage<FondLi
|
|||
fixedIncomeSecurityUpdateRequest.setNominalValue(security.getNominalValue());
|
||||
fixedIncomeSecurityUpdateRequest.setNominalCurrency(security.getNominalCurrency());
|
||||
fixedIncomeSecurityUpdateRequest.setMaturityDate(security.getMaturityDate());
|
||||
fixedIncomeSecurityUpdateRequest.setCouponFrequency(security.getCouponFrequency());
|
||||
fixedIncomeSecurityUpdateRequest.setCouponFrequency(security.getCouponFrequency().longValue());
|
||||
fixedIncomeSecurityUpdateRequest.setIssuerId(companyId);
|
||||
fixedIncomeSecurityUpdateRequest.setShortNameEng(security.getShortNameEng());
|
||||
fixedIncomeSecurityUpdateRequest.setFullNameEng(security.getFullNameEng());
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@ package ru.spcex.clearing.gatewayapi.request;
|
|||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import ru.spcex.clearing.gatewayapi.config.deserializers.InstantDeserializer;
|
||||
import ru.spcex.clearing.gatewayapi.config.serializers.InstantSerializer;
|
||||
import ru.spcex.clearing.gatewayapi.errors.GatewayError;
|
||||
import ru.spcex.clearing.gatewayapi.exception.GatewayException;
|
||||
import ru.spcex.platform.enumeration.Section;
|
||||
|
|
@ -38,6 +40,7 @@ public class CommonRequest {
|
|||
|
||||
@JsonProperty("datetime")
|
||||
@JsonDeserialize(using = InstantDeserializer.class)
|
||||
@JsonSerialize(using = InstantSerializer.class)
|
||||
@ApiModelProperty(
|
||||
value = "Передавать дату и время формирования JSON объекта в формате «ДД.ММ.ГГГГ ЧЧ:ММ:СС:ссс».",
|
||||
example = "01.01.2023 12:34:56:789"
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@ package ru.spcex.clearing.gatewayapi.request;
|
|||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import ru.spcex.clearing.gatewayapi.config.deserializers.InstantDeserializer;
|
||||
import ru.spcex.clearing.gatewayapi.config.serializers.InstantSerializer;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
|
@ -32,6 +34,7 @@ public class InboundRequest {
|
|||
|
||||
@JsonProperty("datetime")
|
||||
@JsonDeserialize(using = InstantDeserializer.class)
|
||||
@JsonSerialize(using = InstantSerializer.class)
|
||||
@ApiModelProperty(
|
||||
value = "Передавать дату и время формирования JSON объекта в формате «ДД.ММ.ГГГГ ЧЧ:ММ:СС:ссс».",
|
||||
example = "01.01.2023 12:34:56:789"
|
||||
|
|
@ -42,7 +45,14 @@ public class InboundRequest {
|
|||
@ApiModelProperty(
|
||||
value = "Секция (FOND или MKR)", example = "FOND"
|
||||
)
|
||||
private String section;
|
||||
private String section = "";
|
||||
|
||||
// todo Пока так, чтобы отсылал null, в дальнейшем тип надо заменить на используемый в запросе. Возможно с помощью параметризации
|
||||
@JsonProperty("content")
|
||||
@ApiModelProperty(
|
||||
value = "Контент", example = "null"
|
||||
)
|
||||
private String content = null;
|
||||
|
||||
|
||||
public UUID getId() {
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ public class FondSecurity extends WithMapId {
|
|||
value = "Дополнительная информация\\Количество купонов в год",
|
||||
example = "1000"
|
||||
)
|
||||
private Long couponFrequency;
|
||||
private BigDecimal couponFrequency;
|
||||
|
||||
|
||||
|
||||
|
|
@ -327,11 +327,11 @@ public class FondSecurity extends WithMapId {
|
|||
this.couponType = couponType;
|
||||
}
|
||||
|
||||
public Long getCouponFrequency() {
|
||||
public BigDecimal getCouponFrequency() {
|
||||
return couponFrequency;
|
||||
}
|
||||
|
||||
public void setCouponFrequency(Long couponFrequency) {
|
||||
public void setCouponFrequency(BigDecimal couponFrequency) {
|
||||
this.couponFrequency = couponFrequency;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import ru.spcex.platform.enumeration.Section;
|
|||
import ru.spcex.platform.enumeration.Task;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -66,6 +67,7 @@ public class GatewayService extends QueueConsumer implements InitializingBean {
|
|||
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("MEMBER_ON_DEMAND");
|
||||
|
|
@ -89,11 +91,10 @@ public class GatewayService extends QueueConsumer implements InitializingBean {
|
|||
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("ON_DEMAND");
|
||||
// todo здесь возникла проблема: место обработки LOCM одно, но в этом месте могут быть сформированы запросы с разными
|
||||
// section, нужно уточнить как определять какой именно section отправлять в запросе
|
||||
inboundRequest.setSection(Section.FOND.getKey());
|
||||
inboundRequest.setDatetime(Instant.now());
|
||||
HttpEntity<InboundRequest> request = new HttpEntity<>(inboundRequest, httpHeaders);
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ gateway-api.kafka-consumer.auto-offset-reset=latest
|
|||
gateway-api.kafka-consumer.linger-ms=1
|
||||
gateway-api.kafka-consumer.buffer-memory=33554432
|
||||
|
||||
gateway-api.inbound-server.enable-ssl=true
|
||||
gateway-api.inbound-server.enable-ssl=false
|
||||
gateway-api.inbound-server.host=localhost
|
||||
gateway-api.inbound-server.port=9999
|
||||
gateway-api.inbound-server.pathLOCM=/inbound_request
|
||||
gateway-api.inbound-server.pathLOSC=/inbound_request
|
||||
gateway-api.inbound-server.port=8080
|
||||
gateway-api.inbound-server.pathLOCM=test_tomcat9/p1
|
||||
gateway-api.inbound-server.pathLOSC=test_tomcat9/p2
|
||||
|
|
@ -15,9 +15,11 @@ public enum SecuritiesError implements IErrorEnumId {
|
|||
CurrencyAlreadyExists(1015L),
|
||||
CurrencyNotFound(1016L),
|
||||
ListingAlreadyExist(1017L), // Инструмент на режиме %s уже существует
|
||||
ListingNotFound(1017L), // Инструмент на режиме %s не найден
|
||||
ListingNotFound(1018L), // Инструмент на режиме %s не найден
|
||||
MarketNotFound(1020L), // Режим %s не найден
|
||||
ListingOnMMSCreatedBySystem(1021L), // Информиция об инструментах Денежного рынка на режимах добавляется автоматически
|
||||
ListingOnMMSCreatedBySystem(1021L), // Информиция об инструментах Денежного рынка на режимах добавляется автоматически.
|
||||
ListingOnMMSUpdatedBySystem(1022L), // Информиция об инструментах Денежного рынка на режимах изменяется автоматически.
|
||||
ListingOnMMSDeletedBySystem(1023L), // Информиция об инструментах Денежного рынка на режимах блокируется автоматически.
|
||||
;
|
||||
private final Long id;
|
||||
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ public class EquitySecurityService extends QueueConsumer implements Initializing
|
|||
equity.setInstrumentType(req.getInstrumentType());
|
||||
equity.setSecurityId(equity.getId());
|
||||
equity.setCreated(Instant.now());
|
||||
equity.setUpdated(equity.getCreated());
|
||||
try {
|
||||
transaction.beginTransaction();
|
||||
Imdg<EquitySecurity> equityImdg = transaction.getImdg(IMDGDistributedNames.Map_EquitySecurity, EquitySecurity.class);
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ public class FixedIncomeSecurityService extends QueueConsumer implements Initial
|
|||
fixedIncome.setInstrumentType(req.getInstrumentType());
|
||||
fixedIncome.setSecurityId(fixedIncome.getId());
|
||||
fixedIncome.setCreated(Instant.now());
|
||||
fixedIncome.setUpdated(fixedIncome.getCreated());
|
||||
try {
|
||||
transaction.beginTransaction();
|
||||
Imdg<FixedIncomeSecurity> fixedIncomeImdg = transaction.getImdg(IMDGDistributedNames.Map_FixedIncomeSecurity, FixedIncomeSecurity.class);
|
||||
|
|
|
|||
|
|
@ -135,7 +135,9 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial
|
|||
mms.setIssuerId(req.getIssuerId());
|
||||
mms.setSecurityId(mms.getId());
|
||||
mms.setDescription(req.getDescription());
|
||||
mms.setConvention(req.getConvention());
|
||||
mms.setCreated(Instant.now());
|
||||
mms.setUpdated(mms.getCreated());
|
||||
if (req.getWorkflowStatus() == null) {
|
||||
mms.setWorkflowStatus(WorkflowStatus.Active.getKey());
|
||||
} else {
|
||||
|
|
@ -206,6 +208,7 @@ public class MoneyMarketSecurityService extends QueueConsumer implements Initial
|
|||
mms.setIssuerId(req.getIssuerId());
|
||||
mms.setSecurityId(mms.getId());
|
||||
mms.setDescription(req.getDescription());
|
||||
mms.setConvention(req.getConvention());
|
||||
if (req.getWorkflowStatus() != null) {
|
||||
mms.setWorkflowStatus(req.getWorkflowStatus());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,14 +2,15 @@ package ru.spcex.clearing.securities.validation;
|
|||
|
||||
import org.springframework.stereotype.Component;
|
||||
import ru.clearing.classes.statics.data.misc.Listing;
|
||||
import ru.clearing.classes.statics.data.scheduler.PlannerTemplate;
|
||||
import ru.clearing.classes.statics.data.security.Security;
|
||||
import ru.clearing.platform.dictionary.CurrencyCodeDictionary;
|
||||
import ru.clearing.platform.dictionary.WorkflowStatusDictionary;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.PlannerTemplateUpdateRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.securitites.*;
|
||||
import ru.spcex.clearing.util.security.SecuritySelector;
|
||||
import ru.spcex.clearing.securities.errors.SecuritiesError;
|
||||
import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule;
|
||||
import ru.spcex.clearing.validation.common.rules.IdPresentRule;
|
||||
import ru.spcex.clearing.validation.common.rules.SpecialIdPresentRule;
|
||||
import ru.spcex.platform.classes.base.SpcexObjectBase;
|
||||
|
|
@ -31,6 +32,7 @@ import java.util.function.Function;
|
|||
@Component
|
||||
public class ListingValidationProvider {
|
||||
final Imdg<SpcexObjectBase> workflowStatusDictionaryImdg;
|
||||
final Imdg<SpcexObjectBase> currencyCodeDictionaryImdg;
|
||||
final Imdg<Listing> listingImdg;
|
||||
final Imdg<ru.clearing.classes.statics.data.misc.Market> marketImdg;
|
||||
final SecuritySelector securitySelector;
|
||||
|
|
@ -39,6 +41,7 @@ public class ListingValidationProvider {
|
|||
public ListingValidationProvider(ImdgProvider imdgProvider, SecuritySelector securitySelector) {
|
||||
this.securitySelector = securitySelector;
|
||||
this.workflowStatusDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_WorkflowStatusDictionary, SpcexObjectBase.class);
|
||||
this.currencyCodeDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CurrencyCodeDictionary, SpcexObjectBase.class);
|
||||
this.listingImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Listing, Listing.class);
|
||||
this.marketImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Market, ru.clearing.classes.statics.data.misc.Market.class);
|
||||
}
|
||||
|
|
@ -49,6 +52,7 @@ public class ListingValidationProvider {
|
|||
ImdgValidationContext<ListingNewRequest> context = new ImdgValidationContext<>();
|
||||
context.setValidatedObject(listingRequest);
|
||||
context.addImdg(IMDGDistributedNames.Map_WorkflowStatusDictionary, workflowStatusDictionaryImdg);
|
||||
context.addImdg(IMDGDistributedNames.Map_CurrencyCodeDictionary, currencyCodeDictionaryImdg);
|
||||
context.addImdg(IMDGDistributedNames.Map_Market, marketImdg);
|
||||
context.addImdg(IMDGDistributedNames.Map_Listing, listingImdg);
|
||||
return new ValidatorImpl<ImdgValidationContext<ListingNewRequest>>(context,
|
||||
|
|
@ -62,6 +66,16 @@ public class ListingValidationProvider {
|
|||
SecuritiesError.RequiredFieldIsEmpty, SecuritiesError.MarketNotFound,
|
||||
true
|
||||
),
|
||||
DictionaryPresentRule.instance("tradingCurrency", ListingNewRequest::getTradingCurrency,
|
||||
IMDGDistributedNames.Map_CurrencyCodeDictionary, CurrencyCodeDictionary.class,
|
||||
SecuritiesError.RequiredFieldIsEmpty, SecuritiesError.WrongFieldValue,
|
||||
false
|
||||
),
|
||||
DictionaryPresentRule.instance("workflowStatus", ListingNewRequest::getWorkflowStatus,
|
||||
IMDGDistributedNames.Map_WorkflowStatusDictionary, WorkflowStatusDictionary.class,
|
||||
SecuritiesError.RequiredFieldIsEmpty, SecuritiesError.WrongFieldValue,
|
||||
false
|
||||
),
|
||||
new NotSameActiveListing<>(ListingNewRequest::getSecurityId, ListingNewRequest::getMarket)
|
||||
);
|
||||
};
|
||||
|
|
@ -72,12 +86,23 @@ public class ListingValidationProvider {
|
|||
ImdgValidationContext<ListingUpdateRequest> context = new ImdgValidationContext<>();
|
||||
context.setValidatedObject(mmsRequest);
|
||||
context.addImdg(IMDGDistributedNames.Map_WorkflowStatusDictionary, workflowStatusDictionaryImdg);
|
||||
context.addImdg(IMDGDistributedNames.Map_CurrencyCodeDictionary, currencyCodeDictionaryImdg);
|
||||
context.addImdg(IMDGDistributedNames.Map_Listing, listingImdg);
|
||||
return new ValidatorImpl<>(context,
|
||||
new PresentById(IMDGDistributedNames.Map_Listing, SecuritiesError.ListingNotFound, true),
|
||||
new SecurityIdPresentRule<ListingUpdateRequest>("securityId", ListingUpdateRequest::getSecurityId,
|
||||
(Security security) ->
|
||||
InstrumentType.RATE.equalsByKey(security.getInstrumentType()) ? SecuritiesError.ListingOnMMSCreatedBySystem : null
|
||||
InstrumentType.RATE.equalsByKey(security.getInstrumentType()) ? SecuritiesError.ListingOnMMSUpdatedBySystem : null
|
||||
),
|
||||
DictionaryPresentRule.instance("tradingCurrency", ListingUpdateRequest::getTradingCurrency,
|
||||
IMDGDistributedNames.Map_CurrencyCodeDictionary, CurrencyCodeDictionary.class,
|
||||
SecuritiesError.RequiredFieldIsEmpty, SecuritiesError.WrongFieldValue,
|
||||
false
|
||||
),
|
||||
DictionaryPresentRule.instance("workflowStatus", ListingUpdateRequest::getWorkflowStatus,
|
||||
IMDGDistributedNames.Map_WorkflowStatusDictionary, WorkflowStatusDictionary.class,
|
||||
SecuritiesError.RequiredFieldIsEmpty, SecuritiesError.WrongFieldValue,
|
||||
false
|
||||
)
|
||||
);
|
||||
};
|
||||
|
|
@ -102,7 +127,7 @@ public class ListingValidationProvider {
|
|||
Security security = securitySelector.selectSecurityById(listing.getSecurityId());
|
||||
if (security != null) {
|
||||
if (InstrumentType.RATE.equalsByKey(security.getInstrumentType()))
|
||||
return SecuritiesError.ListingOnMMSCreatedBySystem;
|
||||
return SecuritiesError.ListingOnMMSDeletedBySystem;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,10 +18,12 @@ import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
|||
import ru.spcex.clearing.securities.config.ErrorResolverConfig;
|
||||
import ru.spcex.clearing.securities.config.ValidationConfig;
|
||||
import ru.spcex.clearing.securities.service.cud.*;
|
||||
import ru.spcex.clearing.securities.validation.ListingValidationProvider;
|
||||
import ru.spcex.clearing.securities.validation.ValidationProvider;
|
||||
import ru.spcex.clearing.test.MatcherFactory;
|
||||
import ru.spcex.clearing.test.config.ImdgTestConfig;
|
||||
import ru.spcex.clearing.test.config.KafkaTestConfig;
|
||||
import ru.spcex.clearing.util.security.SecuritySelector;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
|
||||
|
|
@ -37,7 +39,8 @@ import static ru.spcex.clearing.test.config.ImdgTestConfig.waitAvailableImdgProv
|
|||
EquitySecurityService.class,
|
||||
FixedIncomeSecurityService.class,
|
||||
MoneyMarketSecurityService.class,
|
||||
ListingService.class,
|
||||
ListingService.class, ListingValidationProvider.class,
|
||||
SecuritySelector.class,
|
||||
ImdgTestConfig.class,
|
||||
KafkaTestConfig.class,
|
||||
ValidationProvider.class,
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ class MoneyMarketSecurityFactory {
|
|||
private String fullName = "estat";
|
||||
private String shortName = "esasdftat";
|
||||
private String securitySymbol = "sdfafd";
|
||||
private String convention = "convention";
|
||||
private String istin = "istin";
|
||||
private String termType = AbstractServiceTest.termType;
|
||||
|
||||
|
|
@ -106,6 +107,7 @@ class MoneyMarketSecurityFactory {
|
|||
moneyMarketSecurity.setDescription(description);
|
||||
moneyMarketSecurity.setLotSize(lotSize);
|
||||
moneyMarketSecurity.setSecuritySymbol(securitySymbol);
|
||||
moneyMarketSecurity.setConvention(convention);
|
||||
moneyMarketSecurity.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey());
|
||||
|
||||
return moneyMarketSecurity;
|
||||
|
|
@ -131,6 +133,7 @@ class MoneyMarketSecurityFactory {
|
|||
moneyMarketSecurityUpdateRequest.setIssuerId(issuerId);
|
||||
moneyMarketSecurityUpdateRequest.setDescription(description);
|
||||
moneyMarketSecurityUpdateRequest.setSecuritySymbol(securitySymbol);
|
||||
moneyMarketSecurityUpdateRequest.setConvention(convention);
|
||||
moneyMarketSecurityUpdateRequest.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey());
|
||||
|
||||
return moneyMarketSecurityUpdateRequest;
|
||||
|
|
@ -160,6 +163,7 @@ class MoneyMarketSecurityFactory {
|
|||
keyRequest.setIsin(istin);
|
||||
keyRequest.setDescription(description);
|
||||
keyRequest.setSecuritySymbol(securitySymbol);
|
||||
keyRequest.setConvention(convention);
|
||||
keyRequest.setWorkflowStatus(ru.spcex.platform.enumeration.Status.Active.getKey());
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,13 +3,23 @@ package ru.spcex.clearing.utility.config;
|
|||
import org.apache.kafka.clients.consumer.Consumer;
|
||||
import org.apache.kafka.clients.producer.Producer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.kafka.core.KafkaTemplate;
|
||||
import org.springframework.kafka.core.ProducerFactory;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.config.KafkaConsumerFactory;
|
||||
import ru.spcex.clearing.platform.messaging.config.KafkaProducerFactory;
|
||||
import ru.spcex.clearing.platform.messaging.config.element.KafkaProducerSettings;
|
||||
import ru.spcex.clearing.platform.messaging.service.RequestInfo;
|
||||
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
|
||||
import ru.spcex.clearing.utility.config.settings.UtilityServiceSettings;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgId;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
|
||||
@Configuration
|
||||
public class KafkaConfig {
|
||||
|
|
@ -26,4 +36,30 @@ public class KafkaConfig {
|
|||
return KafkaProducerFactory.producer(settings.getKafkaProducer());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ProducerFactory<String, Object> pf(UtilityServiceSettings settings) {
|
||||
KafkaProducerSettings kafkaSettings = settings.getKafkaProducer();
|
||||
return KafkaProducerFactory.producerFactory(kafkaSettings);
|
||||
}
|
||||
|
||||
@Bean("kafkaTemplate")
|
||||
public KafkaTemplate<String, Object> kafkaTemplate(ProducerFactory<String, Object> pf) {
|
||||
return new KafkaTemplate<>(pf);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
@Bean
|
||||
public KafkaSender kafkaSender(@Qualifier("kafkaTemplate") KafkaTemplate<String, Object> kafkaTemplate,
|
||||
ImdgProvider imdgProvider) {
|
||||
ImdgId imdgIdGenerator = imdgProvider.getImdgIdGenerator();
|
||||
return KafkaSender
|
||||
.setup()
|
||||
.setKafkaTemplate(kafkaTemplate)
|
||||
.idGenerator(imdgIdGenerator::nextId)
|
||||
.imdgProvider(s -> {
|
||||
Imdg<RequestInfo> imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_RequestInfo, RequestInfo.class);
|
||||
return imdg::insert;
|
||||
})
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,102 @@
|
|||
package ru.spcex.clearing.utility.service;
|
||||
|
||||
import org.apache.kafka.clients.consumer.Consumer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.clearing.classes.statics.data.misc.Notification;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.utilities.NotificationFeedbackRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.utilities.NotificationNewRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.utilities.NotificationUpdateRequest;
|
||||
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
|
||||
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
|
||||
import static ru.spcex.clearing.platform.messaging.domain.Consts.*;
|
||||
import static ru.spcex.platform.enumeration.NotificationStatus.PEND;
|
||||
import static ru.spcex.platform.enumeration.ObjectType.statement;
|
||||
|
||||
@Service
|
||||
public class NotificationService extends QueueConsumer implements InitializingBean {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
private final Imdg<Notification> notificationMap;
|
||||
private final KafkaSender kafkaSender;
|
||||
|
||||
@Autowired
|
||||
public NotificationService(Consumer<String, Object> kafkaQueue,
|
||||
ImdgProvider imdgProvider,
|
||||
KafkaSender kafkaSender) {
|
||||
super(kafkaQueue);
|
||||
this.notificationMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Notification, Notification.class);
|
||||
this.kafkaSender = kafkaSender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
callback(NotificationNewRequest.class)
|
||||
.setConsumer(this::notificationNewRequest)
|
||||
.forDestination(NOTIFICATION_NEW, callbacks::put);
|
||||
callback(NotificationUpdateRequest.class)
|
||||
.setConsumer(this::notificationUpdateRequest)
|
||||
.forDestination(NOTIFICATION_UPDATE, callbacks::put);
|
||||
init();
|
||||
}
|
||||
|
||||
private void notificationNewRequest(BaseRequest<NotificationNewRequest> notificationNewRequestBaseRequest) {
|
||||
log.info("Starting notificationNewRequest processing...");
|
||||
NotificationNewRequest request = notificationNewRequestBaseRequest.getRequestPayload();
|
||||
Notification notification = notificationBuilderFromNotificationNewRequest(request);
|
||||
notificationMap.insert(notification);
|
||||
log.info("NotificationNewRequest successfully processed! Generated id:\t{}", notification.getId());
|
||||
}
|
||||
|
||||
private void notificationUpdateRequest(BaseRequest<NotificationUpdateRequest> notificationUpdateRequestBaseRequest) {
|
||||
NotificationUpdateRequest request = notificationUpdateRequestBaseRequest.getRequestPayload();
|
||||
Long id = request.getId();
|
||||
log.info("Starting notificationUpdateRequest processing by id: {} ...", id);
|
||||
Notification notification = notificationMap.getSingleObjectByID(id);
|
||||
if (notification == null) {
|
||||
throw new NullPointerException("Notification by id:{" + id + "} is null!");
|
||||
}
|
||||
notification.setNotificationStatus(request.getNotificationStatus());
|
||||
notification.setUpdated(Instant.now());
|
||||
notificationMap.update(notification);
|
||||
sendFeedbackString(notification.getObjectType(), notification.getNotificationStatus());
|
||||
log.info("NotificationUpdateRequest successfully processed!");
|
||||
}
|
||||
|
||||
private Notification notificationBuilderFromNotificationNewRequest(NotificationNewRequest request) {
|
||||
Notification notification = new Notification();
|
||||
notification.setClearingDate(LocalDate.now());
|
||||
notification.setSenderId(request.getSenderId());
|
||||
notification.setAddresseeId(request.getAddresseeId());
|
||||
notification.setObjectType(request.getObjectType());
|
||||
notification.setObjectId(request.getObjectId());
|
||||
notification.setNotificationStatus(PEND.getKey());
|
||||
notification.setCreated(Instant.now());
|
||||
notification.setUpdated(Instant.now());
|
||||
return notification;
|
||||
}
|
||||
|
||||
private void sendFeedbackString(String objectType, String status) {
|
||||
if (objectType.equalsIgnoreCase(statement.getKey())) {
|
||||
kafkaSender.sendRequestToQueue(CLEARING_NOTIFICATION_FEEDBACK, buildFeedbackRequest(status));
|
||||
} else {
|
||||
log.warn("Unsupported notification type {}", objectType);
|
||||
}
|
||||
}
|
||||
|
||||
private NotificationFeedbackRequest buildFeedbackRequest(String status) {
|
||||
NotificationFeedbackRequest request = new NotificationFeedbackRequest();
|
||||
request.setNotificationStatus(status);
|
||||
return request;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package ru.spcex.platform.enumeration;
|
||||
|
||||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
|
||||
public enum NotificationStatus implements IEnumKey {
|
||||
PEND("PEND"),
|
||||
CNCL("CNCL"),
|
||||
ACPT("ACPT"),
|
||||
READ("READ");
|
||||
|
||||
private final String key;
|
||||
|
||||
NotificationStatus(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
|
@ -14,4 +14,94 @@ public record RegistryTradingParams(RegistryDesignation registryDesignation,
|
|||
return isEqualDesignation && isEqualInstrumentType && isEqualCapacity && isEqualUnit;
|
||||
}
|
||||
|
||||
public final static RegistryTradingParams OS_T;
|
||||
public final static RegistryTradingParams OM_T;
|
||||
public final static RegistryTradingParams TS_T;
|
||||
public final static RegistryTradingParams TM_T;
|
||||
public final static RegistryTradingParams DM_X;
|
||||
public final static RegistryTradingParams DM_T;
|
||||
public final static RegistryTradingParams AM_F;
|
||||
public final static RegistryTradingParams AM_T;
|
||||
public final static RegistryTradingParams AM_B;
|
||||
public final static RegistryTradingParams AS_T;
|
||||
public final static RegistryTradingParams AS_B;
|
||||
public final static RegistryTradingParams AS_F;
|
||||
public final static RegistryTradingParams CM_T;
|
||||
public final static RegistryTradingParams LM_T;
|
||||
public final static RegistryTradingParams CS_T;
|
||||
public final static RegistryTradingParams LS_T;
|
||||
public final static RegistryTradingParams L__T;
|
||||
|
||||
static {
|
||||
OS_T = new RegistryTradingParams(RegistryDesignation.O,
|
||||
RegistryInstrumentType.S,
|
||||
null,
|
||||
RegistryUnit.T);
|
||||
OM_T = new RegistryTradingParams(RegistryDesignation.O,
|
||||
RegistryInstrumentType.M,
|
||||
null,
|
||||
RegistryUnit.T);
|
||||
TS_T = new RegistryTradingParams(RegistryDesignation.T,
|
||||
RegistryInstrumentType.S,
|
||||
null,
|
||||
RegistryUnit.T);
|
||||
|
||||
TM_T = new RegistryTradingParams(RegistryDesignation.T,
|
||||
RegistryInstrumentType.M,
|
||||
null,
|
||||
RegistryUnit.T);
|
||||
DM_X = new RegistryTradingParams(RegistryDesignation.D,
|
||||
RegistryInstrumentType.M,
|
||||
null,
|
||||
RegistryUnit.X);
|
||||
DM_T = new RegistryTradingParams(RegistryDesignation.D,
|
||||
RegistryInstrumentType.M,
|
||||
null,
|
||||
RegistryUnit.T);
|
||||
AM_F = new RegistryTradingParams(RegistryDesignation.A,
|
||||
RegistryInstrumentType.M,
|
||||
null,
|
||||
RegistryUnit.F);
|
||||
AM_T = new RegistryTradingParams(RegistryDesignation.A,
|
||||
RegistryInstrumentType.M,
|
||||
null,
|
||||
RegistryUnit.T);
|
||||
AM_B = new RegistryTradingParams(RegistryDesignation.A,
|
||||
RegistryInstrumentType.M,
|
||||
null,
|
||||
RegistryUnit.B);
|
||||
AS_T = new RegistryTradingParams(RegistryDesignation.A,
|
||||
RegistryInstrumentType.S,
|
||||
null,
|
||||
RegistryUnit.T);
|
||||
AS_B = new RegistryTradingParams(RegistryDesignation.A,
|
||||
RegistryInstrumentType.S,
|
||||
null,
|
||||
RegistryUnit.B);
|
||||
AS_F = new RegistryTradingParams(RegistryDesignation.A,
|
||||
RegistryInstrumentType.S,
|
||||
null,
|
||||
RegistryUnit.F);
|
||||
CM_T = new RegistryTradingParams(RegistryDesignation.C,
|
||||
RegistryInstrumentType.M,
|
||||
null,
|
||||
RegistryUnit.T);
|
||||
LM_T = new RegistryTradingParams(RegistryDesignation.L,
|
||||
RegistryInstrumentType.M,
|
||||
null,
|
||||
RegistryUnit.T);
|
||||
CS_T = new RegistryTradingParams(RegistryDesignation.C,
|
||||
RegistryInstrumentType.S,
|
||||
null,
|
||||
RegistryUnit.T);
|
||||
LS_T = new RegistryTradingParams(RegistryDesignation.L,
|
||||
RegistryInstrumentType.S,
|
||||
null,
|
||||
RegistryUnit.T);
|
||||
L__T = new RegistryTradingParams(RegistryDesignation.L,
|
||||
null,
|
||||
null,
|
||||
RegistryUnit.T);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ public interface Consts {
|
|||
String DESTINATION_PLANNER_UPDATE = "planner-update";
|
||||
String DESTINATION_PLANNER_DELETE = "planner-delete";
|
||||
|
||||
String DESTINATION_COMPANY_MULTIREQUEST = "company-multirequest-new";
|
||||
String DESTINATION_COMPANY_NEW = "company-new";
|
||||
String DESTINATION_COMPANY_DELETE = "company-delete";
|
||||
String DESTINATION_COMPANY_UPDATE = "company-update";
|
||||
|
|
@ -104,6 +105,11 @@ public interface Consts {
|
|||
String DESTINATION_TRADING_CLEARING_REGISTRY_UPDATE = "trading-clearing-registry-update";
|
||||
String DESTINATION_TRADING_CLEARING_REGISTRY_BLOCK = "trading-clearing-registry-block";
|
||||
|
||||
String CLEARING_NOTIFICATION_FEEDBACK = "clearing-notification-feedback";
|
||||
String NOTIFICATION_NEW = "notification-new";
|
||||
String NOTIFICATION_UPDATE = "notification-update";
|
||||
|
||||
|
||||
String DESTINATION_SDF08_NEW = "s-df-08-new";
|
||||
String DESTINATION_SDF02_NEW = "s-df-02-new";
|
||||
|
||||
|
|
@ -139,7 +145,7 @@ public interface Consts {
|
|||
String BALANCE_ACCOUNT_UPDATE = "balance-account-update";
|
||||
String CONTINUE_CLEARING = "continue-clearing";
|
||||
String LAUNCHER_NEW = "launcher-new";
|
||||
String NOTIFICATION_NEW = "notification-new";
|
||||
|
||||
|
||||
String REQUEST_INFO_UPDATE = "request-info-update";
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
package ru.spcex.clearing.platform.messaging.domain.cud.company;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.account.ClientCodeNewRequest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MultiCompanyRequest {
|
||||
@JsonProperty
|
||||
String uuid; // для лога
|
||||
|
||||
@JsonProperty
|
||||
CompanyNewRequest company;
|
||||
@JsonProperty
|
||||
CompanyInfoUpdateRequest companyInfo;
|
||||
@JsonProperty
|
||||
List<ProfileDocumentNewRequest> profileDocuments = new ArrayList<>();
|
||||
@JsonProperty
|
||||
List<CompanySymbolNewRequest> companySymbols = new ArrayList<>();
|
||||
@JsonProperty
|
||||
List<ContactNewRequest> contacts = new ArrayList<>();
|
||||
@JsonProperty
|
||||
List<ClientCodeNewRequest> clientCodes = new ArrayList<>();
|
||||
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public void setUuid(String uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
public CompanyNewRequest getCompany() {
|
||||
return company;
|
||||
}
|
||||
|
||||
public void setCompany(CompanyNewRequest company) {
|
||||
this.company = company;
|
||||
}
|
||||
|
||||
public CompanyInfoUpdateRequest getCompanyInfo() {
|
||||
return companyInfo;
|
||||
}
|
||||
|
||||
public void setCompanyInfo(CompanyInfoUpdateRequest companyInfo) {
|
||||
this.companyInfo = companyInfo;
|
||||
}
|
||||
|
||||
public List<ProfileDocumentNewRequest> getProfileDocuments() {
|
||||
return profileDocuments;
|
||||
}
|
||||
|
||||
public void setProfileDocuments(List<ProfileDocumentNewRequest> profileDocuments) {
|
||||
this.profileDocuments = profileDocuments;
|
||||
}
|
||||
|
||||
public List<CompanySymbolNewRequest> getCompanySymbols() {
|
||||
return companySymbols;
|
||||
}
|
||||
|
||||
public void setCompanySymbols(List<CompanySymbolNewRequest> companySymbols) {
|
||||
this.companySymbols = companySymbols;
|
||||
}
|
||||
|
||||
public List<ContactNewRequest> getContacts() {
|
||||
return contacts;
|
||||
}
|
||||
|
||||
public void setContacts(List<ContactNewRequest> contacts) {
|
||||
this.contacts = contacts;
|
||||
}
|
||||
|
||||
public List<ClientCodeNewRequest> getClientCodes() {
|
||||
return clientCodes;
|
||||
}
|
||||
|
||||
public void setClientCodes(List<ClientCodeNewRequest> clientCodes) {
|
||||
this.clientCodes = clientCodes;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package ru.spcex.clearing.platform.messaging.domain.cud.utilities;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
|
||||
public class NotificationFeedbackRequest {
|
||||
@JsonProperty
|
||||
public String notificationStatus;
|
||||
|
||||
public String getNotificationStatus() {
|
||||
return notificationStatus;
|
||||
}
|
||||
|
||||
public void setNotificationStatus(String notificationStatus) {
|
||||
this.notificationStatus = notificationStatus;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package ru.spcex.clearing.platform.messaging.domain.cud.utilities;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class NotificationUpdateRequest {
|
||||
@JsonProperty
|
||||
public Long id;
|
||||
|
||||
@JsonProperty
|
||||
public String notificationStatus;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getNotificationStatus() {
|
||||
return notificationStatus;
|
||||
}
|
||||
|
||||
public void setNotificationStatus(String notificationStatus) {
|
||||
this.notificationStatus = notificationStatus;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue