шаг 7 для SecondaryAuctionT0 сессии: создание paymentInstruction по ASB/AMB регистрам

This commit is contained in:
etreschenkov 2023-07-31 13:20:52 +03:00
parent a9c9f1d47f
commit cec22d06f8
3 changed files with 545 additions and 22 deletions

View file

@ -0,0 +1,196 @@
package ru.spcex.clearing.service.builder;
import org.apache.commons.lang3.StringUtils;
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.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.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 PaymentInstructionBuilderV2 {
private final static Logger log = LoggerFactory.getLogger(PaymentInstructionBuilderV2.class);
private Registry registry;
private ImdgProvider imdgProvider;
private Imdg<Company> companyImdg;
private Imdg<CompanySymbols> companySymbolsImdg;
private Long sessionId;
private BigDecimal amount;
private Account creditLegAccount;
private Account debitLegAccount;
private String purpose;
protected LocalDate documentNumberResetAt;
protected AtomicLong documentNumberId = new AtomicLong(0L); // порядковый номер (сквозной по всем компаниям за день
private static final DateTimeFormatter DATE_FORMATTER_ddMMyy = DateTimeFormatter.ofPattern("ddMMyy");
private Long senderId;
private Long addresseeId;
public static PaymentInstructionBuilderV2 builder(ImdgProvider imdgProvider) {
return new PaymentInstructionBuilderV2(imdgProvider);
}
private PaymentInstructionBuilderV2(ImdgProvider imdgProvider) {
this.imdgProvider = imdgProvider;
this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
this.companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
}
public PaymentInstructionBuilderV2 sessionId(Long sessionId) {
this.sessionId = sessionId;
return this;
}
public PaymentInstructionBuilderV2 registry(Registry registry) {
this.registry = registry;
return this;
}
public PaymentInstructionBuilderV2 amount(BigDecimal amount) {
this.amount = amount;
return this;
}
public PaymentInstructionBuilderV2 creditLegAccount(Account account) {
this.creditLegAccount = account;
return this;
}
public PaymentInstructionBuilderV2 debitLegAccount(Account account) {
this.debitLegAccount = account;
return this;
}
public PaymentInstructionBuilderV2 purpose(String purpose) {
this.purpose = purpose;
return this;
}
public PaymentInstructionBuilderV2 sender(Long senderId) {
this.senderId = senderId;
return this;
}
public PaymentInstructionBuilderV2 addressee(Long addresseeId) {
this.addresseeId = addresseeId;
return this;
}
public PaymentInstruction build() {
Instant now = Instant.now();
PaymentInstruction payment = new PaymentInstruction();
payment.setCreated(now);
payment.setClearingDate(TimeUtil.toLocalDate(now));
payment.setSenderId(senderId);
payment.setAddresseeId(addresseeId);
{
String tranBic = selectSymbolValue(payment.getAddresseeId(), CompanySymbol.BIC);
if (tranBic == null) {
log.warn("CompanySymbols BIC not found for companyId={}", payment.getAddresseeId());
} else {
payment.setAdresseeBic(tranBic);
}
}
{
Company companyPRC = companyImdg.getSingleObjectByID(Sender.Prc.getId()); // 2 "НКО АО ПРЦ"
if (companyPRC == null) {
log.warn("Company.id={} not found", Sender.Prc.getId());
} else {
payment.setPayeeBankName(companyPRC.getShortName());
payment.setAddresseeBankName(companyPRC.getShortName());
}
}
{
String payeeBic = selectSymbolValue(payment.getSenderId(), CompanySymbol.BIC);
if (payeeBic == null) {
log.warn("payeeBic by senderId={} not found", payment.getSenderId());
} else {
payment.setPayeeBic(payeeBic);
}
}
if (registry.getSettlementDate() != null) {
payment.setPaymentDate(TimeUtil.localDateToInstant(registry.getSettlementDate()));
payment.setSettlementDate(registry.getSettlementDate());
} else {
payment.setPaymentDate(Instant.now());
payment.setSettlementDate(LocalDate.now());
}
payment.setPaymentPurpose(purpose);
payment.setCreditLeg_amount(amount);
payment.setDebitLeg_amount(amount);
{
payment.setCreditLeg_accountId(creditLegAccount.getId());
payment.setCreditLeg_account(creditLegAccount.getAccount());
}
payment.setCredit_csAccount(null);
{
payment.setDebitLeg_accountId(debitLegAccount.getId());
payment.setDebitLeg_account(debitLegAccount.getAccount());
}
payment.setDebit_csAccount(null);
payment.setCreditLeg_currencyCode(CurrencyCode.RUB.getKey());
payment.setDebitLeg_currencyCode(CurrencyCode.RUB.getKey());
payment.setTransactionStatus(TransactionStatus.stld.getKey());
payment.setDocumentNumber(nextDocumentNumber(registry, payment));
payment.setCreditLeg_direction(InOutDirection.out.getKey());
payment.setDebitLeg_direction(InOutDirection.in.getKey());
payment.setCreditLeg_securityId(registry.getSecurityId());
payment.setDebitLeg_securityId(registry.getSecurityId());
payment.setSessionId(sessionId);
return payment;
}
protected String nextDocumentNumber(Registry rgs, PaymentInstruction paymentInstruction) {
if (StringUtils.isEmpty(rgs.getContract())) {
return "";
}
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.getFirstObjectByFieldValues(Map.of(
"companyId", companyId,
"companySymbol", symbol.getKey()));
if (cSymbol == null) {
return null;
} else {
return cSymbol.getCompanySymbolValue();
}
}
}

View file

@ -24,7 +24,6 @@ import ru.spcex.platform.utils.enumeration.IMessageResolver;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -41,8 +40,7 @@ public class SecondaryAuctionT0Session extends AbstractSession implements Initia
private final InclusionObligations inclusionObligations; private final InclusionObligations inclusionObligations;
private final InspectionObligations inspectionObligations; private final InspectionObligations inspectionObligations;
private final FormingRegistersOnOS formingRegistersOnOS; private final FormingRegistersOnOS formingRegistersOnOS;
private final FormingPaymentInstructionSecondaryT0 formingPaymentInstruction; private final FormingPaymentInstructionAssets formingPaymentInstructionAssets;
private final FormingPaymentInstructionDealsFinalMkr formingPaymentInstructionDealsFinalMkr;
private final UnlockResources unlockResources; private final UnlockResources unlockResources;
private final FinishingSession finishingSession; private final FinishingSession finishingSession;
private final EndStageNotification endStageNotification; private final EndStageNotification endStageNotification;
@ -59,8 +57,7 @@ public class SecondaryAuctionT0Session extends AbstractSession implements Initia
ObligationAdmission obligationsAdmission, ObligationAdmission obligationsAdmission,
InclusionObligations inclusionObligations, InclusionObligations inclusionObligations,
FormingRegistersOnOS formingRegistersOnOS, FormingRegistersOnOS formingRegistersOnOS,
FormingPaymentInstructionSecondaryT0 formingPaymentInstruction, FormingPaymentInstructionAssets formingPaymentInstructionAssets,
FormingPaymentInstructionDealsFinalMkr formingPaymentInstructionDealsFinalMkr,
UnlockResources unlockResources, UnlockResources unlockResources,
FinishingSession finishingSession, FinishingSession finishingSession,
EndStageNotification endStageNotification, EndStageNotification endStageNotification,
@ -74,13 +71,12 @@ public class SecondaryAuctionT0Session extends AbstractSession implements Initia
this.obligationsAdmission = obligationsAdmission; this.obligationsAdmission = obligationsAdmission;
this.inclusionObligations = inclusionObligations; this.inclusionObligations = inclusionObligations;
this.formingRegistersOnOS = formingRegistersOnOS; this.formingRegistersOnOS = formingRegistersOnOS;
this.formingPaymentInstruction = formingPaymentInstruction; this.formingPaymentInstructionAssets = formingPaymentInstructionAssets;
this.unlockResources = unlockResources; this.unlockResources = unlockResources;
this.finishingSession = finishingSession; this.finishingSession = finishingSession;
this.endStageNotification = endStageNotification; this.endStageNotification = endStageNotification;
this.executionFondImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionFond, ExecutionFond.class); this.executionFondImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionFond, ExecutionFond.class);
this.inspectionObligations = inspectionObligations; this.inspectionObligations = inspectionObligations;
this.formingPaymentInstructionDealsFinalMkr = formingPaymentInstructionDealsFinalMkr;
this.marketCodes = marketCodes; this.marketCodes = marketCodes;
} }
@ -159,25 +155,14 @@ public class SecondaryAuctionT0Session extends AbstractSession implements Initia
payload.setSessionId(currSession.getId()); payload.setSessionId(currSession.getId());
runStage(TaskType.FormingRegistersOnOS, payload, formingRegistersOnOS); //returns Collection<Registry> runStage(TaskType.FormingRegistersOnOS, payload, formingRegistersOnOS); //returns Collection<Registry>
} }
StageResult<Collection<PaymentInstruction>> returnsPayment = null; //stage 7
{
FormingPaymentInstructionDealsMkrPayload payload = new FormingPaymentInstructionDealsMkrPayload();
payload.setSessionId(currSession.getId());
payload.setSendSdfs(false);
payload.setSection(section());
payload.setPaymentInstructionReturns(new ArrayList<>());
//stage 7
returnsPayment = runStage(TaskType.FormingPaymentInstruction, payload, formingPaymentInstructionDealsFinalMkr);
}
StageResult<Collection<PaymentInstruction>> paymentResult = null; StageResult<Collection<PaymentInstruction>> paymentResult = null;
{ {
FormingPaymentInstructionDealsMkrPayload payload = new FormingPaymentInstructionDealsMkrPayload(); FormingPaymentInstructionPayload payload = new FormingPaymentInstructionPayload();
payload.setSessionId(currSession.getId()); payload.setSessionId(currSession.getId());
payload.setPaymentInstructionReturns(returnsPayment.getStageResult()); paymentResult = runStage(TaskType.FormingPaymentInstruction, payload, formingPaymentInstructionAssets);
//stage 7
paymentResult = runStage(TaskType.FormingPaymentInstruction, payload, formingPaymentInstruction);
} }
if (paymentResult != null && paymentResult.getStageResult().isEmpty()) { if (paymentResult != null && paymentResult.getStageResult().isEmpty()) {
runStage(TaskType.FormingPaymentInstruction, balanceRevise); runStage(TaskType.FormingPaymentInstruction, balanceRevise);
// finishPart(req); // finishPart(req);

View file

@ -0,0 +1,342 @@
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.RegistryManager;
import ru.spcex.clearing.service.Sdf03Creator;
import ru.spcex.clearing.service.builder.PaymentInstructionBuilderV2;
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.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.number.BigDecimalUtil;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.*;
import static ru.spcex.platform.enumeration.RegistryTradingParams.*;
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
@Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class FormingPaymentInstructionAssets 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 final Sdf03Creator sdf03Creator;
private KafkaSender kafkaSender;
private final IMessageResolver msgResolver = new SimpleMessageResolver();
private final RegistryManager rgsMng;
@Autowired
public FormingPaymentInstructionAssets(ImdgProvider imdgProvider,
Sdf03Creator sdf03Creator, KafkaSender kafkaSender, RegistryManager rgsMng) {
this.sdf03Creator = sdf03Creator;
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);
this.rgsMng = rgsMng;
}
@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> selectAMBRegistries() {
ImdgPredicateBuilder rgsPb = registryImdg.predicateBuilder();
RegistryCodeSqlBuilder registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(
AM_B
);
ImdgPredicate rgsCodePrdct = rgsPb.sql(registryCodeSqlBuilder.build());
return registryImdg.getCollectionObjectsByPredicate(rgsCodePrdct);
}
private Collection<Registry> selectASBRegistries() {
ImdgPredicateBuilder rgsPb = registryImdg.predicateBuilder();
RegistryCodeSqlBuilder registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(
AS_B
);
ImdgPredicate rgsCodePrdct = rgsPb.sql(registryCodeSqlBuilder.build());
return registryImdg.getCollectionObjectsByPredicate(rgsCodePrdct);
}
private StageResult<?> formingPaymentInstructions(Long sessionId) {
Collection<Registry> AMBregistries = selectAMBRegistries();
log.debug("found AMB registries.size() = {}", AMBregistries.size());
Instant now = Instant.now();
Account tranAcc = accountImdg.getFirstObjectBySQL("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);
}
Account dtrnAcc = accountImdg.getFirstObjectBySQL("accountType = '%s' and status = '%s' and processingSign = '%s'"
.formatted(AccountType.Dtrn.getKey(), AccountStatus.ACTIVE.getKey(), Allowed.ALLOWED.getKey()));
if (dtrnAcc == null) {
return new StageResult<>(
new EnumMessage(ClearingError.AccountNotPresent, "accountType = " + AccountType.Dtrn.getKey()),
false);
}
List<PaymentInstruction> paymentInstructions = new ArrayList<>();
for (Registry registry : AMBregistries) {
//по каждому AMB регистру создаем PaymentInstruction
//проверяем balance посчитанный на шаге 5
if (registry.getBalance().compareTo(BigDecimal.ZERO) == 0) {
log.debug("Skip creating paymentInstruction by registry with 0 balance");
continue;
}
boolean isPositiveBalance = registry.getBalance().compareTo(BigDecimal.ZERO) > 0;
Account counterAcc = null;
if (AccountType.Clrn.equalsByKey(registry.getAccountType())) {
counterAcc = accountImdg.getSingleObjectByID(registry.getAccountId());
} else if (AccountType.Info.equalsByKey(registry.getAccountType())) {
counterAcc = accountImdg.getFirstObjectByFieldValues(
Map.of("companyId", 1L,
"accountType", AccountType.Anlt.getKey())
);
}
Long senderId;
Long addresseeId;
Account debitLegAccount;
Account creditLegAccount;
BigDecimal amount;
if (isPositiveBalance) {
senderId = registry.getCompanyId();
addresseeId = Sender.One.getId();
debitLegAccount = tranAcc;
creditLegAccount = counterAcc;
amount = registry.getBalance() == null ? null : registry.getBalance().abs().negate();
Optional<Registry> payerAmtO = rgsMng.findRelatedAsset(registry.getTradingClearingRegistryId(), registry.getCompanyId(), AM_T);
payerAmtO.ifPresent(amt -> {
amt.setSettledDebit(safeBD(amt.getSettledDebit()).subtract(safeBD(registry.getBalance())));
setUpdatedStoreInImdg(amt, now);
});
} else {
senderId = Sender.One.getId();
addresseeId = registry.getCompanyId();
debitLegAccount = counterAcc;
creditLegAccount = tranAcc;
amount = registry.getBalance() == null ? null : registry.getBalance().abs();
Optional<Registry> payerAmtO = rgsMng.findRelatedAsset(registry.getTradingClearingRegistryId(), registry.getCompanyId(), AM_T);
payerAmtO.ifPresent(amt -> {
amt.setSettledDebit(safeBD(amt.getSettledDebit()).add(safeBD(registry.getBalance())));
setUpdatedStoreInImdg(amt, now);
});
}
PaymentInstructionBuilderV2 paymentInstructionBuilder = PaymentInstructionBuilderV2.builder(imdgProvider)
.registry(registry)
.sender(senderId)
.addressee(addresseeId)
.debitLegAccount(debitLegAccount)
.creditLegAccount(creditLegAccount)
.amount(amount)
.sessionId(sessionId)
.purpose(String.format("Перевод по итогу клиринга по ТКР %s", registry.getTradingClearingRegistry()));
PaymentInstruction paymentInstruction = paymentInstructionBuilder.build();
log.debug("Created paymentInstruction by registry.id: {}", registry.getId());
paymentInstructionImdg.insert(paymentInstruction);
registry.setPaymentId(paymentInstruction.getId());
registry.setUpdated(now);
registryImdg.update(registry);
paymentInstructions.add(paymentInstruction);
}
Collection<Registry> ASBregistries = selectASBRegistries();
log.debug("found ASB registries.size() = {}", ASBregistries.size());
for (Registry registry : ASBregistries) {
//по каждому AMB регистру создаем PaymentInstruction
//проверяем balance посчитанный на шаге 5
if (registry.getBalance().compareTo(BigDecimal.ZERO) == 0) {
log.debug("Skip creating paymentInstruction by registry with 0 balance");
continue;
}
Account counterAcc = accountImdg.getSingleObjectByID(registry.getAccountId());
boolean isPositiveBalance = registry.getBalance().compareTo(BigDecimal.ZERO) > 0;
Long senderId;
Long addresseeId;
Account debitLegAccount;
Account creditLegAccount;
BigDecimal amount;
if (isPositiveBalance) {
senderId = registry.getCompanyId();
addresseeId = Sender.One.getId();
debitLegAccount = dtrnAcc;
creditLegAccount = counterAcc;
amount = registry.getBalance() == null ? null : registry.getBalance().abs();
Optional<Registry> payerAstO = rgsMng.findRelatedAsset(registry.getTradingClearingRegistryId(), registry.getCompanyId(), AS_T);
payerAstO.ifPresent(amt -> {
amt.setSettledDebit(safeBD(amt.getSettledDebit()).subtract(safeBD(registry.getBalance())));
setUpdatedStoreInImdg(amt, now);
});
} else {
senderId = Sender.One.getId();
addresseeId = registry.getCompanyId();
debitLegAccount = counterAcc;
creditLegAccount = dtrnAcc;
amount = registry.getBalance() == null ? null : registry.getBalance().abs();
Optional<Registry> payerAstO = rgsMng.findRelatedAsset(registry.getTradingClearingRegistryId(), registry.getCompanyId(), AS_T);
payerAstO.ifPresent(amt -> {
amt.setSettledDebit(safeBD(amt.getSettledDebit()).add(safeBD(registry.getBalance())));
setUpdatedStoreInImdg(amt, now);
});
}
PaymentInstructionBuilderV2 paymentInstructionBuilder = PaymentInstructionBuilderV2.builder(imdgProvider)
.registry(registry)
.sender(senderId)
.addressee(addresseeId)
.debitLegAccount(debitLegAccount)
.creditLegAccount(creditLegAccount)
.amount(amount)
.sessionId(sessionId)
.purpose(String.format("Перевод по итогу клиринга по ТКР %s", registry.getTradingClearingRegistry()));
PaymentInstruction paymentInstruction = paymentInstructionBuilder.build();
log.debug("Created paymentInstruction by registry.id: {}", registry.getId());
paymentInstructionImdg.insert(paymentInstruction);
registry.setPaymentId(paymentInstruction.getId());
registry.setUpdated(now);
registryImdg.update(registry);
paymentInstructions.add(paymentInstruction);
}
sendSdfs(paymentInstructions);
StageResult<Collection<PaymentInstruction>> stageResult = new StageResult<>(null, true);
stageResult.setStageResult(paymentInstructions);
return stageResult;
}
private void setUpdatedStoreInImdg(Registry rgs, Instant now) {
rgs.setUpdated(now);
registryImdg.update(rgs);
}
private void sendSdfs(List<PaymentInstruction> formedPaymentInstructions) {
List<SDf03> sDf03Created = new ArrayList<>();
List<SDf12> sDf12Created = new ArrayList<>();
for (PaymentInstruction paymentInstruction : formedPaymentInstructions) {
Account account = accountImdg.getSingleObjectByID(paymentInstruction.getCreditLeg_accountId());
Security security = securityImdg.getSingleObjectByID(paymentInstruction.getCreditLeg_securityId());
if (List.of(AccountType.Corr, AccountType.Clrn, AccountType.Tran, AccountType.Anlt, AccountType.Info)
.contains(IEnumKey.getEnumByKey(AccountType.class, account.getAccountType()))) {
//если info подставить anlt (единственный счет в системе)
sDf03Created.add(sdf03Creator.create(paymentInstruction));
} else if (!InstrumentType.CRNC.equalsByKey(security.getInstrumentType()) &&
List.of(AccountType.Depo, AccountType.Dtrn).contains(IEnumKey.getEnumByKey(AccountType.class, 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("transactionNumber", ""));
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 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(BigDecimalUtil.limitDecimalPlaces(paymentInstruction.getCreditLeg_amount().toString(), 2));
sDf12.setSecurityCode(paymentInstruction.getCreditLeg_securityId().toString());
sDf12.setDepoCodeSender(paymentInstruction.getCreditLeg_account());
sDf12.setDepoCodeAdressee(paymentInstruction.getDebitLeg_account());
// sDf12.setTransactionNumber();
sDf12.setGenerationTime(Instant.now());
return sDf12;
}
}