Merge remote-tracking branch 'origin/dev' into dev
# Conflicts: # clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/Clearing.java # platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/AccountType.java
This commit is contained in:
commit
a27d4c3061
8 changed files with 478 additions and 13 deletions
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--?xml-stylesheet type="text/xsl" href="\..\corp-reports\src\data\meta\meta.server.xslt"?-->
|
||||
<meta version="2.4.0.8">
|
||||
<meta version="2.4.0.9">
|
||||
<!-- _xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" _xsi:noNamespaceSchemaLocation="file:///E:/d/projects/meta/from/meta.xsd" -->
|
||||
<!--Здесь словари-->
|
||||
<enums>
|
||||
|
|
@ -713,8 +713,8 @@
|
|||
</actions>
|
||||
</bankAccount>
|
||||
<informationAccount name="Информационные счета" destination="securities/information-accounts" class="ru.clearing.classes.statics.data.account.InformationAccount" logUpdates="true" table="information_account">
|
||||
<accountId type="1" name="Счет" shortname="Счет" searchable="true" sortable="true" visible="true" link="account" linkCode="account"/>
|
||||
<clearingAccountId type="1" name="Счета" shortname="Счет" searchable="true" sortable="true" visible="true" link="account" linkCode="account"/>
|
||||
<accountId type="1" name="Информационный счет" shortname="Информационный счет" searchable="true" sortable="true" visible="true" link="account" linkCode="account"/>
|
||||
<clearingAccountId type="1" name="Аналитический счет" shortname="Аналитический счет" searchable="true" sortable="true" visible="true" link="account" linkCode="account"/>
|
||||
<companyId type="1" name="Компания" shortname="Компания" searchable="true" sortable="true" visible="true" link="company" linkCode="shortName"/>
|
||||
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
|
||||
</informationAccount>
|
||||
|
|
@ -752,7 +752,7 @@
|
|||
<instrumentType type="12" name="Наименование типа инструмента" shortname="Тип инструмента" searchable="true" sortable="true" visible="true" link="instrumentType" extends="security"/>
|
||||
<fullName type="2" name="Полное наименование инструмента" shortname="Наименование" searchable="true" sortable="true" length="255" visible="true" extends="security"/>
|
||||
<securitySymbol type="2" name="Код инструмента" shortname="Код" searchable="true" sortable="true" length="255" visible="true" extends="security"/>
|
||||
<termType type="12" name="Наименование вида инструмента" shortname="Вид инструмента" searchable="true" sortable="true" visible="true" link="termType"/>
|
||||
<termType type="12" name="Наименование вида инструмента" shortname="Вид инструмента" searchable="true" sortable="true" visible="false" link="termType" ignore="true"/>
|
||||
<lotSize field="securityId" type="11" name="Размер лота" shortname="Размер лота" searchable="true" sortable="true" visible="true" linkKeyCode="securityId" linkCode="lotSize" link="listing"/>
|
||||
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
|
||||
<actions>
|
||||
|
|
@ -907,13 +907,13 @@
|
|||
<secondLegAmount type="11" name="Объем возврата" shortname="Объем возврата" visible="false" searchable="true" sortable="true"/>
|
||||
<interestAmount type="11" name="Объем процентов" shortname="Проценты" visible="false" searchable="true" sortable="true"/>
|
||||
<side type="12" name="Направление сделки" shortname="Направление" visible="true" searchable="true" sortable="true" link="moneyFlowSide"/>
|
||||
<settlementCurrency type="12" name="Валюта расчетов по инструменту" shortname="Валюта" visible="true" searchable="true" sortable="true" link="currencyCode" linkCode="currencyCode"/>
|
||||
<settlementCurrency type="12" name="Валюта расчетов по инструменту" shortname="Валюта" visible="true" searchable="true" sortable="true" link="currencyCode" linkCode="code"/>
|
||||
<companyId type="1" name="Название компании" shortname="Компания" visible="true" searchable="true" sortable="true" link="company" linkCode="shortName"/>
|
||||
<duration type="1" name="Срок, дней" shortname="Срок" visible="true" searchable="true" sortable="true"/>
|
||||
<firstLegSettlementDate type="6" name="Дата размещения" shortname="Дата размещения" visible="true" searchable="true" sortable="true"/>
|
||||
<secondLegSettlementDate type="6" name="Дата возврата" shortname="Дата возврата" visible="true" searchable="true" sortable="true"/>
|
||||
<firstLegSettlementCode type="6" name="Код расчетов при размещении" shortname="Код расчетов при размещении" visible="false" searchable="true" sortable="true"/>
|
||||
<secondLegSettlementCode type="6" name="Код расчетов при возврате" shortname="Код расчетов" visible="true" searchable="true" sortable="true"/>
|
||||
<firstLegSettlementCode type="6" name="Код расчетов при размещении" shortname="Код расчетов при размещении" visible="false" searchable="true" sortable="true" ignore="true"/>
|
||||
<secondLegSettlementCode type="6" name="Код расчетов при возврате" shortname="Код расчетов" visible="false" searchable="true" sortable="true" ignore="true"/>
|
||||
<securityFullName type="2" length="255" name="Наименование инструмента" shortname="Инструмент" visible="true" searchable="true" sortable="true"/>
|
||||
<securitySymbol type="2" length="255" name="Код инструмента в Торговой Системе" shortname="Код инструмента" visible="true" searchable="true" sortable="true"/>
|
||||
<securityId type="1" name="Финансовый инструмент" shortname="Код биржевого инструмента / товара" searchable="true" sortable="true" link="moneyMarketSecurity" linkCode="securitySymbol" ignore="true"/>
|
||||
|
|
|
|||
|
|
@ -51,6 +51,10 @@
|
|||
<artifactId>assertj-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<resources>
|
||||
|
|
|
|||
|
|
@ -6,9 +6,12 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.stereotype.Service;
|
||||
import ru.clearing.classes.statics.data.execution.ExecutionDeposit;
|
||||
import ru.clearing.classes.statics.data.generated.ClearingMemberCategory;
|
||||
import ru.clearing.classes.statics.data.liabilities.LiabilitiesClaimsAssets;
|
||||
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.platform.enumeration.Allowed;
|
||||
import ru.spcex.platform.enumeration.ClearingCategory;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
|
|
@ -28,6 +31,7 @@ public class Clearing {
|
|||
private final Imdg<ClearingMemberCategory> clearingCategoryImdg;
|
||||
private final ExecutionDepositSorter sorter;
|
||||
private final BiFunction<ClearingCategory, ExecutionDeposit, IValidator> validation;
|
||||
private final PaymentInstructionCreator paymentInstructionCreator;
|
||||
private final ImdgId idProvider;
|
||||
//при прохождении по выгруженным ExecutionDeposit, ошибочные статусы проставляются для
|
||||
//контр сделок. В таком случае, в коллекции хранятся не синхронизированные с IMDG ExecutionDeposit
|
||||
|
|
@ -38,10 +42,11 @@ public class Clearing {
|
|||
|
||||
@Autowired
|
||||
public Clearing(ImdgProvider imdgProvider,
|
||||
ExecutionDepositSorter sorter,
|
||||
ExecutionDepositSorter sorter, PaymentInstructionCreator paymentInstructionCreator,
|
||||
BiFunction<ClearingCategory, ExecutionDeposit, IValidator> validation) {
|
||||
this.executionDepositImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionDeposit, ExecutionDeposit.class);
|
||||
this.clearingCategoryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class);
|
||||
this.paymentInstructionCreator = paymentInstructionCreator;
|
||||
this.idProvider = imdgProvider.getImdgIdGenerator();
|
||||
this.sorter = sorter;
|
||||
this.validation = validation;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,423 @@
|
|||
package ru.spcex.clearing.service.order;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
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.company.CompanySymbols;
|
||||
import ru.clearing.classes.statics.data.liabilities.LiabilitiesClaimsAssets;
|
||||
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
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.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.concurrent.atomic.AtomicLong;
|
||||
|
||||
@Service
|
||||
public class PaymentInstructionCreator {
|
||||
protected static final Long SPVB_ID = 1L; // СПВБ
|
||||
protected static final Long PRC_ID = 2L; // 2 "НКО АО ПРЦ"
|
||||
private static final DateTimeFormatter DATE_FORMATTER_ddMMyy = DateTimeFormatter.ofPattern("ddMMyy");
|
||||
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
protected final ImdgId idGenerator;
|
||||
protected final Imdg<LiabilitiesClaimsAssets> liabilitiesClaimsAssetsImdg;
|
||||
protected final Imdg<CompanySymbols> companySymbolsImdg;
|
||||
protected final Imdg<Company> companyImdg;
|
||||
protected final Imdg<Account> accountImdg;
|
||||
protected final Imdg<PaymentInstruction> paymentInstructionImdg;
|
||||
|
||||
protected AtomicLong documentNumberId = new AtomicLong(0L); // порядковый номер (сквозной по всем компаниям за день
|
||||
protected LocalDate documentNumberResetAt;
|
||||
|
||||
@Autowired
|
||||
public PaymentInstructionCreator(ImdgProvider imdgProvider) {
|
||||
this.liabilitiesClaimsAssetsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_LiabilitiesClaimsAssets, LiabilitiesClaimsAssets.class);
|
||||
this.companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
|
||||
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.idGenerator = imdgProvider.getImdgIdGenerator();
|
||||
}
|
||||
|
||||
// 2.2.2
|
||||
public List<PaymentInstruction> createAndSavePaymentInstructions(LiabilitiesClaimsAssets liabilitiesClaimsAssets,
|
||||
Collection<ClearingCategory> clearingCategory) {
|
||||
List<PaymentInstruction> newPaymentInstructions = createPaymentInstructions(liabilitiesClaimsAssets, clearingCategory);
|
||||
log.debug("Created {} PaymentInstruction by LiabilitiesClaimsAssets[{}]",
|
||||
newPaymentInstructions.size(), liabilitiesClaimsAssets.getId());
|
||||
for (PaymentInstruction instruction : newPaymentInstructions) {
|
||||
paymentInstructionImdg.insert(instruction);
|
||||
}
|
||||
return newPaymentInstructions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Создаёт и сохраняет
|
||||
*
|
||||
* @param liabilitiesClaimsAssets
|
||||
* @param clearingCategory
|
||||
* @return
|
||||
*/
|
||||
protected List<PaymentInstruction> createPaymentInstructions(LiabilitiesClaimsAssets liabilitiesClaimsAssets,
|
||||
Collection<ClearingCategory> clearingCategory) {
|
||||
List<PaymentInstruction> newPaymentInstructions = new ArrayList<>();
|
||||
Instant now = Instant.now();
|
||||
|
||||
// I
|
||||
if (clearingCategory.contains(ClearingCategory.I)) {
|
||||
log.debug("By liabilitiesClaimsAssets[{}] create for category I 1 record", liabilitiesClaimsAssets.getId());
|
||||
PaymentInstruction payment1 = new PaymentInstruction();
|
||||
PaymentInstruction payment2 = new PaymentInstruction();
|
||||
|
||||
payment1.setId(idGenerator.nextId());
|
||||
payment1.setCreated(now);
|
||||
payment1.setClearingDate(TimeUtil.toLocalDate(now));
|
||||
payment2.setId(idGenerator.nextId());
|
||||
payment2.setCreated(now);
|
||||
payment2.setClearingDate(TimeUtil.toLocalDate(now));
|
||||
|
||||
payment1.setSenderId(liabilitiesClaimsAssets.getCompanyId());
|
||||
payment2.setSenderId(SPVB_ID); // СПВБ
|
||||
|
||||
payment1.setAddresseeId(SPVB_ID); // СПВБ
|
||||
String sqlLCA = String.format("securityId = %s and companyId <> %s",
|
||||
liabilitiesClaimsAssets.getSecurityId(), liabilitiesClaimsAssets.getCompanyId());
|
||||
LiabilitiesClaimsAssets counterLiabilitiesClaimsAssets = liabilitiesClaimsAssetsImdg.getSingleObjectBySQL(sqlLCA);
|
||||
if (counterLiabilitiesClaimsAssets == null) {
|
||||
log.warn("Counter LiabilitiesClaimsAssets not found for : {}", sqlLCA);
|
||||
} else {
|
||||
payment2.setAddresseeId(counterLiabilitiesClaimsAssets.getCompanyId());
|
||||
}
|
||||
|
||||
String symbol1 = selectSymbolValue(payment1.getAddresseeId(), CompanySymbol.BIC);
|
||||
if (symbol1 == null) {
|
||||
log.warn("CompanySymbols BIC not found for companyId={}", payment1.getAddresseeId());
|
||||
} else {
|
||||
payment1.setAdresseeBic(symbol1);
|
||||
}
|
||||
String symbol2 = selectSymbolValue(payment2.getAddresseeId(), CompanySymbol.BIC);
|
||||
if (symbol2 == null) {
|
||||
log.warn("CompanySymbols BIC not found for companyId={}", payment2.getAddresseeId());
|
||||
} else {
|
||||
payment2.setAdresseeBic(symbol2);
|
||||
}
|
||||
|
||||
Company companyPRC = companyImdg.getSingleObjectByID(PRC_ID); // 2 "НКО АО ПРЦ"
|
||||
String companyPRCName = null;
|
||||
if (companyPRC == null) {
|
||||
log.warn("Company.id=2 not found");
|
||||
} else {
|
||||
companyPRCName = companyPRC.getShortName();
|
||||
}
|
||||
payment1.setPayeeBankName(companyPRCName);
|
||||
payment2.setPayeeBankName(companyPRCName);
|
||||
|
||||
String symbolPRC = selectSymbolValue(PRC_ID, CompanySymbol.BIC); // 2 "НКО АО ПРЦ"
|
||||
payment1.setPayeeBic(symbolPRC);
|
||||
payment2.setPayeeBic(symbolPRC);
|
||||
|
||||
payment1.setAddresseeBankName(companyPRCName);
|
||||
payment2.setAddresseeBankName(companyPRCName);
|
||||
|
||||
payment1.setPaymentDate(TimeUtil.localDateToInstant(liabilitiesClaimsAssets.getSettlementDate()));
|
||||
payment2.setPaymentDate(TimeUtil.localDateToInstant(liabilitiesClaimsAssets.getSettlementDate()));
|
||||
|
||||
payment1.setPaymentPurpose("Размещение депозита " + liabilitiesClaimsAssets.getContract());
|
||||
payment2.setPaymentPurpose("Размещение депозита " + liabilitiesClaimsAssets.getContract());
|
||||
|
||||
payment1.setSettlementDate(liabilitiesClaimsAssets.getSettlementDate());
|
||||
payment2.setSettlementDate(liabilitiesClaimsAssets.getSettlementDate());
|
||||
|
||||
Long amount = liabilitiesClaimsAssets.getLiabilitiesQuantity() == null ? null : liabilitiesClaimsAssets.getLiabilitiesQuantity().abs().longValue();
|
||||
payment1.setCreditLegAmount(amount);
|
||||
payment2.setCreditLegAmount(amount);
|
||||
payment1.setDebitLegAmount(amount);
|
||||
payment2.setDebitLegAmount(amount);
|
||||
|
||||
payment1.setCreditLegAccountId(liabilitiesClaimsAssets.getAccountId());
|
||||
String accSql = String.format("companyId = %s AND accountType=TRAN AND accountStatus=ACTV AND processingSign=ALWD",
|
||||
payment2.getSenderId());
|
||||
Account anotherAcc = accountImdg.getSingleObjectBySQL(accSql);
|
||||
if (anotherAcc == null) {
|
||||
log.warn("Account not found: {}", accSql);
|
||||
} else {
|
||||
payment2.setCreditLegAccountId(anotherAcc.getId());
|
||||
}
|
||||
|
||||
payment1.setCreditCsAccount(null);
|
||||
payment2.setCreditCsAccount(null);
|
||||
|
||||
{
|
||||
Account acc1 = accountImdg.getSingleObjectByID(payment1.getCreditLegAccountId());
|
||||
if (acc1 != null) {
|
||||
payment1.setCreditLegAccount(acc1.getAccount());
|
||||
}
|
||||
Account acc2 = accountImdg.getSingleObjectByID(payment2.getCreditLegAccountId());
|
||||
if (acc2 != null) {
|
||||
payment1.setCreditLegAccount(acc2.getAccount());
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Account acc1 = selectAccount(payment1.getAddresseeId(), AccountType.Tran, Status.Active, Allowed.ALLOWED);
|
||||
if (acc1 != null) {
|
||||
payment1.setDebitLegAccountId(acc1.getId());
|
||||
payment1.setDebitLegAccount(acc1.getAccount());
|
||||
}
|
||||
Account acc2 = selectAccount(payment2.getAddresseeId(), AccountType.Clrn, Status.Active, Allowed.ALLOWED);
|
||||
if (acc2 != null) {
|
||||
payment2.setDebitLegAccountId(acc2.getId());
|
||||
payment2.setDebitLegAccount(acc2.getAccount());
|
||||
}
|
||||
}
|
||||
|
||||
payment1.setDebitCsAccount(null);
|
||||
payment2.setDebitCsAccount(null);
|
||||
|
||||
// payment1.setCreditLegDirection(InOutDirection.out.getKey());
|
||||
// payment2.setCreditLegDirection(InOutDirection.out.getKey());
|
||||
// payment1.setDebitLegDirection(InOutDirection.in.getKey());
|
||||
// payment2.setDebitLegDirection(InOutDirection.in.getKey());
|
||||
|
||||
payment1.setCreditLegCurrencyCode(liabilitiesClaimsAssets.getCurrency());
|
||||
payment2.setCreditLegCurrencyCode(liabilitiesClaimsAssets.getCurrency());
|
||||
payment1.setDebitLegCurrencyCode(liabilitiesClaimsAssets.getCurrency());
|
||||
payment2.setDebitLegCurrencyCode(liabilitiesClaimsAssets.getCurrency());
|
||||
|
||||
payment1.setTransactionStatus(TransactionStatus.stld.getKey());
|
||||
payment2.setTransactionStatus(TransactionStatus.stld.getKey());
|
||||
|
||||
|
||||
payment1.setDocumentNumber(nextDocumentNumber(liabilitiesClaimsAssets, payment1));
|
||||
payment2.setDocumentNumber(nextDocumentNumber(liabilitiesClaimsAssets, payment2));
|
||||
|
||||
newPaymentInstructions.add(payment1);
|
||||
newPaymentInstructions.add(payment2);
|
||||
} else {
|
||||
// V / B
|
||||
if (clearingCategory.contains(ClearingCategory.V)) {
|
||||
log.debug("By liabilitiesClaimsAssets[{}] create for category V 1 record", liabilitiesClaimsAssets.getId());
|
||||
PaymentInstruction payment1 = new PaymentInstruction();
|
||||
payment1.setId(idGenerator.nextId());
|
||||
payment1.setCreated(now);
|
||||
payment1.setClearingDate(TimeUtil.toLocalDate(now));
|
||||
|
||||
payment1.setSenderId(SPVB_ID); // СПВБ
|
||||
|
||||
String sqlLCA = String.format("securityId = %s and companyId <> %s",
|
||||
liabilitiesClaimsAssets.getSecurityId(), liabilitiesClaimsAssets.getCompanyId());
|
||||
LiabilitiesClaimsAssets counterLiabilitiesClaimsAssets = liabilitiesClaimsAssetsImdg.getSingleObjectBySQL(sqlLCA);
|
||||
if (counterLiabilitiesClaimsAssets == null) {
|
||||
log.warn("Counter LiabilitiesClaimsAssets not found for : {}", sqlLCA);
|
||||
} else {
|
||||
payment1.setAddresseeId(counterLiabilitiesClaimsAssets.getCompanyId());
|
||||
}
|
||||
|
||||
String symbol1 = selectSymbolValue(payment1.getAddresseeId(), CompanySymbol.BIC);
|
||||
if (symbol1 == null) {
|
||||
log.warn("CompanySymbols BIC not found for companyId={}", payment1.getAddresseeId());
|
||||
} else {
|
||||
payment1.setAdresseeBic(symbol1);
|
||||
}
|
||||
|
||||
Company companyPRC = companyImdg.getSingleObjectByID(PRC_ID); // 2 "НКО АО ПРЦ"
|
||||
String companyPRCName = null;
|
||||
if (companyPRC == null) {
|
||||
log.warn("Company.id=2 not found");
|
||||
} else {
|
||||
companyPRCName = companyPRC.getShortName();
|
||||
}
|
||||
payment1.setPayeeBankName(companyPRCName);
|
||||
|
||||
String symbolPRC = selectSymbolValue(PRC_ID, CompanySymbol.BIC); // 2 "НКО АО ПРЦ"
|
||||
payment1.setPayeeBic(symbolPRC);
|
||||
|
||||
payment1.setAddresseeBankName(companyPRCName);
|
||||
|
||||
payment1.setPaymentDate(TimeUtil.localDateToInstant(liabilitiesClaimsAssets.getSettlementDate()));
|
||||
|
||||
payment1.setPaymentPurpose("Размещение депозита " + liabilitiesClaimsAssets.getContract());
|
||||
|
||||
payment1.setSettlementDate(liabilitiesClaimsAssets.getSettlementDate());
|
||||
|
||||
Long amount = liabilitiesClaimsAssets.getLiabilitiesQuantity() == null ? null : liabilitiesClaimsAssets.getLiabilitiesQuantity().abs().longValue();
|
||||
payment1.setCreditLegAmount(amount);
|
||||
payment1.setDebitLegAmount(amount);
|
||||
|
||||
{
|
||||
String accSql = String.format("companyId = %s AND accountType=ANLT AND accountStatus=ACTV AND processingSign=ALWD",
|
||||
payment1.getSenderId());
|
||||
Account acc1 = accountImdg.getSingleObjectBySQL(accSql);
|
||||
if (acc1 == null) {
|
||||
log.warn("Account not found: {}", accSql);
|
||||
} else {
|
||||
payment1.setCreditLegAccountId(acc1.getId());
|
||||
payment1.setCreditLegAccount(acc1.getAccount());
|
||||
}
|
||||
}
|
||||
|
||||
payment1.setCreditCsAccount(null);
|
||||
|
||||
{
|
||||
Account acc1 = selectAccount(payment1.getAddresseeId(), AccountType.Corr, Status.Active, Allowed.ALLOWED);
|
||||
if (acc1 != null) {
|
||||
payment1.setDebitLegAccountId(acc1.getId());
|
||||
payment1.setDebitLegAccount(acc1.getAccount());
|
||||
}
|
||||
}
|
||||
|
||||
payment1.setDebitCsAccount(null);
|
||||
|
||||
// payment1.setCreditLegDirection(InOutDirection.out.getKey());
|
||||
// payment1.setDebitLegDirection(InOutDirection.in.getKey());
|
||||
|
||||
payment1.setCreditLegCurrencyCode(liabilitiesClaimsAssets.getCurrency());
|
||||
payment1.setDebitLegCurrencyCode(liabilitiesClaimsAssets.getCurrency());
|
||||
|
||||
payment1.setTransactionStatus(TransactionStatus.stld.getKey());
|
||||
|
||||
|
||||
payment1.setDocumentNumber(nextDocumentNumber(liabilitiesClaimsAssets, payment1));
|
||||
|
||||
newPaymentInstructions.add(payment1);
|
||||
} else // Для V,B только 1 PaymentInstruction
|
||||
if (clearingCategory.contains(ClearingCategory.B)) {
|
||||
log.debug("By liabilitiesClaimsAssets[{}] create for category B 1 record", liabilitiesClaimsAssets.getId());
|
||||
PaymentInstruction payment1 = new PaymentInstruction();
|
||||
payment1.setId(idGenerator.nextId());
|
||||
payment1.setCreated(now);
|
||||
payment1.setClearingDate(TimeUtil.toLocalDate(now));
|
||||
|
||||
payment1.setSenderId(liabilitiesClaimsAssets.getCompanyId());
|
||||
|
||||
payment1.setAddresseeId(SPVB_ID); // СПВБ
|
||||
|
||||
String symbol1 = selectSymbolValue(payment1.getAddresseeId(), CompanySymbol.BIC);
|
||||
if (symbol1 == null) {
|
||||
log.warn("CompanySymbols BIC not found for companyId={}", payment1.getAddresseeId());
|
||||
} else {
|
||||
payment1.setAdresseeBic(symbol1);
|
||||
}
|
||||
|
||||
Company companyPRC = companyImdg.getSingleObjectByID(PRC_ID); // 2 "НКО АО ПРЦ"
|
||||
String companyPRCName = null;
|
||||
if (companyPRC == null) {
|
||||
log.warn("Company.id=2 not found");
|
||||
} else {
|
||||
companyPRCName = companyPRC.getShortName();
|
||||
}
|
||||
payment1.setPayeeBankName(companyPRCName);
|
||||
|
||||
String symbolPRC = selectSymbolValue(PRC_ID, CompanySymbol.BIC); // 2 "НКО АО ПРЦ"
|
||||
payment1.setPayeeBic(symbolPRC);
|
||||
|
||||
payment1.setAddresseeBankName(companyPRCName);
|
||||
|
||||
payment1.setPaymentDate(TimeUtil.localDateToInstant(liabilitiesClaimsAssets.getSettlementDate()));
|
||||
|
||||
payment1.setPaymentPurpose("Размещение депозита " + liabilitiesClaimsAssets.getContract());
|
||||
|
||||
payment1.setSettlementDate(liabilitiesClaimsAssets.getSettlementDate());
|
||||
|
||||
Long amount = liabilitiesClaimsAssets.getLiabilitiesQuantity() == null ? null : liabilitiesClaimsAssets.getLiabilitiesQuantity().abs().longValue();
|
||||
payment1.setCreditLegAmount(amount);
|
||||
payment1.setDebitLegAmount(amount);
|
||||
|
||||
{
|
||||
String accSql = String.format("companyId = %s AND accountType=ANLT AND accountStatus=ACTV AND processingSign=ALWD",
|
||||
payment1.getSenderId());
|
||||
Account acc1 = accountImdg.getSingleObjectBySQL(accSql);
|
||||
if (acc1 == null) {
|
||||
log.warn("Account not found: {}", accSql);
|
||||
} else {
|
||||
payment1.setCreditLegAccountId(acc1.getId());
|
||||
payment1.setCreditLegAccount(acc1.getAccount());
|
||||
}
|
||||
}
|
||||
|
||||
payment1.setCreditCsAccount(null);
|
||||
|
||||
{
|
||||
Account acc1 = selectAccount(payment1.getAddresseeId(), AccountType.Corr, Status.Active, Allowed.ALLOWED);
|
||||
if (acc1 != null) {
|
||||
payment1.setDebitLegAccountId(acc1.getId());
|
||||
payment1.setDebitLegAccount(acc1.getAccount());
|
||||
}
|
||||
}
|
||||
|
||||
payment1.setDebitCsAccount(null);
|
||||
|
||||
// payment1.setCreditLegDirection(InOutDirection.out.getKey());
|
||||
// payment1.setDebitLegDirection(InOutDirection.in.getKey());
|
||||
|
||||
payment1.setCreditLegCurrencyCode(liabilitiesClaimsAssets.getCurrency());
|
||||
payment1.setDebitLegCurrencyCode(liabilitiesClaimsAssets.getCurrency());
|
||||
|
||||
payment1.setTransactionStatus(TransactionStatus.stld.getKey());
|
||||
|
||||
|
||||
payment1.setDocumentNumber(nextDocumentNumber(liabilitiesClaimsAssets, payment1));
|
||||
|
||||
newPaymentInstructions.add(payment1);
|
||||
}
|
||||
}
|
||||
return newPaymentInstructions;
|
||||
}
|
||||
|
||||
protected String nextDocumentNumber(LiabilitiesClaimsAssets liabilitiesClaimsAssets, PaymentInstruction paymentInstruction) {
|
||||
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",
|
||||
liabilitiesClaimsAssets.getContract(), paymentDate,
|
||||
paymentInstruction.getSenderId(), documentNumberId.incrementAndGet()
|
||||
);
|
||||
return num;
|
||||
}
|
||||
|
||||
protected String selectSymbolValue(Long companyId, CompanySymbol symbol) {
|
||||
CompanySymbols cSymbol = companySymbolsImdg.getSingleObjectByFieldValues(Map.of(
|
||||
"companyId", companyId,
|
||||
"companySymbol", symbol.getKey()));
|
||||
if (cSymbol == null) {
|
||||
return null;
|
||||
} else {
|
||||
return cSymbol.getCompanySymbolValue();
|
||||
}
|
||||
}
|
||||
|
||||
protected Account selectAccount(Long companyId, AccountType accountType, Status accountStatus, Allowed processingSign) {
|
||||
Account account = accountImdg.getSingleObjectByFieldValues(Map.of(
|
||||
"companyId", companyId,
|
||||
"accountType", accountType.getKey(),
|
||||
"accountStatus", accountStatus.getKey(),
|
||||
"processingSign", processingSign.getKey()
|
||||
));
|
||||
return account;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package ru.spcex.clearing.service.order;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
import ru.clearing.classes.statics.data.liabilities.LiabilitiesClaimsAssets;
|
||||
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.utils.time.TimeUtil;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class PaymentInstructionCreatorTest {
|
||||
|
||||
@Test
|
||||
void nextDocumentNumber() {
|
||||
ImdgProvider nullImdg = Mockito.mock(ImdgProvider.class);
|
||||
PaymentInstructionCreator instance = new PaymentInstructionCreator(nullImdg);
|
||||
LiabilitiesClaimsAssets liabilitiesClaimsAssets = new LiabilitiesClaimsAssets();
|
||||
liabilitiesClaimsAssets.setContract("contract");
|
||||
PaymentInstruction paymentInstruction = new PaymentInstruction();
|
||||
paymentInstruction.setPaymentDate(TimeUtil.localDateToInstant(LocalDate.of(2023,1,4)));
|
||||
paymentInstruction.setSenderId(1234L);
|
||||
assertEquals("contract/040123/1234/1", instance.nextDocumentNumber(liabilitiesClaimsAssets, paymentInstruction));
|
||||
assertEquals("contract/040123/1234/2", instance.nextDocumentNumber(liabilitiesClaimsAssets, paymentInstruction));
|
||||
assertEquals("contract/040123/1234/3", instance.nextDocumentNumber(liabilitiesClaimsAssets, paymentInstruction));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
package ru.spcex.clearing.dbf.exporter.config;
|
||||
|
||||
import org.apache.kafka.clients.producer.Producer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
|
@ -14,6 +16,7 @@ import ru.spcex.platform.imdg.api.ImdgProvider;
|
|||
//отдельный конфиг для sender чтобы сделать required false
|
||||
@Configuration
|
||||
public class KafkaSenderConfig {
|
||||
Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
private final ImdgProvider imdgProvider;
|
||||
private Producer<String, Object> kafkaProducer;
|
||||
|
|
@ -23,14 +26,15 @@ public class KafkaSenderConfig {
|
|||
this.imdgProvider = imdgProvider;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
@Autowired(required = false)
|
||||
public void setKafkaProducer(Producer<String, Object> kafkaProducer) {
|
||||
this.kafkaProducer = kafkaProducer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public KafkaSender kafkaSender() {
|
||||
if (kafkaProducer == null ||imdgProvider == null) {
|
||||
if (kafkaProducer == null || imdgProvider == null) {
|
||||
log.info("Can not create KafkaSender: kafkaProducer={}, imdgProvider={}", kafkaProducer, imdgProvider);
|
||||
return null;
|
||||
}
|
||||
ImdgId imdgIdGenerator = imdgProvider.getImdgIdGenerator();
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package ru.spcex.platform.enumeration;
|
|||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
|
||||
public enum AccountType implements IEnumKey {
|
||||
Clrn("CLRN"), Bank("BANK"), Info("INFO"), Tran("TRAN"), Anlt("ANLT");
|
||||
Clrn("CLRN"), Bank("BANK"), Info("INFO"), Tran("TRAN"), Corr("CORR"), Anlt("ANLT");
|
||||
|
||||
private final String key;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package ru.spcex.platform.enumeration;
|
|||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
|
||||
public enum InOutDirection implements IEnumKey {
|
||||
in("IN");
|
||||
in("IN"), out("OUT");
|
||||
|
||||
private final String key;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue