diff --git a/clearing-parent/clearing-service/pom.xml b/clearing-parent/clearing-service/pom.xml
index aa206dcf4..1d7d1fd1a 100644
--- a/clearing-parent/clearing-service/pom.xml
+++ b/clearing-parent/clearing-service/pom.xml
@@ -51,6 +51,10 @@
assertj-core
test
+
+ org.mockito
+ mockito-core
+
diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/order/PaymentInstructionCreator.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/order/PaymentInstructionCreator.java
index 541c0353c..950e3c7a3 100644
--- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/order/PaymentInstructionCreator.java
+++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/order/PaymentInstructionCreator.java
@@ -27,6 +27,9 @@ 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 final Logger log = LoggerFactory.getLogger(getClass());
protected final ImdgId idGenerator;
@@ -71,18 +74,11 @@ public class PaymentInstructionCreator {
protected List createPaymentInstructions(LiabilitiesClaimsAssets liabilitiesClaimsAssets,
Collection clearingCategory) {
List newPaymentInstructions = new ArrayList<>();
- int count;
- if (clearingCategory.contains(ClearingCategory.I)) {
- count = 2;
- } else if (clearingCategory.contains(ClearingCategory.V) || clearingCategory.contains(ClearingCategory.B)) {
- count = 1;
- } else {
- count = 0;
- }
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();
@@ -94,9 +90,9 @@ public class PaymentInstructionCreator {
payment2.setClearingDate(TimeUtil.toLocalDate(now));
payment1.setSenderId(liabilitiesClaimsAssets.getCompanyId());
- payment2.setSenderId(1L); // СПВБ
+ payment2.setSenderId(SPVB_ID); // СПВБ
- payment1.setAddresseeId(1L); // СПВБ
+ payment1.setAddresseeId(SPVB_ID); // СПВБ
String sqlLCA = String.format("securityId = %s and companyId <> %s",
liabilitiesClaimsAssets.getSecurityId(), liabilitiesClaimsAssets.getCompanyId());
LiabilitiesClaimsAssets counterLiabilitiesClaimsAssets = liabilitiesClaimsAssetsImdg.getSingleObjectBySQL(sqlLCA);
@@ -119,7 +115,7 @@ public class PaymentInstructionCreator {
payment2.setAdresseeBic(symbol2);
}
- Company companyPRC = companyImdg.getSingleObjectByID(2L); // 2 "НКО АО ПРЦ"
+ Company companyPRC = companyImdg.getSingleObjectByID(PRC_ID); // 2 "НКО АО ПРЦ"
String companyPRCName = null;
if (companyPRC == null) {
log.warn("Company.id=2 not found");
@@ -129,7 +125,7 @@ public class PaymentInstructionCreator {
payment1.setPayeeBankName(companyPRCName);
payment2.setPayeeBankName(companyPRCName);
- String symbolPRC = selectSymbolValue(2L, CompanySymbol.BIC); // 2 "НКО АО ПРЦ"
+ String symbolPRC = selectSymbolValue(PRC_ID, CompanySymbol.BIC); // 2 "НКО АО ПРЦ"
payment1.setPayeeBic(symbolPRC);
payment2.setPayeeBic(symbolPRC);
@@ -191,10 +187,10 @@ public class PaymentInstructionCreator {
payment1.setDebitCsAccount(null);
payment2.setDebitCsAccount(null);
-// payment1.setDebitLegDirection(InOutDirection.out.getKey());
-// payment2.setDebitLegDirection(InOutDirection.out.getKey());
-// payment1.setCreditLegDirection(InOutDirection.in.getKey());
-// payment2.setCreditLegDirection(InOutDirection.in.getKey());
+// 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());
@@ -210,18 +206,191 @@ public class PaymentInstructionCreator {
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);
+ }
}
- //todo сочетания типов??? Другие типы
return newPaymentInstructions;
}
protected String nextDocumentNumber(LiabilitiesClaimsAssets liabilitiesClaimsAssets, PaymentInstruction paymentInstruction) {
- if (documentNumberResetAt == null || documentNumberResetAt.isBefore(LocalDate.now())) {
- documentNumberId.set(0);
- documentNumberResetAt = LocalDate.now();
+ 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;
}
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ddMMyy");
- String num = String.format("%s/%s/%s/",
+ String num = String.format("%s/%s/%s/%s",
liabilitiesClaimsAssets.getContract(), formatter.format(paymentInstruction.getPaymentDate()),
paymentInstruction.getSenderId(), documentNumberId.incrementAndGet()
);
diff --git a/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/service/order/PaymentInstructionCreatorTest.java b/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/service/order/PaymentInstructionCreatorTest.java
new file mode 100644
index 000000000..6e4c63700
--- /dev/null
+++ b/clearing-parent/clearing-service/src/test/java/ru/spcex/clearing/service/order/PaymentInstructionCreatorTest.java
@@ -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/230104/1234/1", instance.nextDocumentNumber(liabilitiesClaimsAssets, paymentInstruction));
+ assertEquals("contract/230104/1234/2", instance.nextDocumentNumber(liabilitiesClaimsAssets, paymentInstruction));
+ assertEquals("contract/230104/1234/3", instance.nextDocumentNumber(liabilitiesClaimsAssets, paymentInstruction));
+ }
+}
\ No newline at end of file
diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/AccountType.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/AccountType.java
index 7c9d342b3..43d0ceebc 100644
--- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/AccountType.java
+++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/AccountType.java
@@ -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");
+ Clrn("CLRN"), Bank("BANK"), Info("INFO"), Tran("TRAN"), Corr("CORR");
private final String key;