registry-service http://jira.mfd.msk:8088/browse/CLS-638 LiabilitiesRegisterService теперь только в файл, backend-api meta после CLS-635 удалили лишнее - вернул

This commit is contained in:
AKurakin 2024-01-30 18:42:50 +03:00
parent d4285494af
commit 24c203a83f
8 changed files with 333 additions and 82 deletions

View file

@ -1,6 +1,6 @@
{
"version": "3.9.0.72",
"version": "3.9.0.73",
"enums": {
@ -5492,6 +5492,17 @@
"fields": []
}
,
{"method":"post",
"destination": "LBSR",
"group": "Формирование реестров",
"name": "Формирование реестра учета обязательств",
"fields": []
}
,
{"method":"post",
"destination": "ECNR",

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--?xml-stylesheet type="text/xsl" href="\..\corp-reports\src\data\meta\meta.server.xslt"?-->
<meta version="3.9.0.72">
<meta version="3.9.0.73">
<!-- _xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" _xsi:noNamespaceSchemaLocation="file:///E:/d/projects/meta/from/meta.xsd" -->
<!--Здесь словари-->
<enums>
@ -1270,6 +1270,8 @@
</post>
<post destination="GORD" group="Формирование реестров" name="Формирование реестра распоряжений, направленных расчетному депозитарию">
</post>
<post destination="LBSR" group="Формирование реестров" name="Формирование реестра учета обязательств">
</post>
<post destination="ECNR" group="Формирование реестров" name="Формирование реестра сделок">
</post>
<post destination="GRET" group="Формирование отчетности" name="Формирование отчетности PFX64/PFX65">

View file

@ -1,6 +1,6 @@
{
"version": "3.9.0.72",
"version": "3.9.0.73",
"enums": {
@ -5492,6 +5492,17 @@
"fields": []
}
,
{"method":"post",
"destination": "LBSR",
"group": "Формирование реестров",
"name": "Формирование реестра учета обязательств",
"fields": []
}
,
{"method":"post",
"destination": "ECNR",

View file

@ -0,0 +1,121 @@
package ru.spcex.clearing.registry.reports.bean;
import com.opencsv.bean.CsvBindByName;
import com.opencsv.bean.CsvBindByPosition;
import com.opencsv.bean.CsvDate;
import com.opencsv.bean.CsvNumber;
import java.math.BigDecimal;
import java.time.LocalDate;
public class LiabilitiesRegistryReport implements FileReport {
@CsvBindByName(column = "клиринговый код")
@CsvBindByPosition(position = 0)
private String clearing_code;
@CsvBindByName(column = "счет")
@CsvBindByPosition(position = 1)
private String account;
@CsvBindByName(column = "код регистра")
@CsvBindByPosition(position = 2)
private String registry_code;
@CsvBindByName(column = "статус")
@CsvBindByPosition(position = 3)
private String registry_status;
@CsvBindByName(column = "инструмент валюта")
@CsvBindByPosition(position = 4)
private String security_symbol;
@CsvBindByName(column = "баланс")
@CsvBindByPosition(position = 5)
@CsvNumber(value = "#0.00", writeFormat = "#0.00")
private BigDecimal balance;
@CsvBindByName(column = "дата расчета")
@CsvBindByPosition(position = 6)
@CsvDate(value = "dd.MM.yyyy")
private LocalDate settlement_date;
@CsvBindByName(column = "продукт")
@CsvBindByPosition(position = 7)
private String contract;
@CsvBindByName(column = "тип сессии")
@CsvBindByPosition(position = 8)
private String session_type;
public String getClearing_code() {
return clearing_code;
}
public void setClearing_code(String clearing_code) {
this.clearing_code = clearing_code;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getRegistry_code() {
return registry_code;
}
public void setRegistry_code(String registry_code) {
this.registry_code = registry_code;
}
public String getRegistry_status() {
return registry_status;
}
public void setRegistry_status(String registry_status) {
this.registry_status = registry_status;
}
public String getSecurity_symbol() {
return security_symbol;
}
public void setSecurity_symbol(String security_symbol) {
this.security_symbol = security_symbol;
}
public BigDecimal getBalance() {
return balance;
}
public void setBalance(BigDecimal balance) {
this.balance = balance;
}
public LocalDate getSettlement_date() {
return settlement_date;
}
public void setSettlement_date(LocalDate settlement_date) {
this.settlement_date = settlement_date;
}
public String getContract() {
return contract;
}
public void setContract(String contract) {
this.contract = contract;
}
public String getSession_type() {
return session_type;
}
public void setSession_type(String session_type) {
this.session_type = session_type;
}
}

View file

@ -0,0 +1,74 @@
package ru.spcex.clearing.registry.reports.builders;
import ru.clearing.classes.statics.data.registry.Registry;
import ru.clearing.platform.dictionary.RegistryStatusDictionary;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.registry.reports.bean.LiabilitiesRegistryReport;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import java.util.Collection;
import java.util.Comparator;
import java.util.Map;
import java.util.stream.Collectors;
public class LiabilitiesRegistryReportBuilder extends XLSXReportBuilder<LiabilitiesRegistryReport, Registry> {
private final Imdg<RegistryStatusDictionary> registryStatusDictionaryImdg;
public LiabilitiesRegistryReportBuilder(ImdgProvider imdgProvider) {
registryStatusDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_RegistryStatusDictionary, RegistryStatusDictionary.class);
}
@Override
protected String reportName() {
return "registry";
}
@Override
protected Class<LiabilitiesRegistryReport> getReportClass() {
return LiabilitiesRegistryReport.class;
}
@Override
protected LiabilitiesRegistryReport toRow(Registry input) {
LiabilitiesRegistryReport entity = new LiabilitiesRegistryReport();
entity.setClearing_code(input.getClearingCode());
entity.setAccount(input.getAccount());
entity.setRegistry_code(input.getRegistryCode());
entity.setRegistry_status(describeRegistryStatus(input.getRegistryStatus())); // CLRD
entity.setSecurity_symbol(input.getSecuritySymbol());
entity.setBalance(input.getBalance());
entity.setSettlement_date(input.getSettlementDate());
entity.setContract(input.getContract());
entity.setSession_type(input.getSessionType());
return entity;
}
/**
* @param registryStatus 'CLRD', ...
* @return из справочника
*/
private String describeRegistryStatus(String registryStatus) {
if (registryStatus == null)
return registryStatus;
RegistryStatusDictionary dictionary = registryStatusDictionaryImdg.getFirstObjectByFieldValues(Map.of(
"code", registryStatus
));
if (dictionary == null) {
log.warn("Dictionary not found for status=\"{}\"", dictionary);
return registryStatus;
}
return dictionary.getName();
}
@Override
protected Collection<Registry> sortInput(Collection<Registry> input) {
return input.stream()
.sorted(Comparator.comparing(Registry::getCreated))
.collect(Collectors.toList());
}
}

View file

@ -70,6 +70,7 @@ public abstract class XLSXReportBuilder<R extends FileReport, I extends SpcexObj
rows = sortOutput(rows).stream().toList();
File reportFile = new File(outFolder, normalizeFilenameForOS(getReportFilename() + ".xlsx"));
log.debug("Создание отчёта {} в файл \"{}\"", reportName(), reportFile.getPath());
try {
Constructor<? extends R> constructor = Objects.requireNonNull(getReportClass()).getDeclaredConstructor();
@ -166,6 +167,7 @@ public abstract class XLSXReportBuilder<R extends FileReport, I extends SpcexObj
return null;
}
log.trace("Отчёт {} создан.", reportName());
return reportFile;
}

View file

@ -6,6 +6,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import ru.clearing.classes.statics.data.company.CompanySymbols;
import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeSecurity;
@ -20,17 +21,26 @@ import ru.spcex.clearing.platform.messaging.domain.Consts;
import ru.spcex.clearing.platform.messaging.domain.cud.registry.LiabilitiesRegisterNewRequest;
import ru.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest;
import ru.spcex.clearing.platform.messaging.service.QueueConsumer;
import ru.spcex.clearing.registry.config.SFTPReportsConfig;
import ru.spcex.clearing.registry.config.settings.RegistryServiceSettings;
import ru.spcex.clearing.registry.reports.ReportUtils;
import ru.spcex.clearing.registry.reports.builders.LiabilitiesRegistryReportBuilder;
import ru.spcex.clearing.registry.util.PreClearMap;
import ru.spcex.platform.enumeration.*;
import ru.spcex.platform.imdg.api.Imdg;
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.imdg.api.predicate.specific.RegistryCodeSqlBuilder;
import ru.spcex.platform.imdg.api.predicate.specific.SecuritySelector;
import ru.spcex.platform.utils.time.TimeUtil;
import ru.spcex.platform.utils.validation.IValidator;
import java.io.File;
import java.time.Instant;
import java.time.LocalDate;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
@ -48,12 +58,20 @@ public class LiabilitiesRegisterService extends QueueConsumer implements Initial
private final SecuritySelector<Security> securitySelector;
private final Function<Map<String, ?>, IValidator> fieldValuesValidator;
private final PreClearMap<LiabilitiesRegister> preClearMap;
private final LiabilitiesRegistryReportBuilder reportBuilder;
private final File outFolder;
private final RegistryServiceSettings settings;
private final SFTPReportsConfig.ReportsGateway reportsSftpGateway;
private final boolean deleteAfterSend;
@Autowired
public LiabilitiesRegisterService(Consumer<String, Object> kafkaQueue,
Producer<String, Object> kafkaProducer,
ImdgProvider imdgProvider,
Function<Map<String, ?>, IValidator> fieldValuesValidator) {
Function<Map<String, ?>, IValidator> fieldValuesValidator,
@Qualifier("reportOutDir") File outFolder,
RegistryServiceSettings settings,
SFTPReportsConfig.ReportsGateway reportsSftpGateway) {
super(kafkaQueue, kafkaProducer);
this.liabilitiesRegisterMap = imdgProvider.getImdg(IMDGDistributedNames.Map_LiabilitiesRegister, LiabilitiesRegister.class);
this.registryMap = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
@ -62,6 +80,11 @@ public class LiabilitiesRegisterService extends QueueConsumer implements Initial
this.securitySelector = new SecuritySelector<>(imdgProvider, Security.class);
this.fieldValuesValidator = fieldValuesValidator;
preClearMap = PreClearMap.instanceForInstantField(liabilitiesRegisterMap, "created");
reportBuilder = new LiabilitiesRegistryReportBuilder(imdgProvider);
this.outFolder = outFolder;
this.settings = settings;
this.reportsSftpGateway = reportsSftpGateway;
this.deleteAfterSend = settings.getReportsStore().isDeleteAfterSend();
}
@Override
@ -77,90 +100,97 @@ public class LiabilitiesRegisterService extends QueueConsumer implements Initial
public void liabilitiesRegisterNew(BaseRequest<?> userRequest) {
log.debug("LiabilitiesRegisterNewRequest received from {}", Consts.REGISTRY_LIABILITIES_REGISTER_NEW);
String sqlConditionForRegistry = getSqlForRegistries();
Collection<Registry> registries = registryMap.getCollectionObjectsBySQL(sqlConditionForRegistry);
log.debug("Found {} Registry by query {}", registries.size(), sqlConditionForRegistry);
preClearMap.preClearMap();
registries.forEach((registry -> {
if (isDuplicateInMap(registry).isEmpty()) {
insertLiabilitiesRegister(registry);
}
log.debug("LiabilitiesRegisterNewRequest received from {}", createRegistry_LBSR.topic());
boolean csvMode = settings.isCsvMode();
ImdgPredicate conditionForRegistry = getPredicateForRegistries();
Collection<Registry> registries = registryMap.getCollectionObjectsByPredicate(conditionForRegistry);
log.debug("Found {} Registry by query {}", registries.size(), conditionForRegistry);
if (!csvMode)
preClearMap.preClearMap();
// registries.forEach((registry -> {
// if (isDuplicateInMap(registry).isEmpty()) {
// if (!csvMode || LocalDate.now().equals(registry.getTradingDate()))
// insertLiabilitiesRegister(registry);
// }
// }
// ));
if (csvMode) {
File reportFile = reportBuilder.buildReport(registries, outFolder);
ReportUtils.sendFilesToSftp(List.of(reportFile), reportsSftpGateway, deleteAfterSend);
}
));
log.debug("successfully processed");
}
private void insertLiabilitiesRegister(Registry registry) {
log.trace("Started generating LiabilitiesRegister entity...");
LiabilitiesRegister liabilitiesRegister = new LiabilitiesRegister();
Session session = sessionMap.getSingleObjectByID(registry.getSessionId());
CompanySymbols companySymbols = companySymbolsMap.getFirstObjectByFieldValues(
Map.of("companyId", registry.getCompanyId(),
"companySymbol", CompanySymbol.INN.getKey()
)
);
Security security = securitySelector.selectSecurityById(registry.getSecurityId());
if (session == null) {
log.warn("Session is empty!");
} else {
liabilitiesRegister.setValidFromDate(session.getClearingDate());
liabilitiesRegister.setValidToDate(TimeUtil.toLocalDate(session.getUpdated()));
}
if (companySymbols == null) {
log.warn("CompanySymbols not found, for companyId={}", registry.getCompanyId());
} else {
liabilitiesRegister.setInn(companySymbols.getCompanySymbolValue());
}
if (security == null) {
log.warn("Security id={} not found for registry id={}", registry.getSecurityId(), registry.getId());
} else {
if (InstrumentType.RATE.equalsByKey(security.getInstrumentType())) {
liabilitiesRegister.setCurrency(((MoneyMarketSecurity) security).getNominalCurrency());
} else if (InstrumentType.BOND.equalsByKey(security.getInstrumentType())) {
liabilitiesRegister.setCurrency(((FixedIncomeSecurity) security).getNominalCurrency());
} else if (InstrumentType.EQTY.equalsByKey(security.getInstrumentType())) {
// не заполняется Currency
} else { // never
log.warn("Unexpected security[{}] type {}", security.getId(), security.getInstrumentType());
}
}
liabilitiesRegister.setSessionId(registry.getSessionId());
liabilitiesRegister.setValidFromDate(session.getClearingDate());
LocalDate validToDate = TimeUtil.toLocalDate(session.getUpdated());
liabilitiesRegister.setValidToDate(validToDate);
liabilitiesRegister.setCompanyId(registry.getCompanyId());
liabilitiesRegister.setCompanyFullName(registry.getFullName());
liabilitiesRegister.setRegistryCode(registry.getRegistryCode());
liabilitiesRegister.setAccount(registry.getAccount());
liabilitiesRegister.setRegistryStatus(registry.getRegistryStatus());
liabilitiesRegister.setSumLiabilities(registry.getBalance());
liabilitiesRegister.setSettlementDate(registry.getSettlementDate());
liabilitiesRegister.setCreated(Instant.now());
liabilitiesRegister.setUpdated(liabilitiesRegister.getCreated());
liabilitiesRegisterMap.insert(liabilitiesRegister);
log.debug("inserted successfully LiabilitiesRegister entity with id: {}", liabilitiesRegister.getId());
}
// private void insertLiabilitiesRegister(Registry registry) {
// log.trace("Started generating LiabilitiesRegister entity...");
// LiabilitiesRegister liabilitiesRegister = new LiabilitiesRegister();
// Session session = sessionMap.getSingleObjectByID(registry.getSessionId());
// CompanySymbols companySymbols = companySymbolsMap.getFirstObjectByFieldValues(
// Map.of("companyId", registry.getCompanyId(),
// "companySymbol", CompanySymbol.INN.getKey()
// )
// );
// Security security = securitySelector.selectSecurityById(registry.getSecurityId());
// if (session == null) {
// log.warn("Session is empty!");
// } else {
// liabilitiesRegister.setValidFromDate(session.getClearingDate());
// liabilitiesRegister.setValidToDate(TimeUtil.toLocalDate(session.getUpdated()));
// }
// if (companySymbols == null) {
// log.warn("CompanySymbols not found, for companyId={}", registry.getCompanyId());
// } else {
// liabilitiesRegister.setInn(companySymbols.getCompanySymbolValue());
// }
// if (security == null) {
// log.warn("Security id={} not found for registry id={}", registry.getSecurityId(), registry.getId());
// } else {
// if (InstrumentType.RATE.equalsByKey(security.getInstrumentType())) {
// liabilitiesRegister.setCurrency(((MoneyMarketSecurity) security).getNominalCurrency());
// } else if (InstrumentType.BOND.equalsByKey(security.getInstrumentType())) {
// liabilitiesRegister.setCurrency(((FixedIncomeSecurity) security).getNominalCurrency());
// } else if (InstrumentType.EQTY.equalsByKey(security.getInstrumentType())) {
// // не заполняется Currency
// } else { // never
// log.warn("Unexpected security[{}] type {}", security.getId(), security.getInstrumentType());
// }
// }
// liabilitiesRegister.setSessionId(registry.getSessionId());
// liabilitiesRegister.setValidFromDate(session.getClearingDate());
// LocalDate validToDate = TimeUtil.toLocalDate(session.getUpdated());
// liabilitiesRegister.setValidToDate(validToDate);
// liabilitiesRegister.setCompanyId(registry.getCompanyId());
// liabilitiesRegister.setCompanyFullName(registry.getFullName());
// liabilitiesRegister.setRegistryCode(registry.getRegistryCode());
// liabilitiesRegister.setAccount(registry.getAccount());
// liabilitiesRegister.setRegistryStatus(registry.getRegistryStatus());
// liabilitiesRegister.setSumLiabilities(registry.getBalance());
// liabilitiesRegister.setSettlementDate(registry.getSettlementDate());
// liabilitiesRegister.setCreated(Instant.now());
// liabilitiesRegister.setUpdated(liabilitiesRegister.getCreated());
// liabilitiesRegisterMap.insert(liabilitiesRegister);
// log.debug("inserted successfully LiabilitiesRegister entity with id: {}", liabilitiesRegister.getId());
// }
protected String getSqlForRegistries() {
return String.format("registryDesignation = '%s' and " +
"registryInstrumentType in ('%s','%s') and " +
"registryUnit = '%s'",
RegistryDesignation.L.getKey(),
RegistryInstrumentType.S.getKey(),
RegistryInstrumentType.M.getKey(),
RegistryUnit.T.getKey());
protected ImdgPredicate getPredicateForRegistries() {
ImdgPredicateBuilder pb = registryMap.predicateBuilder();
return pb.and(
RegistryCodeSqlBuilder.getInstance(RegistryTradingParams.OM_T, RegistryTradingParams.OS_T).buildPredicate(pb),
pb.equals("registryStatus", RegistryStatus.CLRD.getKey()),
pb.equals("settlementDate", LocalDate.now())
);
// return String.format("registryDesignation = '%s' and " +
// "registryInstrumentType in ('%s','%s') and " +
// "registryUnit = '%s'",
// RegistryDesignation.L.getKey(),
// RegistryInstrumentType.S.getKey(),
// RegistryInstrumentType.M.getKey(),
// RegistryUnit.T.getKey());
}
@Override
public Optional<LiabilitiesRegister> isDuplicateInMap(Registry entity) {
return Optional.empty();
// Map<String, ? extends Comparable<?>> fieldValues = Map.of("companyId", entity.getCompanyId(), "sessionId", entity.getSessionId());
// Optional<EnumMessage> message = fieldValuesValidator.apply(fieldValues).tillFirstError();
// if (message.isPresent()) {
// log.warn("Illegal value in map for request to imdg: {}", message.get());
// throw new IllegalArgumentException(MessageFormat.format("Illegal value in request to imdg: {0}", message.get()));
// }
// return Optional.ofNullable(liabilitiesRegisterMap.getFirstObjectByFieldValues(fieldValues));
}
}

View file

@ -40,9 +40,9 @@ public enum Task implements IEnumKey {
createRegistry_GCMR("GCMR"), // Формирование реестра участников клиринга
createRegistry_GSRR("GSRR"), // Формирование реестра отправленных отчетов
createRegistry_GACA("GACA"), // Создание файла остатков CSV по клиринговым счетам
createRegistry_ADLR("ADLR"), // формирование admittedLiabilitiesRegister
createRegistry_CDLR("CDLR"), // формирование coveredLiabilitiesRegister
createRegistry_EXLR("EXLR"), // формирование excludeLiabilitiesRegister
@Deprecated createRegistry_ADLR("ADLR"), // формирование admittedLiabilitiesRegister
@Deprecated createRegistry_CDLR("CDLR"), // формирование coveredLiabilitiesRegister
@Deprecated createRegistry_EXLR("EXLR"), // формирование excludeLiabilitiesRegister
createRegistry_LBSR("LBSR"), // формирование liabilitiesRegister
createRegistry_ECNR("ECNR"), // формирование executionRegister
createRegistry_STRS("STRS"), // Начало торговой сессии