etreschenkov 2023-07-10 13:31:43 +03:00
parent 53e248b674
commit 87349837f3
4 changed files with 74 additions and 13 deletions

View file

@ -23,6 +23,7 @@ import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.enumeration.IMessageResolver;
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;
@ -39,7 +40,7 @@ public class SecondaryAuctionT0Session extends AbstractSession implements Initia
private final InspectionObligations inspectionObligations; private final InspectionObligations inspectionObligations;
private final FormingRegistersOnOS formingRegistersOnOS; private final FormingRegistersOnOS formingRegistersOnOS;
private final FormingPaymentInstructionSecondaryT0 formingPaymentInstruction; private final FormingPaymentInstructionSecondaryT0 formingPaymentInstruction;
private final FormingPaymentInstructionReturnMkr formingPaymentInstructionReturnMkr; 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;
@ -57,7 +58,7 @@ public class SecondaryAuctionT0Session extends AbstractSession implements Initia
InclusionObligations inclusionObligations, InclusionObligations inclusionObligations,
FormingRegistersOnOS formingRegistersOnOS, FormingRegistersOnOS formingRegistersOnOS,
FormingPaymentInstructionSecondaryT0 formingPaymentInstruction, FormingPaymentInstructionSecondaryT0 formingPaymentInstruction,
FormingPaymentInstructionReturnMkr formingPaymentInstructionReturnMkr, FormingPaymentInstructionDealsFinalMkr formingPaymentInstructionDealsFinalMkr,
UnlockResources unlockResources, UnlockResources unlockResources,
FinishingSession finishingSession, FinishingSession finishingSession,
EndStageNotification endStageNotification, EndStageNotification endStageNotification,
@ -77,7 +78,7 @@ public class SecondaryAuctionT0Session extends AbstractSession implements Initia
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.formingPaymentInstructionReturnMkr = formingPaymentInstructionReturnMkr; this.formingPaymentInstructionDealsFinalMkr = formingPaymentInstructionDealsFinalMkr;
this.marketCodes = marketCodes; this.marketCodes = marketCodes;
} }
@ -156,10 +157,13 @@ public class SecondaryAuctionT0Session extends AbstractSession implements Initia
} }
StageResult<Collection<PaymentInstruction>> returnsPayment = null; StageResult<Collection<PaymentInstruction>> returnsPayment = null;
{ {
FormingPaymentInstructionPayload payload = new FormingPaymentInstructionPayload(); FormingPaymentInstructionDealsMkrPayload payload = new FormingPaymentInstructionDealsMkrPayload();
payload.setSessionId(currSession.getId()); payload.setSessionId(currSession.getId());
payload.setSendSdfs(false);
payload.setSection(section());
payload.setPaymentInstructionReturns(new ArrayList<>());
//stage 7 //stage 7
returnsPayment = runStage(TaskType.FormingPaymentInstruction, payload, formingPaymentInstructionReturnMkr); returnsPayment = runStage(TaskType.FormingPaymentInstruction, payload, formingPaymentInstructionDealsFinalMkr);
} }
StageResult<Collection<PaymentInstruction>> paymentResult = null; StageResult<Collection<PaymentInstruction>> paymentResult = null;

View file

@ -89,7 +89,8 @@ public class FormingPaymentInstructionDealsFinalMkr implements ISessionStage {
FormingPaymentInstructionDealsMkrPayload payload = (FormingPaymentInstructionDealsMkrPayload) task.getData(); FormingPaymentInstructionDealsMkrPayload payload = (FormingPaymentInstructionDealsMkrPayload) task.getData();
switch (task.getTaskType()) { switch (task.getTaskType()) {
case FormingPaymentInstruction -> { case FormingPaymentInstruction -> {
return formingPaymentInstructions(payload.getSessionId(), payload.getPaymentInstructionReturns()); return formingPaymentInstructions(payload.getSessionId(), payload.getSection(),
payload.getPaymentInstructionReturns(), payload.isSendSdfs());
} }
default -> { default -> {
throw new IllegalStateException("Unknown task type: " + task.getTaskType()); throw new IllegalStateException("Unknown task type: " + task.getTaskType());
@ -111,6 +112,7 @@ public class FormingPaymentInstructionDealsFinalMkr implements ISessionStage {
.filter(rgs -> Objects.equals(rgs.getValueDate(), rgs.getSettlementDate())) .filter(rgs -> Objects.equals(rgs.getValueDate(), rgs.getSettlementDate()))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
/** /**
* аккаунт-счет с accountType='TRAN' - это счет СПВБ который принадлежит самой бирже<br> * аккаунт-счет с accountType='TRAN' - это счет СПВБ который принадлежит самой бирже<br>
* хранят деньги разных участников<br> * хранят деньги разных участников<br>
@ -119,7 +121,8 @@ public class FormingPaymentInstructionDealsFinalMkr implements ISessionStage {
* регистр LMAT кто переводит деньги (registry.account)<br> * регистр LMAT кто переводит деньги (registry.account)<br>
* в итоге создается 2 PaymentInstruction: LMAT -> TRAN счет -> CMAT счет * в итоге создается 2 PaymentInstruction: LMAT -> TRAN счет -> CMAT счет
*/ */
private StageResult<?> formingPaymentInstructions(Long sessionId, Collection<PaymentInstruction> paymentInstructionReturns) { private StageResult<?> formingPaymentInstructions(Long sessionId, Section section,
Collection<PaymentInstruction> paymentInstructionReturns, boolean sendSdfs) {
Collection<Registry> registries = selectRegistries(); Collection<Registry> registries = selectRegistries();
log.debug("found registries.size() = {}", registries.size()); log.debug("found registries.size() = {}", registries.size());
//клиринговый счет, через который будут проводиться сделки //клиринговый счет, через который будут проводиться сделки
@ -188,13 +191,15 @@ public class FormingPaymentInstructionDealsFinalMkr implements ISessionStage {
groupId, groupId,
cm_t.getId(), cm_t.getId(),
lm_t.getId()); lm_t.getId());
String paymentPurpose = section != null && section == Section.FOND ? "" :
"Размещение депозита " + lm_t.getContract() + " по ТКР " + lm_t.getTradingClearingRegistry();
Pair<PaymentInstruction, PaymentInstruction> pmtInstrs = PaymentInstructionBuilderFinalMkrDeals Pair<PaymentInstruction, PaymentInstruction> pmtInstrs = PaymentInstructionBuilderFinalMkrDeals
.builder(imdgProvider) .builder(imdgProvider)
.cm_t(cm_t) .cm_t(cm_t)
.lm_t(lm_t) .lm_t(lm_t)
.tranAcc(tranAcc) .tranAcc(tranAcc)
.sessionId(sessionId) .sessionId(sessionId)
.paymentPurpose("Размещение депозита " + lm_t.getContract() + " по ТКР " + lm_t.getTradingClearingRegistry()) .paymentPurpose(paymentPurpose)
.build(); .build();
Pair.forEach(pmtInstrs, pmtInstr -> { Pair.forEach(pmtInstrs, pmtInstr -> {
paymentInstructionImdg.insert(pmtInstr); paymentInstructionImdg.insert(pmtInstr);
@ -210,7 +215,9 @@ public class FormingPaymentInstructionDealsFinalMkr implements ISessionStage {
paymentInstructionReturns.size(), paymentInstructionReturns.size(),
paymentInstructionDeals.size()); paymentInstructionDeals.size());
List<PaymentInstruction> returnsAndDeals = Stream.concat(paymentInstructionReturns.stream(), paymentInstructionDeals.stream()).toList(); List<PaymentInstruction> returnsAndDeals = Stream.concat(paymentInstructionReturns.stream(), paymentInstructionDeals.stream()).toList();
sendSdfs(returnsAndDeals); if (sendSdfs) {
sendSdfs(returnsAndDeals);
}
StageResult<Collection<PaymentInstruction>> stageResult = new StageResult<>(null, true); StageResult<Collection<PaymentInstruction>> stageResult = new StageResult<>(null, true);
stageResult.setStageResult(returnsAndDeals); stageResult.setStageResult(returnsAndDeals);
return stageResult; return stageResult;

View file

@ -17,6 +17,7 @@ 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;
import ru.spcex.clearing.platform.messaging.domain.cud.importexport.SwtExporterRequest;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.clearing.service.Sdf03Creator; import ru.spcex.clearing.service.Sdf03Creator;
import ru.spcex.clearing.service.builder.PaymentInstructionBuilderFinalMkrDeals; import ru.spcex.clearing.service.builder.PaymentInstructionBuilderFinalMkrDeals;
@ -122,14 +123,14 @@ public class FormingPaymentInstructionSecondaryT0 implements ISessionStage {
Collection<Registry> registries = selectRegistries(); Collection<Registry> registries = selectRegistries();
log.debug("found registries.size() = {}", registries.size()); log.debug("found registries.size() = {}", registries.size());
//клиринговый счет, через который будут проводиться сделки //клиринговый счет, через который будут проводиться сделки
Account tranAcc = accountImdg.getSingleObjectBySQL("accountType = '%s' and status = '%s' and processingSign = '%s'" Account dtrnAcc = accountImdg.getSingleObjectBySQL("accountType = '%s' and status = '%s' and processingSign = '%s'"
.formatted(AccountType.Dtrn.getKey(), AccountStatus.ACTIVE.getKey(), Allowed.ALLOWED.getKey())); .formatted(AccountType.Dtrn.getKey(), AccountStatus.ACTIVE.getKey(), Allowed.ALLOWED.getKey()));
if (tranAcc == null) { if (dtrnAcc == null) {
return new StageResult<>( return new StageResult<>(
new EnumMessage(ClearingError.AccountNotPresent, "accountType = " + AccountType.Dtrn.getKey()), new EnumMessage(ClearingError.AccountNotPresent, "accountType = " + AccountType.Dtrn.getKey()),
false); false);
} }
log.debug("found tranAcc.id = {}", tranAcc.getId()); log.debug("found dtrnAcc.id = {}", dtrnAcc.getId());
//группируем регистры по groupId //группируем регистры по groupId
Map<Long, List<Registry>> groups = registries Map<Long, List<Registry>> groups = registries
.stream() .stream()
@ -191,7 +192,7 @@ public class FormingPaymentInstructionSecondaryT0 implements ISessionStage {
.builder(imdgProvider) .builder(imdgProvider)
.cm_t(cs_t) .cm_t(cs_t)
.lm_t(ls_t) .lm_t(ls_t)
.tranAcc(tranAcc) .tranAcc(dtrnAcc)
.sessionId(sessionId) .sessionId(sessionId)
.paymentPurpose("")//todo пока неизвестная формулировка .paymentPurpose("")//todo пока неизвестная формулировка
.build(); .build();
@ -234,11 +235,16 @@ public class FormingPaymentInstructionSecondaryT0 implements ISessionStage {
private void sendSdfs(List<PaymentInstruction> formedPaymentInstructions) { private void sendSdfs(List<PaymentInstruction> formedPaymentInstructions) {
List<SDf03> sDf03Created = new ArrayList<>(); List<SDf03> sDf03Created = new ArrayList<>();
List<SDf12> sDf12Created = new ArrayList<>();
for (PaymentInstruction paymentInstruction : formedPaymentInstructions) { for (PaymentInstruction paymentInstruction : formedPaymentInstructions) {
Account account = accountImdg.getSingleObjectByID(paymentInstruction.getCreditLeg_accountId()); 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) if (List.of(AccountType.Corr, AccountType.Clrn, AccountType.Tran, AccountType.Anlt, AccountType.Info)
.contains(IEnumKey.getEnumByKey(AccountType.class, account.getAccountType()))) { .contains(IEnumKey.getEnumByKey(AccountType.class, account.getAccountType()))) {
sDf03Created.add(sdf03Creator.create(paymentInstruction)); sDf03Created.add(sdf03Creator.create(paymentInstruction));
} else if (!InstrumentType.CRNC.equalsByKey(security.getInstrumentType()) &&
AccountType.Depo.equalsByKey(account.getAccountType())) {
sDf12Created.add(newSDf12(paymentInstruction));
} }
} }
@ -254,6 +260,31 @@ public class FormingPaymentInstructionSecondaryT0 implements ISessionStage {
exportToFileRequest.setSdfGroupId(sdf03GroupId); exportToFileRequest.setSdfGroupId(sdf03GroupId);
kafkaSender.sendRequestToQueue(Consts.EXPORT_PROCESS, exportToFileRequest); 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) { private SDf12 newSDf12(PaymentInstruction paymentInstruction) {

View file

@ -1,16 +1,19 @@
package ru.spcex.clearing.session.stage.task; package ru.spcex.clearing.session.stage.task;
import ru.clearing.classes.statics.data.payment.PaymentInstruction; import ru.clearing.classes.statics.data.payment.PaymentInstruction;
import ru.spcex.platform.enumeration.Section;
import java.util.Collection; import java.util.Collection;
public class FormingPaymentInstructionDealsMkrPayload { public class FormingPaymentInstructionDealsMkrPayload {
private Long sessionId; private Long sessionId;
private Section section;
/** /**
* для МКР итоговой сессии SDF будет отправляться по 1. возвратам 2. сделкам * для МКР итоговой сессии SDF будет отправляться по 1. возвратам 2. сделкам
* соотв. поле нужно чтобы передать сделанные пейменты из пункта 1 в 2 * соотв. поле нужно чтобы передать сделанные пейменты из пункта 1 в 2
*/ */
private Collection<PaymentInstruction> paymentInstructionReturns; private Collection<PaymentInstruction> paymentInstructionReturns;
private boolean isSendSdfs = true;
public Long getSessionId() { public Long getSessionId() {
return sessionId; return sessionId;
} }
@ -26,4 +29,20 @@ public class FormingPaymentInstructionDealsMkrPayload {
public void setPaymentInstructionReturns(Collection<PaymentInstruction> paymentInstructionReturns) { public void setPaymentInstructionReturns(Collection<PaymentInstruction> paymentInstructionReturns) {
this.paymentInstructionReturns = paymentInstructionReturns; this.paymentInstructionReturns = paymentInstructionReturns;
} }
public boolean isSendSdfs() {
return isSendSdfs;
}
public void setSendSdfs(boolean sendSdfs) {
isSendSdfs = sendSdfs;
}
public Section getSection() {
return section;
}
public void setSection(Section section) {
this.section = section;
}
} }