From c99fa30bbd141e8c3a567c46f5844b92166e978d Mon Sep 17 00:00:00 2001 From: ialbert Date: Wed, 7 Jun 2023 15:10:11 +0300 Subject: [PATCH] =?UTF-8?q?=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20PaymentInstruction=20=D0=BF=D1=80=D0=B8=20=D0=BE=D0=B1?= =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=B5=20=D1=81=D0=B4=D0=B5?= =?UTF-8?q?=D0=BB=D0=BE=D0=BA=20=D0=B4=D0=BB=D1=8F=20=D0=B8=D1=82=D0=BE?= =?UTF-8?q?=D0=B3=D0=BE=D0=B2=D0=BE=D0=B9=20=D1=81=D0=B5=D1=81=D1=81=D0=B8?= =?UTF-8?q?=D0=B8=20=D0=9C=D0=9A=D0=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PaymentInstructionBuilderFinalMkr.java | 252 +++++++++++++++ .../session/stage/FinalMkrSession.java | 18 +- ...ormingPaymentInstructionDealsFinalMkr.java | 303 ++++++++++++++++++ .../enumeration/RegistryTradingParams.java | 90 ++++++ 4 files changed, 661 insertions(+), 2 deletions(-) create mode 100644 clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilderFinalMkr.java create mode 100644 clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionDealsFinalMkr.java diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilderFinalMkr.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilderFinalMkr.java new file mode 100644 index 000000000..1cec2ecee --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilderFinalMkr.java @@ -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 accountImdg; + private Imdg companyImdg; + private Imdg companySymbolsImdg; + private Imdg 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 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; + } + +} diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/FinalMkrSession.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/FinalMkrSession.java index e6f066121..4b5096a46 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/FinalMkrSession.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/FinalMkrSession.java @@ -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 executionDepositImdg; private final Supplier> marketCodes; + private final Imdg 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,21 @@ 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()); } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionDealsFinalMkr.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionDealsFinalMkr.java new file mode 100644 index 000000000..ae010368e --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionDealsFinalMkr.java @@ -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 registryImdg; + private Imdg paymentInstructionImdg; + private Imdg securityImdg; + private Imdg accountImdg; + private Imdg companyImdg; + private Imdg sDf03Imdg; + private Imdg 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 selectRegistries() { + ImdgPredicateBuilder rgsPb = registryImdg.predicateBuilder(); + RegistryCodeSqlBuilder registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance( + LM_T, CM_T + ); + ImdgPredicate rgsCodePrdct = rgsPb.sql(registryCodeSqlBuilder.build()); + Collection registries = registryImdg.getCollectionObjectsByPredicate(rgsCodePrdct); + return registries.stream() + .filter(rgs -> Objects.equals(rgs.getValueDate(), rgs.getSettlementDate())) + .collect(Collectors.toList()); + } + /** + * аккаунт-счет с accountType='TRAN' - это счет СПВБ который принадлежит самой бирже
+ * хранят деньги разных участников
+ * в сделке:
+ * регистр CMAT кому переводить (registry.account)
+ * регистр LMAT кто переводит деньги (registry.account)
+ * в итоге создается 2 PaymentInstruction: LMAT -> TRAN счет -> CMAT счет + */ + private StageResult formingPaymentInstructions(Long sessionId) { + Collection registries = selectRegistries(); + log.debug("found registries.size() = {}", registries.size()); + Account tranAcc = accountImdg.getSingleObjectBySQL("accountType = '%s' and status = '%s' and processingSign = '%s'" + .formatted(AccountType.Tran.getKey(), AccountStatus.ACTIVE.getKey(), Allowed.ALLOWED.getKey())); + if (tranAcc == null) { + return new StageResult<>( + new EnumMessage(ClearingError.AccountNotPresent, "accountType = " + AccountType.Tran.getKey()), + false); + } + log.debug("found tranAcc.id = {}", tranAcc.getId()); + Map> groups = registries + .stream() + .collect(Collectors.groupingBy(Registry::getGroupId)); + log.debug("groups.size = {}", groups.size()); + List allPaymentInstructions = new ArrayList<>(); + for (Map.Entry> group : groups.entrySet()) { + Long groupId = group.getKey(); + Function 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 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> stageResult = new StageResult<>(null, true); + stageResult.setStageResult(allPaymentInstructions); + return stageResult; + } + + private void sendSdfs(List formedPaymentInstructions) { + List sDf03Created = new ArrayList<>(); + List sDf12Created = new ArrayList<>(); + for (PaymentInstruction paymentInstruction : formedPaymentInstructions) { + Security security = securityImdg.getSingleObjectByID(paymentInstruction.getCreditLeg_securityId()); + Account account = accountImdg.getSingleObjectByID(paymentInstruction.getCreditLeg_accountId()); + if (InstrumentType.CRNC.equalsByKey(security.getInstrumentType()) && + List.of(AccountType.Corr, AccountType.Clrn).contains(IEnumKey.getEnumByKey(AccountType.class, account.getAccountType()))) { + sDf03Created.add(newSDf03(paymentInstruction)); + } else if (!InstrumentType.CRNC.equalsByKey(security.getInstrumentType()) && + AccountType.Depo.equalsByKey(account.getAccountType())) { + sDf12Created.add(newSDf12(paymentInstruction)); + } + } + + Long sdf03GroupId = !sDf03Created.isEmpty() ? imdgProvider.getImdgIdGenerator().nextId() : null; + for (SDf03 sDf03 : sDf03Created) { + sDf03.setGenerationId(sdf03GroupId); + sDf03Imdg.insert(sDf03); + } + + if (sdf03GroupId != null) { + ExportToFileRequest exportToFileRequest = new ExportToFileRequest(); + exportToFileRequest.setNameOfTable("DF-03"); + exportToFileRequest.setSdfGroupId(sdf03GroupId); + kafkaSender.sendRequestToQueue(Consts.EXPORT_PROCESS, exportToFileRequest); + } + + Long sdf12GroupId = null; + Long maxTxNumber = 1L; + if (!sDf12Created.isEmpty()) { + sdf12GroupId = imdgProvider.getImdgIdGenerator().nextId(); + ImdgPredicateBuilder predicateBuilder = sDf12Imdg.predicateBuilder(); + ImdgPredicate notEmptyTransactionNum = predicateBuilder.not(predicateBuilder.equals("transaction_number", "")); + Long maxId = sDf12Imdg.aggregateLongMax("id", notEmptyTransactionNum); + if (maxId != null) { + SDf12 sDf12 = sDf12Imdg.getSingleObjectByID(maxId); + maxTxNumber = Long.parseLong(sDf12.getTransactionNumber()) + 1; + } + } + for (SDf12 sDf12 : sDf12Created) { + sDf12.setGenerationId(sdf03GroupId); + sDf12.setTransactionNumber(maxTxNumber.toString()); + sDf12.setTransactionQuantity(String.valueOf(sDf12Created.size())); + sDf12Imdg.insert(sDf12); + } + + if (sdf12GroupId != null) { + SwtExporterRequest swtExporterRequest = new SwtExporterRequest(); + swtExporterRequest.setType("SDF_12"); + kafkaSender.sendRequestToQueue(Consts.SWT_EXPORTER, swtExporterRequest); + } + } + + private 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()) + ); + + } +} diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/RegistryTradingParams.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/RegistryTradingParams.java index 8be105014..a9594b124 100644 --- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/RegistryTradingParams.java +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/RegistryTradingParams.java @@ -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); + } + }