etreschenkov 2026-04-22 18:19:29 +03:00
parent a7780a114c
commit 30cb352377
4 changed files with 71 additions and 2 deletions

View file

@ -1,12 +1,18 @@
package ru.spcex.clearing.dflt.management.listener;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.producer.Producer;
@ -17,6 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.misc.OrderCurrency;
import ru.clearing.classes.statics.data.misc.OvernightSettings;
import ru.clearing.classes.statics.data.misc.SCrossRate;
import ru.clearing.classes.statics.data.registry.Registry;
import ru.spcex.clearing.dflt.management.config.settings.DefaultManagementSettings;
import ru.spcex.clearing.dflt.management.service.ImdgQueryService;
@ -27,9 +34,13 @@ import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.platform.messaging.domain.BaseRequest;
import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.utilities.NotificationNewRequest;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender;
import ru.spcex.platform.enumeration.CurrencyCode;
import ru.spcex.platform.enumeration.ObjectType;
import ru.spcex.platform.enumeration.OvernightType;
import ru.spcex.platform.enumeration.Priority;
import ru.spcex.platform.enumeration.Task;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
@ -114,6 +125,26 @@ public class TaskListener extends QueueConsumer implements InitializingBean {
}
private void exportToTriAndSendToFix(BaseRequest<LauncherCommandRequest> req) {
log.info("SDOR check balance and send notification, request={}", req);
Collection<OrderCurrency> cretOrderCurrencies = imdgQueryService.getCRETOrderCurrencies();
HashSet<Long> seen = new HashSet<>();
Collection<OrderCurrency> withRegistryIdUnique = cretOrderCurrencies.stream()
.filter(orderCurrency -> seen.add(orderCurrency.getRegistryId()))
.toList();
List<String> messages = withRegistryIdUnique.stream()
.map(this::checkBalance)
.filter(Objects::nonNull)
.toList();
String comment = "После проведения первой части сделок переноса будет получен отрицательный баланс по RUB:\n"
+ String.join("\n", messages);
NotificationNewRequest newReq = new NotificationNewRequest();
newReq.setObjectType(ObjectType.rgst.getKey());
newReq.setPriority(Priority.HIGH.getKey());
newReq.setComment(comment);
kafkaSender.sendRequestToQueue(Consts.NOTIFICATION_NEW, req.getRequestPayload());
log.info("SDOR export and send command to fix, request={}", req);
try {
Collection<OrderCurrency> orders = imdgQueryService.getClccOrderCurrencyIds();
@ -127,6 +158,35 @@ public class TaskListener extends QueueConsumer implements InitializingBean {
}
}
private String checkBalance(OrderCurrency orderCurrency) {
Registry pmtRegistry = imdgQueryService.getRegistryById(orderCurrency.getRegistryId());
Registry amtRegistry = imdgQueryService.findAmtRegistry(pmtRegistry, CurrencyCode.RUB.getKey());
String currency = pmtRegistry.getSecuritySymbol().equals(CurrencyCode.RUB.getKey())
? CurrencyCode.CNY.getKey() : pmtRegistry.getSecuritySymbol();
SCrossRate sCrossRate = imdgQueryService.getSCrossRates(currency, LocalDate.now());
BigDecimal val = orderCurrency.getQuantityLot()
.multiply(orderCurrency.getLotSize())
.multiply(sCrossRate.getUnitRate());
BigDecimal diff;
int compareRes = amtRegistry.getBalance().compareTo(BigDecimal.ZERO);
if (compareRes < 0) {
diff = amtRegistry.getBalance().add(val);
} else {
diff = amtRegistry.getBalance().subtract(val);
}
if (diff.compareTo(BigDecimal.ZERO) < 0) {
NotificationNewRequest request = new NotificationNewRequest();
request.setObjectType(ObjectType.rgst.getKey());
request.setPriority(Priority.HIGH.getKey());
return String.format("Для ТКР %s компании %s: баланс %s RUB;",
amtRegistry.getTradingClearingRegistry(), amtRegistry.getShortName(),
diff.setScale(2, RoundingMode.HALF_UP));
}
return null;
}
private OvernightType resolveOvernightType(Registry registry) {
Optional<OvernightSettings> settingsOpt =
imdgQueryService.findOvernightSettingsByCompany(registry.getCompanyId());

View file

@ -24,6 +24,7 @@ import ru.spcex.clearing.dflt.management.model.CounterpartyInfo;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.platform.enumeration.CompanyRole;
import ru.spcex.platform.enumeration.MarketType;
import ru.spcex.platform.enumeration.OrderStatus;
import ru.spcex.platform.enumeration.RegistryStatus;
import ru.spcex.platform.enumeration.WorkflowStatus;
import ru.spcex.platform.imdg.api.Imdg;
@ -93,6 +94,13 @@ public class ImdgQueryService {
return orderCurrencyImdg.getCollectionObjectsByPredicate(clccOrderPredicate);
}
public Collection<OrderCurrency> getCRETOrderCurrencies() {
ImdgPredicateBuilder builder = orderCurrencyImdg.predicateBuilder();
return orderCurrencyImdg.getCollectionObjectsByPredicate(
builder.equals("status", OrderStatus.CREATED.getKey())
);
}
public Optional<OvernightSettings> findOvernightSettingsByCompany(Long companyId) {
ImdgPredicateBuilder builder = overnightSettingsImdg.predicateBuilder();
ImdgPredicate predicate = builder.and(

View file

@ -7,7 +7,7 @@ public enum CurrencyCode implements IEnumKey {
RUB("RUB"),
RUR("RUR"),//fixme may be remove to separate enum
SUR("SUR"),
CNY("CNY"),
;
public static boolean isRub(String currencyCode) {

View file

@ -3,7 +3,8 @@ package ru.spcex.platform.enumeration;
import ru.spcex.platform.utils.enumeration.IEnumKey;
public enum OrderStatus implements IEnumKey {
NEW("NEW"), PTFL("PTFL"), FILL("FILL"), CNCL("CNCL"), REPL("REPL"), REJECTED("RJCT");
NEW("NEW"), PTFL("PTFL"), FILL("FILL"), CNCL("CNCL"), REPL("REPL"), REJECTED("RJCT"),
CREATED("CRET");
private final String key;