diff --git a/clearing-parent/backend-api/src/main/resources/meta/meta.json b/clearing-parent/backend-api/src/main/resources/meta/meta.json index 908b42dc0..290d1ba10 100644 --- a/clearing-parent/backend-api/src/main/resources/meta/meta.json +++ b/clearing-parent/backend-api/src/main/resources/meta/meta.json @@ -1,6 +1,6 @@ { - "version": "3.9.0.69", + "version": "3.9.0.70", "enums": { @@ -3328,11 +3328,11 @@ "type": 3,"name": "Номер купона","shortname": "Номер","searchable": true,"sortable": true,"visible": true } , - {"code": "periodEndDate", + {"code": "periodStartDate", "type": 6,"name": "Начало периода действия","shortname": "Начало","searchable": true,"sortable": true,"visible": true } , - {"code": "periodStartDate", + {"code": "periodEndDate", "type": 6,"name": "Окончание периода действия","shortname": "Окончание","searchable": true,"sortable": true,"visible": true } , diff --git a/clearing-parent/backend-api/src/main/resources/meta/meta.xml b/clearing-parent/backend-api/src/main/resources/meta/meta.xml index c08dc1188..748f4e6a3 100644 --- a/clearing-parent/backend-api/src/main/resources/meta/meta.xml +++ b/clearing-parent/backend-api/src/main/resources/meta/meta.xml @@ -1,6 +1,6 @@ - + @@ -772,8 +772,8 @@ - - + + diff --git a/clearing-parent/backend-api/src/test/resources/meta.json b/clearing-parent/backend-api/src/test/resources/meta.json index 908b42dc0..290d1ba10 100644 --- a/clearing-parent/backend-api/src/test/resources/meta.json +++ b/clearing-parent/backend-api/src/test/resources/meta.json @@ -1,6 +1,6 @@ { - "version": "3.9.0.69", + "version": "3.9.0.70", "enums": { @@ -3328,11 +3328,11 @@ "type": 3,"name": "Номер купона","shortname": "Номер","searchable": true,"sortable": true,"visible": true } , - {"code": "periodEndDate", + {"code": "periodStartDate", "type": 6,"name": "Начало периода действия","shortname": "Начало","searchable": true,"sortable": true,"visible": true } , - {"code": "periodStartDate", + {"code": "periodEndDate", "type": 6,"name": "Окончание периода действия","shortname": "Окончание","searchable": true,"sortable": true,"visible": true } , diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilderV2.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilderV2.java index 7a4a5211f..14f4c3792 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilderV2.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/builder/PaymentInstructionBuilderV2.java @@ -14,6 +14,9 @@ import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.platform.enumeration.*; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; +import ru.spcex.platform.imdg.api.predicate.specific.RegistryCodeSqlBuilder; import ru.spcex.platform.utils.enumeration.IEnumKey; import ru.spcex.platform.utils.time.TimeUtil; @@ -21,6 +24,7 @@ import java.math.BigDecimal; import java.time.Instant; import java.time.LocalDate; import java.time.format.DateTimeFormatter; +import java.util.Collection; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; @@ -30,6 +34,7 @@ public class PaymentInstructionBuilderV2 { private ImdgProvider imdgProvider; private Imdg companyImdg; private Imdg companySymbolsImdg; + private Imdg rgsImdg; private final Imdg clearingCategoryImdg; private final Imdg cmpRoleImdg; private Long sessionId; @@ -44,6 +49,8 @@ public class PaymentInstructionBuilderV2 { private Long addresseeId; private boolean useCS_BLKD = false; + private Registry am_b; + public static PaymentInstructionBuilderV2 builder(ImdgProvider imdgProvider) { return new PaymentInstructionBuilderV2(imdgProvider); } @@ -52,12 +59,17 @@ public class PaymentInstructionBuilderV2 { this.imdgProvider = imdgProvider; this.companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); this.companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + this.rgsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Registry, Registry.class); this.clearingCategoryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class); this.cmpRoleImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanyRoleSet, CompanyRoleSet.class); } - public PaymentInstructionBuilderV2 useCS_BLKD(boolean useCS_BLKD) { - this.useCS_BLKD = useCS_BLKD; + public PaymentInstructionBuilderV2 checkBLKD(Registry rgs) { + if (rgs == null) { + return this; + } + this.useCS_BLKD = true; + this.am_b = rgs; return this; } @@ -142,8 +154,8 @@ public class PaymentInstructionBuilderV2 { payment.setSettlementDate(LocalDate.now()); } - if (useCS_BLKD && categoryVInitiator(senderId) && companyRoleODEPPresent(senderId)) { - payment.setPaymentPurpose(SpecifFlag.CS_BLKD.getKey() + " " + purpose); + if (useCS_BLKD && checkAgent()) { + payment.setPaymentPurpose(SpecifFlag.CS_BLKD.getKey() + "_" + sessionId + " " + purpose); } else { payment.setPaymentPurpose(purpose); } @@ -212,6 +224,26 @@ public class PaymentInstructionBuilderV2 { } } + private boolean checkAgent() { + ImdgPredicateBuilder pb = rgsImdg.predicateBuilder(); + ImdgPredicate prdct = pb.and( + pb.equals("sessionId", sessionId), + pb.sql(RegistryCodeSqlBuilder.getInstance(RegistryTradingParams.CM__).build()), + pb.equals("companyId", addresseeId), + pb.equals("accountId", am_b.getAccountId()) + ); + Collection claims = rgsImdg.getCollectionObjectsByPredicate(prdct); + boolean hasCounterPartyInitiator = false; + for (Registry claim : claims) { + Long counterPartyId = claim.getCounterPartyId(); + if (categoryVInitiator(counterPartyId) && companyRoleODEPPresent(counterPartyId)) { + hasCounterPartyInitiator = true; + break; + } + } + return hasCounterPartyInitiator; + } + public boolean categoryVInitiator(Long companyId) { ClearingMemberCategory category = clearingCategoryImdg.getFirstObjectByFieldValues( Map.of("companyId", companyId)); diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf57Executor.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf57Executor.java index c1638189a..372d9b04e 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf57Executor.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/executors/Sdf57Executor.java @@ -48,6 +48,7 @@ import ru.spcex.platform.imdg.api.predicate.specific.RegistryCodeSqlBuilder; import ru.spcex.platform.utils.enumeration.EnumMessage; import ru.spcex.platform.utils.enumeration.IEnumKey; import ru.spcex.platform.utils.enumeration.IMessageResolver; +import ru.spcex.platform.utils.log.ExceptionUtils; import ru.spcex.platform.utils.text.TextUtil; import ru.spcex.platform.utils.validation.IValidator; @@ -62,6 +63,7 @@ import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import java.util.function.Function; +import java.util.regex.Matcher; import java.util.regex.Pattern; import static ru.spcex.platform.enumeration.RegistryTradingParams.D__V; @@ -364,10 +366,11 @@ public class Sdf57Executor extends AbstractExecutor { } else if (TextUtil.isEmpty(sdf57.getSpecif()) || !sdf57.getSpecif().contains(SpecifFlag.CS_BLKD.getKey())) { log.trace("sending gateway request for stmt.id={}", stmt.getId()); - kafka.sendRequestToQueue(Consts.ASSET_OPERATION, - gatewayRequest(stmt, - company.getTradingCode(), - asts.a__t().getTradingClearingRegistry())); + Optional gtwReq = gatewayRequest(stmt, + company, + account, + asts.a__t().getTradingClearingRegistry()); + gtwReq.ifPresent(r -> kafka.sendRequestToQueue(Consts.ASSET_OPERATION, r)); } } return Optional.of(asts); @@ -735,25 +738,56 @@ public class Sdf57Executor extends AbstractExecutor { R apply(T1 arg1, T2 arg2, T3 arg3); } - private AssetOperationListRequest gatewayRequest(Statement stmt, String tradingCode, String tcrCode) { + private static final Pattern csBlkd = Pattern.compile(SpecifFlag.CS_BLKD.getKey() + "_(\\d+).*"); + + private Optional gatewayRequest(Statement stmt, Company company, Account account, String tcrCode) { + if (AccountType.Anlt.equalsByKey(account.getAccountType())) { + return Optional.empty(); + } + String tradingCode = company.getTradingCode(); AssetOperationListRequest gatewayRequest = new AssetOperationListRequest(); AssetOperationRequest req = GatewayRequestCreator.from(stmt, tradingCode, tcrCode); - Session existActiveSession = sessionImdg.getFirstObjectByFieldValues(Map.of( - "workflowStatus", SessionStatus.ACTV.getKey() - )); - if (existActiveSession != null) { - log.debug("active session.id={} type {}", existActiveSession.getId(), existActiveSession.getSessionType()); - List d__vs = assets.searchByParams(stmt.getAccount(), CurrencyCode.RUB.getKey(), stmt.getSenderId(), D__V) - .stream() - .filter(rgs -> existActiveSession.getId().equals(rgs.getSessionId())) - .toList(); - BigDecimal d__vSum = d__vs.stream() - .map(rgs -> safeBD(rgs.getBalance())) - .reduce(BigDecimal.ZERO, BigDecimal::add); - BigDecimal amount = req.getAmount(); - req.setAmount(safeBD(amount).subtract(d__vSum)); + String specif = stmt.getComment(); + + Matcher m; + if (!TextUtil.isEmpty(specif) && (m = csBlkd.matcher(specif)).find()) { + try { + Long sessionId = Long.valueOf(m.group(1)); + List d__vs = assets.searchByParams(account.getAccount(), CurrencyCode.RUB.getKey(), company.getId(), D__V) + .stream() + .filter(rgs -> sessionId.equals(rgs.getSessionId())) + .toList(); + BigDecimal d__vSum = d__vs.stream() + .map(rgs -> safeBD(rgs.getBalance())) + .reduce(BigDecimal.ZERO, BigDecimal::add); + BigDecimal amount = req.getAmount(); + req.setAmount(safeBD(amount).subtract(d__vSum)); + } catch (NumberFormatException e) { + log.error("stmt.id={} failed to parse specif {} {}", + stmt.getId(), + specif, + ExceptionUtils.getStackTrace(e)); + } + } + //Session existActiveSession = sessionImdg.getFirstObjectByFieldValues(Map.of( + // "workflowStatus", SessionStatus.ACTV.getKey() + //)); + //if (existActiveSession != null) { + // log.debug("active session.id={} type {}", existActiveSession.getId(), existActiveSession.getSessionType()); + // List d__vs = assets.searchByParams(stmt.getAccount(), CurrencyCode.RUB.getKey(), stmt.getSenderId(), D__V) + // .stream() + // .filter(rgs -> existActiveSession.getId().equals(rgs.getSessionId())) + // .toList(); + // BigDecimal d__vSum = d__vs.stream() + // .map(rgs -> safeBD(rgs.getBalance())) + // .reduce(BigDecimal.ZERO, BigDecimal::add); + // BigDecimal amount = req.getAmount(); + // req.setAmount(safeBD(amount).subtract(d__vSum)); + //} + if (req.getAmount().compareTo(BigDecimal.ZERO) == 0) { + return Optional.empty(); } gatewayRequest.setAssetOperationRequests(List.of(req)); - return gatewayRequest; + return Optional.of(gatewayRequest); } } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionAssets.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionAssets.java index 30a2b7b47..31304592f 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionAssets.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionAssets.java @@ -215,7 +215,8 @@ public class FormingPaymentInstructionAssets implements ISessionStage { .creditLegAccount(creditLegAccount) .amount(amount) .sessionId(sessionId) - .useCS_BLKD(SessionType.FINL.equals(sessionType) || SessionType.MEDM.equals(sessionType)) + .checkBLKD((SessionType.FINL.equals(sessionType) || SessionType.MEDM.equals(sessionType)) + && !isPositiveBalance ? registry : null) .purpose(String.format("Перевод по итогу клиринга по ТКР %s", registry.getTradingClearingRegistry())); PaymentInstruction paymentInstruction = paymentInstructionBuilder.build(); log.debug("Created paymentInstruction by registry.id: {}", registry.getId()); @@ -282,7 +283,6 @@ public class FormingPaymentInstructionAssets implements ISessionStage { .sender(senderId) .addressee(addresseeId) .debitLegAccount(debitLegAccount) - .useCS_BLKD(SessionType.FINL.equals(sessionType) || SessionType.MEDM.equals(sessionType)) .creditLegAccount(creditLegAccount) .amount(amount) .sessionId(sessionId) diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionSecurities.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionSecurities.java index d7891c4ed..fb11195b2 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionSecurities.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/impl/FormingPaymentInstructionSecurities.java @@ -154,7 +154,7 @@ public class FormingPaymentInstructionSecurities implements ISessionStage { .stream() .collect(Collectors.groupingBy(Registry::getGroupId)); log.debug("groups.size = {}", groups.size()); - Map lstGroups = RegistryLiabilitiesGroup.group(registries); + Map lstGroups = RegistryLiabilitiesGroup.group(groups); for (Map.Entry> group : groups.entrySet()) { Long groupId = group.getKey(); Function findByCode = rgsCode -> group.getValue() diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/payment/group/RegistryLiabilitiesGroup.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/payment/group/RegistryLiabilitiesGroup.java index 96a2bf069..b6934aecc 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/payment/group/RegistryLiabilitiesGroup.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/session/stage/payment/group/RegistryLiabilitiesGroup.java @@ -4,44 +4,56 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ru.clearing.classes.statics.data.registry.Registry; import ru.spcex.clearing.service.registry.RegistryManager; +import ru.spcex.platform.enumeration.RegistryTradingParams; +import ru.spcex.platform.utils.collection.Pair; +import ru.spcex.platform.utils.text.TextUtil; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; +import static ru.spcex.platform.enumeration.RegistryTradingParams.CS_T; import static ru.spcex.platform.enumeration.RegistryTradingParams.LS_T; public class RegistryLiabilitiesGroup { - private Logger log = LoggerFactory.getLogger(getClass()); + private static final Logger log = LoggerFactory.getLogger(RegistryLiabilitiesGroup.class); - public static RegistryLiabilitiesGroup builder() { - return new RegistryLiabilitiesGroup(); - } - - private RegistryLiabilitiesGroup() { - } - - public static Map group(Collection registriesCollection) { + public static Map group(Map> registriesCollection) { Map result = new HashMap<>(); - List registries = registriesCollection + List> lstCstGroup = registriesCollection.entrySet() .stream() - .filter(rgs -> RegistryManager.equalsByCode(LS_T, rgs)) + .map(entry -> { + Long groupId = entry.getKey(); + List value = entry.getValue(); + Registry ls_t = obtain(value, LS_T); + Registry cs_t = obtain(value, CS_T); + if (ls_t == null || cs_t == null) { + log.error("groupId {} registries {} failed to find LS_T/CS_T", groupId, value.stream() + .map(Registry::getId) + .map(Object::toString) + .collect(TextUtil.join)); + return null; + } + return new Pair<>(ls_t, cs_t); + }) .collect(Collectors.toList()); - for (int i = 0; i < registries.size(); i++) { - Registry ls_t = registries.get(i); - if (ls_t == null) { + for (int i = 0; i < lstCstGroup.size(); i++) { + var pair = lstCstGroup.get(i); + if (pair == null) { continue; } + Registry ls_t = pair.getFirst(); LinkedList relatedLiabilities = new LinkedList<>(); relatedLiabilities.add(ls_t); - for (int j = i + 1; j < registries.size(); j++) { - Registry related = registries.get(j); - if (related == null) { + for (int j = i + 1; j < lstCstGroup.size(); j++) { + var anotherGroup = lstCstGroup.get(j); + if (anotherGroup == null) { continue; } - if (rgsOfTheSameAgents(ls_t, related)) { + Registry related = anotherGroup.getFirst(); + if (rgsOfTheSameAgents(pair.getFirst(), pair.getSecond(), anotherGroup.getFirst(), anotherGroup.getSecond())) { relatedLiabilities.add(related); - registries.set(j, null); + lstCstGroup.set(j, null); } } PaymentGroup paymentGroup = new PaymentGroup(); @@ -57,10 +69,25 @@ public class RegistryLiabilitiesGroup { return result; } - private static boolean rgsOfTheSameAgents(Registry ls_t1, Registry ls_t2) { + private static boolean rgsOfTheSameAgents(Registry ls_t1, Registry cs_t1, Registry ls_t2, Registry cs_t2) { return Objects.equals(ls_t1.getSecurityId(), ls_t2.getSecurityId()) && Objects.equals(ls_t1.getTradingClearingRegistryId(), ls_t2.getTradingClearingRegistryId()) + && Objects.equals(cs_t1.getTradingClearingRegistryId(), cs_t2.getTradingClearingRegistryId()) && Objects.equals(ls_t1.getCompanyId(), ls_t2.getCompanyId()) && Objects.equals(ls_t1.getCounterPartyId(), ls_t2.getCounterPartyId()); } + + private static Registry obtain(Collection group, RegistryTradingParams cde) { + List allRegistries = group + .stream() + .filter(rgs -> RegistryManager.equalsByCode(cde, rgs)) + .toList(); + if (allRegistries.size() > 1) { + throw new IllegalStateException("more than one " + cde + " entry in group " + group.iterator().next().getGroupId()); + } + if (allRegistries.size() == 1) { + return allRegistries.iterator().next(); + } + return null; + } } diff --git a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/PlannerAllTodayMaker.java b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/PlannerAllTodayMaker.java index c418c0a4e..bcd617eda 100644 --- a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/PlannerAllTodayMaker.java +++ b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/services/PlannerAllTodayMaker.java @@ -47,9 +47,8 @@ public class PlannerAllTodayMaker { public void makeSchedulerAllTodayMap() { LocalDate currentDate = LocalDate.now(); - List listOfPlannerAllToday = new ArrayList<>(); - if (!plannerMap.isEmpty()) listOfPlannerAllToday.addAll(getPlannersAllTodayToDate(currentDate)); + List listOfPlannerAllToday = getPlannersAllTodayToDate(currentDate); log.info("For today find {} plannerTemplates satisfying rules", listOfPlannerAllToday.size()); plannerMap.values().stream() diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/CSVReportBuilder.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/CSVReportBuilder.java index 6f07fde90..53a3b4243 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/CSVReportBuilder.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/CSVReportBuilder.java @@ -1,12 +1,13 @@ package ru.spcex.clearing.reports.builders; -import com.opencsv.CSVWriterBuilder; +import com.opencsv.CSVWriter; import com.opencsv.ICSVWriter; import com.opencsv.bean.*; import com.opencsv.exceptions.CsvBadConverterException; import com.opencsv.exceptions.CsvChainedException; import com.opencsv.exceptions.CsvFieldAssignmentException; import com.opencsv.exceptions.CsvRequiredFieldEmptyException; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ru.clearing.classes.statics.data.misc.Session; @@ -91,23 +92,6 @@ public abstract class CSVReportBuilder { */ 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('\"'); - return csvWriterBuilder.build(); - } - public File createReport(P params, File outFolder) { assert outFolder != null && outFolder.isDirectory(); @@ -118,10 +102,11 @@ public abstract class CSVReportBuilder { assert rows != null; - try (Writer writer = new FileWriter(reportFile)) { + try (Writer writer = new FileWriter(reportFile); + ICSVWriter icsvWriter = new CustomCSVWriter(writer)) { CustomStrategy customStrategy = new CustomStrategy<>(); customStrategy.setType(getReportClass()); - StatefulBeanToCsv sbc = new StatefulBeanToCsvBuilder(writer) + StatefulBeanToCsv sbc = new StatefulBeanToCsvBuilder(icsvWriter) .withMappingStrategy(customStrategy) .withLineEnd("\n") .withSeparator(',') @@ -160,6 +145,24 @@ public abstract class CSVReportBuilder { return sessionIds.stream().toList(); } + static class CustomCSVWriter extends CSVWriter { + public CustomCSVWriter(Writer writer) { + super(writer); + } + + @Override + protected void writeNext(String[] nextLine, boolean applyQuotesToAll, Appendable appendable) throws IOException { + if (nextLine != null) { + for (int i = 0; i < nextLine.length; i++) { + if (StringUtils.isEmpty(nextLine[i])) { + nextLine[i] = null; + } + } + } + super.writeNext(nextLine, applyQuotesToAll, appendable); + } + } + static class CustomStrategy extends ColumnPositionMappingStrategy { public String[] generateHeader(T bean) throws CsvRequiredFieldEmptyException { super.generateHeader(bean); diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/bean/KSCommissionTradesReport.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/bean/KSCommissionTradesReport.java index 5b3031872..cb6699796 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/bean/KSCommissionTradesReport.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/bean/KSCommissionTradesReport.java @@ -57,6 +57,22 @@ public class KSCommissionTradesReport { @CsvBindByPosition(position = 10) private String execStatus; + @CsvBindByName(column = "TR_ID") + @CsvBindByPosition(position = 11) + private Long trId; + + @CsvBindByName(column = "TKR") + @CsvBindByPosition(position = 12) + private String tkr; + + @CsvBindByName(column = "ACCOUNT") + @CsvBindByPosition(position = 13) + private String account; + + @CsvBindByName(column = "SESSION_ID") + @CsvBindByPosition(position = 14) + private Long sessionId; + public String getFirmId() { return firmId; @@ -145,4 +161,36 @@ public class KSCommissionTradesReport { public void setAgreementSettlementDate(LocalDate agreementSettlementDate) { this.agreementSettlementDate = agreementSettlementDate; } + + public Long getTrId() { + return trId; + } + + public void setTrId(Long trId) { + this.trId = trId; + } + + 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 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/builders/ks/KSCommissionTradesReportBuilder.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/ks/KSCommissionTradesReportBuilder.java index cbb29529f..19f333b62 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/ks/KSCommissionTradesReportBuilder.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/builders/ks/KSCommissionTradesReportBuilder.java @@ -1,6 +1,7 @@ package ru.spcex.clearing.reports.builders.ks; import org.springframework.stereotype.Component; +import ru.clearing.classes.statics.data.account.Account; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.execution.ExecutionDeposit; import ru.clearing.classes.statics.data.registry.Registry; @@ -16,12 +17,12 @@ import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; import ru.spcex.platform.imdg.api.predicate.specific.RegistryCodeSqlBuilder; import ru.spcex.platform.utils.enumeration.IEnumKey; -import java.math.BigDecimal; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; @Component public class KSCommissionTradesReportBuilder extends CSVReportBuilder { @@ -30,6 +31,7 @@ public class KSCommissionTradesReportBuilder extends CSVReportBuilder registryImdg; private final Imdg companyImdg; private final Imdg executionDepositImdg; + private final Imdg accountImdg; private List rows = null; @@ -37,6 +39,7 @@ public class KSCommissionTradesReportBuilder extends CSVReportBuilder 1) log.warn("ExecutionDeposit[exchangeExecutionId = {}].size > 1, use first", registry.getGroupId()); ExecutionDeposit executionDeposit = executionDeposits.iterator().next(); + String account = null; + AccountType accountType = IEnumKey.getEnumByKey(AccountType.class, registry.getAccountType()); + if (accountType == AccountType.Clrn) { + account = registry.getAccount(); + } else if (accountType == AccountType.Info) { + Account accountFromImdg = accountImdg.getFirstObjectByFieldValues(Map.of( + "accountType", AccountType.Anlt.getKey(), + "companyId", 1L + )); + account = accountFromImdg.getAccount(); + } + KSCommissionTradesReport ksCommissionTradesReport = new KSCommissionTradesReport(); ksCommissionTradesReport.setFirmId(firmId); ksCommissionTradesReport.setFirmIdInitiator(firmIdInitiator); @@ -160,10 +184,14 @@ public class KSCommissionTradesReportBuilder extends CSVReportBuilder sessionTypeForValue = Set.of( SessionType.IPOT, SessionType.TRDT, @@ -195,21 +197,35 @@ public class KSRepCashNettoReportBuilder extends CSVReportBuilder groupedRegistry = entry.getValue(); try { if (groupedRegistry.isEmpty()) { - log.warn("Empty LS_T and CS_T registries for {}. Registries with id = [{}] was skipped", - pairRegistryId, - groupedRegistry.stream().map(r -> String.valueOf(r.getId())).collect(Collectors.joining(", ")) + log.warn("Empty LS_T and CS_T registries for {}", + pairRegistryId ); continue; } @@ -110,17 +106,17 @@ public class KSRepDepoNettoReportBuilder extends CSVReportBuilder companyImdg; private final Imdg tradingClearingRegistryImdg; private final Imdg accountImdg; + private final Imdg accountSymbolsImdg; private List rows = null; @@ -48,6 +50,7 @@ public class KSRepTradesReportBuilder extends CSVReportBuilder statusForExecution = new HashMap<>(); executions.forEach(execution -> { if (Set.of("S", "SELL").contains(execution.getSide())) { - String status = ""; + String status = null; if (execution.getCoverageStatus() != null) { Long groupId = execution.getExchangeExecutionId(); String coverageStatus = execution.getCoverageStatus().toUpperCase(); @@ -153,7 +156,7 @@ public class KSRepTradesReportBuilder extends CSVReportBuilder req) throws ValidationException { Objects.requireNonNull(roleForVerification); Long requesterId = req.getUserId(); - if (requesterId != null && !userHasRole(requesterId, roleForVerification)) { - log.trace("User {} has no role to allow this action", requesterId); - throw new ValidationException(roleVerificationError); - } else { + if (requesterId == null) { log.trace("Request without userId"); + } else { + if (!userHasRole(requesterId, roleForVerification)) { + log.trace("User {} has no role to allow this action", requesterId); + throw new ValidationException(roleVerificationError); + } } } public RequestInfoUpdate validateRoleAndGetResult(BaseRequest req) { Objects.requireNonNull(roleForVerification); Long requesterId = req.getUserId(); - if (requesterId != null && !userHasRole(requesterId, roleForVerification)) { - String errMsg = messageResolver.resolve(new EnumMessage(roleVerificationError, requesterId)); - log.info("User {} has no role: {}", requesterId, errMsg); - return new RequestInfoUpdate() - .setId(req.getId()) - .setStatus(ru.spcex.clearing.platform.messaging.service.Status.Error) - .setMessage(errMsg); - } else { + if (requesterId == null) { log.debug("Request without userId"); + } else { + if (!userHasRole(requesterId, roleForVerification)) { + String errMsg = messageResolver.resolve(new EnumMessage(roleVerificationError, requesterId)); + log.info("User {} has no role: {}", requesterId, errMsg); + return new RequestInfoUpdate() + .setId(req.getId()) + .setStatus(ru.spcex.clearing.platform.messaging.service.Status.Error) + .setMessage(errMsg); + } else { + log.trace("Request validateRoleAndGetResult for userId={} success", requesterId); + } } return null; }