forming payment instructions by money AM*B registers
This commit is contained in:
parent
0c0bc7d910
commit
122e5f9d26
5 changed files with 389 additions and 98 deletions
|
|
@ -0,0 +1,90 @@
|
||||||
|
package ru.spcex.clearing.service;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import ru.clearing.classes.statics.data.account.Account;
|
||||||
|
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
|
||||||
|
import ru.clearing.classes.statics.data.sdf.SDf12;
|
||||||
|
import ru.clearing.classes.statics.data.security.Security;
|
||||||
|
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||||
|
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.SecuritySelector;
|
||||||
|
import ru.spcex.platform.utils.number.BigDecimalUtil;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class Sdf12Creator {
|
||||||
|
private Logger log = LoggerFactory.getLogger(getClass());
|
||||||
|
private final ImdgId idGenerator;
|
||||||
|
private final SecuritySelector<Security> securitySelector;
|
||||||
|
private final Imdg<SDf12> sDf12Imdg;
|
||||||
|
|
||||||
|
public Sdf12Creator(ImdgProvider imdgProvider) {
|
||||||
|
this.idGenerator = imdgProvider.getImdgIdGenerator();
|
||||||
|
this.securitySelector = new SecuritySelector<>(imdgProvider, Security.class);
|
||||||
|
this.sDf12Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf12, SDf12.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SDf12 create(PaymentInstruction paymentInstruction, Account dtrnAcc) {
|
||||||
|
log.debug("creating sdf12");
|
||||||
|
SDf12 sDf12 = new SDf12();
|
||||||
|
if (Objects.equals(paymentInstruction.getDebitLeg_accountId(), dtrnAcc.getId())) {
|
||||||
|
sDf12.setDirection("RECFREE");
|
||||||
|
sDf12.setDepoCodeSender(paymentInstruction.getDebitLeg_account());
|
||||||
|
sDf12.setDepoCodeAdressee(paymentInstruction.getCreditLeg_account());
|
||||||
|
} else if (Objects.equals(paymentInstruction.getCreditLeg_accountId(), dtrnAcc.getId())) {
|
||||||
|
sDf12.setDirection("DELFREE");
|
||||||
|
sDf12.setDepoCodeSender(paymentInstruction.getCreditLeg_account());
|
||||||
|
sDf12.setDepoCodeAdressee(paymentInstruction.getDebitLeg_account());
|
||||||
|
}
|
||||||
|
sDf12.setId(idGenerator.nextId());
|
||||||
|
sDf12.setOutDocument(sDf12.getId().toString());
|
||||||
|
sDf12.setQuantity(BigDecimalUtil.limitDecimalPlaces(paymentInstruction.getCreditLeg_amount().toString(), 2));
|
||||||
|
Security security = securitySelector.selectSecurityById(paymentInstruction.getCreditLeg_securityId());
|
||||||
|
if (security != null) {
|
||||||
|
sDf12.setSecurityCode(security.getSecuritySymbol());
|
||||||
|
}
|
||||||
|
// sDf12.setTransactionNumber();
|
||||||
|
sDf12.setGenerationTime(Instant.now());
|
||||||
|
return sDf12;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public SDf12 createWithoutIntermediate(PaymentInstruction paymentInstruction) {
|
||||||
|
log.debug("creating sdf12");
|
||||||
|
SDf12 sDf12 = new SDf12(); //todo remove
|
||||||
|
sDf12.setId(idGenerator.nextId());
|
||||||
|
sDf12.setOutDocument(sDf12.getId().toString());
|
||||||
|
sDf12.setDirection("DELFREE");
|
||||||
|
sDf12.setQuantity(BigDecimalUtil.limitDecimalPlaces(paymentInstruction.getCreditLeg_amount().toString(), 2));
|
||||||
|
Security security = securitySelector.selectSecurityById(paymentInstruction.getCreditLeg_securityId());
|
||||||
|
if (security != null) {
|
||||||
|
sDf12.setSecurityCode(security.getSecuritySymbol());
|
||||||
|
}
|
||||||
|
sDf12.setDepoCodeSender(paymentInstruction.getCreditLeg_account());
|
||||||
|
sDf12.setDepoCodeAdressee(paymentInstruction.getDebitLeg_account());
|
||||||
|
// sDf12.setTransactionNumber();
|
||||||
|
sDf12.setGenerationTime(Instant.now());
|
||||||
|
return sDf12;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Long maxTxNumber() {
|
||||||
|
long maxTxNumber = 1L;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
return maxTxNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -39,7 +39,7 @@ public class PrimaryAuctionB0Session extends AbstractSession implements Initiali
|
||||||
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 FormingPaymentInstructionAssets formingPaymentInstruction;
|
private final FormingPaymentInstructionSecurities formingPaymentInstruction;
|
||||||
//TODO CLRNWORM
|
//TODO CLRNWORM
|
||||||
//private final FormingPaymentInstructionDealsFinalMkr formingPaymentInstructionDealsFinalMkr;
|
//private final FormingPaymentInstructionDealsFinalMkr formingPaymentInstructionDealsFinalMkr;
|
||||||
private final UnlockResources unlockResources;
|
private final UnlockResources unlockResources;
|
||||||
|
|
@ -61,7 +61,7 @@ public class PrimaryAuctionB0Session extends AbstractSession implements Initiali
|
||||||
ObligationAdmission obligationsAdmission,
|
ObligationAdmission obligationsAdmission,
|
||||||
InclusionObligations inclusionObligations,
|
InclusionObligations inclusionObligations,
|
||||||
FormingRegistersOnOS formingRegistersOnOS,
|
FormingRegistersOnOS formingRegistersOnOS,
|
||||||
FormingPaymentInstructionAssets formingPaymentInstruction,
|
FormingPaymentInstructionSecurities formingPaymentInstruction,
|
||||||
// FormingPaymentInstructionDealsFinalMkr formingPaymentInstructionDealsFinalMkr,
|
// FormingPaymentInstructionDealsFinalMkr formingPaymentInstructionDealsFinalMkr,
|
||||||
UnlockResources unlockResources,
|
UnlockResources unlockResources,
|
||||||
FinishingSession finishingSession,
|
FinishingSession finishingSession,
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ public class PrimaryAuctionBnSession extends AbstractSession implements Initiali
|
||||||
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 FormingPaymentInstructionAssets formingPaymentInstructionAssets;
|
private final FormingPaymentInstructionSecurities formingPaymentInstruction;
|
||||||
// private final FormingPaymentInstruction formingPaymentInstruction;
|
// private final FormingPaymentInstruction formingPaymentInstruction;
|
||||||
// private final FormingPaymentInstructionDealsFinalMkr formingPaymentInstructionDealsFinalMkr;
|
// private final FormingPaymentInstructionDealsFinalMkr formingPaymentInstructionDealsFinalMkr;
|
||||||
private final UnlockResources unlockResources;
|
private final UnlockResources unlockResources;
|
||||||
|
|
@ -63,7 +63,7 @@ public class PrimaryAuctionBnSession extends AbstractSession implements Initiali
|
||||||
FormingRegistersOnOS formingRegistersOnOS,
|
FormingRegistersOnOS formingRegistersOnOS,
|
||||||
// FormingPaymentInstruction formingPaymentInstruction,
|
// FormingPaymentInstruction formingPaymentInstruction,
|
||||||
// FormingPaymentInstructionDealsFinalMkr formingPaymentInstructionDealsFinalMkr,
|
// FormingPaymentInstructionDealsFinalMkr formingPaymentInstructionDealsFinalMkr,
|
||||||
FormingPaymentInstructionAssets formingPaymentInstructionAssets, UnlockResources unlockResources,
|
FormingPaymentInstructionSecurities formingPaymentInstruction, UnlockResources unlockResources,
|
||||||
FinishingSession finishingSession,
|
FinishingSession finishingSession,
|
||||||
EndStageNotification endStageNotification,
|
EndStageNotification endStageNotification,
|
||||||
IMessageResolver messageResolver,
|
IMessageResolver messageResolver,
|
||||||
|
|
@ -76,7 +76,7 @@ public class PrimaryAuctionBnSession extends AbstractSession implements Initiali
|
||||||
this.obligationsAdmission = obligationsAdmission;
|
this.obligationsAdmission = obligationsAdmission;
|
||||||
this.inclusionObligations = inclusionObligations;
|
this.inclusionObligations = inclusionObligations;
|
||||||
this.formingRegistersOnOS = formingRegistersOnOS;
|
this.formingRegistersOnOS = formingRegistersOnOS;
|
||||||
this.formingPaymentInstructionAssets = formingPaymentInstructionAssets;
|
this.formingPaymentInstruction = formingPaymentInstruction;
|
||||||
// this.formingPaymentInstruction = formingPaymentInstruction;
|
// this.formingPaymentInstruction = formingPaymentInstruction;
|
||||||
this.unlockResources = unlockResources;
|
this.unlockResources = unlockResources;
|
||||||
this.finishingSession = finishingSession;
|
this.finishingSession = finishingSession;
|
||||||
|
|
@ -183,7 +183,7 @@ public class PrimaryAuctionBnSession extends AbstractSession implements Initiali
|
||||||
FormingPaymentInstructionPayload payload = new FormingPaymentInstructionPayload();
|
FormingPaymentInstructionPayload payload = new FormingPaymentInstructionPayload();
|
||||||
payload.setSessionId(currSession.getId());
|
payload.setSessionId(currSession.getId());
|
||||||
//stage 7
|
//stage 7
|
||||||
paymentResult = runStage(TaskType.FormingPaymentInstruction, payload, formingPaymentInstructionAssets);
|
paymentResult = runStage(TaskType.FormingPaymentInstruction, payload, formingPaymentInstruction);
|
||||||
}
|
}
|
||||||
if (paymentResult.getStageResult().getPaymentInstructions().isEmpty()) {
|
if (paymentResult.getStageResult().getPaymentInstructions().isEmpty()) {
|
||||||
log.info("no payment instructions were created, sending SDF56");
|
log.info("no payment instructions were created, sending SDF56");
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import ru.clearing.classes.statics.data.registry.Registry;
|
||||||
import ru.clearing.classes.statics.data.sdf.SDf03;
|
import ru.clearing.classes.statics.data.sdf.SDf03;
|
||||||
import ru.clearing.classes.statics.data.sdf.SDf12;
|
import ru.clearing.classes.statics.data.sdf.SDf12;
|
||||||
import ru.clearing.classes.statics.data.security.Security;
|
import ru.clearing.classes.statics.data.security.Security;
|
||||||
|
import ru.spcex.clearing.error.ClearingError;
|
||||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||||
import ru.spcex.clearing.platform.messaging.domain.Consts;
|
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.balance.ExportToFileRequest;
|
||||||
|
|
@ -21,15 +22,14 @@ import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
|
||||||
import ru.spcex.clearing.service.RegistryManager;
|
import ru.spcex.clearing.service.RegistryManager;
|
||||||
import ru.spcex.clearing.service.Sdf03Creator;
|
import ru.spcex.clearing.service.Sdf03Creator;
|
||||||
import ru.spcex.clearing.service.builder.PaymentInstructionBuilderForSecurities;
|
import ru.spcex.clearing.service.builder.PaymentInstructionBuilderForSecurities;
|
||||||
|
import ru.spcex.clearing.service.builder.PaymentInstructionBuilderV2;
|
||||||
import ru.spcex.clearing.session.stage.ISessionStage;
|
import ru.spcex.clearing.session.stage.ISessionStage;
|
||||||
import ru.spcex.clearing.session.stage.StageResult;
|
import ru.spcex.clearing.session.stage.StageResult;
|
||||||
import ru.spcex.clearing.session.stage.Task;
|
import ru.spcex.clearing.session.stage.Task;
|
||||||
import ru.spcex.clearing.session.stage.payment.group.PaymentGroup;
|
import ru.spcex.clearing.session.stage.payment.group.PaymentGroup;
|
||||||
import ru.spcex.clearing.session.stage.payment.group.RegistryLiabilitiesGroup;
|
import ru.spcex.clearing.session.stage.payment.group.RegistryLiabilitiesGroup;
|
||||||
import ru.spcex.clearing.session.stage.task.FormingPaymentInstructionPayload;
|
import ru.spcex.clearing.session.stage.task.FormingPaymentInstructionPayload;
|
||||||
import ru.spcex.platform.enumeration.AccountType;
|
import ru.spcex.platform.enumeration.*;
|
||||||
import ru.spcex.platform.enumeration.InstrumentType;
|
|
||||||
import ru.spcex.platform.enumeration.RegistryTradingParams;
|
|
||||||
import ru.spcex.platform.imdg.api.Imdg;
|
import ru.spcex.platform.imdg.api.Imdg;
|
||||||
import ru.spcex.platform.imdg.api.ImdgId;
|
import ru.spcex.platform.imdg.api.ImdgId;
|
||||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||||
|
|
@ -37,17 +37,18 @@ import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
|
||||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
||||||
import ru.spcex.platform.imdg.api.predicate.specific.RegistryCodeSqlBuilder;
|
import ru.spcex.platform.imdg.api.predicate.specific.RegistryCodeSqlBuilder;
|
||||||
import ru.spcex.platform.imdg.api.predicate.specific.SecuritySelector;
|
import ru.spcex.platform.imdg.api.predicate.specific.SecuritySelector;
|
||||||
|
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||||
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
||||||
import ru.spcex.platform.utils.enumeration.SimpleMessageResolver;
|
import ru.spcex.platform.utils.enumeration.SimpleMessageResolver;
|
||||||
import ru.spcex.platform.utils.number.BigDecimalUtil;
|
import ru.spcex.platform.utils.number.BigDecimalUtil;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import static ru.spcex.platform.enumeration.RegistryTradingParams.*;
|
import static ru.spcex.platform.enumeration.RegistryTradingParams.*;
|
||||||
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
|
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
|
||||||
|
|
@ -71,10 +72,11 @@ public class FormingPaymentInstructionSecurities implements ISessionStage {
|
||||||
private final IMessageResolver msgResolver = new SimpleMessageResolver();
|
private final IMessageResolver msgResolver = new SimpleMessageResolver();
|
||||||
private final RegistryManager rgsMng;
|
private final RegistryManager rgsMng;
|
||||||
private final SecuritySelector<Security> securitySelector;
|
private final SecuritySelector<Security> securitySelector;
|
||||||
|
private final Sdf03And12Sender sdf03And12Sender;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public FormingPaymentInstructionSecurities(ImdgProvider imdgProvider,
|
public FormingPaymentInstructionSecurities(ImdgProvider imdgProvider,
|
||||||
KafkaSender kafkaSender, Sdf03Creator sdf03Creator, RegistryManager rgsMng) {
|
KafkaSender kafkaSender, Sdf03Creator sdf03Creator, RegistryManager rgsMng, Sdf03And12Sender sdf03And12Sender) {
|
||||||
this.kafkaSender = kafkaSender;
|
this.kafkaSender = kafkaSender;
|
||||||
this.imdgProvider = imdgProvider;
|
this.imdgProvider = imdgProvider;
|
||||||
this.idGenerator = imdgProvider.getImdgIdGenerator();
|
this.idGenerator = imdgProvider.getImdgIdGenerator();
|
||||||
|
|
@ -88,6 +90,7 @@ public class FormingPaymentInstructionSecurities implements ISessionStage {
|
||||||
this.sdf03Creator = sdf03Creator;
|
this.sdf03Creator = sdf03Creator;
|
||||||
this.rgsMng = rgsMng;
|
this.rgsMng = rgsMng;
|
||||||
this.securitySelector = new SecuritySelector<>(imdgProvider, Security.class);
|
this.securitySelector = new SecuritySelector<>(imdgProvider, Security.class);
|
||||||
|
this.sdf03And12Sender = sdf03And12Sender;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -95,7 +98,7 @@ public class FormingPaymentInstructionSecurities implements ISessionStage {
|
||||||
FormingPaymentInstructionPayload payload = (FormingPaymentInstructionPayload) task.getData();
|
FormingPaymentInstructionPayload payload = (FormingPaymentInstructionPayload) task.getData();
|
||||||
switch (task.getTaskType()) {
|
switch (task.getTaskType()) {
|
||||||
case FormingPaymentInstruction -> {
|
case FormingPaymentInstruction -> {
|
||||||
return formingPaymentInstructions(payload.getSessionId(), payload.getPaymentInstructionReturns());
|
return formingPaymentInstructions(payload.getSessionId());
|
||||||
}
|
}
|
||||||
default -> {
|
default -> {
|
||||||
throw new IllegalStateException("Unknown task type: " + task.getTaskType());
|
throw new IllegalStateException("Unknown task type: " + task.getTaskType());
|
||||||
|
|
@ -104,7 +107,7 @@ public class FormingPaymentInstructionSecurities implements ISessionStage {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Collection<Registry> selectRegistries() {
|
private Collection<Registry> selectSecurityRegistries() {
|
||||||
ImdgPredicateBuilder rgsPb = registryImdg.predicateBuilder();
|
ImdgPredicateBuilder rgsPb = registryImdg.predicateBuilder();
|
||||||
RegistryCodeSqlBuilder registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(
|
RegistryCodeSqlBuilder registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(
|
||||||
CS_T, LS_T
|
CS_T, LS_T
|
||||||
|
|
@ -118,104 +121,198 @@ public class FormingPaymentInstructionSecurities implements ISessionStage {
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Collection<Registry> selectMoneyRegistries() {
|
||||||
|
ImdgPredicateBuilder rgsPb = registryImdg.predicateBuilder();
|
||||||
|
RegistryCodeSqlBuilder registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(
|
||||||
|
AM_B
|
||||||
|
);
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* часть для бумаг по первичке IPO0 IPOT IPOB
|
* часть для бумаг по первичке IPO0 IPOT IPOB
|
||||||
* вторичка прошла идеально
|
* вторичка прошла идеально
|
||||||
* из нее нужно будет взять кусок про деньги
|
* из нее нужно будет взять кусок про деньги
|
||||||
*/
|
*/
|
||||||
private StageResult<?> formingPaymentInstructions(Long sessionId, Collection<PaymentInstruction> paymentInstructionReturns) {
|
private StageResult<?> formingPaymentInstructions(Long sessionId) {
|
||||||
|
List<PaymentInstruction> paymentInstructionAll = new ArrayList<>();
|
||||||
Instant now = Instant.now();
|
Instant now = Instant.now();
|
||||||
Collection<Registry> registries = selectRegistries();
|
{
|
||||||
log.debug("found registries.size() = {}", registries.size());
|
Collection<Registry> registries = selectSecurityRegistries();
|
||||||
//группируем регистры по groupId
|
log.debug("found registries.size() = {}", registries.size());
|
||||||
Map<Long, List<Registry>> groups = registries
|
//группируем регистры по groupId
|
||||||
.stream()
|
Map<Long, List<Registry>> groups = registries
|
||||||
.collect(Collectors.groupingBy(Registry::getGroupId));
|
|
||||||
log.debug("groups.size = {}", groups.size());
|
|
||||||
List<PaymentInstruction> paymentInstructionDeals = new ArrayList<>();
|
|
||||||
Map<Long, PaymentGroup> lstGroups = RegistryLiabilitiesGroup.group(registries);
|
|
||||||
for (Map.Entry<Long, List<Registry>> group : groups.entrySet()) {
|
|
||||||
Long groupId = group.getKey();
|
|
||||||
Function<RegistryTradingParams, Registry> findByCode = rgsCode -> group.getValue()
|
|
||||||
.stream()
|
.stream()
|
||||||
.filter(rgs -> RegistryManager.equalsByCode(rgsCode, rgs))
|
.collect(Collectors.groupingBy(Registry::getGroupId));
|
||||||
.findFirst()
|
log.debug("groups.size = {}", groups.size());
|
||||||
.orElse(null);
|
Map<Long, PaymentGroup> lstGroups = RegistryLiabilitiesGroup.group(registries);
|
||||||
//интересуют обязательства и требования по деньгам
|
for (Map.Entry<Long, List<Registry>> group : groups.entrySet()) {
|
||||||
Registry cs_t = findByCode.apply(CS_T);
|
Long groupId = group.getKey();
|
||||||
Registry ls_t = findByCode.apply(LS_T);
|
Function<RegistryTradingParams, Registry> findByCode = rgsCode -> group.getValue()
|
||||||
if (cs_t == null || ls_t == null) {
|
.stream()
|
||||||
log.error("groupId {} cmt_t {} ls_t {} - both must be present", groupId, cs_t, ls_t);
|
.filter(rgs -> RegistryManager.equalsByCode(rgsCode, rgs))
|
||||||
continue;
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
//интересуют обязательства и требования по деньгам
|
||||||
|
Registry cs_t = findByCode.apply(CS_T);
|
||||||
|
Registry ls_t = findByCode.apply(LS_T);
|
||||||
|
if (cs_t == null || ls_t == null) {
|
||||||
|
log.error("groupId {} cmt_t {} ls_t {} - both must be present", groupId, cs_t, ls_t);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
PaymentGroup ls_t_group = lstGroups.get(ls_t.getId());
|
||||||
|
if (ls_t_group == null) {
|
||||||
|
log.debug("groupId {} cmt_t {} ls_t {} were included in a group, skipping", groupId, cs_t, ls_t);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Optional<Registry> payerAstO = rgsMng.findRelatedAsset(
|
||||||
|
ls_t.getTradingClearingRegistryId(),
|
||||||
|
ls_t.getCompanyId(),
|
||||||
|
ls_t.getSecuritySymbol(),
|
||||||
|
AS_T
|
||||||
|
);
|
||||||
|
payerAstO.ifPresent(as_t -> {
|
||||||
|
log.debug("groupId {} cmt_t {} ls_t {} changing AS*T.id={} sender", groupId, cs_t, ls_t, as_t.getId());
|
||||||
|
as_t.setSettledDebit(safeBD(as_t.getSettledDebit()).add(safeBD(ls_t_group.getSum())));
|
||||||
|
setUpdatedStoreInImdg(as_t, now);
|
||||||
|
});
|
||||||
|
Optional<Registry> receiverAstO = rgsMng.findRelatedAsset(
|
||||||
|
cs_t.getTradingClearingRegistryId(),
|
||||||
|
cs_t.getCompanyId(),
|
||||||
|
cs_t.getSecuritySymbol(),
|
||||||
|
AS_T
|
||||||
|
);
|
||||||
|
receiverAstO.ifPresent(as_t -> {
|
||||||
|
log.debug("groupId {} cmt_t {} ls_t {} changing AS*T.id={} receiver", groupId, cs_t, ls_t, as_t.getId());
|
||||||
|
as_t.setSettledCredit(safeBD(as_t.getSettledCredit()).add(safeBD(ls_t_group.getSum())));
|
||||||
|
setUpdatedStoreInImdg(as_t, now);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
log.trace("generating payment instruction for groupId {} cmt_t {} ls_t {}, matched ls_t total {}, total balance {}, LS*T.id={}",
|
||||||
|
groupId,
|
||||||
|
cs_t.getId(),
|
||||||
|
ls_t.getId(),
|
||||||
|
ls_t_group.getLs_tRegistries().size(),
|
||||||
|
ls_t_group.getSum(),
|
||||||
|
ls_t_group.getLs_tRegistries().stream()
|
||||||
|
.map(Registry::getId)
|
||||||
|
.map(String::valueOf)
|
||||||
|
.collect(Collectors.joining(",", "[", "]"))
|
||||||
|
);
|
||||||
|
|
||||||
|
PaymentInstruction pmt = PaymentInstructionBuilderForSecurities.builder(imdgProvider)
|
||||||
|
.ls_t(ls_t)
|
||||||
|
.creditLegAccountId(ls_t.getAccountId())
|
||||||
|
.creditLegAccount(ls_t.getAccount())
|
||||||
|
.debitLegAccountId(cs_t.getAccountId())
|
||||||
|
.debitLegAccount(cs_t.getAccount())
|
||||||
|
.sessionId(sessionId)
|
||||||
|
.sender(ls_t.getCompanyId())
|
||||||
|
.addressee(cs_t.getCompanyId())
|
||||||
|
.purpose("Перевод по итогу клиринга")
|
||||||
|
.amount(ls_t_group.getSum())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
paymentInstructionImdg.insert(pmt);
|
||||||
|
paymentInstructionAll.add(pmt);
|
||||||
|
log.trace("generated PaymentInstructions for groupId {}: pmtInstr.id={}", groupId, pmt.getId());
|
||||||
}
|
}
|
||||||
PaymentGroup ls_t_group = lstGroups.get(ls_t.getId());
|
}
|
||||||
if (ls_t_group == null) {
|
{
|
||||||
log.debug("groupId {} cmt_t {} ls_t {} were included in a group, skipping", groupId, cs_t, ls_t);
|
Collection<Registry> registries = selectMoneyRegistries();
|
||||||
continue;
|
Account tranAcc = accountImdg.getFirstObjectBySQL("accountType = '%s' and status = '%s' and processingSign = '%s'"
|
||||||
|
.formatted(AccountType.Tran.getKey(), AccountStatus.ACTIVE.getKey(), Allowed.ALLOWED.getKey()));
|
||||||
|
Account dtrnAcc = accountImdg.getFirstObjectBySQL("accountType = '%s' and status = '%s' and processingSign = '%s'"
|
||||||
|
.formatted(AccountType.Dtrn.getKey(), AccountStatus.ACTIVE.getKey(), Allowed.ALLOWED.getKey()));
|
||||||
|
|
||||||
|
if (tranAcc == null || dtrnAcc == null) {
|
||||||
|
return new StageResult<>(
|
||||||
|
new EnumMessage(ClearingError.AccountNotPresent, "accountType = %s/%s"
|
||||||
|
.formatted(AccountType.Tran.getKey(), AccountType.Dtrn.getKey())),
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<Registry> payerAstO = rgsMng.findRelatedAsset(
|
log.debug("found AS*B.size() = {}", registries.size());
|
||||||
ls_t.getTradingClearingRegistryId(),
|
//группируем регистры по groupId
|
||||||
ls_t.getCompanyId(),
|
for (Registry registry : registries) {
|
||||||
ls_t.getSecuritySymbol(),
|
if (registry.getBalance().compareTo(BigDecimal.ZERO) == 0) {
|
||||||
AS_T
|
log.debug("Skip creating paymentInstruction by registry with 0 balance");
|
||||||
);
|
continue;
|
||||||
payerAstO.ifPresent(as_t -> {
|
}
|
||||||
log.debug("groupId {} cmt_t {} ls_t {} changing AS*T.id={} sender", groupId, cs_t, ls_t, as_t.getId());
|
boolean isPositiveBalance = registry.getBalance().compareTo(BigDecimal.ZERO) > 0;
|
||||||
as_t.setSettledDebit(safeBD(as_t.getSettledDebit()).add(safeBD(ls_t_group.getSum())));
|
Account counterAcc = null;
|
||||||
setUpdatedStoreInImdg(as_t, now);
|
if (AccountType.Clrn.equalsByKey(registry.getAccountType())) {
|
||||||
});
|
counterAcc = accountImdg.getSingleObjectByID(registry.getAccountId());
|
||||||
Optional<Registry> receiverAstO = rgsMng.findRelatedAsset(
|
} else if (AccountType.Info.equalsByKey(registry.getAccountType())) {
|
||||||
cs_t.getTradingClearingRegistryId(),
|
counterAcc = accountImdg.getFirstObjectByFieldValues(Map.of("companyId", 1L, "accountType", AccountType.Anlt.getKey()));
|
||||||
cs_t.getCompanyId(),
|
}
|
||||||
cs_t.getSecuritySymbol(),
|
Long senderId;
|
||||||
AS_T
|
Long addresseeId;
|
||||||
);
|
Account debitLegAccount;
|
||||||
receiverAstO.ifPresent(as_t -> {
|
Account creditLegAccount;
|
||||||
log.debug("groupId {} cmt_t {} ls_t {} changing AS*T.id={} receiver", groupId, cs_t, ls_t, as_t.getId());
|
BigDecimal amount;
|
||||||
as_t.setSettledCredit(safeBD(as_t.getSettledCredit()).add(safeBD(ls_t_group.getSum())));
|
if (isPositiveBalance) {
|
||||||
setUpdatedStoreInImdg(as_t, now);
|
senderId = registry.getCompanyId();
|
||||||
});
|
addresseeId = Sender.One.getId();
|
||||||
|
debitLegAccount = tranAcc;
|
||||||
|
creditLegAccount = counterAcc;
|
||||||
log.trace("generating payment instruction for groupId {} cmt_t {} ls_t {}, matched ls_t total {}, total balance {}, LS*T.id={}",
|
amount = registry.getBalance() == null ? null : registry.getBalance().abs();
|
||||||
groupId,
|
Optional<Registry> payerAmtO = rgsMng.findRelatedAsset(
|
||||||
cs_t.getId(),
|
registry.getTradingClearingRegistryId(),
|
||||||
ls_t.getId(),
|
registry.getCompanyId(),
|
||||||
ls_t_group.getLs_tRegistries().size(),
|
registry.getSecuritySymbol(),
|
||||||
ls_t_group.getSum(),
|
AM_T);
|
||||||
ls_t_group.getLs_tRegistries().stream()
|
payerAmtO.ifPresent(amt -> {
|
||||||
.map(Registry::getId)
|
amt.setSettledDebit(safeBD(amt.getSettledDebit()).add(safeBD(registry.getBalance().abs())));
|
||||||
.map(String::valueOf)
|
setUpdatedStoreInImdg(amt, now);
|
||||||
.collect(Collectors.joining(",", "[", "]"))
|
});
|
||||||
);
|
} else {
|
||||||
|
senderId = Sender.One.getId();
|
||||||
PaymentInstruction pmt = PaymentInstructionBuilderForSecurities.builder(imdgProvider)
|
addresseeId = registry.getCompanyId();
|
||||||
.ls_t(ls_t)
|
debitLegAccount = counterAcc;
|
||||||
.creditLegAccountId(ls_t.getAccountId())
|
creditLegAccount = tranAcc;
|
||||||
.creditLegAccount(ls_t.getAccount())
|
amount = registry.getBalance() == null ? null : registry.getBalance().abs();
|
||||||
.debitLegAccountId(cs_t.getAccountId())
|
Optional<Registry> payerAmtO = rgsMng.findRelatedAsset(
|
||||||
.debitLegAccount(cs_t.getAccount())
|
registry.getTradingClearingRegistryId(),
|
||||||
.sessionId(sessionId)
|
registry.getCompanyId(),
|
||||||
.sender(ls_t.getCompanyId())
|
registry.getSecuritySymbol(),
|
||||||
.addressee(cs_t.getCompanyId())
|
AM_T
|
||||||
.purpose("Перевод по итогу клиринга")
|
);
|
||||||
.amount(ls_t_group.getSum())
|
payerAmtO.ifPresent(amt -> {
|
||||||
.build();
|
amt.setSettledCredit(safeBD(amt.getSettledCredit()).add(safeBD(registry.getBalance().abs())));
|
||||||
|
setUpdatedStoreInImdg(amt, now);
|
||||||
paymentInstructionImdg.insert(pmt);
|
});
|
||||||
paymentInstructionDeals.add(pmt);
|
}
|
||||||
|
PaymentInstructionBuilderV2 paymentInstructionBuilder = PaymentInstructionBuilderV2.builder(imdgProvider)
|
||||||
log.trace("generated PaymentInstructions for groupId {}: pmtInstr.id={}", groupId, pmt.getId());
|
.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);
|
||||||
|
paymentInstructionAll.add(paymentInstruction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("PaymentInstructions return size {}, PaymentInstructions deals size {}. sending SDF03",
|
log.debug("PaymentInstruction size {}", paymentInstructionAll.size());
|
||||||
paymentInstructionReturns.size(),
|
sdf03And12Sender.sendSdfs(paymentInstructionAll, sessionId);
|
||||||
paymentInstructionDeals.size());
|
|
||||||
List<PaymentInstruction> returnsAndDeals = Stream.concat(paymentInstructionReturns.stream(), paymentInstructionDeals.stream()).toList();
|
|
||||||
sendSdfs(returnsAndDeals, sessionId);
|
|
||||||
StageResult<Collection<PaymentInstruction>> stageResult = new StageResult<>(null, true);
|
StageResult<Collection<PaymentInstruction>> stageResult = new StageResult<>(null, true);
|
||||||
stageResult.setStageResult(returnsAndDeals);
|
stageResult.setStageResult(paymentInstructionAll);
|
||||||
return stageResult;
|
return stageResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,104 @@
|
||||||
|
package ru.spcex.clearing.session.stage.impl;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import ru.clearing.classes.statics.data.account.Account;
|
||||||
|
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
|
||||||
|
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.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.Sdf12Creator;
|
||||||
|
import ru.spcex.platform.enumeration.AccountType;
|
||||||
|
import ru.spcex.platform.enumeration.InstrumentType;
|
||||||
|
import ru.spcex.platform.enumeration.SdfTable;
|
||||||
|
import ru.spcex.platform.imdg.api.Imdg;
|
||||||
|
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||||
|
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class Sdf03And12Sender {
|
||||||
|
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
|
private final ImdgProvider imdgProvider;
|
||||||
|
private final Imdg<Security> securityImdg;
|
||||||
|
private final Imdg<Account> accountImdg;
|
||||||
|
private final Imdg<SDf03> sDf03Imdg;
|
||||||
|
private final Imdg<SDf12> sDf12Imdg;
|
||||||
|
private final KafkaSender kafkaSender;
|
||||||
|
private final Sdf03Creator sdf03Creator;
|
||||||
|
private final Sdf12Creator sdf12Creator;
|
||||||
|
|
||||||
|
public Sdf03And12Sender(ImdgProvider imdgProvider,
|
||||||
|
KafkaSender kafkaSender, Sdf03Creator sdf03Creator, Sdf12Creator sdf12Creator, RegistryManager rgsMng) {
|
||||||
|
this.kafkaSender = kafkaSender;
|
||||||
|
this.imdgProvider = imdgProvider;
|
||||||
|
this.securityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Security, Security.class);
|
||||||
|
this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
|
||||||
|
this.sDf03Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf03, SDf03.class);
|
||||||
|
this.sDf12Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf12, SDf12.class);
|
||||||
|
this.sdf03Creator = sdf03Creator;
|
||||||
|
this.sdf12Creator = sdf12Creator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<SdfTable> sendSdfs(List<PaymentInstruction> formedPaymentInstructions, Long sessionId) {
|
||||||
|
Collection<SdfTable> sentSdfs = new ArrayList<>();
|
||||||
|
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()))) {
|
||||||
|
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(sdf12Creator.createWithoutIntermediate(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;
|
||||||
|
if (!sDf12Created.isEmpty()) {
|
||||||
|
sdf12GroupId = imdgProvider.getImdgIdGenerator().nextId();
|
||||||
|
Long maxTxNumber = sdf12Creator.maxTxNumber();
|
||||||
|
for (SDf12 sDf12 : sDf12Created) {
|
||||||
|
sDf12.setGenerationId(sdf12GroupId);
|
||||||
|
sDf12.setTransactionNumber(maxTxNumber.toString());
|
||||||
|
sDf12.setTransactionQuantity(String.valueOf(sDf12Created.size()));
|
||||||
|
sDf12Imdg.insert(sDf12);
|
||||||
|
}
|
||||||
|
SwtExporterRequest swtExporterRequest = new SwtExporterRequest();
|
||||||
|
swtExporterRequest.setType("SDF_12");
|
||||||
|
swtExporterRequest.setGroupId(sdf12GroupId);
|
||||||
|
swtExporterRequest.setSessionId(sessionId);
|
||||||
|
kafkaSender.sendRequestToQueue(Consts.SWT_EXPORTER, swtExporterRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sdf03GroupId != null) sentSdfs.add(SdfTable.SDF_03);
|
||||||
|
if (sdf12GroupId != null) sentSdfs.add(SdfTable.SDF_12);
|
||||||
|
return sentSdfs;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue