From 68c74360d5a7412dd61578d746d83fa00e69023b Mon Sep 17 00:00:00 2001 From: AKurakin Date: Thu, 2 Feb 2023 14:22:48 +0300 Subject: [PATCH 1/3] =?UTF-8?q?balance-service=20=D0=BF=D0=BE=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=B8=D0=BB=20=D1=8E=D0=BD=D0=B8=D1=82=D1=82=D0=B5?= =?UTF-8?q?=D1=81=D1=82=20=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=208e787597131e333?= =?UTF-8?q?6f9610f912151c34079702521?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../balance/config/KafkaTestConfig.java | 23 +++++++++++++++++++ .../balance/service/AbstractServiceTest.java | 1 - 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/clearing-parent/balance-service/src/test/java/ru/spcex/clearing/balance/config/KafkaTestConfig.java b/clearing-parent/balance-service/src/test/java/ru/spcex/clearing/balance/config/KafkaTestConfig.java index b56fef2b1..962b45615 100644 --- a/clearing-parent/balance-service/src/test/java/ru/spcex/clearing/balance/config/KafkaTestConfig.java +++ b/clearing-parent/balance-service/src/test/java/ru/spcex/clearing/balance/config/KafkaTestConfig.java @@ -5,9 +5,16 @@ import org.apache.kafka.clients.consumer.OffsetResetStrategy; import org.apache.kafka.clients.producer.MockProducer; import org.apache.kafka.clients.producer.Producer; import org.apache.kafka.common.serialization.StringSerializer; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.serialization.JsonSerializer; +import ru.spcex.clearing.platform.messaging.service.RequestInfo; +import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgId; +import ru.spcex.platform.imdg.api.ImdgProvider; @Configuration public class KafkaTestConfig { @@ -21,4 +28,20 @@ public class KafkaTestConfig { public Producer createTestProducer() { return new MockProducer<>(true, new StringSerializer(), new JsonSerializer()); } + + + @Autowired + @Bean + public KafkaSender kafkaSender(Producer kafkaProducer, ImdgProvider imdgProvider) { + ImdgId imdgIdGenerator = imdgProvider.getImdgIdGenerator(); + return KafkaSender + .setup() + .producer(kafkaProducer) + .idGenerator(imdgIdGenerator::nextId) + .imdgProvider(s -> { + Imdg imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_RequestInfo, RequestInfo.class); + return imdg::insert; + }) + .build(); + } } diff --git a/clearing-parent/balance-service/src/test/java/ru/spcex/clearing/balance/service/AbstractServiceTest.java b/clearing-parent/balance-service/src/test/java/ru/spcex/clearing/balance/service/AbstractServiceTest.java index 1b1aad983..06739ae92 100644 --- a/clearing-parent/balance-service/src/test/java/ru/spcex/clearing/balance/service/AbstractServiceTest.java +++ b/clearing-parent/balance-service/src/test/java/ru/spcex/clearing/balance/service/AbstractServiceTest.java @@ -42,7 +42,6 @@ import static ru.spcex.clearing.balance.utils.MatcherFactory.usingIgnoringFields ValidationConfig.class, SdfExecutorsConfig.class, BalanceImdgTestConfig.class, - KafkaSenderConfig.class, KafkaTestConfig.class}) public abstract class AbstractServiceTest { protected static final MatcherFactory.Matcher ACCOUNT_BALANCE_MATCHER = usingIgnoringFieldsComparator("created", "updated", "clearingDate", "id"); From 118ad70db00faa647d251087291666c1d73fd93b Mon Sep 17 00:00:00 2001 From: AKurakin Date: Thu, 2 Feb 2023 14:31:17 +0300 Subject: [PATCH 2/3] =?UTF-8?q?clearing-service=20http://jira.mfd.msk:8088?= =?UTF-8?q?/browse/CLS-189=20=D0=B4=D0=BE=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=20?= =?UTF-8?q?2.2.2.2,=20=D0=BE=D1=81=D1=82=D0=B0=D0=BB=D0=BE=D1=81=D1=8C=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B8=D0=BC=D0=B5=D0=BD=D0=B8=D1=82=D1=8C=20(?= =?UTF-8?q?=D0=B2=D1=8B=D0=B7=D0=B2=D0=B0=D1=82=D1=8C)=202.2.2=20=D0=B8=20?= =?UTF-8?q?=D0=B4=D0=BE=D0=BF=D0=B8=D1=81=D0=B0=D1=82=D1=8C=20=D0=BD=D0=B0?= =?UTF-8?q?=D1=87=D0=B0=D0=BB=D0=BE.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ru/spcex/clearing/service/Clearing.java | 2 +- .../builder/PaymentInstructionCreator.java | 122 +++++++++++++++++- 2 files changed, 122 insertions(+), 2 deletions(-) diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/Clearing.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/Clearing.java index ade3a551f..935866921 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/Clearing.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/Clearing.java @@ -11,7 +11,7 @@ import ru.clearing.classes.statics.data.payment.PaymentInstruction; import ru.spcex.clearing.error.ClearingErrorInternal; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.service.order.ExecutionDepositSorter; -import ru.spcex.clearing.service.order.PaymentInstructionCreator; +import ru.spcex.clearing.service.builder.PaymentInstructionCreator; import ru.spcex.platform.enumeration.Allowed; import ru.spcex.platform.enumeration.ClearingCategory; import ru.spcex.platform.imdg.api.Imdg; diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionCreator.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionCreator.java index e0dba4ea3..dccab61c4 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionCreator.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionCreator.java @@ -8,14 +8,17 @@ import ru.clearing.classes.statics.data.account.Account; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.CompanySymbols; import ru.clearing.classes.statics.data.liabilities.LiabilitiesClaimsAssets; +import ru.clearing.classes.statics.data.liabilities.LiabilitiesClaimsMoney; import ru.clearing.classes.statics.data.payment.PaymentInstruction; import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.enumeration.*; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; import ru.spcex.platform.utils.time.TimeUtil; +import java.math.BigDecimal; import java.time.Instant; import java.time.LocalDate; import java.time.format.DateTimeFormatter; @@ -24,7 +27,15 @@ import java.util.Collection; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; +import java.util.stream.Collectors; +/* +todo использовать так: + paymentInstructionCreator.createAndSavePaymentInstructions() + paymentInstructionCreator.updateLiabilitiesClaimsAssetsByPaymentInstruction(); + paymentInstructionCreator.updateLiabilitiesClaimsMoneyByPaymentInstruction(); + + */ @Service public class PaymentInstructionCreator { protected static final Long SPVB_ID = 1L; // СПВБ @@ -39,6 +50,7 @@ public class PaymentInstructionCreator { protected final Imdg companyImdg; protected final Imdg accountImdg; protected final Imdg paymentInstructionImdg; + protected final Imdg liabilitiesClaimsMoneyImdg; protected AtomicLong documentNumberId = new AtomicLong(0L); // порядковый номер (сквозной по всем компаниям за день protected LocalDate documentNumberResetAt; @@ -50,10 +62,14 @@ public class PaymentInstructionCreator { this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class); this.paymentInstructionImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PaymentInstruction, PaymentInstruction.class); + this.liabilitiesClaimsMoneyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_LiabilitiesClaimsMoney, LiabilitiesClaimsMoney.class); this.idGenerator = imdgProvider.getImdgIdGenerator(); } - // 2.2.2 + /** + * 2.2.2. Выполнить Создание paymentInstruction по liabilitiesClaimsAssets + * @return Созданные PaymentInstruction, может быть несколько. Они уже сохранены в IMDG. + */ public List createAndSavePaymentInstructions(LiabilitiesClaimsAssets liabilitiesClaimsAssets, Collection clearingCategory) { List newPaymentInstructions = createPaymentInstructions(liabilitiesClaimsAssets, clearingCategory); @@ -420,4 +436,108 @@ public class PaymentInstructionCreator { } + /** + * 2.2.2.1. Выполнить Изменение liabilitiesClaimsAssets по paymentInstruction. + */ + public LiabilitiesClaimsAssets updateLiabilitiesClaimsAssetsByPaymentInstruction(LiabilitiesClaimsAssets liabilitiesClaimsAssets, + List paymentInstructions, + Collection clearingCategory) { + Long lId = liabilitiesClaimsAssets.getId(); + log.debug("Update LiabilitiesClaimsAssets[{}] by paymentInstructions {}", lId, paymentInstructions.stream().map(SpcexObjectBase::getId).collect(Collectors.toList())); + liabilitiesClaimsAssets = liabilitiesClaimsAssetsImdg.getSingleObjectByID(lId); // update data for update + if (liabilitiesClaimsAssets == null) { + throw new RuntimeException("IMDG not contains liabilitiesClaimsAssets.id=" + lId); + } + + updateFieldLiabilitiesClaimsAssetsByPayment(liabilitiesClaimsAssets, paymentInstructions, clearingCategory); + + liabilitiesClaimsAssetsImdg.update(liabilitiesClaimsAssets); + return liabilitiesClaimsAssets; + } + + protected void updateFieldLiabilitiesClaimsAssetsByPayment(LiabilitiesClaimsAssets liabilitiesClaimsAssets, + List paymentInstructions, + Collection clearingCategory) { + + PaymentInstruction paymentIAny=paymentInstructions.iterator().next(); + + if (clearingCategory.contains(ClearingCategory.I) || clearingCategory.contains(ClearingCategory.V)) { + BigDecimal amount = paymentIAny.getCreditLegAmount() == null ? BigDecimal.ZERO : new BigDecimal((Long)paymentIAny.getCreditLegAmount()); +// При обновлении (по paymentInstruction и категория I и счет CLRN):=liabilitiesClaimsAssets.liabilitiesQuantity - paymentInstruction.creditLeg_amount +// При обновлении (по paymentInstruction и категория V и счет INFO):=liabilitiesClaimsAssets.liabilitiesQuantity - paymentInstruction.creditLeg_amount + amount = liabilitiesClaimsAssets.getLiabilitiesQuantity().subtract(amount); + liabilitiesClaimsAssets.setLiabilitiesQuantity(amount); + } + if (clearingCategory.contains(ClearingCategory.B)) { + BigDecimal amount = paymentIAny.getCreditLegAmount() == null ? BigDecimal.ZERO : new BigDecimal((Long)paymentIAny.getCreditLegAmount()); + // При обновлении (по paymentInstruction и категория B и счет CLRN): из paymentInstruction.creditLeg_amount + liabilitiesClaimsAssets.setLiabilitiesQuantity(amount); + } + + if (clearingCategory.contains(ClearingCategory.I) || clearingCategory.contains(ClearingCategory.V)) { + BigDecimal amount = new BigDecimal((Long)paymentIAny.getDebitLegAmount()); + liabilitiesClaimsAssets.setClaimsQuantity(amount); + } + if (clearingCategory.contains(ClearingCategory.B)) { + BigDecimal amount = new BigDecimal((Long)paymentIAny.getDebitLegAmount()); + amount = liabilitiesClaimsAssets.getClaimsQuantity().subtract(amount); + liabilitiesClaimsAssets.setClaimsQuantity(amount); + } + +// //на базе успешного/неуспешного изменения по paymentInstruction +// if (TransactionStatus.fail.equalsByKey(paymentIAny.getTransactionStatus())) { +// liabilitiesClaimsAssets.setClearingStatus(ClearingStatus.FAIL.getKey()); +// } else if (TransactionStatus.ok.equalsByKey(paymentIAny.getTransactionStatus())) { +// liabilitiesClaimsAssets.setClearingStatus(ClearingStatus.OK.getKey()); +// } + + liabilitiesClaimsAssets.setUpdated(Instant.now()); + } + + + /** + * 2.2.2.2. Выполнить Изменение liabilitiesClaimsMoney по paymentInstruction. + */ + public LiabilitiesClaimsMoney updateLiabilitiesClaimsMoneyByPaymentInstruction(LiabilitiesClaimsAssets liabilitiesClaimsAssets, + List paymentInstructions, + Collection clearingCategory) { + Long lmId = liabilitiesClaimsAssets.getLiabilitiesClaimsMoneyId(); + log.debug("Update LiabilitiesClaimsMoney[{}] by paymentInstructions {}", lmId, paymentInstructions.stream().map(SpcexObjectBase::getId).collect(Collectors.toList())); + LiabilitiesClaimsMoney liabilitiesClaimsMoney = liabilitiesClaimsMoneyImdg.getSingleObjectByID(lmId); // update data for update + if (liabilitiesClaimsAssets == null) { + throw new RuntimeException("IMDG not found LiabilitiesClaimsMoney.id=" + lmId); + } + + updateFieldLiabilitiesClaimsMoneyByPayment(liabilitiesClaimsMoney, liabilitiesClaimsAssets, paymentInstructions, clearingCategory); + + liabilitiesClaimsMoneyImdg.update(liabilitiesClaimsMoney); + return liabilitiesClaimsMoney; + } + + protected boolean updateFieldLiabilitiesClaimsMoneyByPayment(LiabilitiesClaimsMoney liabilitiesClaimsMoney, + LiabilitiesClaimsAssets liabilitiesClaimsAssets, + List paymentInstructions, + Collection clearingCategory) { + boolean modified = false; + boolean isFirstLeg = true; // todo уточню ТЗ и допишу. + + PaymentInstruction paymentIAny=paymentInstructions.iterator().next(); + + if ((clearingCategory.contains(ClearingCategory.I) || clearingCategory.contains(ClearingCategory.V)) && isFirstLeg) { + BigDecimal amount = liabilitiesClaimsMoney.getLiabilitiesAmount().subtract(new BigDecimal((Long)paymentIAny.getCreditLegAmount())); + liabilitiesClaimsMoney.setLiabilitiesAmount(amount); + modified = true; + } + + if ((clearingCategory.contains(ClearingCategory.B)) && isFirstLeg) { + BigDecimal amount = liabilitiesClaimsMoney.getClaimsAmount().subtract(new BigDecimal((Long)paymentIAny.getDebitLegAmount())); + liabilitiesClaimsMoney.setClaimsAmount(amount); + modified = true; + } + + if (modified) { + liabilitiesClaimsMoney.setUpdated(Instant.now()); + } + return modified; + } } From 560ffc160af9483f2c16537c86ac4898868cd35a Mon Sep 17 00:00:00 2001 From: AKurakin Date: Thu, 2 Feb 2023 15:33:59 +0300 Subject: [PATCH 3/3] =?UTF-8?q?clearing-service=20http://jira.mfd.msk:8088?= =?UTF-8?q?/browse/CLS-189=20=D0=B4=D0=BE=D0=B4=D0=B5=D0=BB=D0=BA=D0=B8=20?= =?UTF-8?q?2.2.2.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../builder/PaymentInstructionCreator.java | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionCreator.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionCreator.java index dccab61c4..8cff462fe 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionCreator.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionCreator.java @@ -22,10 +22,7 @@ import java.math.BigDecimal; import java.time.Instant; import java.time.LocalDate; import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Collectors; @@ -507,29 +504,38 @@ public class PaymentInstructionCreator { if (liabilitiesClaimsAssets == null) { throw new RuntimeException("IMDG not found LiabilitiesClaimsMoney.id=" + lmId); } - - updateFieldLiabilitiesClaimsMoneyByPayment(liabilitiesClaimsMoney, liabilitiesClaimsAssets, paymentInstructions, clearingCategory); + if (!Objects.equals(liabilitiesClaimsMoney.getSettlementDate(), liabilitiesClaimsAssets.getSettlementDate())) { + log.warn("Date not match: LiabilitiesClaimsMoney[{}].settlementDate={} and LiabilitiesClaimsAssets[{}].settlementDate={}. It is first leg?", + liabilitiesClaimsMoney.getId(), liabilitiesClaimsMoney.getSettlementDate(), liabilitiesClaimsAssets.getId(), liabilitiesClaimsAssets.getSettlementDate() + ); + } + updateFieldLiabilitiesClaimsMoneyByPayment(liabilitiesClaimsMoney, paymentInstructions, clearingCategory); liabilitiesClaimsMoneyImdg.update(liabilitiesClaimsMoney); return liabilitiesClaimsMoney; } + /** + * Обновление liabilitiesClaimsMoney первой ноги по liabilitiesClaimsAssets + * @param liabilitiesClaimsMoney обновить этот объект + * @param paymentInstructions + * @param clearingCategory + * @return были внесены изменения в liabilitiesClaimsMoney + */ protected boolean updateFieldLiabilitiesClaimsMoneyByPayment(LiabilitiesClaimsMoney liabilitiesClaimsMoney, - LiabilitiesClaimsAssets liabilitiesClaimsAssets, List paymentInstructions, Collection clearingCategory) { boolean modified = false; - boolean isFirstLeg = true; // todo уточню ТЗ и допишу. PaymentInstruction paymentIAny=paymentInstructions.iterator().next(); - if ((clearingCategory.contains(ClearingCategory.I) || clearingCategory.contains(ClearingCategory.V)) && isFirstLeg) { + if ((clearingCategory.contains(ClearingCategory.I) || clearingCategory.contains(ClearingCategory.V))) { BigDecimal amount = liabilitiesClaimsMoney.getLiabilitiesAmount().subtract(new BigDecimal((Long)paymentIAny.getCreditLegAmount())); liabilitiesClaimsMoney.setLiabilitiesAmount(amount); modified = true; } - if ((clearingCategory.contains(ClearingCategory.B)) && isFirstLeg) { + if ((clearingCategory.contains(ClearingCategory.B))) { BigDecimal amount = liabilitiesClaimsMoney.getClaimsAmount().subtract(new BigDecimal((Long)paymentIAny.getDebitLegAmount())); liabilitiesClaimsMoney.setClaimsAmount(amount); modified = true;