From 05ca97688a2a296f1d22049d8d4d64dcf9a63344 Mon Sep 17 00:00:00 2001 From: akulikov Date: Wed, 2 Oct 2024 16:39:34 +0300 Subject: [PATCH] http://jira.mfd.msk:8088/browse/CLS-767 --- .../builders/bean/KSRepLccNettoReport.java | 111 +++++++ .../builders/bean/KSRepLccTradesReport.java | 181 +++++++++++ .../ks/KSRepLccNettoReportBuilder.java | 126 ++++++++ .../ks/KSRepLccTradesReportBuilder.java | 281 ++++++++++++++++++ .../reports/config/ReportBuildersConfig.java | 31 +- .../config/validation/ValidationConfig.java | 31 +- .../reports/services/ReportService.java | 30 +- .../services/ReportServiceTest_KS.java | 276 +++++++++++++++++ .../ks/KS_REP_LCC_NETTO_expected.csv | 19 ++ .../ks/KS_REP_LCC_TRADES_expected.csv | 3 + .../enumeration/ReportBuilderType.java | 2 + .../platform/enumeration/ReportKeys.java | 2 + 12 files changed, 1079 insertions(+), 14 deletions(-) create mode 100644 clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/bean/KSRepLccNettoReport.java create mode 100644 clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/bean/KSRepLccTradesReport.java create mode 100644 clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/ks/KSRepLccNettoReportBuilder.java create mode 100644 clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/ks/KSRepLccTradesReportBuilder.java create mode 100644 clearing-parent/reports-service/src/test/resources/expected_reports_csv/ks/KS_REP_LCC_NETTO_expected.csv create mode 100644 clearing-parent/reports-service/src/test/resources/expected_reports_csv/ks/KS_REP_LCC_TRADES_expected.csv diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/bean/KSRepLccNettoReport.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/bean/KSRepLccNettoReport.java new file mode 100644 index 000000000..f04e5c7d1 --- /dev/null +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/bean/KSRepLccNettoReport.java @@ -0,0 +1,111 @@ +package ru.spcex.clearing.reports.builders.bean; + +import java.math.BigDecimal; +import java.time.LocalDate; +import com.opencsv.bean.CsvBindByName; +import com.opencsv.bean.CsvBindByPosition; +import com.opencsv.bean.CsvDate; +import com.opencsv.bean.CsvNumber; + +public class KSRepLccNettoReport { + @CsvBindByName(column = "FIRM_ID") + @CsvBindByPosition(position = 0) + private String firmId; + + @CsvBindByName(column = "TKR") + @CsvBindByPosition(position = 1) + private String tkr; + + @CsvBindByName(column = "CURRENCYID") + @CsvBindByPosition(position = 2) + private String currencyId; + + @CsvBindByName(column = "DATE") + @CsvBindByPosition(position = 3) + @CsvDate(value = "yyyy-MM-dd") + private LocalDate date; + + @CsvBindByName(column = "NETTO_SUM") + @CsvBindByPosition(position = 4) + @CsvNumber(value = "#0", writeFormat = "#0") + private BigDecimal nettoSum; + + @CsvBindByName(column = "DATA_TYPE") + @CsvBindByPosition(position = 5) + private String dataType; + + @CsvBindByName(column = "DEBIT") + @CsvBindByPosition(position = 6) + @CsvNumber(value = "#0.00", writeFormat = "#0.00") + private BigDecimal debit; + + @CsvBindByName(column = "NETTO_SUM") + @CsvBindByPosition(position = 7) + @CsvNumber(value = "#0.00", writeFormat = "#0.00") + private BigDecimal credit; + + + public String getFirmId() { + return firmId; + } + + public void setFirmId(String firmId) { + this.firmId = firmId; + } + + public String getTkr() { + return tkr; + } + + public void setTkr(String tkr) { + this.tkr = tkr; + } + + public String getCurrencyId() { + return currencyId; + } + + public void setCurrencyId(String currencyId) { + this.currencyId = currencyId; + } + + public LocalDate getDate() { + return date; + } + + public void setDate(LocalDate date) { + this.date = date; + } + + public BigDecimal getNettoSum() { + return nettoSum; + } + + public void setNettoSum(BigDecimal nettoSum) { + this.nettoSum = nettoSum; + } + + public String getDataType() { + return dataType; + } + + public void setDataType(String dataType) { + this.dataType = dataType; + } + + public BigDecimal getDebit() { + return debit; + } + + public void setDebit(BigDecimal debit) { + this.debit = debit; + } + + public BigDecimal getCredit() { + return credit; + } + + public void setCredit(BigDecimal credit) { + this.credit = credit; + } +} diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/bean/KSRepLccTradesReport.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/bean/KSRepLccTradesReport.java new file mode 100644 index 000000000..9d731537f --- /dev/null +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/bean/KSRepLccTradesReport.java @@ -0,0 +1,181 @@ +package ru.spcex.clearing.reports.builders.bean; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import com.opencsv.bean.CsvBindByName; +import com.opencsv.bean.CsvBindByPosition; +import com.opencsv.bean.CsvDate; + +public class KSRepLccTradesReport { + @CsvBindByName(column = "SESSION_ID") + @CsvBindByPosition(position = 0) + private Long sessionId; + + @CsvBindByName(column = "SESSION_DATE") + @CsvBindByPosition(position = 1) + @CsvDate(value = "dd.MM.yyyy'T'HH:mm:ss") + private LocalDateTime sessionDate; + + @CsvBindByName(column = "TRADE_NUM") + @CsvBindByPosition(position = 2) + private Long tradeNum; + + @CsvBindByName(column = "SECCODE") + @CsvBindByPosition(position = 3) + private String secCode; + + @CsvBindByName(column = "FIRM_ID") + @CsvBindByPosition(position = 4) + private String firmId; + + @CsvBindByName(column = "TKR") + @CsvBindByPosition(position = 5) + private String tkr; + + @CsvBindByName(column = "ACCOUNT") + @CsvBindByPosition(position = 6) + private String account; + + @CsvBindByName(column = "CLASS_CODE") + @CsvBindByPosition(position = 7) + private String classCode; + + @CsvBindByName(column = "TRADE_DATE") + @CsvBindByPosition(position = 8) + @CsvDate(value = "dd.MM.yyyy'T'HH:mm:ss") + private LocalDateTime tradeDate; + + @CsvBindByName(column = "TRADE_GROUP") + @CsvBindByPosition(position = 9) + private String tradeGroup; + + @CsvBindByName(column = "BUY_SELL") + @CsvBindByPosition(position = 10) + private String buySell; + + @CsvBindByName(column = "LOT_CURRENCY") + @CsvBindByPosition(position = 11) + private String lotCurrency; + + @CsvBindByName(column = "CO_CURRENCY") + @CsvBindByPosition(position = 12) + private String coCurrency; + + @CsvBindByName(column = "SETTLEDATE") + @CsvBindByPosition(position = 13) + @CsvDate(value = "yyyy-MM-dd") + private LocalDate settleDate; + + + public Long getSessionId() { + return sessionId; + } + + public void setSessionId(Long sessionId) { + this.sessionId = sessionId; + } + + public LocalDateTime getSessionDate() { + return sessionDate; + } + + public void setSessionDate(LocalDateTime sessionDate) { + this.sessionDate = sessionDate; + } + + public Long getTradeNum() { + return tradeNum; + } + + public void setTradeNum(Long tradeNum) { + this.tradeNum = tradeNum; + } + + public String getSecCode() { + return secCode; + } + + public void setSecCode(String secCode) { + this.secCode = secCode; + } + + public String getFirmId() { + return firmId; + } + + public void setFirmId(String firmId) { + this.firmId = firmId; + } + + public String getTkr() { + return tkr; + } + + public void setTkr(String tkr) { + this.tkr = tkr; + } + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getClassCode() { + return classCode; + } + + public void setClassCode(String classCode) { + this.classCode = classCode; + } + + public LocalDateTime getTradeDate() { + return tradeDate; + } + + public void setTradeDate(LocalDateTime tradeDate) { + this.tradeDate = tradeDate; + } + + public String getTradeGroup() { + return tradeGroup; + } + + public void setTradeGroup(String tradeGroup) { + this.tradeGroup = tradeGroup; + } + + public String getBuySell() { + return buySell; + } + + public void setBuySell(String buySell) { + this.buySell = buySell; + } + + public String getLotCurrency() { + return lotCurrency; + } + + public void setLotCurrency(String lotCurrency) { + this.lotCurrency = lotCurrency; + } + + public String getCoCurrency() { + return coCurrency; + } + + public void setCoCurrency(String coCurrency) { + this.coCurrency = coCurrency; + } + + public LocalDate getSettleDate() { + return settleDate; + } + + public void setSettleDate(LocalDate settleDate) { + this.settleDate = settleDate; + } +} diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/ks/KSRepLccNettoReportBuilder.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/ks/KSRepLccNettoReportBuilder.java new file mode 100644 index 000000000..78f3e0e28 --- /dev/null +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/ks/KSRepLccNettoReportBuilder.java @@ -0,0 +1,126 @@ +package ru.spcex.clearing.reports.builders.ks; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import org.springframework.stereotype.Component; +import ru.clearing.classes.statics.data.registry.Registry; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.reports.builders.CSVReportBuilder; +import ru.spcex.clearing.reports.builders.EmptyParams; +import ru.spcex.clearing.reports.builders.bean.KSRepLccNettoReport; +import ru.spcex.platform.enumeration.RegistryDesignation; +import ru.spcex.platform.enumeration.RegistryStatus; +import ru.spcex.platform.enumeration.RegistryTradingParams; +import ru.spcex.platform.enumeration.ReportBuilderType; +import ru.spcex.platform.enumeration.ReportKeys; +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.utils.enumeration.IEnumKey; + +@Component +public class KSRepLccNettoReportBuilder extends CSVReportBuilder { + private final Imdg registryImdg; + + private List rows = null; + + public KSRepLccNettoReportBuilder(ImdgProvider imdgProvider) { + registryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); + } + + @Override + protected List getRows() { + return rows; + } + + @Override + public ReportBuilderType getReportType() { + return ReportBuilderType.KS_REP_LCC_NETTO; + } + + @Override + public ReportKeys getReportKey() { + return ReportKeys.KS_REP_LCC_NETTO_REPORT; + } + + @Override + public Class getParamsClass() { + return EmptyParams.class; + } + + @Override + public Class getReportClass() { + return KSRepLccNettoReport.class; + } + + @Override + protected void collect(EmptyParams params) { + rows = new ArrayList<>(); + LocalDate now = LocalDate.now(); + ImdgPredicateBuilder pb = registryImdg.predicateBuilder(); + ImdgPredicate registryPredicate = RegistryCodeSqlBuilder.getInstance( + RegistryTradingParams.AM_T, RegistryTradingParams.OM_T, RegistryTradingParams.TM_T + ).buildPredicate(pb); + Collection registries = registryImdg.getCollectionObjectsByPredicate( + pb.and( + registryPredicate, + pb.equals("settlementDate", now) + ) + ); + for (Registry registry : registries) { + for (DataTypes dataType : DataTypes.values()) { + KSRepLccNettoReport ksRepLccNettoReport = new KSRepLccNettoReport(); + ksRepLccNettoReport.setFirmId(registry.getTradingCode()); + ksRepLccNettoReport.setTkr(registry.getTradingClearingRegistry()); + ksRepLccNettoReport.setCurrencyId(registry.getSecuritySymbol()); + ksRepLccNettoReport.setDate(now); + RegistryStatus status = IEnumKey.getEnumByKey(RegistryStatus.class, registry.getRegistryStatus()); + RegistryDesignation designation = IEnumKey.getEnumByKey(RegistryDesignation.class, registry.getRegistryDesignation()); + BigDecimal debit = BigDecimal.ZERO; + BigDecimal credit = BigDecimal.ZERO; + if (dataType == DataTypes.FX_OBLIG) { + if (status == RegistryStatus.PROC || status == RegistryStatus.MNG) { + if (designation == RegistryDesignation.O) + debit = registry.getBalance() != null ? registry.getBalance() : BigDecimal.ZERO; + if (designation == RegistryDesignation.T) + credit = registry.getBalance() != null ? registry.getBalance() : BigDecimal.ZERO; + } + } else if (dataType == DataTypes.PR_NETTOSUM) { + if (status == RegistryStatus.CLRD) { + if (designation == RegistryDesignation.O) + debit = registry.getBalance() != null ? registry.getBalance() : BigDecimal.ZERO; + if (designation == RegistryDesignation.T) + credit = registry.getBalance() != null ? registry.getBalance() : BigDecimal.ZERO; + } + } else if (dataType == DataTypes.FX_DEBT) { + if (designation == RegistryDesignation.A) { + if (registry.getBalance() != null && registry.getBalance().compareTo(BigDecimal.ZERO) < 0) + debit = registry.getBalance(); + } + } + ksRepLccNettoReport.setDataType(dataType.value); + ksRepLccNettoReport.setDebit(debit); + ksRepLccNettoReport.setCredit(credit); + ksRepLccNettoReport.setNettoSum(credit.subtract(debit)); + rows.add(ksRepLccNettoReport); + } + } + } + + private enum DataTypes { + FX_OBLIG("FX_OBLIG"), + PR_NETTOSUM("PR_NETTOSUM"), + FX_DEBT("FX_DEBT") + ; + private final String value; + + DataTypes(String value) { + this.value = value; + } + } +} diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/ks/KSRepLccTradesReportBuilder.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/ks/KSRepLccTradesReportBuilder.java new file mode 100644 index 000000000..550dc2688 --- /dev/null +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/ks/KSRepLccTradesReportBuilder.java @@ -0,0 +1,281 @@ +package ru.spcex.clearing.reports.builders.ks; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +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.ExecutionCurrency; +import ru.clearing.classes.statics.data.misc.Session; +import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; +import ru.clearing.classes.statics.data.security.CurrencyPairSecurity; +import ru.clearing.platform.dictionary.CurrencyPairDictionary; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.reports.builders.CSVReportBuilder; +import ru.spcex.clearing.reports.builders.EmptyParams; +import ru.spcex.clearing.reports.builders.bean.KSRepLccTradesReport; +import ru.spcex.platform.enumeration.AccountType; +import ru.spcex.platform.enumeration.ReportBuilderType; +import ru.spcex.platform.enumeration.ReportKeys; +import ru.spcex.platform.enumeration.Side; +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.utils.enumeration.IEnumKey; + +@Component +public class KSRepLccTradesReportBuilder extends CSVReportBuilder { + private final Imdg sessionImdg; + private final Imdg companyImdg; + private final Imdg accountImdg; + private final Imdg executionCurrencyImdg; + private final Imdg currencyPairDictionaryImdg; + private final Imdg currencyPairSecurityImdg; + private final Imdg tradingClearingRegistryImdg; + + private List rows = null; + + public KSRepLccTradesReportBuilder(ImdgProvider imdgProvider) { + sessionImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Session, Session.class); + companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class); + executionCurrencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionCurrency, ExecutionCurrency.class); + currencyPairDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CurrencyPairDictionary, CurrencyPairDictionary.class); + currencyPairSecurityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CurrencyPairSecurity, CurrencyPairSecurity.class); + tradingClearingRegistryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_TradingClearingRegistry, TradingClearingRegistry.class); + } + + @Override + protected List getRows() { + return rows; + } + + @Override + public ReportBuilderType getReportType() { + return ReportBuilderType.KS_REP_LCC_TRADES; + } + + @Override + public ReportKeys getReportKey() { + return ReportKeys.KS_REP_LCC_TRADES_REPORT; + } + + @Override + public Class getParamsClass() { + return EmptyParams.class; + } + + @Override + public Class getReportClass() { + return KSRepLccTradesReport.class; + } + + @Override + protected void collect(EmptyParams params) { + + LocalDate now = LocalDate.now(); + ImdgPredicateBuilder pb = executionCurrencyImdg.predicateBuilder(); + Collection executions = executionCurrencyImdg.getCollectionObjectsByPredicate( + pb.or( + pb.equals("tradingDate", now), + pb.equals("settlementDate", now) + ) + ); + + rows = new ArrayList<>(executions.size()); + for (ExecutionCurrency execution : executions) { + try { + KSRepLccTradesReport ksRepLccTradesReport = new KSRepLccTradesReport(); + + if (execution.getPartyTradingClearingRegistryId() == null) { + log.warn("For execution id = {} field trading_clearing_registry is empty, skipped", execution.getId()); + continue; + } + TradingClearingRegistry tkr = tradingClearingRegistryImdg.getSingleObjectByID(execution.getTradingClearingRegistryId()); + if (tkr == null) { + log.warn( + "For execution id = {} not found trading clearing registry for " + + "execution.trading_clearing_registry_id = {}, execution was skipped", + execution.getId(), + execution.getTradingClearingRegistryId() + ); + continue; + } + if (tkr.getCode() != null) { + ksRepLccTradesReport.setTkr(tkr.getCode()); + } else { + log.warn( + "trading_clearing_registry.code is empty for execution id {} (execution.trading_clearing_registry_id = {}), skipped", + execution.getId(), + execution.getPartyTradingClearingRegistryId() + ); + } + + if (execution.getSessionId() != null) { + Session session = sessionImdg.getSingleObjectByID(execution.getSessionId()); + ksRepLccTradesReport.setSessionId(execution.getSessionId()); + if (session != null && session.getCreated() != null) { + ksRepLccTradesReport.setSessionDate(LocalDateTime.ofInstant(session.getCreated(), getReportZoneId())); + } else { + log.warn( + "Can't find session (or session.updated_at is empty) for execution.session_id = {}, execution id = {} skipped", + execution.getSessionId(), + execution.getId() + ); + continue; + } + } else { + log.warn("For execution id = {} session_id is empty, skipped", execution.getId()); + continue; + } + + if (execution.getExchangeExecutionId() == null) { + log.warn("For execution id = {} exchange_execution_id is empty, skipped", execution.getId()); + continue; + } + ksRepLccTradesReport.setTradeNum(execution.getExchangeExecutionId()); + + if (execution.getSecuritySymbol() == null) { + log.warn("For execution id = {} security_symbol is empty, skipped", execution.getId()); + continue; + } + ksRepLccTradesReport.setSecCode(execution.getSecuritySymbol()); + + if (execution.getCompanyId() != null) { + Company company = companyImdg.getSingleObjectByID(execution.getCompanyId()); + if (company != null) { + ksRepLccTradesReport.setFirmId(company.getTradingCode()); + } else { + log.warn( + "Can't find company for execution.company_id = {}, execution id = {}, skipped", + execution.getCompanyId(), + execution.getId() + ); + continue; + } + } else { + log.warn("For execution id = {} company_id is empty, skipped", execution.getId()); + continue; + } + + Account account = accountImdg.getSingleObjectByID(tkr.getMoneyAccountId()); + if (account != null) { + AccountType accountType = IEnumKey.getEnumByKey(AccountType.class, account.getAccountType()); + if (accountType == AccountType.Info) { + pb = accountImdg.predicateBuilder(); + ImdgPredicate finalPredicate = pb.and( + pb.equals("accountType", AccountType.Anlt.getKey()), + pb.equals("companyId", 5L) + ); + if (execution.getSecuritySymbol() != null) + finalPredicate = pb.and(finalPredicate, pb.equals("currency", execution.getSecuritySymbol())); + account = accountImdg.getFirstObjectByPredicate(finalPredicate); + } + if (account != null) { + ksRepLccTradesReport.setAccount(account.getAccount()); + } else { + log.warn( + "For trading_clearing_registry.money_account_id = {} account with company_id = 5 not found, skipped", + tkr.getMoneyAccountId() + ); + continue; + } + } else { + log.warn( + "For trading_clearing_registry.money_account_id = {} account not found, execution id = {}, skipped", + tkr.getMoneyAccountId(), + execution.getId() + ); + continue; + } + + if (execution.getMarket() == null) { + log.warn("For execution id = {} market is empty, skipped", execution.getId()); + continue; + } + ksRepLccTradesReport.setClassCode(execution.getMarket()); + + if (execution.getExchangeExecutionTime() != null) { + ksRepLccTradesReport.setTradeDate( + LocalDateTime.ofInstant(execution.getExchangeExecutionTime(), getReportZoneId()) + ); + } else { + log.warn("For execution id = {} field exchange_execution_time is empty, skipped", execution.getId()); + continue; + } + + ksRepLccTradesReport.setTradeGroup("T"); + + if (Arrays.asList(Side.SELL.getKey(), "S", "SELL").contains(execution.getSide())) { + ksRepLccTradesReport.setBuySell("S"); + } else if (Arrays.asList(Side.BUY.getKey(), "B", "BUY").contains(execution.getSide())) { + ksRepLccTradesReport.setBuySell("B"); + } else { + log.warn( + "For execution id = {} unknown execution.side ({}) value, skipped", + execution.getId(), + execution.getSide() + ); + continue; + } + + if (execution.getSecurityId() != null) { + pb = currencyPairDictionaryImdg.predicateBuilder(); + CurrencyPairSecurity currencyPairSecurity = currencyPairSecurityImdg.getFirstObjectByPredicate( + pb.equals("securityId", execution.getSecurityId()) + ); + if (currencyPairSecurity != null) { + if (currencyPairSecurity.getCurrencyPairId() != null) { + CurrencyPairDictionary currencyPairDictionary = currencyPairDictionaryImdg.getSingleObjectByID( + currencyPairSecurity.getCurrencyPairId() + ); + if (currencyPairDictionary != null) { + ksRepLccTradesReport.setLotCurrency(currencyPairDictionary.getBaseCurrency()); + ksRepLccTradesReport.setCoCurrency(currencyPairDictionary.getQuoteCurrency()); + } else { + log.warn( + "For currency_pair_id = {} not found currency_pair_dictionary, execution id = {}, skipped", + currencyPairSecurity.getCurrencyPairId(), + execution.getId() + ); + continue; + } + } else { + log.warn( + "For currency pair security (id = {}) empty field currency_pair_id, execution id = {}, skipped", + currencyPairSecurity.getId(), + execution.getId() + ); + continue; + } + } else { + log.warn( + "For execution.security_id = {} (execution.id = {}) currency_pair_security not found, skipped", + execution.getSecurityId(), + execution.getId() + ); + continue; + } + } else { + log.warn("For execution id = {} field security_id is empty, skipped", execution.getId()); + continue; + } + + if (execution.getSettlementDate() == null) { + log.warn("For execution id = {} empty settlement_date, skipped", execution.getId()); + continue; + } + ksRepLccTradesReport.setSettleDate(execution.getSettlementDate()); + + rows.add(ksRepLccTradesReport); + } catch (Exception e) { + log.error("Can't create report row for execution (id = %d), skipped".formatted(execution.getId()), e); + } + } + } +} diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/config/ReportBuildersConfig.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/config/ReportBuildersConfig.java index 0de9211c2..3f25b7cac 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/config/ReportBuildersConfig.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/config/ReportBuildersConfig.java @@ -1,19 +1,32 @@ package ru.spcex.clearing.reports.config; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import ru.spcex.clearing.reports.builders.CSVReportBuilder; import ru.spcex.clearing.reports.builders.EmptyParams; import ru.spcex.clearing.reports.builders.SessionIdParam; -import ru.spcex.clearing.reports.builders.bp.*; -import ru.spcex.clearing.reports.builders.ks.*; +import ru.spcex.clearing.reports.builders.bp.ExecutedDealReportBuilder_INFTYPE_1; +import ru.spcex.clearing.reports.builders.bp.ExecutedDealReportBuilder_INFTYPE_2; +import ru.spcex.clearing.reports.builders.bp.ExecutedDealReportBuilder_INFTYPE_3; +import ru.spcex.clearing.reports.builders.bp.ExecutedDealReportBuilder_INFTYPE_4; +import ru.spcex.clearing.reports.builders.bp.UnfulfilledDealReportBuilder; +import ru.spcex.clearing.reports.builders.ks.KSCommissionTradesReportBuilder; +import ru.spcex.clearing.reports.builders.ks.KSRepCashNettoReportBuilder; +import ru.spcex.clearing.reports.builders.ks.KSRepCashRegisterSumsReportBuilder; +import ru.spcex.clearing.reports.builders.ks.KSRepCashRegistersReportBuilder; +import ru.spcex.clearing.reports.builders.ks.KSRepDepoNettoReportBuilder; +import ru.spcex.clearing.reports.builders.ks.KSRepDepoRegisterQuantitiesReportBuilder; +import ru.spcex.clearing.reports.builders.ks.KSRepDepoRegistersReportBuilder; +import ru.spcex.clearing.reports.builders.ks.KSRepLccNettoReportBuilder; +import ru.spcex.clearing.reports.builders.ks.KSRepLccTradesReportBuilder; +import ru.spcex.clearing.reports.builders.ks.KSRepTradesReportBuilder; +import ru.spcex.clearing.reports.builders.ks.KSSessionListReportBuilder; import ru.spcex.platform.enumeration.ReportBuilderType; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - @Configuration @ComponentScan(basePackages = "ru.spcex.clearing.reports.builders") public class ReportBuildersConfig { @@ -25,7 +38,9 @@ public class ReportBuildersConfig { KSRepDepoRegisterQuantitiesReportBuilder ksRepDepoRegisterQuantitiesReportBuilder, KSRepTradesReportBuilder ksRepTradesReportBuilder, KSSessionListReportBuilder ksSessionListReportBuilder, - KSCommissionTradesReportBuilder ksCommissionTradesReportBuilder + KSCommissionTradesReportBuilder ksCommissionTradesReportBuilder, + KSRepLccTradesReportBuilder ksRepLccTradesReportBuilder, + KSRepLccNettoReportBuilder ksRepLccNettoReportBuilder ) { Map>> resultMap = new HashMap<>(); resultMap.put(ReportBuilderType.KS_REP_CASH_REGISTERS, List.of(ksRepCashRegistersReportBuilder)); @@ -35,6 +50,8 @@ public class ReportBuildersConfig { resultMap.put(ReportBuilderType.KS_REP_TRADES, List.of(ksRepTradesReportBuilder)); resultMap.put(ReportBuilderType.KS_SESSION_LIST, List.of(ksSessionListReportBuilder)); resultMap.put(ReportBuilderType.KS_COMMISSION_TRADES, List.of(ksCommissionTradesReportBuilder)); + resultMap.put(ReportBuilderType.KS_REP_LCC_TRADES, List.of(ksRepLccTradesReportBuilder)); + resultMap.put(ReportBuilderType.KS_REP_LCC_NETTO, List.of(ksRepLccNettoReportBuilder)); return resultMap; } diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/config/validation/ValidationConfig.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/config/validation/ValidationConfig.java index 3e0ca4b97..c9bf01d64 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/config/validation/ValidationConfig.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/config/validation/ValidationConfig.java @@ -1,6 +1,10 @@ package ru.spcex.clearing.reports.config.validation; +import java.util.HashMap; +import java.util.Map; +import java.util.function.BiConsumer; +import java.util.function.Function; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import ru.clearing.classes.statics.data.company.Company; @@ -22,11 +26,6 @@ import ru.spcex.platform.utils.enumeration.IMessageResolver; import ru.spcex.platform.utils.validation.IValidator; import ru.spcex.platform.utils.validation.ValidatorImpl; -import java.util.HashMap; -import java.util.Map; -import java.util.function.BiConsumer; -import java.util.function.Function; - @Configuration public class ValidationConfig { @@ -63,7 +62,9 @@ public class ValidationConfig { ReportBuilderType.KS_REP_TRADES, ReportBuilderType.KS_REP_FIRM_DETAILS, ReportBuilderType.KS_SESSION_LIST, - ReportBuilderType.KS_COMMISSION_TRADES + ReportBuilderType.KS_COMMISSION_TRADES, + ReportBuilderType.KS_REP_LCC_TRADES, + ReportBuilderType.KS_REP_LCC_NETTO, }, ReportError.WrongFieldValue, ReportError.RequiredFieldEmpty) @@ -154,6 +155,24 @@ public class ValidationConfig { }; } + // todo оставил бин валидатора на будущее, если в дальнейшем придется проверять запрос. в текущей версии, по факту, + // запрос не проверяется: в случае если sessionId не указан отчеты не строятся + @Bean("reportRequestGRECValidator") + public Function reportRequestGRECValidator( + Map> imdgForValidation + ) { + return launcherCommandRequest -> { + ImdgValidationContext context = new ImdgValidationContext<>(); + context.setValidatedObject(launcherCommandRequest); + return new ValidatorImpl<>(context, + FieldRequiredRule.instance( + "sessionId", + LauncherCommandRequest::getSessionId, + ReportError.RequiredFieldEmpty, + false) + ); + }; + } } diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/ReportService.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/ReportService.java index 4f3ef4bb6..770d15dc1 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/ReportService.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/ReportService.java @@ -24,7 +24,6 @@ import ru.spcex.clearing.platform.messaging.domain.cud.gateway.SendReportRequest import ru.spcex.clearing.platform.messaging.domain.cud.reports.ReportRequest; import ru.spcex.clearing.platform.messaging.domain.cud.reports.ReportRequestWithSessionId; import ru.spcex.clearing.platform.messaging.domain.cud.schedule.LauncherCommandRequest; -import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.clearing.platform.messaging.service.QueueConsumerV2; import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate; import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; @@ -55,12 +54,14 @@ public class ReportService extends QueueConsumerV2 implements InitializingBean { private final Function reportRequestGREPValidator; private final Function reportRequestGRETValidator; private final Function reportRequestGREFValidator; + private final Function reportRequestGRECValidator; private final Map>> reportBuildersWithoutParams; private final Map>> reportBuildersWithSessionIdParam; private final Map>> reportBuildersForGREP; private final Map>> reportBuildersForGREF; private final Map>> reportBuildersForGRET; + private final Map>> reportBuildersForGREC; private final Imdg sessionImdg; @@ -85,6 +86,8 @@ public class ReportService extends QueueConsumerV2 implements InitializingBean { Map>> reportBuildersForGREF, @Qualifier("reportBuildersForGRET") Map>> reportBuildersForGRET, + @Qualifier("reportBuildersForGRET") + Map>> reportBuildersForGREC, @Qualifier("reportRequestValidator") Function reportRequestValidator, @@ -97,6 +100,8 @@ public class ReportService extends QueueConsumerV2 implements InitializingBean { Function reportRequestGRETValidator, @Qualifier("reportRequestGREFValidator") Function reportRequestGREFValidator, + @Qualifier("reportRequestGREFValidator") + Function reportRequestGRECValidator, ImdgProvider imdgProvider, SFTPReportsConfig.ReportsGateway reportsSftpGateway @@ -111,9 +116,11 @@ public class ReportService extends QueueConsumerV2 implements InitializingBean { this.reportRequestGREPValidator = reportRequestGREPValidator; this.reportRequestGRETValidator = reportRequestGRETValidator; this.reportRequestGREFValidator = reportRequestGREFValidator; + this.reportRequestGRECValidator = reportRequestGRECValidator; this.reportBuildersForGREP = reportBuildersForGREP; this.reportBuildersForGREF = reportBuildersForGREF; this.reportBuildersForGRET = reportBuildersForGRET; + this.reportBuildersForGREC = reportBuildersForGREC; this.reportsSftpGateway = reportsSftpGateway; this.sessionImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Session, Session.class); this.outFolder = new File(reportsServiceSettings.getReportsStore().getLocalTempDir()); @@ -144,6 +151,9 @@ public class ReportService extends QueueConsumerV2 implements InitializingBean { callback(LauncherCommandRequest.class) .setFunction(this::createReportForGREF) .forDestination(Task.createDealsReport_GREF.topic(), callbacks::put); + callback(LauncherCommandRequest.class) + .setFunction(this::createReportForGREC) + .forDestination(Task.createReport_GREC.topic(), callbacks::put); init(); } @@ -314,6 +324,24 @@ public class ReportService extends QueueConsumerV2 implements InitializingBean { return null; } + public RequestInfoUpdate createReportForGREC(BaseRequest userRequest) { + log.debug("GREC task received"); + + try { + RequestInfoUpdate requestInfoUpdate = validationHelper.validateTillFirstError(userRequest, reportRequestGRECValidator); + if (requestInfoUpdate != null) return null; + logUnknownProperties(userRequest); + + Map outFiles = createReportsForTask(List.of(), reportBuildersForGREC.values()); + + sendReportsToGateway(List.of(), outFiles, ReportType.REPORT_KS_FINAL.getKey()); + sendFilesToSftp(outFiles.keySet()); + } catch (Exception e) { + log.error("Unexpected exception", e); + } + return null; + } + private Map createReportsForTask(List sessionIds, Collection>> buildersForTask) { Map outFiles = new HashMap<>(); int cntErrors = 0; diff --git a/clearing-parent/reports-service/src/test/java/ru/spcex/clearing/reports/services/ReportServiceTest_KS.java b/clearing-parent/reports-service/src/test/java/ru/spcex/clearing/reports/services/ReportServiceTest_KS.java index b3c41b6c6..215edfdc2 100644 --- a/clearing-parent/reports-service/src/test/java/ru/spcex/clearing/reports/services/ReportServiceTest_KS.java +++ b/clearing-parent/reports-service/src/test/java/ru/spcex/clearing/reports/services/ReportServiceTest_KS.java @@ -46,6 +46,7 @@ import ru.clearing.classes.statics.data.account.AccountSymbols; import ru.clearing.classes.statics.data.company.ClearingMemberCategory; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.CompanySymbols; +import ru.clearing.classes.statics.data.execution.ExecutionCurrency; import ru.clearing.classes.statics.data.execution.ExecutionDeposit; import ru.clearing.classes.statics.data.execution.ExecutionFond; import ru.clearing.classes.statics.data.instrument.issue.EquitySecurity; @@ -55,7 +56,9 @@ import ru.clearing.classes.statics.data.misc.Session; import ru.clearing.classes.statics.data.profile.ProfileDocument; import ru.clearing.classes.statics.data.registry.Registry; import ru.clearing.classes.statics.data.registry.TradingClearingRegistry; +import ru.clearing.classes.statics.data.security.CurrencyPairSecurity; import ru.clearing.classes.statics.data.statement.Statement; +import ru.clearing.platform.dictionary.CurrencyPairDictionary; import ru.clearing.platform.dictionary.RegistryCodeDictionary; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.platform.messaging.domain.Consts; @@ -116,6 +119,7 @@ public class ReportServiceTest_KS { private Imdg registryCodeDictionaryImdg; private Imdg executionDepositImdg; private Imdg executionFondImdg; + private Imdg executionCurrencyImdg; private Imdg sessionImdg; private Imdg companySymbolsImdg; private Imdg profileDocumentImdg; @@ -124,6 +128,8 @@ public class ReportServiceTest_KS { private Imdg sTradesImdg; private Imdg accountSymbolsImdg; private Imdg clearingMemberCategoryImdg; + private Imdg currencyPairSecurityImdg; + private Imdg currencyPairDictionaryImdg; private Long COMPANY_ID; @Autowired @@ -1275,6 +1281,273 @@ public class ReportServiceTest_KS { sessionImdg.delete(session); } + @Test + @Order(12) + public void createReportTest_KSRepLccNettoReport() throws IOException, CsvValidationException { + clearTestDir(); + + Long SESSION_ID_1 = 32121L; + Long SESSION_ID_2 = 32125L; + Long CURRENCY_PAIR_ID_1 = 7896L; + Long CURRENCY_PAIR_ID_2 = 7821L; + Long SECURITY_ID_1 = 56465L; + Long SECURITY_ID_2 = 5645L; + Long COMPANY_ID_1 = 3215L; + Long COMPANY_ID_2 = 3216L; + Long TKR_ID_1 = 578439L; + Long TKR_ID_2 = 57842L; + Long MONEY_ACCOUNT_ID_1 = 321312L; + Long MONEY_ACCOUNT_ID_2 = 321311L; + + ReportRequest reportRequest = new ReportRequest(); + reportRequest.setReportId(ReportBuilderType.KS_REP_LCC_TRADES.getKey()); + + TradingClearingRegistry tkr_1 = new TradingClearingRegistry(); + tkr_1.setId(TKR_ID_1); + tkr_1.setCode("TKR_CODE_1"); + tkr_1.setMoneyAccountId(MONEY_ACCOUNT_ID_1); + tradingClearingRegistryImdg.insert(tkr_1); + + TradingClearingRegistry tkr_2 = new TradingClearingRegistry(); + tkr_2.setId(TKR_ID_2); + tkr_2.setCode("TKR_CODE_2"); + tkr_2.setMoneyAccountId(MONEY_ACCOUNT_ID_2); + tradingClearingRegistryImdg.insert(tkr_2); + + Session session_1 = new Session(); + session_1.setId(SESSION_ID_1); + session_1.setCreated(Instant.now()); + + Session session_2 = new Session(); + session_2.setId(SESSION_ID_2); + session_2.setCreated(Instant.now()); + + sessionImdg.insert(session_1); + sessionImdg.insert(session_2); + + Account account_11 = new Account(); + account_11.setId(MONEY_ACCOUNT_ID_1); + account_11.setAccountType("INFO"); + + Account account_1 = new Account(); + account_1.setCurrency("RUR"); + account_1.setCompanyId(5L); + account_1.setAccountType("ANLT"); + account_1.setAccount("ACCOUNT_1"); + + Account account_2 = new Account(); + account_2.setId(MONEY_ACCOUNT_ID_2); + account_2.setAccountType("CLRN"); + account_2.setAccount("ACCOUNT_2"); + + accountImdg.insert(account_1); + accountImdg.insert(account_11); + accountImdg.insert(account_2); + + Company company_1 = new Company(); + company_1.setId(COMPANY_ID_1); + company_1.setTradingCode("TRADING_CODE_1"); + + Company company_2 = new Company(); + company_2.setId(COMPANY_ID_2); + company_2.setTradingCode("TRADING_CODE_2"); + + companyImdg.insert(company_1); + companyImdg.insert(company_2); + + CurrencyPairSecurity currencyPairSecurity_1 = new CurrencyPairSecurity(); + currencyPairSecurity_1.setSecurityId(SECURITY_ID_1); + currencyPairSecurity_1.setCurrencyPairId(CURRENCY_PAIR_ID_1); + + CurrencyPairSecurity currencyPairSecurity_2 = new CurrencyPairSecurity(); + currencyPairSecurity_2.setSecurityId(SECURITY_ID_2); + currencyPairSecurity_2.setCurrencyPairId(CURRENCY_PAIR_ID_2); + + currencyPairSecurityImdg.insert(currencyPairSecurity_1); + currencyPairSecurityImdg.insert(currencyPairSecurity_2); + + CurrencyPairDictionary currencyPairDictionary_1 = new CurrencyPairDictionary(); + currencyPairDictionary_1.setId(CURRENCY_PAIR_ID_1); + currencyPairDictionary_1.setBaseCurrency("BASE_CURRENCY_1"); + currencyPairDictionary_1.setQuoteCurrency("QUOTE_CURRENCY_1"); + + CurrencyPairDictionary currencyPairDictionary_2 = new CurrencyPairDictionary(); + currencyPairDictionary_2.setId(CURRENCY_PAIR_ID_2); + currencyPairDictionary_2.setBaseCurrency("BASE_CURRENCY_2"); + currencyPairDictionary_2.setQuoteCurrency("QUOTE_CURRENCY_2"); + + currencyPairDictionaryImdg.insert(currencyPairDictionary_1); + currencyPairDictionaryImdg.insert(currencyPairDictionary_2); + + + ExecutionCurrency executionCurrency_1 = new ExecutionCurrency(); + executionCurrency_1.setSessionId(session_1.getId()); + executionCurrency_1.setSettlementDate(LocalDate.now()); + executionCurrency_1.setTradingDate(LocalDate.now()); + executionCurrency_1.setSessionId(SESSION_ID_1); + executionCurrency_1.setExchangeExecutionId(321L); + executionCurrency_1.setSecuritySymbol("RUR"); + executionCurrency_1.setTradingClearingRegistryId(TKR_ID_1); + executionCurrency_1.setMarket("MARKET_1"); + executionCurrency_1.setExchangeExecutionTime(Instant.now()); + executionCurrency_1.setSide("SELL"); + executionCurrency_1.setSecurityId(SECURITY_ID_1); + executionCurrency_1.setCompanyId(COMPANY_ID_1); + + ExecutionCurrency executionCurrency_2 = new ExecutionCurrency(); + executionCurrency_2.setSessionId(session_2.getId()); + executionCurrency_2.setSettlementDate(LocalDate.now()); + executionCurrency_2.setSessionId(SESSION_ID_2); + executionCurrency_2.setExchangeExecutionId(123L); + executionCurrency_2.setSecuritySymbol("EUR"); + executionCurrency_2.setTradingClearingRegistryId(TKR_ID_2); + executionCurrency_2.setMarket("MARKET_2"); + executionCurrency_2.setExchangeExecutionTime(Instant.now()); + executionCurrency_2.setSide("BUY"); + executionCurrency_2.setSecurityId(SECURITY_ID_2); + executionCurrency_2.setCompanyId(COMPANY_ID_2); + + executionCurrencyImdg.insert(executionCurrency_1); + executionCurrencyImdg.insert(executionCurrency_2); + + String jsonString = TestUtils.getJsonStringForSystem(reportRequest, 0L); + + TestUtils.addRecordToKafka((MockConsumer) reportService.getConsumer(), + Consts.CREATE_REPORT, + reportRequestCnt++, + 0, + jsonString); + + TestUtils.waitingSendAndCheckRecord(0L, producer); + + File outFile = outFolder.listFiles()[0]; + File expectedFile = new File(getClass().getClassLoader().getResource("expected_reports_csv/ks/KS_REP_LCC_TRADES_expected.csv").getFile()); + compareCSVFiles(expectedFile, outFile, Arrays.asList("SESSION_DATE", "TRADE_DATE", "SETTLE_DATE")); + + accountImdg.delete(account_11); + accountImdg.delete(account_1); + accountImdg.delete(account_2); + companyImdg.delete(company_1); + companyImdg.delete(company_2); + tradingClearingRegistryImdg.delete(tkr_1); + tradingClearingRegistryImdg.delete(tkr_2); + sessionImdg.delete(session_1); + executionCurrencyImdg.delete(executionCurrency_1); + executionCurrencyImdg.delete(executionCurrency_2); + currencyPairSecurityImdg.delete(currencyPairSecurity_1); + currencyPairSecurityImdg.delete(currencyPairSecurity_2); + currencyPairDictionaryImdg.delete(currencyPairDictionary_1); + currencyPairDictionaryImdg.delete(currencyPairDictionary_2); + } + + @Test + @Order(13) + public void createReportTest_KSRepLccTradesReport() throws IOException, CsvValidationException { + clearTestDir(); + + ReportRequest reportRequest = new ReportRequest(); + reportRequest.setReportId(ReportBuilderType.KS_REP_LCC_NETTO.getKey()); + + Registry registry_AMT_1 = new Registry(); + registry_AMT_1.setTradingCode("AMT_1_TRADING_CODE"); + registry_AMT_1.setTradingClearingRegistry("TKR_AMT_1"); + registry_AMT_1.setSecuritySymbol("SEC_SYMBOL_AMT_1"); + registry_AMT_1.setSettlementDate(LocalDate.now()); + registry_AMT_1.setRegistryCode("AM_T"); + registry_AMT_1.setRegistryDesignation(RegistryDesignation.A.getKey()); + registry_AMT_1.setRegistryInstrumentType(RegistryInstrumentType.M.getKey()); + registry_AMT_1.setRegistryUnit(RegistryUnit.T.getKey()); + registry_AMT_1.setBalance(BigDecimal.TEN); + + Registry registry_AMT_2 = new Registry(); + registry_AMT_2.setTradingCode("AMT_2_TRADING_CODE"); + registry_AMT_2.setTradingClearingRegistry("TKR_AMT_2"); + registry_AMT_2.setSecuritySymbol("SEC_SYMBOL_AMT_2"); + registry_AMT_2.setSettlementDate(LocalDate.now()); + registry_AMT_2.setRegistryCode("AM_T"); + registry_AMT_2.setRegistryDesignation(RegistryDesignation.A.getKey()); + registry_AMT_2.setRegistryInstrumentType(RegistryInstrumentType.M.getKey()); + registry_AMT_2.setRegistryUnit(RegistryUnit.T.getKey()); + registry_AMT_1.setBalance(BigDecimal.TEN.negate()); + + Registry registry_OMT_1 = new Registry(); + registry_OMT_1.setTradingCode("OMT_1_TRADING_CODE"); + registry_OMT_1.setTradingClearingRegistry("TKR_OMT_1"); + registry_OMT_1.setSecuritySymbol("SEC_SYMBOL_OMT_1"); + registry_OMT_1.setSettlementDate(LocalDate.now()); + registry_OMT_1.setRegistryCode("OM_T"); + registry_OMT_1.setRegistryDesignation(RegistryDesignation.O.getKey()); + registry_OMT_1.setRegistryInstrumentType(RegistryInstrumentType.M.getKey()); + registry_OMT_1.setRegistryUnit(RegistryUnit.T.getKey()); + registry_OMT_1.setRegistryStatus(RegistryStatus.PROC.getKey()); + registry_OMT_1.setBalance(BigDecimal.valueOf(321321)); + + Registry registry_OMT_2 = new Registry(); + registry_OMT_2.setTradingCode("OMT_2_TRADING_CODE"); + registry_OMT_2.setTradingClearingRegistry("TKR_OMT_2"); + registry_OMT_2.setSecuritySymbol("SEC_SYMBOL_OMT_2"); + registry_OMT_2.setSettlementDate(LocalDate.now()); + registry_OMT_2.setRegistryCode("OM_T"); + registry_OMT_2.setRegistryDesignation(RegistryDesignation.O.getKey()); + registry_OMT_2.setRegistryInstrumentType(RegistryInstrumentType.M.getKey()); + registry_OMT_2.setRegistryUnit(RegistryUnit.T.getKey()); + registry_OMT_2.setRegistryStatus(RegistryStatus.CLRD.getKey()); + registry_OMT_2.setBalance(BigDecimal.valueOf(547893)); + + Registry registry_TMT_1 = new Registry(); + registry_TMT_1.setTradingCode("TMT_1_TRADING_CODE"); + registry_TMT_1.setTradingClearingRegistry("TKR_TMT_1"); + registry_TMT_1.setSecuritySymbol("SEC_SYMBOL_TMT_1"); + registry_TMT_1.setSettlementDate(LocalDate.now()); + registry_TMT_1.setRegistryCode("TM_T"); + registry_TMT_1.setRegistryDesignation(RegistryDesignation.T.getKey()); + registry_TMT_1.setRegistryInstrumentType(RegistryInstrumentType.M.getKey()); + registry_TMT_1.setRegistryUnit(RegistryUnit.T.getKey()); + registry_TMT_1.setRegistryStatus(RegistryStatus.MNG.getKey()); + registry_TMT_1.setBalance(BigDecimal.valueOf(5783949)); + + Registry registry_TMT_2 = new Registry(); + registry_TMT_2.setTradingCode("TMT_2_TRADING_CODE"); + registry_TMT_2.setTradingClearingRegistry("TKR_TMT_2"); + registry_TMT_2.setSecuritySymbol("SEC_SYMBOL_TMT_2"); + registry_TMT_2.setSettlementDate(LocalDate.now()); + registry_TMT_2.setRegistryCode("TM_T"); + registry_TMT_2.setRegistryDesignation(RegistryDesignation.T.getKey()); + registry_TMT_2.setRegistryInstrumentType(RegistryInstrumentType.M.getKey()); + registry_TMT_2.setRegistryUnit(RegistryUnit.T.getKey()); + registry_TMT_2.setRegistryStatus(RegistryStatus.CLRD.getKey()); + registry_TMT_2.setBalance(BigDecimal.valueOf(434213)); + + registryImdg.insert(registry_AMT_1); + registryImdg.insert(registry_AMT_2); + registryImdg.insert(registry_TMT_1); + registryImdg.insert(registry_TMT_2); + registryImdg.insert(registry_OMT_1); + registryImdg.insert(registry_OMT_2); + + + String jsonString = TestUtils.getJsonStringForSystem(reportRequest, 0L); + + TestUtils.addRecordToKafka((MockConsumer) reportService.getConsumer(), + Consts.CREATE_REPORT, + reportRequestCnt++, + 0, + jsonString); + + TestUtils.waitingSendAndCheckRecord(0L, producer); + + File outFile = outFolder.listFiles()[0]; + File expectedFile = new File(getClass().getClassLoader().getResource("expected_reports_csv/ks/KS_REP_LCC_NETTO_expected.csv").getFile()); + compareCSVFiles(expectedFile, outFile, Arrays.asList("DATE")); + + registryImdg.delete(registry_AMT_1); + registryImdg.delete(registry_TMT_1); + registryImdg.delete(registry_OMT_1); + registryImdg.delete(registry_AMT_2); + registryImdg.delete(registry_TMT_2); + registryImdg.delete(registry_OMT_2); + } + private void compareCSVFiles(File expectedFile, File actualFile, List columnsForSkip) throws IOException, CsvValidationException { if (columnsForSkip == null) columnsForSkip = Collections.emptyList(); @@ -1373,6 +1646,7 @@ public class ReportServiceTest_KS { executionDepositImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionDeposit, ExecutionDeposit.class); executionFondImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionFond, ExecutionFond.class); + executionCurrencyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ExecutionCurrency, ExecutionCurrency.class); sessionImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Session, Session.class); companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); profileDocumentImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ProfileDocument, ProfileDocument.class); @@ -1384,6 +1658,8 @@ public class ReportServiceTest_KS { sTradesImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_STrades, STrades.class); accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class); clearingMemberCategoryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class); + currencyPairSecurityImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CurrencyPairSecurity, CurrencyPairSecurity.class); + currencyPairDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CurrencyPairDictionary, CurrencyPairDictionary.class); } private void clearTestDir() throws IOException { diff --git a/clearing-parent/reports-service/src/test/resources/expected_reports_csv/ks/KS_REP_LCC_NETTO_expected.csv b/clearing-parent/reports-service/src/test/resources/expected_reports_csv/ks/KS_REP_LCC_NETTO_expected.csv new file mode 100644 index 000000000..9be9a2e70 --- /dev/null +++ b/clearing-parent/reports-service/src/test/resources/expected_reports_csv/ks/KS_REP_LCC_NETTO_expected.csv @@ -0,0 +1,19 @@ +"FIRM_ID","TKR","CURRENCYID","DATE","NETTO_SUM","DATA_TYPE","DEBIT","NETTO_SUM" +"AMT_1_TRADING_CODE","TKR_AMT_1","SEC_SYMBOL_AMT_1","2024-10-02","0","FX_OBLIG","0.00","0.00" +"AMT_1_TRADING_CODE","TKR_AMT_1","SEC_SYMBOL_AMT_1","2024-10-02","0","PR_NETTOSUM","0.00","0.00" +"AMT_1_TRADING_CODE","TKR_AMT_1","SEC_SYMBOL_AMT_1","2024-10-02","10","FX_DEBT","-10.00","0.00" +"TMT_2_TRADING_CODE","TKR_TMT_2","SEC_SYMBOL_TMT_2","2024-10-02","0","FX_OBLIG","0.00","0.00" +"TMT_2_TRADING_CODE","TKR_TMT_2","SEC_SYMBOL_TMT_2","2024-10-02","434213","PR_NETTOSUM","0.00","434213.00" +"TMT_2_TRADING_CODE","TKR_TMT_2","SEC_SYMBOL_TMT_2","2024-10-02","0","FX_DEBT","0.00","0.00" +"TMT_1_TRADING_CODE","TKR_TMT_1","SEC_SYMBOL_TMT_1","2024-10-02","5783949","FX_OBLIG","0.00","5783949.00" +"TMT_1_TRADING_CODE","TKR_TMT_1","SEC_SYMBOL_TMT_1","2024-10-02","0","PR_NETTOSUM","0.00","0.00" +"TMT_1_TRADING_CODE","TKR_TMT_1","SEC_SYMBOL_TMT_1","2024-10-02","0","FX_DEBT","0.00","0.00" +"OMT_1_TRADING_CODE","TKR_OMT_1","SEC_SYMBOL_OMT_1","2024-10-02","-321321","FX_OBLIG","321321.00","0.00" +"OMT_1_TRADING_CODE","TKR_OMT_1","SEC_SYMBOL_OMT_1","2024-10-02","0","PR_NETTOSUM","0.00","0.00" +"OMT_1_TRADING_CODE","TKR_OMT_1","SEC_SYMBOL_OMT_1","2024-10-02","0","FX_DEBT","0.00","0.00" +"AMT_2_TRADING_CODE","TKR_AMT_2","SEC_SYMBOL_AMT_2","2024-10-02","0","FX_OBLIG","0.00","0.00" +"AMT_2_TRADING_CODE","TKR_AMT_2","SEC_SYMBOL_AMT_2","2024-10-02","0","PR_NETTOSUM","0.00","0.00" +"AMT_2_TRADING_CODE","TKR_AMT_2","SEC_SYMBOL_AMT_2","2024-10-02","0","FX_DEBT","0.00","0.00" +"OMT_2_TRADING_CODE","TKR_OMT_2","SEC_SYMBOL_OMT_2","2024-10-02","0","FX_OBLIG","0.00","0.00" +"OMT_2_TRADING_CODE","TKR_OMT_2","SEC_SYMBOL_OMT_2","2024-10-02","-547893","PR_NETTOSUM","547893.00","0.00" +"OMT_2_TRADING_CODE","TKR_OMT_2","SEC_SYMBOL_OMT_2","2024-10-02","0","FX_DEBT","0.00","0.00" diff --git a/clearing-parent/reports-service/src/test/resources/expected_reports_csv/ks/KS_REP_LCC_TRADES_expected.csv b/clearing-parent/reports-service/src/test/resources/expected_reports_csv/ks/KS_REP_LCC_TRADES_expected.csv new file mode 100644 index 000000000..dfee178bb --- /dev/null +++ b/clearing-parent/reports-service/src/test/resources/expected_reports_csv/ks/KS_REP_LCC_TRADES_expected.csv @@ -0,0 +1,3 @@ +"SESSION_ID","SESSION_DATE","TRADE_NUM","SECCODE","FIRM_ID","TKR","ACCOUNT","CLASS_CODE","TRADE_DATE","TRADE_GROUP","BUY_SELL","LOT_CURRENCY","CO_CURRENCY","SETTLEDATE" +"32121","02.10.2024T15:54:33","321","RUR","TRADING_CODE_1","TKR_CODE_1","ACCOUNT_1","MARKET_1","02.10.2024T15:54:33","T","S","BASE_CURRENCY_1","QUOTE_CURRENCY_1","2024-10-02" +"32125","02.10.2024T15:54:33","123","EUR","TRADING_CODE_2","TKR_CODE_2","ACCOUNT_2","MARKET_2","02.10.2024T15:54:33","T","B","BASE_CURRENCY_2","QUOTE_CURRENCY_2","2024-10-02" diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/ReportBuilderType.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/ReportBuilderType.java index dee144f70..180ab1c01 100644 --- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/ReportBuilderType.java +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/ReportBuilderType.java @@ -19,6 +19,8 @@ public enum ReportBuilderType implements IEnumKey { KS_REP_FIRM_DETAILS("ks_rep_firm_details"), KS_SESSION_LIST("ks_session_list"), KS_COMMISSION_TRADES("ks_commission_trades"), + KS_REP_LCC_TRADES("ks_rep_lcc_trades"), + KS_REP_LCC_NETTO("ks_rep_lcc_netto") ; private final String key; diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/ReportKeys.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/ReportKeys.java index 93d2bdd0c..81eede910 100644 --- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/ReportKeys.java +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/ReportKeys.java @@ -18,6 +18,8 @@ public enum ReportKeys implements IEnumKey { KS_REP_FIRM_DETAILS("KS_REP_FIRM_DETAILS"), KS_SESSION_LIST("KS_SESSION_LIST"), KS_COMMISSION_TRADES("KS_COMMISSION_TRADES"), + KS_REP_LCC_TRADES_REPORT("KS_REP_LCC_TRADES_REPORT"), + KS_REP_LCC_NETTO_REPORT("KS_REP_LCC_NETTO_REPORT") ; private final String key;