Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
7647a0ff5b
25 changed files with 868 additions and 385 deletions
|
|
@ -24,6 +24,8 @@ import ru.spcex.clearing.backendapi.security.KeycloakUtils;
|
|||
import ru.spcex.clearing.backendapi.service.IOperator;
|
||||
import ru.spcex.clearing.backendapi.service.IStateLoader;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.Consts;
|
||||
import ru.spcex.platform.enumeration.Task;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
|
|
@ -67,7 +69,7 @@ public class LauncherController extends AbstractQueueController {
|
|||
@RequestMapping(value = "/{task-code}", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
public CudResponse add(@ApiParam(value = "Код задания из taskDictionary", required = true, example = "ABLK")
|
||||
@PathVariable("task-code") String dictionaryName) throws ExecutionException, InterruptedException {
|
||||
@PathVariable("task-code") String dictionaryName) throws ExecutionException, InterruptedException {
|
||||
AbstractDictionary taskEnum = taskDictionary.getSingleObjectByFieldValues(Map.of("code", dictionaryName));
|
||||
if (taskEnum == null) {
|
||||
throw new NotFound404Exception("task dictionary element with code '" + dictionaryName + "'");
|
||||
|
|
@ -81,11 +83,37 @@ public class LauncherController extends AbstractQueueController {
|
|||
}
|
||||
launcherCommand.setTask(dictionaryName);
|
||||
launcherCommand.setUserId(user.getId());
|
||||
// пока здесь, это требуется для сохранения истории
|
||||
saveLauncher(dictionaryName, user.getId());
|
||||
//топики ограничиваются наличием в taskDictionary
|
||||
//подписываются на разные топики в разных модулях, см. ru.spcex.platform.enumeration.Task#topic
|
||||
return processRequest("launcher-" + dictionaryName, launcherCommand);
|
||||
return processRequest(Consts.LAUNCHER_NEW, launcherCommand);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "create specific launcher.")
|
||||
@ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = CudResponse.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)})
|
||||
@RequestMapping(value = "/specific/{task-code}", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@ResponseBody
|
||||
public CudResponse addSpecific(@ApiParam(value = "Код задания из taskDictionary", required = true, example = "ABLK")
|
||||
@PathVariable("task-code") String dictionaryName,
|
||||
@RequestBody LauncherNew launcherNew) throws ExecutionException, InterruptedException {
|
||||
AbstractDictionary taskEnum = taskDictionary.getSingleObjectByFieldValues(Map.of("code", dictionaryName));
|
||||
if (taskEnum == null) {
|
||||
throw new NotFound404Exception("task dictionary element with code '" + dictionaryName + "'");
|
||||
}
|
||||
if (!Task.startOfClearing.getKey().equals(taskEnum.getCode())) {
|
||||
throw new IllegalStateException(String.format("Task %s not support request with body", taskEnum.getCode()));
|
||||
}
|
||||
LauncherNew launcherCommand = new LauncherNew();
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
String username = KeycloakUtils.getUserNameFromAuthentication(authentication);
|
||||
User user = userImdg.getSingleObjectByFieldValues(Map.of("identifier", username));
|
||||
if (user == null) {
|
||||
throw new IllegalStateException("cannot obtain userId from logged in user " + username);
|
||||
}
|
||||
launcherCommand.setTask(dictionaryName);
|
||||
launcherCommand.setUserId(user.getId());
|
||||
launcherCommand.setCompanyId(launcherNew.getCompanyId());
|
||||
launcherCommand.setSecurityId(launcherNew.getSecurityId());
|
||||
return processRequest(Consts.LAUNCHER_NEW, launcherCommand);
|
||||
}
|
||||
|
||||
private void saveLauncher(String taskCode, Long userId) {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,12 @@ public class LauncherNew implements IAction<Object> {
|
|||
@ApiModelProperty(value = "Идентификатор единоличного исполнительного органа", example = "ABCD")
|
||||
@JsonProperty
|
||||
private String task;
|
||||
@ApiModelProperty(value = "Идентификатор инициатора", example = "1000")
|
||||
@JsonProperty
|
||||
private Long companyId;
|
||||
@ApiModelProperty(value = "Идентификатор инструмента", example = "1000")
|
||||
@JsonProperty
|
||||
private Long securityId;
|
||||
|
||||
@JsonIgnore
|
||||
private Long userId;
|
||||
|
|
@ -32,6 +38,8 @@ public class LauncherNew implements IAction<Object> {
|
|||
} else {
|
||||
LauncherCommandRequest taskRunnerCommandRequest = new LauncherCommandRequest();
|
||||
taskRunnerCommandRequest.setTaskName(task);
|
||||
taskRunnerCommandRequest.setCompanyId(companyId);
|
||||
taskRunnerCommandRequest.setSecurityId(securityId);
|
||||
taskRunnerCommandRequest.setUserId(userId);
|
||||
return taskRunnerCommandRequest;
|
||||
}
|
||||
|
|
@ -65,4 +73,20 @@ public class LauncherNew implements IAction<Object> {
|
|||
public void setUserId(Long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public Long getCompanyId() {
|
||||
return companyId;
|
||||
}
|
||||
|
||||
public void setCompanyId(Long companyId) {
|
||||
this.companyId = companyId;
|
||||
}
|
||||
|
||||
public Long getSecurityId() {
|
||||
return securityId;
|
||||
}
|
||||
|
||||
public void setSecurityId(Long securityId) {
|
||||
this.securityId = securityId;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1576,7 +1576,7 @@
|
|||
<generationId type="1" name="Идентификатор взаимодействия" shortname="ID взаимодействия" searchable="true" sortable="true"/>
|
||||
<inSDf12Id type="1" name="Идентификатор соответствующей записи из таблицы-источника" shortname="Входящая запись" searchable="true" sortable="true"/>
|
||||
</sDf18>
|
||||
<s_trade name="Сделки из Торговой системы" class="" table="s_trade">
|
||||
<s_trade name="Сделки из Торговой системы" class="ru.clearing.classes.statics.data.misc.STrade" table="s_trade">
|
||||
<id type="1" name="Идентификатор записи" shortname="ID" searchable="true" sortable="true"/>
|
||||
<trade_num type="1" name="Номер сделки" shortname="Номер сделки" searchable="true" sortable="true"/>
|
||||
<sec_code type="2" length="255" name="Код ценной бумаги" shortname="Код ценной бумаги" searchable="true" sortable="true"/>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@
|
|||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<external_libraries.kafka.version>3.0.1</external_libraries.kafka.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
|
@ -57,23 +56,6 @@
|
|||
<artifactId>assertj-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.kafka</groupId>
|
||||
<artifactId>spring-kafka-test</artifactId>
|
||||
<version>2.8.8</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.kafka</groupId>
|
||||
<artifactId>spring-kafka</artifactId>
|
||||
<version>2.8.8</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<resources>
|
||||
|
|
|
|||
|
|
@ -1,17 +1,24 @@
|
|||
package ru.spcex.clearing.balance.config;
|
||||
|
||||
import org.apache.kafka.clients.consumer.MockConsumer;
|
||||
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.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import ru.spcex.clearing.platform.messaging.serialization.JsonSerializer;
|
||||
|
||||
@Configuration
|
||||
public class KafkaTestConfig {
|
||||
|
||||
// @Bean
|
||||
// public MockConsumer<String, Object> createTestConsumer() {
|
||||
// return new MockConsumer<>(OffsetResetStrategy.EARLIEST);
|
||||
// }
|
||||
//
|
||||
// @Bean
|
||||
// public Producer<String, Object> createTestProducer() {
|
||||
// return new MockProducer<>(true, new StringSerializer(), new JsonSerializer());
|
||||
// }
|
||||
@Bean
|
||||
public MockConsumer<String, Object> createTestConsumer() {
|
||||
return new MockConsumer<>(OffsetResetStrategy.EARLIEST);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Producer<String, Object> createTestProducer() {
|
||||
return new MockProducer<>(true, new StringSerializer(), new JsonSerializer());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
package ru.spcex.clearing.balance.config;
|
||||
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.kafka.annotation.KafkaListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
@Component
|
||||
public class KafkaTestConsumer {
|
||||
|
||||
public static final String TOPIC_GALB = "launcher-GALB";
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(KafkaTestConsumer.class);
|
||||
private final String TOPIC_NAME = "com.madadipouya.kafka.user";
|
||||
private CountDownLatch latch = new CountDownLatch(1);
|
||||
|
||||
private String payload;
|
||||
|
||||
@KafkaListener(topics = TOPIC_GALB)
|
||||
public void receive(ConsumerRecord<?, ?> consumerRecord) {
|
||||
LOGGER.info("received payload='{}'", consumerRecord.toString());
|
||||
|
||||
payload = consumerRecord.toString();
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
public CountDownLatch getLatch() {
|
||||
return latch;
|
||||
}
|
||||
|
||||
public void resetLatch() {
|
||||
latch = new CountDownLatch(1);
|
||||
}
|
||||
|
||||
public String getPayload() {
|
||||
return payload;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
package ru.spcex.clearing.balance.service;
|
||||
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||
import org.apache.kafka.clients.producer.Producer;
|
||||
import org.apache.kafka.clients.producer.ProducerRecord;
|
||||
import org.apache.kafka.common.serialization.StringDeserializer;
|
||||
import org.apache.kafka.common.serialization.StringSerializer;
|
||||
import org.junit.jupiter.api.*;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.kafka.core.DefaultKafkaConsumerFactory;
|
||||
import org.springframework.kafka.core.DefaultKafkaProducerFactory;
|
||||
import org.springframework.kafka.core.KafkaTemplate;
|
||||
import org.springframework.kafka.listener.ContainerProperties;
|
||||
import org.springframework.kafka.listener.KafkaMessageListenerContainer;
|
||||
import org.springframework.kafka.listener.MessageListener;
|
||||
import org.springframework.kafka.test.EmbeddedKafkaBroker;
|
||||
import org.springframework.kafka.test.context.EmbeddedKafka;
|
||||
import org.springframework.kafka.test.utils.ContainerTestUtils;
|
||||
import org.springframework.kafka.test.utils.KafkaTestUtils;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import ru.spcex.clearing.balance.config.KafkaTestConsumer;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static ru.spcex.clearing.balance.config.KafkaTestConsumer.TOPIC_GALB;
|
||||
|
||||
@EmbeddedKafka//(partitions = 1, brokerProperties = {"listeners=PLAINTEXT://localhost:9092", "port=9092"})
|
||||
@SpringBootTest(properties = "spring.kafka.bootstrap-servers=${spring.embedded.kafka.brokers}")
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class EmbeddedKafkaTest {
|
||||
static {
|
||||
Path path = Paths.get("src", "main", "resources");
|
||||
String currentPath = path.toAbsolutePath().toString();
|
||||
System.setProperty("spring.config.location", currentPath + File.separator);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public KafkaTemplate<String, String> template;
|
||||
BlockingQueue<ConsumerRecord<String, String>> records;
|
||||
KafkaMessageListenerContainer<String, String> container;
|
||||
@Autowired
|
||||
private EmbeddedKafkaBroker embeddedKafkaBroker;
|
||||
@Autowired
|
||||
private KafkaTestConsumer consumer;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
consumer.resetLatch();
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
void setUp() {
|
||||
Map<String, Object> configs = new HashMap<>(KafkaTestUtils.consumerProps("consumer", "false", embeddedKafkaBroker));
|
||||
DefaultKafkaConsumerFactory<String, String> consumerFactory = new DefaultKafkaConsumerFactory<>(configs, new StringDeserializer(), new StringDeserializer());
|
||||
ContainerProperties containerProperties = new ContainerProperties(TOPIC_GALB);
|
||||
container = new KafkaMessageListenerContainer<>(consumerFactory, containerProperties);
|
||||
records = new LinkedBlockingQueue<>();
|
||||
container.setupMessageListener((MessageListener<String, String>) records::add);
|
||||
container.start();
|
||||
ContainerTestUtils.waitForAssignment(container, embeddedKafkaBroker.getPartitionsPerTopic());
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
void tearDown() {
|
||||
container.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void kafkaSetup_withTopic_ensureSendMessageIsReceived() throws Exception {
|
||||
// Arrange
|
||||
Map<String, Object> configs = new HashMap<>(KafkaTestUtils.producerProps(embeddedKafkaBroker));
|
||||
Producer<String, String> producer = new DefaultKafkaProducerFactory<>(configs, new StringSerializer(), new StringSerializer()).createProducer();
|
||||
|
||||
String data = "Sending with default template";
|
||||
//Act
|
||||
producer.send(new ProducerRecord<>(TOPIC_GALB, "my-aggregate-id", data));
|
||||
// producer.flush();
|
||||
|
||||
// template.send(TOPIC, data);
|
||||
|
||||
// Assert
|
||||
ConsumerRecord<String, String> singleRecord = records.poll(10, TimeUnit.SECONDS);
|
||||
boolean messageConsumed = consumer.getLatch()
|
||||
.await(30, TimeUnit.SECONDS);
|
||||
assertTrue(messageConsumed);
|
||||
assertThat(consumer.getPayload(), containsString(data));
|
||||
// assertThat(singleRecord).isNotNull();
|
||||
// assertThat(singleRecord.key()).isEqualTo("my-aggregate-id");
|
||||
// assertThat(singleRecord.value()).isEqualTo("{\"event\":\"Test Event\"}");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
package ru.spcex.clearing.balance.service;
|
||||
|
||||
import org.apache.kafka.clients.producer.Producer;
|
||||
import org.apache.kafka.clients.producer.ProducerRecord;
|
||||
import org.apache.kafka.common.serialization.StringSerializer;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.kafka.core.DefaultKafkaProducerFactory;
|
||||
import org.springframework.kafka.core.KafkaTemplate;
|
||||
import org.springframework.kafka.test.EmbeddedKafkaBroker;
|
||||
import org.springframework.kafka.test.context.EmbeddedKafka;
|
||||
import org.springframework.kafka.test.utils.KafkaTestUtils;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import ru.spcex.clearing.balance.config.KafkaTestConsumer;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static ru.spcex.clearing.balance.config.KafkaTestConsumer.TOPIC_GALB;
|
||||
|
||||
@EmbeddedKafka//(partitions = 1, brokerProperties = {"listeners=PLAINTEXT://localhost:9092", "port=9092"})
|
||||
@SpringBootTest(properties = "spring.kafka.bootstrap-servers=${spring.embedded.kafka.brokers}")
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class Sdf08ServiceKafkaTest {
|
||||
static {
|
||||
Path path = Paths.get("src", "main", "resources");
|
||||
String currentPath = path.toAbsolutePath().toString();
|
||||
System.setProperty("spring.config.location", currentPath + File.separator);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public KafkaTemplate<String, String> template;
|
||||
|
||||
@Autowired
|
||||
private EmbeddedKafkaBroker embeddedKafkaBroker;
|
||||
@Autowired
|
||||
private KafkaTestConsumer consumer;
|
||||
|
||||
@Test
|
||||
public void newSDf08() throws Exception {
|
||||
// Arrange
|
||||
Map<String, Object> configs = new HashMap<>(KafkaTestUtils.producerProps(embeddedKafkaBroker));
|
||||
Producer<String, String> producer = new DefaultKafkaProducerFactory<>(configs, new StringSerializer(), new StringSerializer()).createProducer();
|
||||
|
||||
|
||||
String data = "Sending with default template";
|
||||
//Act
|
||||
producer.send(new ProducerRecord<>(TOPIC_GALB, "my-aggregate-id", data));
|
||||
// producer.flush();
|
||||
// template.send(TOPIC, data);
|
||||
|
||||
// Assert
|
||||
boolean messageConsumed = consumer.getLatch()
|
||||
.await(10, TimeUnit.SECONDS);
|
||||
assertTrue(messageConsumed);
|
||||
assertThat(consumer.getPayload(), containsString(data));
|
||||
}
|
||||
}
|
||||
|
|
@ -4,22 +4,22 @@ import ru.clearing.classes.ConstSerializable;
|
|||
import ru.clearing.classes.objects.BusinessObject;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
|
||||
public class LiabilitiesClaimsAssets extends BusinessObject {
|
||||
private static final long serialVersionUID = ConstSerializable.serialVersionUID;
|
||||
|
||||
private Long companyId;
|
||||
private Instant clearingDate;
|
||||
private LocalDate clearingDate;
|
||||
private Long accountId;
|
||||
private String accountType;
|
||||
private String account;
|
||||
private BigDecimal liabilitiesQuantity;
|
||||
private BigDecimal claimsQuantity;
|
||||
private String currency;
|
||||
private Instant settlementDate;
|
||||
private Instant tradingDate;
|
||||
private Instant refundDate;
|
||||
private LocalDate settlementDate;
|
||||
private LocalDate tradingDate;
|
||||
private LocalDate refundDate;
|
||||
private BigDecimal price;
|
||||
private Long securityId;
|
||||
private String tradingCode;
|
||||
|
|
@ -42,11 +42,11 @@ public class LiabilitiesClaimsAssets extends BusinessObject {
|
|||
this.companyId = value;
|
||||
}
|
||||
|
||||
public Instant getClearingDate() {
|
||||
public LocalDate getClearingDate() {
|
||||
return clearingDate;
|
||||
}
|
||||
|
||||
public void setClearingDate(Instant value) {
|
||||
public void setClearingDate(LocalDate value) {
|
||||
this.clearingDate = value;
|
||||
}
|
||||
|
||||
|
|
@ -98,27 +98,27 @@ public class LiabilitiesClaimsAssets extends BusinessObject {
|
|||
this.currency = value;
|
||||
}
|
||||
|
||||
public Instant getSettlementDate() {
|
||||
public LocalDate getSettlementDate() {
|
||||
return settlementDate;
|
||||
}
|
||||
|
||||
public void setSettlementDate(Instant value) {
|
||||
public void setSettlementDate(LocalDate value) {
|
||||
this.settlementDate = value;
|
||||
}
|
||||
|
||||
public Instant getTradingDate() {
|
||||
public LocalDate getTradingDate() {
|
||||
return tradingDate;
|
||||
}
|
||||
|
||||
public void setTradingDate(Instant value) {
|
||||
public void setTradingDate(LocalDate value) {
|
||||
this.tradingDate = value;
|
||||
}
|
||||
|
||||
public Instant getRefundDate() {
|
||||
public LocalDate getRefundDate() {
|
||||
return refundDate;
|
||||
}
|
||||
|
||||
public void setRefundDate(Instant value) {
|
||||
public void setRefundDate(LocalDate value) {
|
||||
this.refundDate = value;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,189 @@
|
|||
package ru.clearing.classes.statics.data.misc;
|
||||
|
||||
import ru.clearing.classes.ConstSerializable;
|
||||
import ru.spcex.platform.classes.base.SpcexObjectBase;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* Сделки из Торговой системы
|
||||
* <p>
|
||||
* DB table: S_TRADE
|
||||
**/
|
||||
public class STrade extends SpcexObjectBase {
|
||||
private static final long serialVersionUID = ConstSerializable.serialVersionUID;
|
||||
|
||||
private Long tradeNum;
|
||||
private String secCode;
|
||||
private Instant tradeDateTime;
|
||||
private LocalDate settleDate;
|
||||
private BigDecimal price;
|
||||
private BigDecimal value;
|
||||
private BigDecimal qty;
|
||||
private BigDecimal accruedint;
|
||||
private String firmId;
|
||||
private String clientCode;
|
||||
private BigDecimal exchangeCommission;
|
||||
private String classCode;
|
||||
private String operation;
|
||||
private String issueAccount;
|
||||
private String moneyAccount;
|
||||
private String tradeType;
|
||||
private Long daysToMatDate;
|
||||
private String collateral;
|
||||
private String settleCode;
|
||||
|
||||
public Long getTradeNum() {
|
||||
return tradeNum;
|
||||
}
|
||||
|
||||
public void setTradeNum(Long value) {
|
||||
this.tradeNum = value;
|
||||
}
|
||||
|
||||
public String getSecCode() {
|
||||
return secCode;
|
||||
}
|
||||
|
||||
public void setSecCode(String value) {
|
||||
this.secCode = value;
|
||||
}
|
||||
|
||||
public Instant getTradeDateTime() {
|
||||
return tradeDateTime;
|
||||
}
|
||||
|
||||
public void setTradeDateTime(Instant value) {
|
||||
this.tradeDateTime = value;
|
||||
}
|
||||
|
||||
public LocalDate getSettleDate() {
|
||||
return settleDate;
|
||||
}
|
||||
|
||||
public void setSettleDate(LocalDate value) {
|
||||
this.settleDate = value;
|
||||
}
|
||||
|
||||
public BigDecimal getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(BigDecimal value) {
|
||||
this.price = value;
|
||||
}
|
||||
|
||||
public BigDecimal getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(BigDecimal value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public BigDecimal getQty() {
|
||||
return qty;
|
||||
}
|
||||
|
||||
public void setQty(BigDecimal value) {
|
||||
this.qty = value;
|
||||
}
|
||||
|
||||
public BigDecimal getAccruedint() {
|
||||
return accruedint;
|
||||
}
|
||||
|
||||
public void setAccruedint(BigDecimal value) {
|
||||
this.accruedint = value;
|
||||
}
|
||||
|
||||
public String getFirmId() {
|
||||
return firmId;
|
||||
}
|
||||
|
||||
public void setFirmId(String value) {
|
||||
this.firmId = value;
|
||||
}
|
||||
|
||||
public String getClientCode() {
|
||||
return clientCode;
|
||||
}
|
||||
|
||||
public void setClientCode(String value) {
|
||||
this.clientCode = value;
|
||||
}
|
||||
|
||||
public BigDecimal getExchangeCommission() {
|
||||
return exchangeCommission;
|
||||
}
|
||||
|
||||
public void setExchangeCommission(BigDecimal value) {
|
||||
this.exchangeCommission = value;
|
||||
}
|
||||
|
||||
public String getClassCode() {
|
||||
return classCode;
|
||||
}
|
||||
|
||||
public void setClassCode(String value) {
|
||||
this.classCode = value;
|
||||
}
|
||||
|
||||
public String getOperation() {
|
||||
return operation;
|
||||
}
|
||||
|
||||
public void setOperation(String value) {
|
||||
this.operation = value;
|
||||
}
|
||||
|
||||
public String getIssueAccount() {
|
||||
return issueAccount;
|
||||
}
|
||||
|
||||
public void setIssueAccount(String value) {
|
||||
this.issueAccount = value;
|
||||
}
|
||||
|
||||
public String getMoneyAccount() {
|
||||
return moneyAccount;
|
||||
}
|
||||
|
||||
public void setMoneyAccount(String value) {
|
||||
this.moneyAccount = value;
|
||||
}
|
||||
|
||||
public String getTradeType() {
|
||||
return tradeType;
|
||||
}
|
||||
|
||||
public void setTradeType(String value) {
|
||||
this.tradeType = value;
|
||||
}
|
||||
|
||||
public Long getDaysToMatDate() {
|
||||
return daysToMatDate;
|
||||
}
|
||||
|
||||
public void setDaysToMatDate(Long value) {
|
||||
this.daysToMatDate = value;
|
||||
}
|
||||
|
||||
public String getCollateral() {
|
||||
return collateral;
|
||||
}
|
||||
|
||||
public void setCollateral(String value) {
|
||||
this.collateral = value;
|
||||
}
|
||||
|
||||
public String getSettleCode() {
|
||||
return settleCode;
|
||||
}
|
||||
|
||||
public void setSettleCode(String value) {
|
||||
this.settleCode = value;
|
||||
}
|
||||
}
|
||||
|
|
@ -3,8 +3,11 @@ package ru.spcex.clearing.error;
|
|||
import ru.spcex.platform.utils.enumeration.IEnumId;
|
||||
|
||||
public enum ClearingError implements IEnumId {
|
||||
GeneralError(5400L),
|
||||
RecordNotFound(5406L),
|
||||
CompanyCreditCheck(5412L),
|
||||
CompanyDebitCheck(5413L),
|
||||
CompanyNotFound(5410L),
|
||||
;
|
||||
private final Long id;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
package ru.spcex.clearing.error;
|
||||
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
|
||||
public class ClearingException extends Exception {
|
||||
final EnumMessage enumMsg;
|
||||
|
||||
public ClearingException(EnumMessage msg) {
|
||||
this.enumMsg = msg;
|
||||
}
|
||||
|
||||
public ClearingException(ClearingError code) {
|
||||
this.enumMsg = new EnumMessage(code);
|
||||
}
|
||||
|
||||
public ClearingException(ClearingError code, String message) {
|
||||
super(code == null ? message : code.getId() + " " + message);
|
||||
this.enumMsg = new EnumMessage(code);
|
||||
}
|
||||
|
||||
public ClearingException(ClearingError code, String message, Throwable cause) {
|
||||
super(code == null ? message : code.getId() + " " + message, cause);
|
||||
this.enumMsg = new EnumMessage(code);
|
||||
}
|
||||
|
||||
public ClearingException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
this.enumMsg = new EnumMessage(ClearingError.GeneralError);
|
||||
}
|
||||
|
||||
public EnumMessage getEnumMsg() {
|
||||
return enumMsg;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,340 @@
|
|||
package ru.spcex.clearing.service;
|
||||
|
||||
import org.apache.kafka.clients.producer.Producer;
|
||||
import org.apache.kafka.clients.producer.ProducerRecord;
|
||||
import org.apache.kafka.clients.producer.RecordMetadata;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
import ru.clearing.classes.statics.data.account.Account;
|
||||
import ru.clearing.classes.statics.data.company.Company;
|
||||
import ru.clearing.classes.statics.data.execution.ExecutionDeposit;
|
||||
import ru.clearing.classes.statics.data.misc.Listing;
|
||||
import ru.clearing.classes.statics.data.misc.STrade;
|
||||
import ru.clearing.classes.statics.data.security.Security;
|
||||
import ru.spcex.clearing.error.ClearingError;
|
||||
import ru.spcex.clearing.error.ClearingException;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.ActionType;
|
||||
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.Consts;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.registry.CoveredDealRegisterNewRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.securitites.MoneyMarketSecurityNewRequest;
|
||||
import ru.spcex.platform.enumeration.Allowed;
|
||||
import ru.spcex.platform.enumeration.Market;
|
||||
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.imdg.api.predicate.ImdgPredicate;
|
||||
import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.log.ExceptionUtils;
|
||||
import ru.spcex.platform.utils.time.TimeUtil;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 1.35. executionDeposit - Сделки
|
||||
* I - Изменение executionDeposit при получении новых сделок из ТС (s_trade)
|
||||
*/
|
||||
@Component
|
||||
@EnableScheduling
|
||||
public class ExecutionDepositComponent {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
private final ImdgProvider imdgProvider;
|
||||
private Imdg<STrade> sTradeImdg;
|
||||
private Imdg<Security> securityImdg;
|
||||
private Imdg<ExecutionDeposit> executionDepositImdg;
|
||||
private Imdg<Company> companyImdg;
|
||||
private Imdg<Account> accountImdg;
|
||||
private Imdg<Listing> listingImdg;
|
||||
|
||||
private ImdgId idGenerator;
|
||||
Producer<String, Object> kafka;
|
||||
|
||||
Long tradeNum;
|
||||
Instant tradingDay;
|
||||
|
||||
|
||||
@Autowired
|
||||
public ExecutionDepositComponent(ImdgProvider imdgProvider, Producer<String, Object> kafka) {
|
||||
this.imdgProvider = imdgProvider;
|
||||
this.sTradeImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_STrade, STrade.class);
|
||||
this.securityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Security, Security.class);
|
||||
this.executionDepositImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionDeposit, ExecutionDeposit.class);
|
||||
this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
|
||||
this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class);
|
||||
this.listingImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Listing, Listing.class);
|
||||
|
||||
this.idGenerator = imdgProvider.getImdgIdGenerator();
|
||||
this.kafka = kafka;
|
||||
|
||||
resetTradingDay();
|
||||
}
|
||||
|
||||
/**
|
||||
* Сбрасывать каждый день в 01:00:01 "0 1 0 1 * ?"
|
||||
*/
|
||||
@Scheduled(cron = "${clearing-service.scheduler.check-s-trade}")
|
||||
public void resetTradingDay() {
|
||||
Instant today = TimeUtil.localDateToInstant(LocalDate.now());
|
||||
if (tradingDay == null || !tradingDay.equals(today)) {
|
||||
tradeNum = -1L;
|
||||
tradingDay = today;
|
||||
}
|
||||
log.info("Reset trading day for search STrade: tradeNum={}, tradeDat={}", tradeNum, tradingDay);
|
||||
}
|
||||
|
||||
public void processNewTS() {
|
||||
Long tradeNum = -1L; // todo уточнить как он обновляется
|
||||
ImdgPredicateBuilder pb = sTradeImdg.predicateBuilder();
|
||||
ImdgPredicate sql = pb.and(pb.greater("tradeNum", tradeNum), pb.greatEqual("tradeDateTime", tradingDay));
|
||||
Collection<STrade> sTrades = sTradeImdg.getCollectionObjectsByPredicate(sql);
|
||||
log.info("Found {} new s_trade with trade_num>{}", sTrades.size(), tradeNum);
|
||||
|
||||
if (sTrades.isEmpty()) {
|
||||
log.info("No new sTrades.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Выявление новых сделок необходимо выполнить следующие контрольные проверки:
|
||||
|
||||
// Проверить все инструменты.
|
||||
{
|
||||
Set<String> secCodesOfSTrade = sTrades.stream().map(STrade::getSecCode).filter(Objects::nonNull).collect(Collectors.toSet());
|
||||
log.debug("Verify {} instruments for {} STrade's.", secCodesOfSTrade.size(), sTrades.size());
|
||||
ImdgPredicate allIn = securityImdg.predicateBuilder().in("securitySymbol", secCodesOfSTrade.toArray(new String[0]));
|
||||
Collection<Security> foundSecurities = securityImdg.getCollectionObjectsByPredicate(allIn);
|
||||
Set<String> secCodesOfSecurity = foundSecurities.stream().map(Security::getSecuritySymbol).filter(Objects::nonNull).collect(Collectors.toSet());
|
||||
if (secCodesOfSecurity.containsAll(secCodesOfSTrade)) {
|
||||
log.debug("All {} Security found by {} secCodes from STrade",
|
||||
secCodesOfSecurity.size(), secCodesOfSTrade.size());
|
||||
} else {
|
||||
HashSet<String> notFoundSymbol = new HashSet<>(secCodesOfSTrade);
|
||||
notFoundSymbol.removeAll(secCodesOfSecurity);
|
||||
log.info("Found only {} Security by {} secCodes from STrade. Not found: {}",
|
||||
secCodesOfSecurity.size(), secCodesOfSTrade.size(), notFoundSymbol);
|
||||
createNewSecurities(notFoundSymbol);
|
||||
log.info("Stop till they all will be created");
|
||||
|
||||
auditMessage("В security нет записей с securitySymbol", notFoundSymbol);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Long generationId = idGenerator.nextId();
|
||||
log.info("generationId = {}", generationId);
|
||||
for (STrade trade : sTrades) {
|
||||
log.trace("Check s_trade[{}].tradeNum={}", trade.getId(), trade.getTradeNum());
|
||||
Collection<ExecutionDeposit> existsEDeposit = executionDepositImdg.getCollectionObjectsByFieldValues(Map.of(
|
||||
"exchangeExecutionId", trade.getTradeNum(),
|
||||
"exchangeExecutionTime", trade.getTradeDateTime()
|
||||
));
|
||||
|
||||
if (existsEDeposit.isEmpty()) {
|
||||
log.trace("S_TRADE[{}] new", trade.getId());
|
||||
ExecutionDeposit newED = null;
|
||||
try {
|
||||
newED = createExecutionDeposit(trade, Allowed.ALLOWED/*todo уточнить момент заполнения*/, generationId);
|
||||
verification(newED);
|
||||
executionDepositImdg.insert(newED);
|
||||
sendNotification(newED);
|
||||
} catch (ClearingException ce) {
|
||||
auditMessage(ce);
|
||||
} catch (Exception e) {
|
||||
if (newED != null) {
|
||||
newED.setCoverageStatus(Allowed.DENIED.getKey());
|
||||
}
|
||||
log.error("When create new ExecutionDeposit by STrade[{}]", trade.getId());
|
||||
}
|
||||
|
||||
} else {
|
||||
long[] idToLong = existsEDeposit.stream().mapToLong(ed -> ed.getId()).toArray();
|
||||
log.warn("S_TRADE[{}] already has executionDeposit: {}", trade.getId(), Arrays.toString(idToLong));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Long newMaxTradeNum = sTrades.stream().mapToLong(STrade::getTradeNum).max().orElseGet(() -> tradeNum);
|
||||
log.debug("Next tradeNum is {}", newMaxTradeNum);
|
||||
}
|
||||
|
||||
protected void verification(ExecutionDeposit forED) throws ClearingException {
|
||||
/*todo Рассчитанные в КС контрольные суммы (общее количество сделок и суммарный объем заключенных сделок в денежном выражении)
|
||||
должны совпадать со значениями, рассчитанными Торговой системой:
|
||||
count(execution[tradingDay]) = count (trade_arqua)
|
||||
*/
|
||||
// использовать ли VerificationResultComponent для сверки или здесь код добавить.
|
||||
|
||||
}
|
||||
|
||||
protected void auditMessage(ClearingException ce) {
|
||||
log.error("AUDIT error code {}: {}", ce.getEnumMsg(), ce.getMessage());
|
||||
}
|
||||
|
||||
protected void auditMessage(String message, Object... ids) {
|
||||
String txt = message;
|
||||
if (ids != null && ids.length > 0) {
|
||||
txt += " object:" + Arrays.toString(ids);
|
||||
}
|
||||
log.error("audit \"clearing-service\", errorText: {}", txt);
|
||||
}
|
||||
|
||||
/**
|
||||
* в очередь kafka для модуля securities-service сообщение о добавлении инструмента с параметром securitySymbol=s_trade.sec_code
|
||||
*
|
||||
* @param newSymbolRequest
|
||||
*/
|
||||
protected void createNewSecurities(Collection<String> newSymbolRequest) {
|
||||
final String destination = Consts.DESTINATION_MONEY_MARKET_SECURITY_NEW;
|
||||
List<String> symbolRequests = new ArrayList<>(newSymbolRequest); // чтобы в случае ошибки отобразить номер в логе
|
||||
List<Future<RecordMetadata>> sendAll = new ArrayList<>(symbolRequests.size());
|
||||
for (String newSymbol : symbolRequests) {
|
||||
if (newSymbol == null || newSymbol.isEmpty()) {
|
||||
log.warn("Empty SecuritySumbol");
|
||||
} else {
|
||||
MoneyMarketSecurityNewRequest requestPayload = new MoneyMarketSecurityNewRequest();
|
||||
requestPayload.setSecuritySymbol(newSymbol);
|
||||
|
||||
BaseRequest<Object> request = new BaseRequest<>();
|
||||
request.setId(idGenerator.nextId());
|
||||
request.setActionType(ActionType.NEW);
|
||||
request.setRequestPayload(requestPayload);
|
||||
|
||||
// saveRequestToStorage(destination, request); //сохраняет данные о запросе в хранилище
|
||||
log.trace("Send to {} new symbol \"{}\" ", destination, newSymbol);
|
||||
Future<RecordMetadata> send = kafka.send(new ProducerRecord<>(destination, request));
|
||||
sendAll.add(send);
|
||||
}
|
||||
}
|
||||
int i = 0;
|
||||
for (Future<RecordMetadata> future : sendAll) {
|
||||
try {
|
||||
future.get(); // get exception
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
String about = i < symbolRequests.size() ? symbolRequests.get(i) : "(out of range i=" + i + ")";
|
||||
log.warn("Thread interrupted! On send symbol \"{}\"", about);
|
||||
throw new RuntimeException(e);
|
||||
} catch (ExecutionException e) {
|
||||
String about = i < symbolRequests.size() ? symbolRequests.get(i) : "(out of range i=" + i + ")";
|
||||
log.error("Error send message for symbol \"{}\" to {}: {}", destination,
|
||||
about, ExceptionUtils.getStackTrace(e.getCause() == null ? e : e.getCause()));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
protected void sendNotification(ExecutionDeposit forED) {
|
||||
final String destination = Consts.REGISTRY_COVERED_DEAL_REGISTER_NEW;
|
||||
CoveredDealRegisterNewRequest requestPayload = new CoveredDealRegisterNewRequest();
|
||||
requestPayload.setExecutionId(forED.getId());
|
||||
// requestPayload.setCompanyFullName(forED.getCompanyFullName());
|
||||
requestPayload.setTradingDate(forED.getTradingDate());
|
||||
requestPayload.setExchangeExecutionId(forED.getExchangeExecutionId());
|
||||
requestPayload.setExchangeExecutionTime(forED.getExchangeExecutionTime());
|
||||
requestPayload.setSecuritySymbol(forED.getSecuritySymbol());
|
||||
requestPayload.setSecurityFullName(forED.getSecurityFullName());
|
||||
// requestPayload.setSellerFullName(forED.getSellerFullName());
|
||||
// requestPayload.setSellerClearingCode(forED.getSellerClearingCode());
|
||||
// String requestPayload.setSellerAccount(forED.getAccountId());
|
||||
// String requestPayload.setBuyerFullName(forED.getBuyerFullName());
|
||||
// requestPayload.setBuyerClearingCode(forED.getBuyerClearingCode());
|
||||
// String requestPayload.setBuyerAccount(forED.getBuyerAccount());
|
||||
// BigDecimal requestPayload.setAmount(forED.getAmount());
|
||||
requestPayload.setId(idGenerator.nextId());
|
||||
requestPayload.setCreatedAt(forED.getCreated());
|
||||
requestPayload.setUpdatedAt(forED.getUpdated());
|
||||
requestPayload.setClearingDate(forED.getClearingDate());
|
||||
|
||||
BaseRequest<Object> request = new BaseRequest<>();
|
||||
request.setId(idGenerator.nextId());
|
||||
request.setActionType(ActionType.NEW);
|
||||
request.setRequestPayload(requestPayload);
|
||||
log.trace("Send to {} new ExecutionDeposit[{}]", destination, forED.getId());
|
||||
Future<RecordMetadata> send = kafka.send(new ProducerRecord<>(destination, request));
|
||||
try {
|
||||
send.get();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new RuntimeException(e);
|
||||
} catch (ExecutionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected ExecutionDeposit createExecutionDeposit(STrade sTrade,
|
||||
Allowed coverageStatus, Long sessionId) throws ClearingException {
|
||||
Account account = accountImdg.getSingleObjectByFieldValues(Map.of("account", sTrade.getMoneyAccount()));
|
||||
Security security = securityImdg.getSingleObjectByFieldValues(Map.of("securitySymbol", sTrade.getSecCode()));
|
||||
if (security == null) {
|
||||
log.warn("security securitySymbol=\"{}\" not found", sTrade.getSecCode());
|
||||
throw new ClearingException(new EnumMessage(ClearingError.RecordNotFound, sTrade.getSecCode()));
|
||||
}
|
||||
Listing listing = null;
|
||||
if (security != null) {
|
||||
listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", security.getId()));
|
||||
}
|
||||
Company company = companyImdg.getSingleObjectByFieldValues(Map.of("tradingCode", sTrade.getFirmId()));
|
||||
if (company == null) {
|
||||
throw new ClearingException(new EnumMessage(ClearingError.CompanyNotFound, sTrade.getFirmId()));
|
||||
}
|
||||
|
||||
return createExecutionDeposit(sTrade, account, listing, company, security, coverageStatus, sessionId);
|
||||
}
|
||||
|
||||
private ExecutionDeposit createExecutionDeposit(STrade sTrade, Account account, Listing listing,
|
||||
Company company, Security security,
|
||||
Allowed coverageStatus, Long sessionId) {
|
||||
ExecutionDeposit eDeposit = new ExecutionDeposit();
|
||||
eDeposit.setId(idGenerator.nextId());
|
||||
final Instant now = Instant.now();
|
||||
final LocalDate nowDay = TimeUtil.toLocalDate(now);
|
||||
eDeposit.setCreated(now);
|
||||
eDeposit.setTradingDate(nowDay);
|
||||
eDeposit.setClearingDate(nowDay);
|
||||
|
||||
eDeposit.setExchangeExecutionId(sTrade.getTradeNum());
|
||||
eDeposit.setExchangeExecutionTime(sTrade.getTradeDateTime());
|
||||
if (account != null) {
|
||||
eDeposit.setAccountId(account.getId());
|
||||
}
|
||||
eDeposit.setMarket(Market.mkrs.getKey());
|
||||
eDeposit.setPrice(sTrade.getPrice());
|
||||
eDeposit.setLots(sTrade.getQty());
|
||||
if (listing != null && listing.getLotSize() != null && eDeposit.getLots() != null) {
|
||||
BigDecimal quantity = eDeposit.getLots().multiply(listing.getLotSize());
|
||||
eDeposit.setQuantity(quantity);
|
||||
}
|
||||
eDeposit.setFirstLegAmount(sTrade.getValue());
|
||||
eDeposit.setSecondLegAmount(sTrade.getValue());
|
||||
//eDeposit.setInterestAmount(null);
|
||||
eDeposit.setSide(sTrade.getOperation());//Символьный код по справочнику moneyFlowSide), соответствующий значению из s_trade.operation (sTrade.getOperation())
|
||||
eDeposit.setSettlementCurrency("RUB"); // (справочник currencyCode)
|
||||
eDeposit.setCompanyId(company.getId());
|
||||
eDeposit.setDuration(sTrade.getDaysToMatDate());
|
||||
eDeposit.setFirstLegSettlementDate(nowDay);
|
||||
eDeposit.setSecondLegSettlementDate(sTrade.getSettleDate());
|
||||
//eDeposit.setFirstLegSettlementCode(null);
|
||||
//eDeposit.setSecondLegSettlementCode(null);
|
||||
eDeposit.setSecurityFullName(security.getFullName());
|
||||
eDeposit.setSecuritySymbol(security.getSecuritySymbol());
|
||||
eDeposit.setSecurityId(security.getId());
|
||||
//eDeposit.setCounterPartyId(null);
|
||||
eDeposit.setCoverageStatus(coverageStatus == null ? null : coverageStatus.getKey()); // Заполняется по справочнику allowed в результате расчета требований и обязательств. TODO
|
||||
eDeposit.setSessionId(sessionId);
|
||||
|
||||
return eDeposit;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package ru.spcex.clearing.service;
|
||||
|
||||
import org.apache.kafka.clients.consumer.Consumer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest;
|
||||
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
|
||||
import ru.spcex.platform.enumeration.Task;
|
||||
|
||||
@Service
|
||||
public class LauncherCommandReceiver extends QueueConsumer implements InitializingBean {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
private final ClearingService clearingService;
|
||||
@Autowired
|
||||
public LauncherCommandReceiver(Consumer<String, Object> kafkaQueue,
|
||||
ClearingService clearingService) {
|
||||
super(kafkaQueue);
|
||||
this.clearingService = clearingService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
callback(LauncherCommandRequest.class)
|
||||
.setConsumer(action -> clearingService.executeVerification())
|
||||
.forDestination(Task.createOrderConfirm.topic(), callbacks::put); // CORC
|
||||
|
||||
init();
|
||||
}
|
||||
}
|
||||
|
|
@ -19,4 +19,5 @@ clearing-service.kafka-producer.batch-size=16384
|
|||
clearing-service.kafka-producer.linger-ms=1
|
||||
clearing-service.kafka-producer.buffer-memory=33554432
|
||||
|
||||
clearing-service.scheduler.check-payment-instruction=*/5 * * * * *
|
||||
clearing-service.scheduler.check-payment-instruction=*/5 * * * * *
|
||||
clearing-service.scheduler.check-s-trade=0 1 0 1 * ?
|
||||
|
|
|
|||
|
|
@ -45,16 +45,16 @@ public class LiabilitiesClaimsAssetsMapStore extends TemplateMapStore<Liabilitie
|
|||
object.setCompanyId(resultSet.getObject("COMPANY_ID", Long.class));
|
||||
object.setCreated(getInstantFromTimestamp(resultSet, "CREATED_AT"));
|
||||
object.setUpdated(getInstantFromTimestamp(resultSet, "UPDATED_AT"));
|
||||
object.setClearingDate(getInstantFromTimestamp(resultSet, "CLEARING_DATE"));
|
||||
object.setClearingDate(getLocalDateFromSqlDate(resultSet, "CLEARING_DATE"));
|
||||
object.setAccountId(resultSet.getObject("ACCOUNT_ID", Long.class));
|
||||
object.setAccountType(resultSet.getObject("ACCOUNT_TYPE", String.class));
|
||||
object.setAccount(resultSet.getObject("ACCOUNT", String.class));
|
||||
object.setLiabilitiesQuantity(resultSet.getObject("LIABILITIES_QUANTITY", BigDecimal.class));
|
||||
object.setClaimsQuantity(resultSet.getObject("CLAIMS_QUANTITY", BigDecimal.class));
|
||||
object.setCurrency(resultSet.getObject("CURRENCY", String.class));
|
||||
object.setSettlementDate(getInstantFromTimestamp(resultSet, "SETTLEMENT_DATE"));
|
||||
object.setTradingDate(getInstantFromTimestamp(resultSet, "TRADING_DATE"));
|
||||
object.setRefundDate(getInstantFromTimestamp(resultSet, "REFUND_DATE"));
|
||||
object.setSettlementDate(getLocalDateFromSqlDate(resultSet, "SETTLEMENT_DATE"));
|
||||
object.setTradingDate(getLocalDateFromSqlDate(resultSet, "TRADING_DATE"));
|
||||
object.setRefundDate(getLocalDateFromSqlDate(resultSet, "REFUND_DATE"));
|
||||
object.setPrice(resultSet.getObject("PRICE", BigDecimal.class));
|
||||
object.setSecurityId(resultSet.getObject("SECURITY_ID", Long.class));
|
||||
object.setTradingCode(resultSet.getObject("TRADING_CODE", String.class));
|
||||
|
|
@ -78,16 +78,16 @@ public class LiabilitiesClaimsAssetsMapStore extends TemplateMapStore<Liabilitie
|
|||
object.getCompanyId(),
|
||||
TimeUtil.toDateFromInstant(object.getCreated()),
|
||||
TimeUtil.toDateFromInstant(object.getUpdated()),
|
||||
TimeUtil.toDateFromInstant(object.getClearingDate()),
|
||||
TimeUtil.toDateFromLocalDate(object.getClearingDate()),
|
||||
object.getAccountId(),
|
||||
object.getAccountType(),
|
||||
object.getAccount(),
|
||||
object.getLiabilitiesQuantity(),
|
||||
object.getClaimsQuantity(),
|
||||
object.getCurrency(),
|
||||
TimeUtil.toDateFromInstant(object.getSettlementDate()),
|
||||
TimeUtil.toDateFromInstant(object.getTradingDate()),
|
||||
TimeUtil.toDateFromInstant(object.getRefundDate()),
|
||||
TimeUtil.toDateFromLocalDate(object.getSettlementDate()),
|
||||
TimeUtil.toDateFromLocalDate(object.getTradingDate()),
|
||||
TimeUtil.toDateFromLocalDate(object.getRefundDate()),
|
||||
object.getPrice(),
|
||||
object.getSecurityId(),
|
||||
object.getTradingCode(),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,94 @@
|
|||
package ru.spcex.clearing.imdg.object;
|
||||
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
import ru.clearing.classes.statics.data.misc.STrade;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.imdg.base.TemplateMapStore;
|
||||
import ru.spcex.platform.utils.time.TimeUtil;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.time.LocalDate;
|
||||
|
||||
@Component
|
||||
public class STradeMapStore extends TemplateMapStore<STrade> {
|
||||
|
||||
public STradeMapStore(JdbcTemplate jdbcTemplate) {
|
||||
super(jdbcTemplate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMapName() {
|
||||
return IMDGDistributedNames.Map_STrade;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTableName() {
|
||||
return "S_TRADE";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getFields() {
|
||||
return new String[]{
|
||||
"ID", "TRADE_NUM", "SEC_CODE", "TRADE_DATE_TIME", "SETTLE_DATE", "PRICE", "VALUE", "QTY", "ACCRUEDINT",
|
||||
"FIRM_ID", "CLIENT_CODE", "EXCHANGE_COMMISSION", "CLASS_CODE", "OPERATION", "ISSUE_ACCOUNT",
|
||||
"MONEY_ACCOUNT", "TRADE_TYPE", "DAYS_TO_MAT_DATE", "COLLATERAL", "SETTLE_CODE"
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public STrade objectReader(ResultSet resultSet) throws SQLException {
|
||||
STrade object = new STrade();
|
||||
object.setId(resultSet.getObject("ID", Long.class));
|
||||
object.setTradeNum(resultSet.getObject("TRADE_NUM", Long.class));
|
||||
object.setSecCode(resultSet.getObject("SEC_CODE", String.class));
|
||||
object.setTradeDateTime(getInstantFromTimestamp(resultSet, "TRADE_DATE_TIME"));
|
||||
object.setSettleDate(resultSet.getObject("SETTLE_DATE", LocalDate.class));
|
||||
object.setPrice(resultSet.getObject("PRICE", BigDecimal.class));
|
||||
object.setValue(resultSet.getObject("VALUE", BigDecimal.class));
|
||||
object.setQty(resultSet.getObject("QTY", BigDecimal.class));
|
||||
object.setAccruedint(resultSet.getObject("ACCRUEDINT", BigDecimal.class));
|
||||
object.setFirmId(resultSet.getObject("FIRM_ID", String.class));
|
||||
object.setClientCode(resultSet.getObject("CLIENT_CODE", String.class));
|
||||
object.setExchangeCommission(resultSet.getObject("EXCHANGE_COMMISSION", BigDecimal.class));
|
||||
object.setClassCode(resultSet.getObject("CLASS_CODE", String.class));
|
||||
object.setOperation(resultSet.getObject("OPERATION", String.class));
|
||||
object.setIssueAccount(resultSet.getObject("ISSUE_ACCOUNT", String.class));
|
||||
object.setMoneyAccount(resultSet.getObject("MONEY_ACCOUNT", String.class));
|
||||
object.setTradeType(resultSet.getObject("TRADE_TYPE", String.class));
|
||||
object.setDaysToMatDate(resultSet.getObject("DAYS_TO_MAT_DATE", Long.class));
|
||||
object.setCollateral(resultSet.getObject("COLLATERAL", String.class));
|
||||
object.setSettleCode(resultSet.getObject("SETTLE_CODE", String.class));
|
||||
return object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] objectToField(STrade object) {
|
||||
Object[] args = new Object[]{
|
||||
object.getId(),
|
||||
object.getTradeNum(),
|
||||
object.getSecCode(),
|
||||
TimeUtil.toDateFromInstant(object.getTradeDateTime()),
|
||||
object.getSettleDate(),
|
||||
object.getPrice(),
|
||||
object.getValue(),
|
||||
object.getQty(),
|
||||
object.getAccruedint(),
|
||||
object.getFirmId(),
|
||||
object.getClientCode(),
|
||||
object.getExchangeCommission(),
|
||||
object.getClassCode(),
|
||||
object.getOperation(),
|
||||
object.getIssueAccount(),
|
||||
object.getMoneyAccount(),
|
||||
object.getTradeType(),
|
||||
object.getDaysToMatDate(),
|
||||
object.getCollateral(),
|
||||
object.getSettleCode()
|
||||
};
|
||||
return args;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -12,11 +12,15 @@ import ru.clearing.classes.statics.data.generated.ClearingMemberCategory;
|
|||
import ru.clearing.classes.statics.data.journal.InDocumentJournal;
|
||||
import ru.clearing.classes.statics.data.journal.ManagementJournal;
|
||||
import ru.clearing.classes.statics.data.journal.OutDocumentJournal;
|
||||
import ru.clearing.classes.statics.data.liabilities.LiabilitiesClaimsAssets;
|
||||
import ru.clearing.classes.statics.data.liabilities.LiabilitiesClaimsMoney;
|
||||
import ru.clearing.classes.statics.data.messages.ErrorText;
|
||||
import ru.clearing.classes.statics.data.misc.*;
|
||||
import ru.clearing.classes.statics.data.payment.PaymentInstruction;
|
||||
import ru.clearing.classes.statics.data.profile.Contact;
|
||||
import ru.clearing.classes.statics.data.profile.ProfileDocument;
|
||||
import ru.clearing.classes.statics.data.register.OrderRegister;
|
||||
import ru.clearing.classes.statics.data.register.ReportRegister;
|
||||
import ru.clearing.classes.statics.data.scheduler.*;
|
||||
import ru.clearing.classes.statics.data.sdf.*;
|
||||
import ru.clearing.classes.statics.data.security.Security;
|
||||
|
|
@ -66,6 +70,10 @@ public class RunnableMapNamesForTesting {
|
|||
usingIgnoringFieldsComparator("profile.clearingCode", "profile.fullName", "profile.registrationCode", "profile.shortName", "profile.tradingCode")));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_ErrorText, ErrorText.class));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_Launcher, Launcher.class));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_LiabilitiesClaimsAssets, LiabilitiesClaimsAssets.class));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_LiabilitiesClaimsMoney, LiabilitiesClaimsMoney.class,
|
||||
new SettingOperation("setClaimsAmount", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("04.92")}),
|
||||
new SettingOperation("setLiabilitiesAmount", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("06.26")})));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_Listing, Listing.class,
|
||||
new SettingOperation("setLotSize", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("21.11")})));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_ManagementJournal, ManagementJournal.class));
|
||||
|
|
@ -78,11 +86,6 @@ public class RunnableMapNamesForTesting {
|
|||
new SettingOperation("setAmount", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("23.22")})));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_UserConnect, UserConnect.class));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_User, User.class));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_VerificationResult, VerificationResult.class,
|
||||
new SettingOperation("setDiffSum", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("13.22")}),
|
||||
new SettingOperation("setInSum", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("14.22")}),
|
||||
new SettingOperation("setOutExtSum", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("15.22")}),
|
||||
new SettingOperation("setOutIntSum", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("19.22")})));
|
||||
|
||||
//dictionary
|
||||
dictionaryObjectForCheckMapStores.add(new DictionaryObjectForCheckMapStore<>(IMDGDistributedNames.Map_AccountStatusDictionary, AccountStatusDictionary.class));
|
||||
|
|
@ -128,12 +131,26 @@ public class RunnableMapNamesForTesting {
|
|||
|
||||
//object
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_AccountRouting, AccountRouting.class));
|
||||
// businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_AdmittedDealRegister, AdmittedDealRegister.class,
|
||||
// new SettingOperation("setAmount", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("19.12")})));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_BankAccount, BankAccount.class));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_ClearMemberRegister, ClearMemberRegister.class));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_CompanyRoleSet, CompanyRoleSet.class));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_Contact, Contact.class));
|
||||
// businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_ContractRegister, ContractRegister.class));
|
||||
// businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_CoveredDealRegister, CoveredDealRegister.class,
|
||||
// new SettingOperation("setAmount", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("11.11")})));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_Currency, Currency.class));
|
||||
// businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_DealRegister, DealRegister.class,
|
||||
//// new SettingOperation("setAmount", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("11.11")})));
|
||||
// businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_ExecutionDeposit, ExecutionDeposit.class,
|
||||
// new SettingOperation("setFirstLegAmount", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("03.22")}),
|
||||
// new SettingOperation("setSecondLegAmount", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("03.33")}),
|
||||
// new SettingOperation("setInterestAmount", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("04.22")}),
|
||||
// new SettingOperation("setLots", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("05.22")}),
|
||||
// new SettingOperation("setQuantity", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("09.22")})));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_InDocumentJournal, InDocumentJournal.class,
|
||||
new SettingOperation("setAmount", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("22.12")})));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_InformationAccount, InformationAccount.class));
|
||||
|
|
@ -141,11 +158,13 @@ public class RunnableMapNamesForTesting {
|
|||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_MoneyMarketSecurity, MoneyMarketSecurity.class,
|
||||
new SettingOperation("setNominalValue", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("25.25")})));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_Notification, Notification.class));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_OrderRegister, OrderRegister.class));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_OutDocumentJournal, OutDocumentJournal.class,
|
||||
new SettingOperation("setAmount", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("28.28")})));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_PaymentInstruction, PaymentInstruction.class));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_PlannerAllToday, PlannerAllToday.class));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_ProfileDocument, ProfileDocument.class));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_ReportRegister, ReportRegister.class));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_SDf01, SDf01.class));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_SDf02, SDf02.class));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_SDf03, SDf03.class));
|
||||
|
|
@ -161,7 +180,16 @@ public class RunnableMapNamesForTesting {
|
|||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_SDf17, SDf17.class));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_SDf18, SDf18.class));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_Session, Session.class));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_STrade, STrade.class,
|
||||
new SettingOperation("setQty", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("23.92")}),
|
||||
new SettingOperation("setValue", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("24.92")}),
|
||||
new SettingOperation("setExchange_commission", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("26.26")})));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_UserRoleSession, UserRoleSession.class));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_UserSettings, UserSettings.class));
|
||||
businessObjectAndBusinessEventForCheckMapStores.add(new BusinessObjectAndBusinessEventForCheckMapStore<>(IMDGDistributedNames.Map_VerificationResult, VerificationResult.class,
|
||||
new SettingOperation("setDiffSum", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("13.22")}),
|
||||
new SettingOperation("setInSum", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("14.22")}),
|
||||
new SettingOperation("setOutExtSum", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("15.22")}),
|
||||
new SettingOperation("setOutIntSum", new Class[]{BigDecimal.class}, new Object[]{new BigDecimal("19.22")})));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
-- DB version: 2.4.4.0
|
||||
-- DB version: 2.4.0.7
|
||||
/* Dictionaries */
|
||||
|
||||
-- chargeDirection - Направление начисления комиссии
|
||||
|
|
@ -1532,7 +1532,7 @@ COMMENT ON COLUMN ACCOUNT_BALANCE.COMPANY_ID IS 'Наименование уча
|
|||
|
||||
COMMENT ON COLUMN ACCOUNT_BALANCE.ACCOUNT_ID IS 'Наименование счета (linked to account)';
|
||||
|
||||
COMMENT ON COLUMN ACCOUNT_BALANCE.ACCOUNT_TYPE IS 'Тип счета (linked to account)';
|
||||
COMMENT ON COLUMN ACCOUNT_BALANCE.ACCOUNT_TYPE IS 'Тип счета (linked to accountType)';
|
||||
|
||||
COMMENT ON COLUMN ACCOUNT_BALANCE.ACCOUNT IS 'Наименование счета';
|
||||
|
||||
|
|
@ -1586,7 +1586,7 @@ COMMENT ON COLUMN ACCOUNT_BALANCE_HISTORY.COMPANY_ID IS 'Наименовани
|
|||
|
||||
COMMENT ON COLUMN ACCOUNT_BALANCE_HISTORY.ACCOUNT_ID IS 'Наименование счета (linked to account)';
|
||||
|
||||
COMMENT ON COLUMN ACCOUNT_BALANCE_HISTORY.ACCOUNT_TYPE IS 'Тип счета (linked to account)';
|
||||
COMMENT ON COLUMN ACCOUNT_BALANCE_HISTORY.ACCOUNT_TYPE IS 'Тип счета (linked to accountType)';
|
||||
|
||||
COMMENT ON COLUMN ACCOUNT_BALANCE_HISTORY.ACCOUNT IS 'Наименование счета';
|
||||
|
||||
|
|
@ -3414,110 +3414,5 @@ COMMENT ON COLUMN MONEY_MARKET_SESSION_HISTORY.USER_ID IS 'Наименован
|
|||
|
||||
/* views */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- Data types
|
||||
|
||||
|
|
@ -12,6 +12,7 @@ import ru.spcex.clearing.reports.reports.ReportId;
|
|||
import ru.spcex.clearing.reports.services.builders.XMLReportBuilder;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
import ru.spcex.platform.utils.log.ExceptionUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
|
@ -74,12 +75,20 @@ public class ReportsServiceCommand implements InitializingBean {
|
|||
public void generateReportAll(@Nullable String reportGroup, LocalDate startDate, LocalDate endDate) throws IOException {
|
||||
for (ReportWithPeriodCollector<?> reportDataCollector : allPeriodReports) {
|
||||
if (reportGroup == null || QUEUE_RUN_REPORT_COMMAND.equals(reportGroup)) {
|
||||
makeSingleReport(reportDataCollector, startDate, endDate);
|
||||
try {
|
||||
makeSingleReport(reportDataCollector, startDate, endDate);
|
||||
} catch (Exception e) {
|
||||
log.error("Error generate report of type {}: {}", reportDataCollector, ExceptionUtils.getStackTrace(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (SimpleReportCollector<?> reportDataCollector : allSimpleReports) {
|
||||
if (reportGroup == null || QUEUE_RUN_DAILY_REPORT_COMMAND.equals(reportGroup)) {
|
||||
makeSingleReport(reportDataCollector);
|
||||
try {
|
||||
makeSingleReport(reportDataCollector);
|
||||
} catch (Exception e) {
|
||||
log.error("Error generate report of type {}: {}", reportDataCollector, ExceptionUtils.getStackTrace(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,6 +68,10 @@ public class ReportBR_0420314_P2_Collector extends ReportWithPeriodCollector<Rep
|
|||
final Long companyId = entry.getKey();
|
||||
List<PaymentInstruction> paymentInstructionsByCompany = entry.getValue();
|
||||
Company company = companyImdg.getSingleObjectByID(companyId);
|
||||
if (company == null) {
|
||||
log.warn("Company not found, id={}", companyId);
|
||||
continue;
|
||||
}
|
||||
ProfileDocument profileDocumentCntr = profileDocumentImdg.getSingleObjectByFieldValues(Map.of(
|
||||
"companyId", companyId,
|
||||
"documentType", DocumentTypes.cntr.getKey()
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ public class ReportBR_0420318_Collector extends ReportWithPeriodCollector<Report
|
|||
for (LiabilitiesClaimsAssets liability : liabilitiesByCompany) {
|
||||
final String currencyCode = liability.getCurrency();
|
||||
|
||||
Instant liabilitiesClaimsAssets_settlementDate = null;
|
||||
LocalDate liabilitiesClaimsAssets_settlementDate = null;
|
||||
if (checkCategoryB) {
|
||||
liabilitiesClaimsAssets_settlementDate = liability.getRefundDate();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@ package ru.spcex.clearing.scheduler.service;
|
|||
|
||||
import org.apache.kafka.clients.consumer.Consumer;
|
||||
import org.apache.kafka.clients.producer.Producer;
|
||||
import org.apache.kafka.clients.producer.ProducerRecord;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.clearing.classes.statics.data.scheduler.Launcher;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
|
||||
|
|
@ -20,14 +22,17 @@ import java.time.Instant;
|
|||
|
||||
import static ru.spcex.platform.utils.enumeration.IEnumKey.getEnumByKey;
|
||||
|
||||
@Service
|
||||
public class LauncherService extends QueueConsumer implements InitializingBean {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
private final Imdg<Launcher> launcherMap;
|
||||
private final Producer<String, Object> kafkaProducer;
|
||||
|
||||
@Autowired
|
||||
public LauncherService(Consumer<String, Object> kafkaQueue, Producer<String, Object> kafkaProducer,
|
||||
ImdgProvider imdgProvider) {
|
||||
super(kafkaQueue, kafkaProducer);
|
||||
this.kafkaProducer = kafkaProducer;
|
||||
this.launcherMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Launcher, Launcher.class);
|
||||
}
|
||||
|
||||
|
|
@ -53,6 +58,7 @@ public class LauncherService extends QueueConsumer implements InitializingBean {
|
|||
launcher.setUpdated(created);
|
||||
launcherMap.insert(launcher);
|
||||
log.debug("successfully processed, new id {}", launcher.getId());
|
||||
kafkaProducer.send(new ProducerRecord<>("launcher-" + launcher.getTask(), req));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ public final class IMDGDistributedNames {
|
|||
public static final String Map_ContractRegister = "Map_ContractRegister";
|
||||
public static final String Map_OrderRegister = "Map_OrderRegister";
|
||||
public static final String Map_VerificationResult = "Map_VerificationResult";
|
||||
public static final String Map_STrade = "Map_STrade";
|
||||
|
||||
public static final String MAP_SEQUENCE_NAME = "MAP_SEQUENCE_NAME";
|
||||
|
||||
|
|
|
|||
|
|
@ -6,9 +6,12 @@ public class LauncherCommandRequest {
|
|||
|
||||
@JsonProperty
|
||||
private Long userId;
|
||||
|
||||
@JsonProperty
|
||||
private String taskName;
|
||||
@JsonProperty
|
||||
private Long companyId;
|
||||
@JsonProperty
|
||||
private Long securityId;
|
||||
|
||||
|
||||
public Long getUserId() {
|
||||
|
|
@ -26,4 +29,20 @@ public class LauncherCommandRequest {
|
|||
public void setTaskName(String taskName) {
|
||||
this.taskName = taskName;
|
||||
}
|
||||
|
||||
public Long getCompanyId() {
|
||||
return companyId;
|
||||
}
|
||||
|
||||
public void setCompanyId(Long companyId) {
|
||||
this.companyId = companyId;
|
||||
}
|
||||
|
||||
public Long getSecurityId() {
|
||||
return securityId;
|
||||
}
|
||||
|
||||
public void setSecurityId(Long securityId) {
|
||||
this.securityId = securityId;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue