Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
c59d010444
4 changed files with 155 additions and 7 deletions
|
|
@ -5,9 +5,16 @@ import org.apache.kafka.clients.consumer.OffsetResetStrategy;
|
||||||
import org.apache.kafka.clients.producer.MockProducer;
|
import org.apache.kafka.clients.producer.MockProducer;
|
||||||
import org.apache.kafka.clients.producer.Producer;
|
import org.apache.kafka.clients.producer.Producer;
|
||||||
import org.apache.kafka.common.serialization.StringSerializer;
|
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.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
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.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
|
@Configuration
|
||||||
public class KafkaTestConfig {
|
public class KafkaTestConfig {
|
||||||
|
|
@ -21,4 +28,20 @@ public class KafkaTestConfig {
|
||||||
public Producer<String, Object> createTestProducer() {
|
public Producer<String, Object> createTestProducer() {
|
||||||
return new MockProducer<>(true, new StringSerializer(), new JsonSerializer());
|
return new MockProducer<>(true, new StringSerializer(), new JsonSerializer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Bean
|
||||||
|
public KafkaSender kafkaSender(Producer<String, Object> kafkaProducer, ImdgProvider imdgProvider) {
|
||||||
|
ImdgId imdgIdGenerator = imdgProvider.getImdgIdGenerator();
|
||||||
|
return KafkaSender
|
||||||
|
.setup()
|
||||||
|
.producer(kafkaProducer)
|
||||||
|
.idGenerator(imdgIdGenerator::nextId)
|
||||||
|
.imdgProvider(s -> {
|
||||||
|
Imdg<RequestInfo> imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_RequestInfo, RequestInfo.class);
|
||||||
|
return imdg::insert;
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,6 @@ import static ru.spcex.clearing.balance.utils.MatcherFactory.usingIgnoringFields
|
||||||
ValidationConfig.class,
|
ValidationConfig.class,
|
||||||
SdfExecutorsConfig.class,
|
SdfExecutorsConfig.class,
|
||||||
BalanceImdgTestConfig.class,
|
BalanceImdgTestConfig.class,
|
||||||
KafkaSenderConfig.class,
|
|
||||||
KafkaTestConfig.class})
|
KafkaTestConfig.class})
|
||||||
public abstract class AbstractServiceTest {
|
public abstract class AbstractServiceTest {
|
||||||
protected static final MatcherFactory.Matcher<AccountBalance> ACCOUNT_BALANCE_MATCHER = usingIgnoringFieldsComparator("created", "updated", "clearingDate", "id");
|
protected static final MatcherFactory.Matcher<AccountBalance> ACCOUNT_BALANCE_MATCHER = usingIgnoringFieldsComparator("created", "updated", "clearingDate", "id");
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import ru.clearing.classes.statics.data.payment.PaymentInstruction;
|
||||||
import ru.spcex.clearing.error.ClearingErrorInternal;
|
import ru.spcex.clearing.error.ClearingErrorInternal;
|
||||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||||
import ru.spcex.clearing.service.order.ExecutionDepositSorter;
|
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.Allowed;
|
||||||
import ru.spcex.platform.enumeration.ClearingCategory;
|
import ru.spcex.platform.enumeration.ClearingCategory;
|
||||||
import ru.spcex.platform.imdg.api.Imdg;
|
import ru.spcex.platform.imdg.api.Imdg;
|
||||||
|
|
|
||||||
|
|
@ -8,23 +8,31 @@ import ru.clearing.classes.statics.data.account.Account;
|
||||||
import ru.clearing.classes.statics.data.company.Company;
|
import ru.clearing.classes.statics.data.company.Company;
|
||||||
import ru.clearing.classes.statics.data.company.CompanySymbols;
|
import ru.clearing.classes.statics.data.company.CompanySymbols;
|
||||||
import ru.clearing.classes.statics.data.liabilities.LiabilitiesClaimsAssets;
|
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.clearing.classes.statics.data.payment.PaymentInstruction;
|
||||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||||
|
import ru.spcex.platform.classes.base.SpcexObjectBase;
|
||||||
import ru.spcex.platform.enumeration.*;
|
import ru.spcex.platform.enumeration.*;
|
||||||
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;
|
||||||
import ru.spcex.platform.utils.time.TimeUtil;
|
import ru.spcex.platform.utils.time.TimeUtil;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/*
|
||||||
|
todo использовать так:
|
||||||
|
paymentInstructionCreator.createAndSavePaymentInstructions()
|
||||||
|
paymentInstructionCreator.updateLiabilitiesClaimsAssetsByPaymentInstruction();
|
||||||
|
paymentInstructionCreator.updateLiabilitiesClaimsMoneyByPaymentInstruction();
|
||||||
|
|
||||||
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class PaymentInstructionCreator {
|
public class PaymentInstructionCreator {
|
||||||
protected static final Long SPVB_ID = 1L; // СПВБ
|
protected static final Long SPVB_ID = 1L; // СПВБ
|
||||||
|
|
@ -39,6 +47,7 @@ public class PaymentInstructionCreator {
|
||||||
protected final Imdg<Company> companyImdg;
|
protected final Imdg<Company> companyImdg;
|
||||||
protected final Imdg<Account> accountImdg;
|
protected final Imdg<Account> accountImdg;
|
||||||
protected final Imdg<PaymentInstruction> paymentInstructionImdg;
|
protected final Imdg<PaymentInstruction> paymentInstructionImdg;
|
||||||
|
protected final Imdg<LiabilitiesClaimsMoney> liabilitiesClaimsMoneyImdg;
|
||||||
|
|
||||||
protected AtomicLong documentNumberId = new AtomicLong(0L); // порядковый номер (сквозной по всем компаниям за день
|
protected AtomicLong documentNumberId = new AtomicLong(0L); // порядковый номер (сквозной по всем компаниям за день
|
||||||
protected LocalDate documentNumberResetAt;
|
protected LocalDate documentNumberResetAt;
|
||||||
|
|
@ -50,10 +59,14 @@ public class PaymentInstructionCreator {
|
||||||
this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
|
this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
|
||||||
this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
|
this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
|
||||||
this.paymentInstructionImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PaymentInstruction, PaymentInstruction.class);
|
this.paymentInstructionImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PaymentInstruction, PaymentInstruction.class);
|
||||||
|
this.liabilitiesClaimsMoneyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_LiabilitiesClaimsMoney, LiabilitiesClaimsMoney.class);
|
||||||
this.idGenerator = imdgProvider.getImdgIdGenerator();
|
this.idGenerator = imdgProvider.getImdgIdGenerator();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2.2.2
|
/**
|
||||||
|
* 2.2.2. Выполнить Создание paymentInstruction по liabilitiesClaimsAssets
|
||||||
|
* @return Созданные PaymentInstruction, может быть несколько. Они уже сохранены в IMDG.
|
||||||
|
*/
|
||||||
public List<PaymentInstruction> createAndSavePaymentInstructions(LiabilitiesClaimsAssets liabilitiesClaimsAssets,
|
public List<PaymentInstruction> createAndSavePaymentInstructions(LiabilitiesClaimsAssets liabilitiesClaimsAssets,
|
||||||
Collection<ClearingCategory> clearingCategory) {
|
Collection<ClearingCategory> clearingCategory) {
|
||||||
List<PaymentInstruction> newPaymentInstructions = createPaymentInstructions(liabilitiesClaimsAssets, clearingCategory);
|
List<PaymentInstruction> newPaymentInstructions = createPaymentInstructions(liabilitiesClaimsAssets, clearingCategory);
|
||||||
|
|
@ -420,4 +433,117 @@ public class PaymentInstructionCreator {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2.2.2.1. Выполнить Изменение liabilitiesClaimsAssets по paymentInstruction.
|
||||||
|
*/
|
||||||
|
public LiabilitiesClaimsAssets updateLiabilitiesClaimsAssetsByPaymentInstruction(LiabilitiesClaimsAssets liabilitiesClaimsAssets,
|
||||||
|
List<PaymentInstruction> paymentInstructions,
|
||||||
|
Collection<ClearingCategory> 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<PaymentInstruction> paymentInstructions,
|
||||||
|
Collection<ClearingCategory> 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<PaymentInstruction> paymentInstructions,
|
||||||
|
Collection<ClearingCategory> 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);
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
List<PaymentInstruction> paymentInstructions,
|
||||||
|
Collection<ClearingCategory> clearingCategory) {
|
||||||
|
boolean modified = false;
|
||||||
|
|
||||||
|
PaymentInstruction paymentIAny=paymentInstructions.iterator().next();
|
||||||
|
|
||||||
|
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))) {
|
||||||
|
BigDecimal amount = liabilitiesClaimsMoney.getClaimsAmount().subtract(new BigDecimal((Long)paymentIAny.getDebitLegAmount()));
|
||||||
|
liabilitiesClaimsMoney.setClaimsAmount(amount);
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modified) {
|
||||||
|
liabilitiesClaimsMoney.setUpdated(Instant.now());
|
||||||
|
}
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue