diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/CSVReportBuilder.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/CSVReportBuilder.java
new file mode 100644
index 000000000..92f57089d
--- /dev/null
+++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/CSVReportBuilder.java
@@ -0,0 +1,115 @@
+package ru.spcex.clearing.reports.reports;
+
+import com.opencsv.CSVWriterBuilder;
+import com.opencsv.ICSVWriter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import ru.spcex.platform.enumeration.ReportType;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+
+/**
+ * Класс для построения отчетов в формате CSV
+ *
+ * @param
тип параметров, используемых при построении отчета
+ */
+public abstract class CSVReportBuilder
{
+ protected static final Logger log = LoggerFactory.getLogger(CSVReportBuilder.class);
+
+ protected DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
+ protected DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy'T'HH:mm:ss");
+ protected DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
+
+ /**
+ * Метод получения заголовков для CSV отчета
+ */
+ protected abstract String[] getHeaders();
+
+ /**
+ * Возвращает списком значения CSV отчета. Каждый элемент списка - строка, элемент массива внутри списка - столбец.
+ */
+ protected abstract List getLines();
+
+ /**
+ * Название отчета, используется для формирования имени отчета
+ *
+ * @param params Параметры формирования отчета
+ */
+ protected abstract String getReportFilename(P params);
+
+ /**
+ * Тип отчета по {@link ReportType}
+ */
+ protected abstract ReportType getReportType();
+
+ /**
+ * Формирование отчета на основе параметров
+ *
+ * @param params Параметры формирования отчета
+ */
+ protected abstract void collect(P params);
+
+ /**
+ * Создает CSVWriter. Если требуется изменить параметры выходного CSV файла, этот метод следует переопределить.
+ *
+ * @param file Файл отчета
+ * @return Созданный CSVWriter
+ *
+ * todo check it
+ */
+ protected ICSVWriter createCsvWriter(File file) throws IOException {
+ Writer writer = new FileWriter(file);
+ CSVWriterBuilder csvWriterBuilder = new CSVWriterBuilder(writer)
+ .withLineEnd("\n")
+ .withSeparator(',')
+ .withQuoteChar('\'')
+ .withEscapeChar('\"');
+ return csvWriterBuilder.build();
+ }
+
+ public File createReport(P params, File outFolder) {
+ assert outFolder != null && outFolder.isDirectory();
+
+ File reportFile = new File(outFolder, normalizeFilenameForOS(getReportFilename(params)));
+
+ collect(params);
+ String[] headers = getHeaders();
+ List lines = getLines();
+
+ assert headers != null;
+ assert lines != null;
+
+ try (ICSVWriter csvWriter = createCsvWriter(reportFile)) {
+ csvWriter.writeNext(headers);
+ csvWriter.writeAll(lines, true);
+ } catch (IOException e) {
+ // todo check it
+ e.printStackTrace();
+ }
+
+ return reportFile;
+ }
+
+ protected String normalizeFilenameForOS(String filename) {
+ if (System.getProperty("os.name").toLowerCase().contains("windows"))
+ return filename.replace(":", "_");
+ return filename;
+ }
+
+ public void setDateFormatter(DateTimeFormatter dateFormatter) {
+ this.dateFormatter = dateFormatter;
+ }
+
+ public void setDateTimeFormatter(DateTimeFormatter dateTimeFormatter) {
+ this.dateTimeFormatter = dateTimeFormatter;
+ }
+
+ public void setTimeFormatter(DateTimeFormatter timeFormatter) {
+ this.timeFormatter = timeFormatter;
+ }
+}
diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/PeriodParams.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/PeriodParams.java
new file mode 100644
index 000000000..4d30c335a
--- /dev/null
+++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/PeriodParams.java
@@ -0,0 +1,27 @@
+package ru.spcex.clearing.reports.reports;
+
+import java.time.LocalDate;
+
+/**
+ * Параметры для формирования отчета на период
+ */
+public class PeriodParams {
+ private LocalDate startDate;
+ private LocalDate endDate;
+
+ public LocalDate getStartDate() {
+ return startDate;
+ }
+
+ public void setStartDate(LocalDate startDate) {
+ this.startDate = startDate;
+ }
+
+ public LocalDate getEndDate() {
+ return endDate;
+ }
+
+ public void setEndDate(LocalDate endDate) {
+ this.endDate = endDate;
+ }
+}
diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/SessionIdParam.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/SessionIdParam.java
new file mode 100644
index 000000000..e2a529e6b
--- /dev/null
+++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/SessionIdParam.java
@@ -0,0 +1,16 @@
+package ru.spcex.clearing.reports.reports;
+
+/**
+ * Параметры для формирования отчета по SessionId
+ */
+public class SessionIdParam {
+ private Long sessionId;
+
+ public Long getSessionId() {
+ return sessionId;
+ }
+
+ public void setSessionId(Long sessionId) {
+ this.sessionId = sessionId;
+ }
+}
diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bp/ExecutedDealReport.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bp/ExecutedDealReport.java
deleted file mode 100644
index ab4b4faf2..000000000
--- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bp/ExecutedDealReport.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package ru.spcex.clearing.reports.reports.bp;
-
-import ru.spcex.clearing.reports.reports.ReportId;
-import ru.spcex.clearing.reports.reports.ReportWithPeriod;
-
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-
-public class ExecutedDealReport extends ReportWithPeriod {
-
- private final String[] headers = {
- "id", "securityId", "tradeNo", "tradeDate", "tradeTime", "settleDate", "settleCode", "price", "quanity", "value"
- };
-
- public ExecutedDealReport(LocalDate startDate, LocalDate endDate) {
- super(ReportId.EXECUTED_DEAL_REPORT,
- "0.0.1",
- "BP",
- "Реестр сделок, принятых на клиринг",
- startDate,
- endDate);
- }
-
- @Override
- public String getReportName(LocalDateTime reportDateTime) {
- return "executed_deal_report.%s-%s.%s".formatted(
- DATE_FORMATTER.format(startDate),
- DATE_FORMATTER.format(endDate),
- DATE_TIME_FORMATTER.format(reportDateTime)
- );
- }
-
- public String[] getHeaders() {
- return headers;
- }
-
- public record InfoExecutedDeal(String id, String securityId, String tradeNo, String tradeDate, String tradeTime,
- String settleDate, String settleCode, String price, String quanity, String value) {
- }
-}
diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bp/ExecutedDealReportBuilder.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bp/ExecutedDealReportBuilder.java
new file mode 100644
index 000000000..e44f37993
--- /dev/null
+++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bp/ExecutedDealReportBuilder.java
@@ -0,0 +1,108 @@
+package ru.spcex.clearing.reports.reports.bp;
+
+import ru.clearing.classes.statics.data.company.Company;
+import ru.clearing.classes.statics.data.execution.ExecutionFond;
+import ru.clearing.classes.statics.data.misc.STrades;
+import ru.spcex.clearing.imdg.IMDGDistributedNames;
+import ru.spcex.clearing.reports.reports.CSVReportBuilder;
+import ru.spcex.clearing.reports.reports.SessionIdParam;
+import ru.spcex.platform.enumeration.Allowed;
+import ru.spcex.platform.enumeration.ReportType;
+import ru.spcex.platform.enumeration.WorkflowStatus;
+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 java.math.RoundingMode;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+public class ExecutedDealReportBuilder extends CSVReportBuilder {
+ private final Imdg executionFondImdg;
+ private final Imdg companyImdg;
+ private final Imdg sTradesImdg;
+
+ private final String[] headers = {
+ "id", "securityId", "tradeNo", "tradeDate", "tradeTime",
+ "settleDate", "settleCode", "price", "quanity", "value"
+ };
+ private List lines = null;
+
+ public ExecutedDealReportBuilder(ImdgProvider imdgProvider) {
+ this.executionFondImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionFond, ExecutionFond.class);
+ this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
+ this.sTradesImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_STrades, STrades.class);
+ }
+
+ @Override
+ public String[] getHeaders() {
+ return headers;
+ }
+
+ @Override
+ protected List getLines() {
+ return lines;
+ }
+
+ @Override
+ protected String getReportFilename(SessionIdParam params) {
+ return "executed_deal_report.%s".formatted(LocalDateTime.now());
+ }
+
+ @Override
+ protected ReportType getReportType() {
+ return ReportType.EXECUTED_DEAL_REPORT;
+ }
+
+ @Override
+ protected void collect(SessionIdParam params) {
+ ImdgPredicateBuilder pb = executionFondImdg.predicateBuilder();
+ ImdgPredicate predicate = pb.and(
+ pb.equals("sessionId", params.getSessionId()),
+ pb.equals("coverageStatus", Allowed.DENIED.getKey())
+ );
+ Collection executionFonds = executionFondImdg.getCollectionObjectsByPredicate(predicate);
+
+ lines = new ArrayList<>(executionFonds.size());
+ for (ExecutionFond executionFond : executionFonds) {
+ Company company = companyImdg.getSingleObjectByID(executionFond.getCompanyId());
+ if (!WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus())) continue;
+ STrades sTrade = sTradesImdg.getSingleObjectByFieldValues(
+ Map.of(
+ "tradeNum", executionFond.getExchangeExecutionId(),
+ "operation", executionFond.getSide()
+ )
+ );
+
+ String id = String.valueOf(executionFond.getId());
+ String securityId = String.valueOf(executionFond.getSecurityId());
+ String tradeNo = String.valueOf(executionFond.getExchangeExecutionId());
+ String tradeDate = dateFormatter.format(executionFond.getTradingDate());
+ String tradeTime = dateFormatter.format(executionFond.getCreated());
+ String settleDate = dateFormatter.format(executionFond.getSettlementDate());
+ String settleCode = sTrade != null ? sTrade.getSettleCode() : "";
+ String quantity = String.valueOf(executionFond.getQuantity());
+ String value = String.valueOf(executionFond.getSettlementAmount());
+ String price = String.valueOf(executionFond.getSettlementAmount().divide(executionFond.getQuantity(), RoundingMode.HALF_UP));
+
+ int valueIdx = 0;
+ String[] line = new String[getHeaders().length];
+ line[valueIdx++] = id;
+ line[valueIdx++] = securityId;
+ line[valueIdx++] = tradeNo;
+ line[valueIdx++] = tradeDate;
+ line[valueIdx++] = tradeTime;
+ line[valueIdx++] = settleDate;
+ line[valueIdx++] = settleCode;
+ line[valueIdx++] = price;
+ line[valueIdx++] = quantity;
+ line[valueIdx++] = value;
+ lines.add(line);
+ }
+ }
+
+}
diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bp/OperationalLiabilitiesClaimsReport.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bp/OperationalLiabilitiesClaimsReport.java
deleted file mode 100644
index 7953a2614..000000000
--- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bp/OperationalLiabilitiesClaimsReport.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package ru.spcex.clearing.reports.reports.bp;
-
-import ru.spcex.clearing.reports.reports.ReportId;
-import ru.spcex.clearing.reports.reports.ReportWithPeriod;
-
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-
-// todo check typo
-public class OperationalLiabilitiesClaimsReport extends ReportWithPeriod {
-
- private final String[] headers = {
- "id", "doc_date", "doc_time", "doc_type", "clearingHouse", "firmId", "firName", "session_id",
- "clearing_date", "clearing_time", "trdAccId", "account", "depo_account", "currency", "tr_id", "securityId",
- "tr_buySell", "tr_date", "tr_execDate", "exec_status", "repaym_date", "tr_price", "nominal", "lot_value",
- "tr_lot", "tr_quantity", "tr_value", "tr_accruedint", "accruedint", "tr_clrComm", "tr_exhComm", "cash_liability",
- "depo_liability", "cash_netto", "depo_netto"
- };
-
- public OperationalLiabilitiesClaimsReport(LocalDate startDate, LocalDate endDate) {
- super(ReportId.OPERATIONAL_LIABILITIES_CLAIMS,
- "0.0.1",
- "BP2",
- "Операционный отчет. Отчет об обязательствах",
- startDate,
- endDate);
- }
-
- @Override
- public String getReportName(LocalDateTime reportDateTime) {
- return "operational_liabilities_claims.%s-%s.%s".formatted(
- DATE_FORMATTER.format(startDate),
- DATE_FORMATTER.format(endDate),
- DATE_TIME_FORMATTER.format(reportDateTime)
- );
- }
-
- public String[] getHeaders() {
- return headers;
- }
-
- public record InfoOperationalLiabilitiesClaims(String id, String docDate, String docTime, String docName,
- String docType, String clearingHouse, String firmId, String firName,
- String sessionId, String clearingDate, String clearingTime,
- String trdAccId, String account, String depoAccount, String currency,
- String trId, String securityId, String trBuySell, String trDate,
- String trExecDate, String execStatus, String repaymDate, String trPrice,
- String nominal, String lotValue, String trLot, String trQuantity,
- String trValue, String trAccruedInt, String accruedInt, String trClrComm,
- String trExhComm, String cashLiability, String depoLiability,
- String cashNetto, String depoNetto) {
- }
-}
diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bp/OperationalLiabilitiesClaimsReportBuilder.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bp/OperationalLiabilitiesClaimsReportBuilder.java
new file mode 100644
index 000000000..766f436a8
--- /dev/null
+++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bp/OperationalLiabilitiesClaimsReportBuilder.java
@@ -0,0 +1,263 @@
+package ru.spcex.clearing.reports.reports.bp;
+
+import ru.clearing.classes.statics.data.company.Company;
+import ru.clearing.classes.statics.data.execution.ExecutionCommon;
+import ru.clearing.classes.statics.data.execution.ExecutionDeposit;
+import ru.clearing.classes.statics.data.execution.ExecutionFond;
+import ru.clearing.classes.statics.data.instrument.issue.FixedIncomeSecurity;
+import ru.clearing.classes.statics.data.misc.Listing;
+import ru.clearing.classes.statics.data.registry.Registry;
+import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
+import ru.spcex.clearing.imdg.IMDGDistributedNames;
+import ru.spcex.clearing.reports.reports.CSVReportBuilder;
+import ru.spcex.clearing.reports.reports.SessionIdParam;
+import ru.spcex.platform.enumeration.Market;
+import ru.spcex.platform.enumeration.ReportType;
+import ru.spcex.platform.enumeration.Side;
+import ru.spcex.platform.enumeration.WorkflowStatus;
+import ru.spcex.platform.imdg.api.Imdg;
+import ru.spcex.platform.imdg.api.ImdgProvider;
+import ru.spcex.platform.imdg.api.predicate.ImdgPredicate;
+
+import java.math.RoundingMode;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+// todo check typo
+public class OperationalLiabilitiesClaimsReportBuilder extends CSVReportBuilder {
+ private final Imdg executionFondImdg;
+ private final Imdg executionDepositImdg;
+ private final Imdg companyImdg;
+ private final Imdg registryImdg;
+ private final Imdg listingImdg;
+ private final Imdg fixedIncomeSecurityImdg;
+ private final Imdg tradingClearingRegistryImdg;
+
+ private final String[] headers = {
+ "id", "doc_date", "doc_time", "doc_type", "clearingHouse", "firmId", "firName", "session_id",
+ "clearing_date", "clearing_time", "trdAccId", "account", "depo_account", "currency", "tr_id", "securityId",
+ "tr_buySell", "tr_date", "tr_execDate", "exec_status", "repaym_date", "tr_price", "nominal", "lot_value",
+ "tr_lot", "tr_quantity", "tr_value", "tr_accruedint", "accruedint", "tr_clrComm", "tr_exhComm", "cash_liability",
+ "depo_liability", "cash_netto", "depo_netto"
+ };
+ private List lines = null;
+
+ public OperationalLiabilitiesClaimsReportBuilder(ImdgProvider imdgProvider) {
+ this.executionFondImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionFond, ExecutionFond.class);
+ this.executionDepositImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionDeposit, ExecutionDeposit.class);
+ this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
+ this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
+ this.listingImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Listing, Listing.class);
+ this.fixedIncomeSecurityImdg = imdgProvider.getImdg(
+ IMDGDistributedNames.Map_FixedIncomeSecurity, FixedIncomeSecurity.class
+ );
+ this.tradingClearingRegistryImdg = imdgProvider.getImdg(
+ IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class
+ );
+ }
+
+ @Override
+ public String[] getHeaders() {
+ return headers;
+ }
+
+ @Override
+ protected List getLines() {
+ return lines;
+ }
+
+ @Override
+ protected String getReportFilename(SessionIdParam params) {
+ return "operational_liabilities_claims.%s".formatted(LocalDateTime.now());
+ }
+
+ @Override
+ protected ReportType getReportType() {
+ return ReportType.OPERATIONAL_LIABILITIES_CLAIMS;
+ }
+
+ @Override
+ protected void collect(SessionIdParam params) {
+ ImdgPredicate executionFondPredicate = executionFondImdg
+ .predicateBuilder()
+ .equals("sessionId", params.getSessionId());
+ Collection executionFonds = executionFondImdg.getCollectionObjectsByPredicate(executionFondPredicate);
+
+ ImdgPredicate executionDepositPredicate = executionDepositImdg
+ .predicateBuilder()
+ .equals("sessionId", params.getSessionId());
+ Collection executionDeposits = executionDepositImdg.getCollectionObjectsByPredicate(executionDepositPredicate);
+
+ List executions = new ArrayList<>(executionFonds.size() + executionDeposits.size());
+ executions.addAll(executionFonds);
+ executions.addAll(executionDeposits);
+
+ Company clearingHouseCompany = companyImdg.getSingleObjectByID(1L);
+ String clearingHouse = clearingHouseCompany.getFullName();
+
+ Instant now = Instant.now();
+ lines = new ArrayList<>(executions.size());
+ for (ExecutionCommon execution : executions) {
+ Company company = companyImdg.getSingleObjectByID(execution.getCompanyId());
+ if (!WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus())) continue;
+
+ Registry registry = registryImdg.getSingleObjectByFieldValues(Map.of("companyId", execution.getCompanyId()));
+ Collection registriesForSessionId = registryImdg.getCollectionObjectsByFieldValues(
+ Map.of("sessionId", execution.getSessionId())
+ );
+ Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", execution.getSecurityId()));
+ FixedIncomeSecurity fixedIncomeSecurity = fixedIncomeSecurityImdg.getSingleObjectByFieldValues(
+ Map.of("securityId", execution.getSecurityId())
+ );
+ TradingClearingRegistry tradingClearingRegistry = tradingClearingRegistryImdg.getSingleObjectByID(
+ execution.getTradingClearingRegistryId()
+ );
+
+ String id = String.valueOf(execution.getId());
+ String docDate = dateFormatter.format(now);
+ String docTime = timeFormatter.format(now);
+ String docName = "Отчет об обязательствах/требованиях Участника клиринга";
+ String docType = "KS_FIRMID_LIABILITIES";
+ String firmId = String.valueOf(execution.getCompanyId());
+ String firName = company.getFullName();
+ String sessionId = String.valueOf(execution.getSessionId());
+ String clearingDate = dateFormatter.format(execution.getClearingDate());
+ String trdAccId = registry.getTradingClearingRegistry();
+ String account = String.valueOf(tradingClearingRegistry.getMoneyAccountId());
+ String depoAccount = String.valueOf(tradingClearingRegistry.getDepoAaccountId());
+ String currency = execution.getSettlementCurrency();
+ String trId = String.valueOf(execution.getExchangeExecutionId());
+ String securityId = String.valueOf(execution.getSecurityId());
+
+ String trBuySell = "";
+ if (Side.BUY.equalsByKey(execution.getSide()))
+ trBuySell = "B";
+ else if (Side.SELL.equalsByKey(execution.getSide()))
+ trBuySell = "S";
+ String trDate = dateFormatter.format(execution.getTradingDate());
+
+ String trExecDate = "";
+ String execStatus = "";
+ String repaymDate = "";
+ String trPrice = "";
+ String nominal = "";
+ String trQuantity = "";
+ String trValue = "";
+ String trAccruedInt = "";
+ String accruedInt = "";
+ String cashLiability = "";
+ String depoLiability = "";
+ if (execution instanceof ExecutionDeposit executionDeposit) {
+ trExecDate = dateFormatter.format(executionDeposit.getSecondLegSettlementDate());
+ if (Market.mkrs.equalsByKey(execution.getMarket())) {
+ execStatus = "Y";
+ repaymDate = dateFormatter.format(executionDeposit.getSecondLegSettlementDate());
+ trPrice = String.valueOf(executionDeposit.getPrice());
+ trValue = String.valueOf(executionDeposit.getFirstLegAmount());
+ cashLiability = String.valueOf(executionDeposit.getFirstLegAmount());
+ }
+ } else if (execution instanceof ExecutionFond executionFond) {
+ trExecDate = dateFormatter.format(executionFond.getSettlementDate());
+ if (Market.fond.equalsByKey(execution.getMarket())) {
+ trPrice = String.valueOf(
+ executionFond.getSettlementAmount().divide(executionFond.getQuantity(), RoundingMode.HALF_UP)
+ );
+ trQuantity = String.valueOf(executionFond.getQuantity());
+ nominal = String.valueOf(fixedIncomeSecurity.getNominalValue());
+ trValue = String.valueOf(executionFond.getSettlementAmount());
+ trAccruedInt = String.valueOf(fixedIncomeSecurity.getCoupon());
+ accruedInt = String.valueOf(
+ fixedIncomeSecurity.getCoupon().divide(executionFond.getQuantity(), RoundingMode.HALF_UP)
+ );
+ cashLiability = String.valueOf(executionFond.getSettlementAmount());
+ depoLiability = String.valueOf(executionFond.getQuantity());
+ }
+ }
+
+ String lotValue = String.valueOf(listing.getLotSize());
+ String trLot = String.valueOf(execution.getLots());
+ String trClrComm = "";
+ String trExhComm = "";
+
+ Registry tm_tRegistry = null;
+ Registry om_tRegistry = null;
+ Registry ts_tRegistry = null;
+ Registry os_tRegistry = null;
+ for (Registry currRegistry : registriesForSessionId) {
+ String registryCode = currRegistry.getRegistryCode();
+ if (registryCode.endsWith("T")) {
+ if (registryCode.startsWith("TM")) {
+ if (tm_tRegistry != null && tm_tRegistry.getUpdatedAt().isAfter(currRegistry.getUpdatedAt())) continue;
+ tm_tRegistry = currRegistry;
+ }
+ if (registryCode.startsWith("OM")) {
+ if (om_tRegistry != null && om_tRegistry.getUpdatedAt().isAfter(currRegistry.getUpdatedAt())) continue;
+ om_tRegistry = currRegistry;
+ }
+ if (registryCode.startsWith("TS")) {
+ if (ts_tRegistry != null && ts_tRegistry.getUpdatedAt().isAfter(currRegistry.getUpdatedAt())) continue;
+ ts_tRegistry = currRegistry;
+ }
+ if (registryCode.startsWith("OS")) {
+ if (os_tRegistry != null && os_tRegistry.getUpdatedAt().isAfter(currRegistry.getUpdatedAt())) continue;
+ os_tRegistry = currRegistry;
+ }
+ }
+ }
+ String cashNetto = "";
+ if (tm_tRegistry != null && om_tRegistry != null) {
+ cashNetto = String.valueOf(tm_tRegistry.getBalance().subtract(om_tRegistry.getBalance()));
+ }
+
+ String depoNetto = "";
+ if (ts_tRegistry != null && os_tRegistry != null) {
+ depoNetto = String.valueOf(ts_tRegistry.getBalance().subtract(os_tRegistry.getBalance()));
+ }
+
+
+ int valueIdx = 0;
+ String[] line = new String[getHeaders().length];
+ line[valueIdx++] = id;
+ line[valueIdx++] = docDate;
+ line[valueIdx++] = docTime;
+ line[valueIdx++] = docName;
+ line[valueIdx++] = docType;
+ line[valueIdx++] = clearingHouse;
+ line[valueIdx++] = firmId;
+ line[valueIdx++] = firName;
+ line[valueIdx++] = sessionId;
+ line[valueIdx++] = clearingDate;
+ line[valueIdx++] = trdAccId;
+ line[valueIdx++] = account;
+ line[valueIdx++] = depoAccount;
+ line[valueIdx++] = currency;
+ line[valueIdx++] = trId;
+ line[valueIdx++] = securityId;
+ line[valueIdx++] = trBuySell;
+ line[valueIdx++] = trDate;
+ line[valueIdx++] = trExecDate;
+ line[valueIdx++] = execStatus;
+ line[valueIdx++] = repaymDate;
+ line[valueIdx++] = trPrice;
+ line[valueIdx++] = nominal;
+ line[valueIdx++] = lotValue;
+ line[valueIdx++] = trLot;
+ line[valueIdx++] = trQuantity;
+ line[valueIdx++] = trValue;
+ line[valueIdx++] = trAccruedInt;
+ line[valueIdx++] = accruedInt;
+ line[valueIdx++] = trClrComm;
+ line[valueIdx++] = trExhComm;
+ line[valueIdx++] = cashLiability;
+ line[valueIdx++] = depoLiability;
+ line[valueIdx++] = cashNetto;
+ line[valueIdx] = depoNetto;
+ lines.add(line);
+ }
+ }
+
+}
diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bp/OperationalMoneyChangeReport.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bp/OperationalMoneyChangeReport.java
index 2f253b5b2..cc99998bf 100644
--- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bp/OperationalMoneyChangeReport.java
+++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bp/OperationalMoneyChangeReport.java
@@ -1,49 +1,148 @@
package ru.spcex.clearing.reports.reports.bp;
-import ru.spcex.clearing.reports.reports.ReportId;
-import ru.spcex.clearing.reports.reports.ReportWithPeriod;
+import ru.clearing.classes.statics.data.company.Company;
+import ru.clearing.classes.statics.data.misc.Listing;
+import ru.clearing.classes.statics.data.payment.PaymentInstruction;
+import ru.clearing.classes.statics.data.registry.Registry;
+import ru.clearing.classes.statics.data.statement.Statement;
+import ru.spcex.clearing.imdg.IMDGDistributedNames;
+import ru.spcex.clearing.reports.reports.CSVReportBuilder;
+import ru.spcex.clearing.reports.reports.PeriodParams;
+import ru.spcex.platform.enumeration.InOutDirection;
+import ru.spcex.platform.enumeration.ReportType;
+import ru.spcex.platform.enumeration.WorkflowStatus;
+import ru.spcex.platform.imdg.api.Imdg;
+import ru.spcex.platform.imdg.api.ImdgProvider;
+import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder;
-import java.time.LocalDate;
+import java.time.Instant;
import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
-public class OperationalMoneyChangeReport extends ReportWithPeriod {
-
+public class OperationalMoneyChangeReport extends CSVReportBuilder {
+ private final Imdg registryImdg;
+ private final Imdg companyImdg;
+ private final Imdg listingImdg;
+ private final Imdg statementImdg;
+ private final Imdg paymentInstructionImdg;
private final String[] headers = {
"id", "doc_date", "doc_time", "doc_name", "doc_type", "clearingHouse", "firmId", "firName", "trdAccId",
"account", "currency", "registry_code", "registry_name", "open_balance", "change_balance", "add_withdraw",
"close_balance", "remarks", "add_sum", "add_time", "withdraw_sum", "withdraw_time"
};
+ private List lines = null;
-
- public OperationalMoneyChangeReport(LocalDate startDate, LocalDate endDate) {
- super(ReportId.OPERATIONAL_MONEY_CHANGE,
- "0.0.1",
- "BP3",
- "Операционный отчет. Отчет о денежных средствах",
- startDate,
- endDate);
+ public OperationalMoneyChangeReport(ImdgProvider imdgProvider) {
+ this.registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class);
+ this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
+ this.listingImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Listing, Listing.class);
+ this.statementImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Statement, Statement.class);
+ this.paymentInstructionImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PaymentInstruction, PaymentInstruction.class);
}
@Override
- public String getReportName(LocalDateTime reportDateTime) {
- return "operational_money_change.%s-%s.%s".formatted(
- DATE_FORMATTER.format(startDate),
- DATE_FORMATTER.format(endDate),
- DATE_TIME_FORMATTER.format(reportDateTime)
- );
- }
-
public String[] getHeaders() {
return headers;
}
- public record InfoOperationalMoneyChangeReport(String id, String docDate, String docTime, String docName,
- String docType, String clearingHouse, String firmId, String firName,
- String trdAccId, String account, String currency, String registryCode,
- String registryName, String openBalance, String changeBalance,
- String addWithdraw, String closeBalance, String remarks, String addSum,
- String addTime, String withdrawSum, String withdrawTime) {
+ @Override
+ protected List getLines() {
+ return lines;
+ }
+ @Override
+ protected String getReportFilename(PeriodParams params) {
+ return "operational_money_change.%s-%s.%s".formatted(
+ dateFormatter.format(params.getStartDate()),
+ dateFormatter.format(params.getEndDate()),
+ dateTimeFormatter.format(LocalDateTime.now())
+ );
+ }
+
+ @Override
+ protected ReportType getReportType() {
+ return ReportType.OPERATIONAL_MONEY_CHANGE;
+ }
+
+ @Override
+ protected void collect(PeriodParams params) {
+ ImdgPredicateBuilder pb = registryImdg.predicateBuilder();
+ Collection registries = registryImdg.getCollectionObjectsByPredicate(
+ pb.and(
+ pb.greatEqual("clearingDate", params.getStartDate()),
+ pb.lessEqual("clearingDate", params.getEndDate())
+ )
+ );
+
+ Company clearingHouseCompany = companyImdg.getSingleObjectByID(1L);
+ String clearingHouse = clearingHouseCompany.getFullName();
+
+ Instant now = Instant.now();
+ lines = new ArrayList<>(registries.size());
+ for (Registry registry : registries) {
+ Company company = companyImdg.getSingleObjectByID(registry.getCompanyId());
+ if (!WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus())) continue;
+
+ Listing listing = listingImdg.getSingleObjectByFieldValues(Map.of("securityId", registry.getSecurityId()));
+ Statement statement = statementImdg.getSingleObjectByFieldValues(Map.of("addresseeId", registry.getCompanyId()));
+ PaymentInstruction paymentInstruction = paymentInstructionImdg.getSingleObjectByFieldValues(
+ Map.of(
+ "id", registry.getPaymentId(),
+ "creditLegDirection", InOutDirection.out.getKey()
+ )
+ );
+
+ String id = String.valueOf(registry.getId());
+ String docDate = dateFormatter.format(now);
+ String docTime = timeFormatter.format(now);
+ String docName = "Отчет об изменении суммы денежных средств и (или) количества иного имущества Участника клиринга";
+ String docType = "KS_FIRMID_ASSETS";
+ String firmId = String.valueOf(registry.getCompanyId());
+ String firName = company.getFullName();
+ String trdAccId = registry.getTradingClearingRegistry();
+ String account = String.valueOf(registry.getAccountId()); // todo *
+ String currency = listing.getTradingCurrency(); // todo *
+ String registryCode = String.valueOf(registry.getId());
+ String registryName = registry.getFullName(); // todo *
+ String openBalance = String.valueOf(registry.getOpenBalance());
+ String changeBalance = String.valueOf(registry.getCloseBalance().subtract(registry.getOpenBalance()));
+ String addWithdraw = String.valueOf(registry.getCredit().subtract(registry.getDebit()));
+ String closeBalance = String.valueOf(registry.getCloseBalance());
+ String remarks = "";
+ String addSum = String.valueOf(registry.getCredit());
+ String addTime = dateTimeFormatter.format(statement.getCreated());
+ String withdrawSum = String.valueOf(registry.getDebit());
+ String withdrawTime = dateTimeFormatter.format(paymentInstruction.getPaymentDate());
+
+ int valueIdx = 0;
+ String[] line = new String[getHeaders().length];
+ line[valueIdx++] = id;
+ line[valueIdx++] = docDate;
+ line[valueIdx++] = docTime;
+ line[valueIdx++] = docName;
+ line[valueIdx++] = docTime;
+ line[valueIdx++] = clearingHouse;
+ line[valueIdx++] = firmId;
+ line[valueIdx++] = firName;
+ line[valueIdx++] = trdAccId;
+ line[valueIdx++] = account;
+ line[valueIdx++] = currency;
+ line[valueIdx++] = registryCode;
+ line[valueIdx++] = registryName;
+ line[valueIdx++] = openBalance;
+ line[valueIdx++] = changeBalance;
+ line[valueIdx++] = addWithdraw;
+ line[valueIdx++] = closeBalance;
+ line[valueIdx++] = remarks;
+ line[valueIdx++] = addSum;
+ line[valueIdx++] = addTime;
+ line[valueIdx++] = withdrawSum;
+ line[valueIdx++] = withdrawTime;
+ lines.add(line);
+ }
}
}
diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bp/UnfulfilledDealReport.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bp/UnfulfilledDealReport.java
index 8de76a447..4f5d8d585 100644
--- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bp/UnfulfilledDealReport.java
+++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bp/UnfulfilledDealReport.java
@@ -1,39 +1,95 @@
package ru.spcex.clearing.reports.reports.bp;
-import ru.spcex.clearing.reports.reports.ReportId;
-import ru.spcex.clearing.reports.reports.ReportWithPeriod;
+import ru.clearing.classes.statics.data.company.Company;
+import ru.clearing.classes.statics.data.execution.ExecutionFond;
+import ru.clearing.classes.statics.data.misc.STrades;
+import ru.spcex.clearing.imdg.IMDGDistributedNames;
+import ru.spcex.clearing.reports.reports.CSVReportBuilder;
+import ru.spcex.clearing.reports.reports.SessionIdParam;
+import ru.spcex.platform.enumeration.Allowed;
+import ru.spcex.platform.enumeration.ReportType;
+import ru.spcex.platform.enumeration.WorkflowStatus;
+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 java.time.LocalDate;
-import java.time.LocalDateTime;
-
-public class UnfulfilledDealReport extends ReportWithPeriod {
+import java.time.Instant;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+public class UnfulfilledDealReport extends CSVReportBuilder {
+ private final Imdg executionFondImdg;
+ private final Imdg companyImdg;
+ private final Imdg sTradesImdg;
private final String[] headers = {
"id", "securityId", "tradeNo", "tradeDate", "settleCode"
};
+ private final List lines = null;
- public UnfulfilledDealReport(LocalDate startDate, LocalDate endDate) {
- super(ReportId.UNFULFILLED_DEAL_REPORT,
- "0.0.1",
- "BP",
- "Реестр сделок, принятых на клиринг",
- startDate,
- endDate);
+ public UnfulfilledDealReport(ImdgProvider imdgProvider) {
+ executionFondImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionFond, ExecutionFond.class);
+ companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
+ sTradesImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_STrades, STrades.class);
}
@Override
- public String getReportName(LocalDateTime reportDateTime) {
- return "unfulfilled_deal_report.%s-%s.%s".formatted(
- DATE_FORMATTER.format(startDate),
- DATE_FORMATTER.format(endDate),
- DATE_TIME_FORMATTER.format(reportDateTime)
- );
- }
-
public String[] getHeaders() {
return headers;
}
- public record InfoUnfulfilledDealReport(String id, String securityId, String tradeNo, String tradeDate, String settleCode) {
+ @Override
+ protected List getLines() {
+ return lines;
}
+
+ @Override
+ protected String getReportFilename(SessionIdParam params) {
+ return "unfulfilled_deal_report.%s".formatted(
+ dateTimeFormatter.format(Instant.now())
+ );
+ }
+
+ @Override
+ protected ReportType getReportType() {
+ return ReportType.UNFULFILLED_DEAL_REPORT;
+ }
+
+ @Override
+ protected void collect(SessionIdParam params) {
+ ImdgPredicateBuilder pb = executionFondImdg.predicateBuilder();
+ ImdgPredicate predicate = pb.and(
+ pb.equals("sessionId", params.getSessionId()),
+ pb.equals("coverageStatus", Allowed.DENIED.getKey())
+ );
+ Collection executionFonds = executionFondImdg.getCollectionObjectsByPredicate(predicate);
+
+ for (ExecutionFond executionFond : executionFonds) {
+ Company company = companyImdg.getSingleObjectByID(executionFond.getCompanyId());
+ if (!WorkflowStatus.Active.equalsByKey(company.getWorkflowStatus())) continue;
+ STrades sTrade = sTradesImdg.getSingleObjectByFieldValues(
+ Map.of(
+ "settleCode", executionFond.getSettlementCode(),
+ "operation", executionFond.getSide()
+ )
+ );
+
+ String id = String.valueOf(executionFond.getId());
+ String securityId = String.valueOf(executionFond.getSecurityId());
+ String tradeNo = String.valueOf(executionFond.getExchangeExecutionId());
+ String tradeDate = dateFormatter.format(executionFond.getTradingDate());
+ String settleCode = sTrade != null ? sTrade.getClassCode() : null;
+
+ int valueIdx = 0;
+ String[] line = new String[getHeaders().length];
+ line[valueIdx++] = id;
+ line[valueIdx++] = securityId;
+ line[valueIdx++] = tradeNo;
+ line[valueIdx++] = tradeDate;
+ line[valueIdx++] = settleCode;
+ lines.add(line);
+ }
+ }
+
}
diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/Market.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/Market.java
index 8d20c67ef..ff11d32b0 100644
--- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/Market.java
+++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/Market.java
@@ -3,7 +3,9 @@ package ru.spcex.platform.enumeration;
import ru.spcex.platform.utils.enumeration.IEnumKey;
public enum Market implements IEnumKey {
- mkrs("MKRS");
+ mkrs("MKRS"),
+ fond("FOND"),
+ ;
private final String key;