Compare commits
1 commit
10_01_2024
...
sdf03group
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b15c547e6a |
7 changed files with 198 additions and 10 deletions
|
|
@ -0,0 +1,107 @@
|
|||
package ru.spcex.clearing.service;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import ru.clearing.classes.statics.data.account.Account;
|
||||
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
|
||||
import ru.spcex.clearing.service.group.Direction;
|
||||
import ru.spcex.clearing.service.payment.group.PaymentGroup;
|
||||
import ru.spcex.platform.enumeration.Sender;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class PaymentInstructionGroup {
|
||||
private Logger log = LoggerFactory.getLogger(getClass());
|
||||
private Account tranAcc;
|
||||
|
||||
public static PaymentInstructionGroup builder() {
|
||||
return new PaymentInstructionGroup();
|
||||
}
|
||||
|
||||
public PaymentInstructionGroup tran(Account acc) {
|
||||
this.tranAcc = acc;
|
||||
return this;
|
||||
}
|
||||
|
||||
private PaymentInstructionGroup() {}
|
||||
|
||||
public Collection<PaymentGroup> group(List<PaymentInstruction> pmts) {
|
||||
Collection<PaymentGroup> result = new ArrayList<>();
|
||||
pmts = pmts
|
||||
.stream()
|
||||
.sorted(Comparator.comparing(PaymentInstruction::getId))
|
||||
.toList();
|
||||
for (int i = 0; i < pmts.size(); i++) {
|
||||
PaymentInstruction pmt = pmts.get(i);
|
||||
if (pmt == null) {
|
||||
continue;
|
||||
}
|
||||
Direction direction = getDirection(pmt);
|
||||
if (direction.equals(Direction.unknown)) {
|
||||
result.add(new PaymentGroup(pmt));
|
||||
}
|
||||
LinkedList<PaymentInstruction> relatedPmts = new LinkedList<>();
|
||||
relatedPmts.add(pmt);
|
||||
for (int j = i + 1; j < pmts.size(); j++) {
|
||||
PaymentInstruction related = pmts.get(j);
|
||||
if (related == null) {
|
||||
continue;
|
||||
}
|
||||
if (pmtsOfTheSameAgentsToSpvb(pmt, related) || pmtsOfTheSameAgentsFromSpvb(pmt, related)) {
|
||||
relatedPmts.add(related);
|
||||
pmts.set(j, null);
|
||||
}
|
||||
}
|
||||
PaymentGroup paymentGroup = new PaymentGroup();
|
||||
paymentGroup.setPaymentInstructions(relatedPmts);
|
||||
paymentGroup.setDirection(direction);
|
||||
Function<PaymentInstruction, BigDecimal> amountGetter;
|
||||
switch (direction) {
|
||||
case to_spvb -> amountGetter = PaymentInstruction::getCreditLeg_amount;
|
||||
case from_spvb -> amountGetter = PaymentInstruction::getDebitLeg_amount;
|
||||
default -> throw new IllegalStateException("Unexpected value: " + direction);
|
||||
}
|
||||
paymentGroup.setSum(relatedPmts
|
||||
.stream()
|
||||
.map(amountGetter)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add));
|
||||
result.add(paymentGroup);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean pmtsOfTheSameAgentsToSpvb(PaymentInstruction pmt, PaymentInstruction related) {
|
||||
return addresseeIsSpvb(pmt)
|
||||
&& addresseeIsSpvb(related)
|
||||
&& Objects.equals(pmt.getCreditLeg_accountId(), related.getCreditLeg_accountId())
|
||||
&& Objects.equals(pmt.getPaymentPurpose(), related.getPaymentPurpose());
|
||||
}
|
||||
|
||||
private boolean pmtsOfTheSameAgentsFromSpvb(PaymentInstruction pmt, PaymentInstruction related) {
|
||||
return senderIsSpvb(pmt)
|
||||
&& senderIsSpvb(related)
|
||||
&& Objects.equals(pmt.getDebitLeg_accountId(), related.getDebitLeg_accountId())
|
||||
&& Objects.equals(pmt.getPaymentPurpose(), related.getPaymentPurpose());
|
||||
}
|
||||
|
||||
private Direction getDirection(PaymentInstruction p) {
|
||||
if (addresseeIsSpvb(p)) {
|
||||
return Direction.to_spvb;
|
||||
} else if (senderIsSpvb(p)) {
|
||||
return Direction.from_spvb;
|
||||
} else {
|
||||
return Direction.unknown;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean addresseeIsSpvb(PaymentInstruction p) {
|
||||
return p.getAddresseeId().equals(Sender.One.getId()) && p.getDebitLeg_accountId().equals(tranAcc.getId());
|
||||
}
|
||||
|
||||
private boolean senderIsSpvb(PaymentInstruction p) {
|
||||
return p.getSenderId().equals(Sender.One.getId()) && p.getCreditLeg_accountId().equals(tranAcc.getId());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ import ru.clearing.classes.statics.data.payment.PaymentInstruction;
|
|||
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
|
||||
import ru.clearing.classes.statics.data.sdf.SDf03;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.service.payment.group.PaymentGroup;
|
||||
import ru.spcex.platform.enumeration.AccountType;
|
||||
import ru.spcex.platform.enumeration.Status;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
|
|
@ -20,6 +21,7 @@ import ru.spcex.platform.utils.time.TimeUtil;
|
|||
|
||||
import java.time.Instant;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
public class Sdf03Creator {
|
||||
|
|
@ -114,6 +116,17 @@ public class Sdf03Creator {
|
|||
return sDf03;
|
||||
}
|
||||
|
||||
public SDf03 create(PaymentGroup group) {
|
||||
Optional<PaymentInstruction> pmt = group.getPaymentInstructions().stream().findFirst();
|
||||
if (pmt.isEmpty()) {
|
||||
throw new IllegalStateException("empty group"); //never
|
||||
}
|
||||
SDf03 sDf03 = create(pmt.get());
|
||||
String sumDeb = group.getSum() != null ? group.getSum().toString() : "";
|
||||
sDf03.setSum_deb(BigDecimalUtil.limitDecimalPlaces(sumDeb, 2));
|
||||
return sDf03;
|
||||
}
|
||||
|
||||
private AccountType getAccountType(Long accountId) {
|
||||
Account account = accountImdg.getSingleObjectByID(accountId);
|
||||
return IEnumKey.getEnumByKey(AccountType.class, account.getAccountType());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
package ru.spcex.clearing.service.payment.group;
|
||||
|
||||
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
|
||||
import ru.spcex.clearing.service.group.Direction;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class PaymentGroup {
|
||||
private List<PaymentInstruction> paymentInstructions;
|
||||
private BigDecimal sum;
|
||||
private Direction direction;
|
||||
|
||||
public PaymentGroup() {
|
||||
}
|
||||
|
||||
public PaymentGroup(PaymentInstruction pmt) {
|
||||
this.paymentInstructions = Collections.singletonList(pmt);
|
||||
//fixme в старом заполнении нашел только поле sDf03.setSum_deb (pmt.getDebitLeg_amount)
|
||||
this.sum = pmt.getDebitLeg_amount();
|
||||
this.direction = Direction.unknown;
|
||||
}
|
||||
|
||||
public List<PaymentInstruction> getPaymentInstructions() {
|
||||
return paymentInstructions;
|
||||
}
|
||||
|
||||
public void setPaymentInstructions(List<PaymentInstruction> paymentInstructions) {
|
||||
this.paymentInstructions = paymentInstructions;
|
||||
}
|
||||
|
||||
public BigDecimal getSum() {
|
||||
return sum;
|
||||
}
|
||||
|
||||
public void setSum(BigDecimal sum) {
|
||||
this.sum = sum;
|
||||
}
|
||||
|
||||
public Direction getDirection() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
public void setDirection(Direction direction) {
|
||||
this.direction = direction;
|
||||
}
|
||||
}
|
||||
|
|
@ -19,9 +19,11 @@ 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.PaymentInstructionGroup;
|
||||
import ru.spcex.clearing.service.RegistryManager;
|
||||
import ru.spcex.clearing.service.Sdf03Creator;
|
||||
import ru.spcex.clearing.service.builder.PaymentInstructionBuilderFinalMkrDeals;
|
||||
import ru.spcex.clearing.service.payment.group.PaymentGroup;
|
||||
import ru.spcex.clearing.session.stage.ISessionStage;
|
||||
import ru.spcex.clearing.session.stage.StageResult;
|
||||
import ru.spcex.clearing.session.stage.Task;
|
||||
|
|
@ -194,7 +196,7 @@ public class FormingPaymentInstructionDealsFinalMkr implements ISessionStage {
|
|||
cm_t.getId(),
|
||||
lm_t.getId());
|
||||
String paymentPurpose = section != null && section == Section.FOND ? "" :
|
||||
"Размещение депозита " + lm_t.getContract() + " по ТКР " + lm_t.getTradingClearingRegistry();
|
||||
"Перевод по итогу клиринга по ТКР " + lm_t.getTradingClearingRegistry();
|
||||
Pair<PaymentInstruction, PaymentInstruction> pmtInstrs = PaymentInstructionBuilderFinalMkrDeals
|
||||
.builder(imdgProvider)
|
||||
.cm_t(cm_t)
|
||||
|
|
@ -218,7 +220,7 @@ public class FormingPaymentInstructionDealsFinalMkr implements ISessionStage {
|
|||
paymentInstructionDeals.size());
|
||||
List<PaymentInstruction> returnsAndDeals = Stream.concat(paymentInstructionReturns.stream(), paymentInstructionDeals.stream()).toList();
|
||||
if (sendSdfs) {
|
||||
sendSdfs(returnsAndDeals);
|
||||
sendSdfs(returnsAndDeals, tranAcc);
|
||||
}
|
||||
StageResult<Collection<PaymentInstruction>> stageResult = new StageResult<>(null, true);
|
||||
stageResult.setStageResult(returnsAndDeals);
|
||||
|
|
@ -231,26 +233,39 @@ public class FormingPaymentInstructionDealsFinalMkr implements ISessionStage {
|
|||
registryImdg.update(rgs);
|
||||
}
|
||||
|
||||
private void sendSdfs(List<PaymentInstruction> formedPaymentInstructions) {
|
||||
List<SDf03> sDf03Created = new ArrayList<>();
|
||||
private void sendSdfs(List<PaymentInstruction> formedPaymentInstructions, Account tranAcc) {
|
||||
List<SDf12> sDf12Created = new ArrayList<>();
|
||||
List<PaymentInstruction> forSdf03 = 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));
|
||||
forSdf03.add(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) {
|
||||
Long sdf03GroupId = !forSdf03.isEmpty() ? imdgProvider.getImdgIdGenerator().nextId() : null;
|
||||
Collection<PaymentGroup> groups = PaymentInstructionGroup.builder()
|
||||
.tran(tranAcc)
|
||||
.group(forSdf03);
|
||||
for(PaymentGroup group : groups) {
|
||||
SDf03 sDf03 = sdf03Creator.create(group);
|
||||
sDf03.setGenerationId(sdf03GroupId);
|
||||
sDf03Imdg.insert(sDf03);
|
||||
log.debug("created SDF03.groupId/id={}/{} for {} by paymentInstructions: {} ",
|
||||
sdf03GroupId,
|
||||
sDf03.getId(),
|
||||
group.getPaymentInstructions().size(),
|
||||
group.getPaymentInstructions()
|
||||
.stream()
|
||||
.map(PaymentInstruction::getId)
|
||||
.map(String::valueOf)
|
||||
.collect(Collectors.joining(",", "[", "]"))
|
||||
);
|
||||
}
|
||||
|
||||
if (sdf03GroupId != null) {
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ public class FormingPaymentInstructionDepositReturn implements ISessionStage {
|
|||
.cm_t(cm_t)
|
||||
.tranAcc(tranAcc)
|
||||
.sessionId(sessionId)
|
||||
.paymentPurpose("Возврат депозита " + cm_t.getContract() + " по ТКР " + cm_t.getTradingClearingRegistry())
|
||||
.paymentPurpose("Перевод по итогу клиринга по ТКР " + cm_t.getTradingClearingRegistry())
|
||||
.build();
|
||||
paymentInstructionImdg.insert(pmts.getFirst());
|
||||
paymentInstructionImdg.insert(pmts.getSecond());
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ public class FormingPaymentInstructionReturnMkr implements ISessionStage {
|
|||
.cm_t(cm_t)
|
||||
.tranAcc(tranAcc)
|
||||
.sessionId(sessionId)
|
||||
.paymentPurpose("Возврат депозита " + cm_t.getContract() + " по ТКР " + cm_t.getTradingClearingRegistry())
|
||||
.paymentPurpose("Перевод по итогу клиринга по ТКР " + cm_t.getTradingClearingRegistry())
|
||||
.build();
|
||||
paymentInstructionImdg.insert(pmts.getFirst());
|
||||
paymentInstructionImdg.insert(pmts.getSecond());
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
package ru.spcex.clearing.service.group;
|
||||
|
||||
public enum Direction {
|
||||
to_spvb, from_spvb, unknown;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue