IPOT 7 шаг по формированию PaymentInstruction по бумагам
This commit is contained in:
parent
6b3eaa1e24
commit
0c0bc7d910
5 changed files with 624 additions and 7 deletions
|
|
@ -0,0 +1,211 @@
|
|||
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.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.CompanySymbol;
|
||||
import ru.spcex.platform.enumeration.CurrencyCode;
|
||||
import ru.spcex.platform.enumeration.InOutDirection;
|
||||
import ru.spcex.platform.enumeration.TransactionStatus;
|
||||
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 PaymentInstructionBuilderForSecurities {
|
||||
private final static Logger log = LoggerFactory.getLogger(PaymentInstructionBuilderForSecurities.class);
|
||||
private Registry registry;
|
||||
private ImdgProvider imdgProvider;
|
||||
private Imdg<Company> companyImdg;
|
||||
private Imdg<CompanySymbols> companySymbolsImdg;
|
||||
private Long sessionId;
|
||||
private BigDecimal amount;
|
||||
private Long creditLegAccountId;
|
||||
private String creditLegAccount;
|
||||
private Long debitLegAccountId;
|
||||
private String 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 PaymentInstructionBuilderForSecurities builder(ImdgProvider imdgProvider) {
|
||||
return new PaymentInstructionBuilderForSecurities(imdgProvider);
|
||||
}
|
||||
|
||||
private PaymentInstructionBuilderForSecurities(ImdgProvider imdgProvider) {
|
||||
this.imdgProvider = imdgProvider;
|
||||
this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
|
||||
this.companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
|
||||
}
|
||||
|
||||
public PaymentInstructionBuilderForSecurities sessionId(Long sessionId) {
|
||||
this.sessionId = sessionId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PaymentInstructionBuilderForSecurities ls_t(Registry registry) {
|
||||
this.registry = registry;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PaymentInstructionBuilderForSecurities amount(BigDecimal amount) {
|
||||
this.amount = amount;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PaymentInstructionBuilderForSecurities creditLegAccount(String account) {
|
||||
this.creditLegAccount = account;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PaymentInstructionBuilderForSecurities debitLegAccount(String account) {
|
||||
this.debitLegAccount = account;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PaymentInstructionBuilderForSecurities creditLegAccountId(Long accountId) {
|
||||
this.creditLegAccountId = accountId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PaymentInstructionBuilderForSecurities debitLegAccountId(Long accountId) {
|
||||
this.debitLegAccountId = accountId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PaymentInstructionBuilderForSecurities purpose(String purpose) {
|
||||
this.purpose = purpose;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PaymentInstructionBuilderForSecurities sender(Long senderId) {
|
||||
this.senderId = senderId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PaymentInstructionBuilderForSecurities 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(creditLegAccountId);
|
||||
payment.setCreditLeg_account(creditLegAccount);
|
||||
}
|
||||
|
||||
payment.setCredit_csAccount(null);
|
||||
|
||||
{
|
||||
payment.setDebitLeg_accountId(debitLegAccountId);
|
||||
payment.setDebitLeg_account(debitLegAccount);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import org.springframework.stereotype.Service;
|
|||
import ru.clearing.classes.statics.data.execution.ExecutionCommon;
|
||||
import ru.clearing.classes.statics.data.execution.ExecutionFond;
|
||||
import ru.clearing.classes.statics.data.misc.Session;
|
||||
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
|
||||
import ru.spcex.clearing.session.stage.impl.*;
|
||||
|
|
@ -25,6 +26,7 @@ import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
|||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
|
@ -39,7 +41,7 @@ public class PrimaryAuctionT0Session extends AbstractSession implements Initiali
|
|||
private final InclusionObligations inclusionObligations;
|
||||
private final InspectionObligations inspectionObligations;
|
||||
private final FormingRegistersOnOS formingRegistersOnOS;
|
||||
private final FormingPaymentInstructionAssets formingPaymentInstructionAssets;
|
||||
private final FormingPaymentInstructionSecurities formingPaymentInstruction;
|
||||
// private final FormingPaymentInstruction formingPaymentInstruction;
|
||||
// private final FormingPaymentInstructionDealsFinalMkr formingPaymentInstructionDealsFinalMkr;
|
||||
private final UnlockResources unlockResources;
|
||||
|
|
@ -60,7 +62,7 @@ public class PrimaryAuctionT0Session extends AbstractSession implements Initiali
|
|||
ObligationAdmission obligationsAdmission,
|
||||
InclusionObligations inclusionObligations,
|
||||
FormingRegistersOnOS formingRegistersOnOS,
|
||||
FormingPaymentInstructionAssets formingPaymentInstructionAssets,
|
||||
FormingPaymentInstructionSecurities formingPaymentInstruction,
|
||||
// FormingPaymentInstruction formingPaymentInstruction,
|
||||
// FormingPaymentInstructionDealsFinalMkr formingPaymentInstructionDealsFinalMkr,
|
||||
UnlockResources unlockResources,
|
||||
|
|
@ -76,7 +78,7 @@ public class PrimaryAuctionT0Session extends AbstractSession implements Initiali
|
|||
this.obligationsAdmission = obligationsAdmission;
|
||||
this.inclusionObligations = inclusionObligations;
|
||||
this.formingRegistersOnOS = formingRegistersOnOS;
|
||||
this.formingPaymentInstructionAssets = formingPaymentInstructionAssets;
|
||||
this.formingPaymentInstruction = formingPaymentInstruction;
|
||||
// this.formingPaymentInstruction = formingPaymentInstruction;
|
||||
this.unlockResources = unlockResources;
|
||||
this.finishingSession = finishingSession;
|
||||
|
|
@ -177,18 +179,18 @@ public class PrimaryAuctionT0Session extends AbstractSession implements Initiali
|
|||
payload.setSessionId(currSession.getId());
|
||||
runStage(TaskType.FormingRegistersOnOS, payload, formingRegistersOnOS); //returns Collection<Registry>
|
||||
}
|
||||
StageResult<PaymentInfo> paymentResult = null;
|
||||
StageResult<Collection<PaymentInstruction>> paymentResult = null;
|
||||
{
|
||||
FormingPaymentInstructionPayload payload = new FormingPaymentInstructionPayload();
|
||||
payload.setSessionId(currSession.getId());
|
||||
//stage 7
|
||||
paymentResult = runStage(TaskType.FormingPaymentInstruction, payload, formingPaymentInstructionAssets);
|
||||
paymentResult = runStage(TaskType.FormingPaymentInstruction, payload, formingPaymentInstruction);
|
||||
}
|
||||
if (paymentResult.getStageResult().getPaymentInstructions().isEmpty()) {
|
||||
if (paymentResult.getStageResult().isEmpty()) {
|
||||
log.info("no payment instructions were created, sending SDF56");
|
||||
sendSdf56();
|
||||
} else {
|
||||
log.info("created {} PaymentInstructions, waiting for SDF04/SDF13", paymentResult.getStageResult().getPaymentInstructions().size());
|
||||
log.info("created {} PaymentInstructions, waiting for SDF04/SDF13", paymentResult.getStageResult().size());
|
||||
this.afterPaymentsSdf4And13Monitor = SessionMonitorFactory.paymentsWereCreated(section());
|
||||
}
|
||||
} catch (StageException e) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,301 @@
|
|||
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.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.PaymentInstructionBuilderForSecurities;
|
||||
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.payment.group.PaymentGroup;
|
||||
import ru.spcex.clearing.session.stage.payment.group.RegistryLiabilitiesGroup;
|
||||
import ru.spcex.clearing.session.stage.task.FormingPaymentInstructionPayload;
|
||||
import ru.spcex.platform.enumeration.AccountType;
|
||||
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.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.imdg.api.predicate.specific.SecuritySelector;
|
||||
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.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static ru.spcex.platform.enumeration.RegistryTradingParams.*;
|
||||
import static ru.spcex.platform.utils.number.BigDecimalUtil.safeBD;
|
||||
|
||||
@Service
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public class FormingPaymentInstructionSecurities implements ISessionStage {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
//todo remove (set all in single method setImdg(provider -> setImdg1();setIdGenerator();...)
|
||||
private ImdgProvider imdgProvider;
|
||||
private ImdgId idGenerator;
|
||||
private Imdg<Registry> registryImdg;
|
||||
private Imdg<PaymentInstruction> paymentInstructionImdg;
|
||||
private Imdg<Security> securityImdg;
|
||||
private Imdg<Account> accountImdg;
|
||||
private Imdg<Company> companyImdg;
|
||||
private Imdg<SDf03> sDf03Imdg;
|
||||
private Imdg<SDf12> sDf12Imdg;
|
||||
private KafkaSender kafkaSender;
|
||||
private final Sdf03Creator sdf03Creator;
|
||||
private final IMessageResolver msgResolver = new SimpleMessageResolver();
|
||||
private final RegistryManager rgsMng;
|
||||
private final SecuritySelector<Security> securitySelector;
|
||||
|
||||
@Autowired
|
||||
public FormingPaymentInstructionSecurities(ImdgProvider imdgProvider,
|
||||
KafkaSender kafkaSender, Sdf03Creator sdf03Creator, RegistryManager rgsMng) {
|
||||
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.sdf03Creator = sdf03Creator;
|
||||
this.rgsMng = rgsMng;
|
||||
this.securitySelector = new SecuritySelector<>(imdgProvider, Security.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StageResult<?> submit(Task<?> task) {
|
||||
FormingPaymentInstructionPayload payload = (FormingPaymentInstructionPayload) task.getData();
|
||||
switch (task.getTaskType()) {
|
||||
case FormingPaymentInstruction -> {
|
||||
return formingPaymentInstructions(payload.getSessionId(), payload.getPaymentInstructionReturns());
|
||||
}
|
||||
default -> {
|
||||
throw new IllegalStateException("Unknown task type: " + task.getTaskType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Collection<Registry> selectRegistries() {
|
||||
ImdgPredicateBuilder rgsPb = registryImdg.predicateBuilder();
|
||||
RegistryCodeSqlBuilder registryCodeSqlBuilder = RegistryCodeSqlBuilder.getInstance(
|
||||
CS_T, LS_T
|
||||
);
|
||||
ImdgPredicate rgsCodePrdct = rgsPb.and(
|
||||
rgsPb.sql(registryCodeSqlBuilder.build()),
|
||||
rgsPb.equals("settlementDate", LocalDate.now()));
|
||||
Collection<Registry> registries = registryImdg.getCollectionObjectsByPredicate(rgsCodePrdct);
|
||||
return registries.stream()
|
||||
.filter(rgs -> Objects.equals(rgs.getValueDate(), rgs.getSettlementDate()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* часть для бумаг по первичке IPO0 IPOT IPOB
|
||||
* вторичка прошла идеально
|
||||
* из нее нужно будет взять кусок про деньги
|
||||
*/
|
||||
private StageResult<?> formingPaymentInstructions(Long sessionId, Collection<PaymentInstruction> paymentInstructionReturns) {
|
||||
Instant now = Instant.now();
|
||||
Collection<Registry> registries = selectRegistries();
|
||||
log.debug("found registries.size() = {}", registries.size());
|
||||
//группируем регистры по groupId
|
||||
Map<Long, List<Registry>> groups = registries
|
||||
.stream()
|
||||
.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()
|
||||
.filter(rgs -> RegistryManager.equalsByCode(rgsCode, rgs))
|
||||
.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);
|
||||
paymentInstructionDeals.add(pmt);
|
||||
|
||||
log.trace("generated PaymentInstructions for groupId {}: pmtInstr.id={}", groupId, pmt.getId());
|
||||
}
|
||||
|
||||
log.debug("PaymentInstructions return size {}, PaymentInstructions deals size {}. sending SDF03",
|
||||
paymentInstructionReturns.size(),
|
||||
paymentInstructionDeals.size());
|
||||
List<PaymentInstruction> returnsAndDeals = Stream.concat(paymentInstructionReturns.stream(), paymentInstructionDeals.stream()).toList();
|
||||
sendSdfs(returnsAndDeals, sessionId);
|
||||
StageResult<Collection<PaymentInstruction>> stageResult = new StageResult<>(null, true);
|
||||
stageResult.setStageResult(returnsAndDeals);
|
||||
return stageResult;
|
||||
}
|
||||
|
||||
|
||||
private void setUpdatedStoreInImdg(Registry rgs, Instant now) {
|
||||
rgs.setUpdated(now);
|
||||
registryImdg.update(rgs);
|
||||
}
|
||||
|
||||
private void sendSdfs(List<PaymentInstruction> formedPaymentInstructions, Long sessionId) {
|
||||
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(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(sdf12GroupId);
|
||||
sDf12.setTransactionNumber(maxTxNumber.toString());
|
||||
sDf12.setTransactionQuantity(String.valueOf(sDf12Created.size()));
|
||||
sDf12Imdg.insert(sDf12);
|
||||
}
|
||||
|
||||
if (sdf12GroupId != null) {
|
||||
SwtExporterRequest swtExporterRequest = new SwtExporterRequest();
|
||||
swtExporterRequest.setType("SDF_12");
|
||||
swtExporterRequest.setGroupId(sdf12GroupId);
|
||||
swtExporterRequest.setSessionId(sessionId);
|
||||
kafkaSender.sendRequestToQueue(Consts.SWT_EXPORTER, swtExporterRequest);
|
||||
}
|
||||
}
|
||||
|
||||
private SDf12 newSDf12(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;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package ru.spcex.clearing.session.stage.payment.group;
|
||||
|
||||
import ru.clearing.classes.statics.data.registry.Registry;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
public class PaymentGroup {
|
||||
private List<Registry> ls_tRegistries;
|
||||
private BigDecimal sum;
|
||||
private Long ls_tId;
|
||||
|
||||
public List<Registry> getLs_tRegistries() {
|
||||
return ls_tRegistries;
|
||||
}
|
||||
|
||||
public void setLs_tRegistries(List<Registry> ls_tRegistries) {
|
||||
this.ls_tRegistries = ls_tRegistries;
|
||||
}
|
||||
|
||||
public BigDecimal getSum() {
|
||||
return sum;
|
||||
}
|
||||
|
||||
public void setSum(BigDecimal sum) {
|
||||
this.sum = sum;
|
||||
}
|
||||
|
||||
public Long getLs_tId() {
|
||||
return ls_tId;
|
||||
}
|
||||
|
||||
public void setLs_tId(Long ls_tId) {
|
||||
this.ls_tId = ls_tId;
|
||||
}
|
||||
// private Direction direction;
|
||||
//
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package ru.spcex.clearing.session.stage.payment.group;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import ru.clearing.classes.statics.data.registry.Registry;
|
||||
import ru.spcex.clearing.service.RegistryManager;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
|
||||
import static ru.spcex.platform.enumeration.RegistryTradingParams.LS_T;
|
||||
|
||||
public class RegistryLiabilitiesGroup {
|
||||
private Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
public static RegistryLiabilitiesGroup builder() {
|
||||
return new RegistryLiabilitiesGroup();
|
||||
}
|
||||
|
||||
private RegistryLiabilitiesGroup() {
|
||||
}
|
||||
|
||||
public static Map<Long, PaymentGroup> group(Collection<Registry> registriesCollection) {
|
||||
Map<Long, PaymentGroup> result = new HashMap<>();
|
||||
List<Registry> registries = registriesCollection
|
||||
.stream()
|
||||
.filter(rgs -> RegistryManager.equalsByCode(LS_T, rgs))
|
||||
.toList();
|
||||
for (int i = 0; i < registries.size(); i++) {
|
||||
Registry ls_t = registries.get(i);
|
||||
if (ls_t == null) {
|
||||
continue;
|
||||
}
|
||||
LinkedList<Registry> relatedLiabilities = new LinkedList<>();
|
||||
relatedLiabilities.add(ls_t);
|
||||
for (int j = i + 1; j < registries.size(); j++) {
|
||||
Registry related = registries.get(j);
|
||||
if (related == null) {
|
||||
continue;
|
||||
}
|
||||
if (rgsOfTheSameAgents(ls_t, related)) {
|
||||
relatedLiabilities.add(related);
|
||||
registries.set(j, null);
|
||||
}
|
||||
}
|
||||
PaymentGroup paymentGroup = new PaymentGroup();
|
||||
paymentGroup.setLs_tRegistries(relatedLiabilities);
|
||||
paymentGroup.setLs_tId(ls_t.getId());
|
||||
paymentGroup.setSum(relatedLiabilities
|
||||
.stream()
|
||||
.map(Registry::getBalance)
|
||||
.filter(Objects::nonNull)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add));
|
||||
result.put(paymentGroup.getLs_tId(), paymentGroup);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean rgsOfTheSameAgents(Registry ls_t1, Registry ls_t2) {
|
||||
return Objects.equals(ls_t1.getSecurityId(), ls_t2.getSecurityId())
|
||||
&& Objects.equals(ls_t1.getTradingClearingRegistryId(), ls_t2.getTradingClearingRegistryId())
|
||||
&& Objects.equals(ls_t1.getCompanyId(), ls_t2.getCompanyId())
|
||||
&& Objects.equals(ls_t1.getCounterPartyId(), ls_t2.getCounterPartyId());
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue