diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/ClearingService.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/ClearingService.java index a2c9487a8..a1df6934e 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/ClearingService.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/ClearingService.java @@ -2,6 +2,7 @@ package ru.spcex.clearing.service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; @@ -12,16 +13,19 @@ import java.util.concurrent.Executors; @Service @EnableScheduling -public class ClearingService { +public class ClearingService implements DisposableBean { private final Logger log = LoggerFactory.getLogger(getClass()); private final ExecutorService executor; private final SdfCreatorBySTLDPayment sdfCreator; private final PaymentUpdateBySdf04 paymentUpdater; + private final VerificationResultComponent verificationResultComponent; @Autowired - public ClearingService(SdfCreatorBySTLDPayment sdfCreator, PaymentUpdateBySdf04 paymentUpdater) { + public ClearingService(SdfCreatorBySTLDPayment sdfCreator, PaymentUpdateBySdf04 paymentUpdater, + VerificationResultComponent verificationResultComponent) { this.sdfCreator = sdfCreator; this.paymentUpdater = paymentUpdater; + this.verificationResultComponent = verificationResultComponent; this.executor = Executors.newSingleThreadExecutor(); } @@ -35,4 +39,14 @@ public class ClearingService { log.info("updating payment.transactionStatus by sdf04 task added to queue"); executor.execute(() -> paymentUpdater.updatePayments(sdf04GroupId)); } + + public void executeVerification() { + log.info("execute verification"); + executor.execute(() -> verificationResultComponent.executeRevision()); + } + + @Override + public void destroy() throws Exception { + executor.shutdown(); + } } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/EventsReceiver.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/EventsReceiver.java index bd4bfef11..f7911379f 100644 --- a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/EventsReceiver.java +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/EventsReceiver.java @@ -28,6 +28,9 @@ public class EventsReceiver extends QueueConsumer implements InitializingBean { callback(LauncherCommandRequest.class) .setConsumer(event -> clearingService.sdfCreate()) .forDestination(Task.createOrder.topic(), callbacks::put); + callback(LauncherCommandRequest.class) + .setConsumer(event -> clearingService.executeVerification()) + .forDestination(Task.getVerification.topic(), callbacks::put); init(); } } diff --git a/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/VerificationResultComponent.java b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/VerificationResultComponent.java new file mode 100644 index 000000000..09df1cc26 --- /dev/null +++ b/clearing-parent/clearing-service/src/main/java/ru/spcex/clearing/service/VerificationResultComponent.java @@ -0,0 +1,301 @@ +package ru.spcex.clearing.service; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; +import ru.clearing.classes.objects.BusinessObject; +import ru.clearing.classes.statics.data.account.Account; +import ru.clearing.classes.statics.data.sdf.SDf01; +import ru.clearing.classes.statics.data.account.AccountBalance; +import ru.clearing.classes.statics.data.sdf.SDf03; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.platform.classes.base.interfaces.WithId; +import ru.spcex.platform.enumeration.AccountType; +import ru.spcex.platform.enumeration.ResultStatuses; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; + +import java.math.BigDecimal; +import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * 1.70. verificationResult - Результаты сверки + * Раздел I - Функционал сверок + */ +@Component +public class VerificationResultComponent { + private final Logger log = LoggerFactory.getLogger(getClass()); + + // private final ImdgProvider imdgProvider; + private Imdg sdf01Imdg; + private Imdg accountBalanceImdg; + private Imdg accountImdg; + + + @Autowired + public VerificationResultComponent(ImdgProvider imdgProvider + ) { +// this.imdgProvider = imdgProvider; + this.sdf01Imdg = imdgProvider.getImdg(IMDGDistributedNames.Map_SDf01, SDf01.class); + this.accountBalanceImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_AccountBalance, AccountBalance.class); + this.accountImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Account, Account.class); + + //this.idGenerator = imdgProvider.getImdgIdGenerator(); + //this.kafkaSender = KafkaSender kafkaSender + } + + protected void executeRevision() { + Collection allSDf01 = sdf01Imdg.getAllValues(); + Collection allAccountBalance = accountBalanceImdg.getAllValues(); + Collection allAccount = accountImdg.getAllValues(); + executeRevision(allSDf01, allAccountBalance, allAccount); + + //todo результат logic... см. как было в корпе? + } + + protected void executeRevision(Collection allSDf01, Collection allAccountBalance, Collection allAccount) { + // 1. Сумму по остаткам + List vResLst = new ArrayList<>(); + /* todo use: + + + + + + + + + + + + + + + */ + { + Map indexSDf01 = index(allSDf01, SDf01::getAccount); + for (AccountBalance account : allAccountBalance) { + VerificationResult vResult = new VerificationResult(); + vResult.setAccountId(account.getAccountId()); + + SDf01 document = indexSDf01.get(account.getAccount()); + if (document == null) { + log.warn("s_df01 not found by AccountBalance[{}].account=\"{}\"", account.getId(), account.getAccount()); + } else { + BigDecimal remainder = BigDecimal.ZERO; + if (document.getRemainder() != null) { + try { + remainder = new BigDecimal(document.getRemainder()); + } catch (NumberFormatException nfe) { + log.warn("SDf01[{}].remainder=\"{}\" is not parseable: {}", + document.getId(), document.getRemainder(), nfe.getMessage()); + } + } + BigDecimal balance = account.getCloseBalanceAmount() == null ? BigDecimal.ZERO : account.getCloseBalanceAmount(); + //todo сравнить правильно, remainder там без точек. remainder==balance + BigDecimal diff = balance.subtract(remainder).abs(); + vResult.setDiffSum(diff); + if (BigDecimal.ZERO.compareTo(diff) == 0) { + vResult.setResultStatus(ResultStatuses.success.getKey()); + } else { + vResult.setResultStatus(ResultStatuses.notSuccess.getKey()); + } + } + } + } + + // 2.1 Номера торговых/клиринговых счетов, соответствующие загруженным в КС + // -sDf01.deal = account.account & accountType=CLRN & accountStatus=UNBL + { +// Map indexSDf01 = index(allSDf01, SDf01::getDeal); + Set sDf01Keys = allSDf01.stream() + .filter(sdf01 -> sdf01.getDeal() != null) + .map(sdf01 -> sdf01.getDeal()) + .collect(Collectors.toSet()); + Set accountKeys = allAccount.stream() + .filter(account -> AccountType.Clrn.equalsByKey(account.getAccountType()) && "UNBL".equals(account.getAccountStatus())) + .map(sdf01 -> sdf01.getAccount()) + .collect(Collectors.toSet()); + boolean isOk = sDf01Keys.size() == accountKeys.size() && + sDf01Keys.containsAll(accountKeys) && accountKeys.containsAll(sDf01Keys); +// for (Account account:allAccount) { +// if (AccountType.Clrn.equalsByKey(account.getAccountType()) & "UNBL".equals(account.getAccountStatus())) { +// // todo use enum/const ? +// SDf01 document = indexSDf01.get(account.getAccount()); +// if (document == null) { +// //todo найдено несоответствие. +// } else { +// } +// } +// } + } + + // 2.2 Количество торговых/клиринговых счетов, соответствующие загруженным в КС - COUNT[sDf01.deal] = COUNT [account.account] + { + long countSDf01 = allSDf01.stream().filter(sDf01 -> sDf01.getDeal() != null).count(); + long countAccount = allAccount.stream().filter(account -> account.getAccount() != null).count(); + log.info("countSDf01={}, countAccount={}", countSDf01 ,countAccount); + //todo countSDf01 != countAccount + } + + // 2.3 Суммарный остаток по счетам + { + //todo не понял условия [sDf01.account = accountBalance.account] + long summSDf01 = 0; + for (SDf01 document : allSDf01) { + if (StringUtils.isEmpty(document.getRemainder())) { + try { + long value = Long.parseLong(document.getRemainder()); + summSDf01 += value; + } catch (NumberFormatException nfe) { + log.warn("SDf01[{}].remainder=\"{}\" is not parseable: {}", + document.getId(), document.getRemainder(), nfe.getMessage()); + } + } else { + log.debug("SDf01[{}].remainder is null or empty", document.getId()); + } + } + long summAccount = 0; + for (AccountBalance account : allAccountBalance) { + if (account.getCloseBalanceAmount() != null) { + long value = account.getCloseBalanceAmount().longValue(); + summAccount += value; + } + } + // todo summSDf01==summAccount теперь с точностью и погрешностью сравнений проблема. + } + + // 3. Сверка остатков по клиринговым счетам СПВБ + { + //todo не понял [sDf01.account = accountBalance.account & accountType=INFO] + } + } + + + protected void onSuccessRevisionResult() { + //todo 17.1 - Сообщение пользователю об успешной сверке + } + + protected void onDetectDiffRevisionResult() { + //todo 17.2 - Сообщение пользователю в случае выявления расхождений + } + + /* + Сумму по остаткам в бизнес-объекте accountBalance - sDf01.remainder = accountBalance.closeBalanceAmount [sDf01.account = accountBalance.account] + 2. Расчет контрольных сумм: + 2.1 Номера торговых/клиринговых счетов, соответствующие загруженным в КС -sDf01.deal = account.account & accountType=CLRN & accountStatus=UNBL + 2.2 Количество торговых/клиринговых счетов, соответствующие загруженным в КС - COUNT[sDf01.deal] = COUNT [account.account] + 2.3 Суммарный остаток по счетам - ∑sDf01.remainder = ∑accountBalance.closeBalanceAmount[sDf01.account = accountBalance.account] + 3. Сверка остатков по клиринговым счетам СПВБ в бизнес-объекте accountBalance - sDf01.remainder = accountBalance.closeBalanceAmount [sDf01.account = accountBalance.account & accountType=INFO] + */ + + + Map index(Collection from, Function indexFieldExtractor) { + Map index = new HashMap<>(); + for (V obj : from) { + K key = indexFieldExtractor.apply(obj); + V exist = index.put(key, obj); + if (exist != null) { + log.warn("{} with id={},{} has duplicate Account=\"{}\"", + exist.getClass().getSimpleName(), exist.getId(), obj.getId(), key); + } + } + return index; + } + + //todo to classes: VerificationResult! + static class VerificationResult extends BusinessObject { + private String clearingCode; // type="2" + private Long accountId; // type="1" + private BigDecimal inSum; // type="11" + private BigDecimal outIntSum; // type="11" + private BigDecimal outExtSum; // type="11" + private BigDecimal diffSum; // type="11" + private Long generationId; // type="1" + private String generationStatus; // type="12" + private String resultStatus; // type="12" + + public String getClearingCode() { + return clearingCode; + } + + public void setClearingCode(String clearingCode) { + this.clearingCode = clearingCode; + } + + public Long getAccountId() { + return accountId; + } + + public void setAccountId(Long accountId) { + this.accountId = accountId; + } + + public BigDecimal getInSum() { + return inSum; + } + + public void setInSum(BigDecimal inSum) { + this.inSum = inSum; + } + + public BigDecimal getOutIntSum() { + return outIntSum; + } + + public void setOutIntSum(BigDecimal outIntSum) { + this.outIntSum = outIntSum; + } + + public BigDecimal getOutExtSum() { + return outExtSum; + } + + public void setOutExtSum(BigDecimal outExtSum) { + this.outExtSum = outExtSum; + } + + public BigDecimal getDiffSum() { + return diffSum; + } + + public void setDiffSum(BigDecimal diffSum) { + this.diffSum = diffSum; + } + + public Long getGenerationId() { + return generationId; + } + + public void setGenerationId(Long generationId) { + this.generationId = generationId; + } + + public String getGenerationStatus() { + return generationStatus; + } + + public void setGenerationStatus(String generationStatus) { + this.generationStatus = generationStatus; + } + + public String getResultStatus() { + return resultStatus; + } + + public void setResultStatus(String resultStatus) { + this.resultStatus = resultStatus; + } + } + +} diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/ReportsServiceApplication.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/ReportsServiceApplication.java index c12ab17d1..643b8f596 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/ReportsServiceApplication.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/ReportsServiceApplication.java @@ -6,6 +6,7 @@ import org.slf4j.LoggerFactory; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.context.ConfigurableApplicationContext; +import ru.spcex.clearing.reports.reports.AbstractReport; import ru.spcex.clearing.reports.services.ReportDataCollector; import ru.spcex.clearing.reports.services.ReportsService; import ru.spcex.clearing.reports.services.builders.XMLReportBuilder; @@ -29,12 +30,13 @@ public class ReportsServiceApplication { log.info("Run generate report."); Map allReports = context.getBeansOfType(ReportDataCollector.class); log.info("Report types: {}", allReports); - for (ReportDataCollector collector:allReports.values()) { + for (ReportDataCollector collector : allReports.values()) { log.info("Make report {}", collector); - XMLReportBuilder xmlReportBuilder = new XMLReportBuilder(collector.getReportClass(), collector); + XMLReportBuilder xmlReportBuilder = new XMLReportBuilder(collector.getReportClass()); LocalDate date2 = LocalDate.now(); LocalDate date1 = LocalDate.of(date2.getYear(), date2.getMonth(), 1);//date2.minusMonths(1); - xmlReportBuilder.createReport(date1, date2); + AbstractReport report = collector.collectReportWithPeriod(date1, date2); + xmlReportBuilder.createReport(report); } log.info("Shutdown application after work"); context.close(); // todo если будет запущен как сервис, сделать выход опционально, по другому. diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/notifications/NotificationBuilder.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/notifications/NotificationBuilder.java new file mode 100644 index 000000000..56cdad6b8 --- /dev/null +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/notifications/NotificationBuilder.java @@ -0,0 +1,64 @@ +package ru.spcex.clearing.reports.notifications; + +import ru.spcex.clearing.reports.exceptions.ConfigException; +import ru.spcex.clearing.reports.services.DOCXService; + +import java.io.File; +import java.net.URL; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.TextStyle; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +public abstract class NotificationBuilder { + protected final DateTimeFormatter filenameDateTimeFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy'T'HH:mm:ss"); + protected final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy"); + protected final DOCXService docxService; + + protected NotificationBuilder(String keyPattern) { + this.docxService = new DOCXService(); + if (!docxService.init(getTemplateFile(), keyPattern)) + throw new ConfigException("Can't create NotificationBuilder: docxService not initialized"); + } + + abstract public File buildNotification(Long consumerId); + + protected void fillHeaderValues(Map valuesMap, Long notificationId) { + LocalDate notificationDate = LocalDate.now(); + int day = notificationDate.getDayOfMonth(); + int month = notificationDate.getMonthValue(); + int year = notificationDate.getYear(); + String dateStr = "%04d%02d%02d".formatted(year, month, day); + + valuesMap.put("${dateStr}", dateStr); + valuesMap.put("${count}", String.valueOf(notificationId)); + valuesMap.put("${currDay}", "%02d".formatted(day)); + valuesMap.put("${currMonth}", notificationDate.getMonth().getDisplayName(TextStyle.FULL, new Locale("ru"))); + valuesMap.put("${currYear}", "%02d".formatted(year % 100)); + + } + + protected File getTemplateFile() { + File templateFile; + String templateResourceName = getTemplateResourceName(); + try { + URL resource = getClass().getClassLoader().getResource(templateResourceName); + if (resource == null) throw new Exception(); + templateFile = new File(resource.toURI()); + } catch (Exception e) { + throw new ConfigException("Can't read template resource " + templateResourceName, e); + } + return templateFile; + } + + protected String normalizeFilenameForOS(String filename) { + if (System.getProperty("os.name").toLowerCase().contains("windows")) + return filename.replace(":", "_"); + return filename; + } + + abstract protected String getTemplateResourceName(); +} diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/notifications/REXNotificationBuilder.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/notifications/REXNotificationBuilder.java new file mode 100644 index 000000000..b09df0225 --- /dev/null +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/notifications/REXNotificationBuilder.java @@ -0,0 +1,95 @@ +package ru.spcex.clearing.reports.notifications; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.profile.ProfileDocument; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; + +import java.io.File; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.TextStyle; +import java.util.*; + +@Component +public class REXNotificationBuilder extends NotificationBuilder { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final Imdg profileDocumentImdg; + private final Imdg companyImdg; + + public REXNotificationBuilder(ImdgProvider imdgProvider) { + super(null); + profileDocumentImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ProfileDocument, ProfileDocument.class); + companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + } + + @Override + public File buildNotification(Long consumerId) { + String sql = "companyId = %d AND documentType = 'XCNT'".formatted(consumerId); + Collection profileDocuments = profileDocumentImdg.getCollectionObjectsBySQL(sql); + ProfileDocument currentProfileDocument = null; + if (profileDocuments.size() >= 1) { + Optional profileDocumentOptional = profileDocuments.stream().max((o1, o2) -> { + LocalDate o1ValidFromDate = o1.getValidFromDate(); + LocalDate o2ValidFromDate = o2.getValidFromDate(); + o1ValidFromDate = o1ValidFromDate == null ? LocalDate.MIN : o1ValidFromDate; + o2ValidFromDate = o2ValidFromDate == null ? LocalDate.MIN : o2ValidFromDate; + return o1ValidFromDate.compareTo(o2ValidFromDate); + }); + currentProfileDocument = profileDocumentOptional.get(); + } else { + log.warn("Profile_document with sql {} not found", sql); + return null; + } + + Long notificationId = currentProfileDocument.getId(); + LocalDate validFromDate = currentProfileDocument.getValidFromDate(); + if (validFromDate == null) { + log.error("validFromDate is null for profile_document {}", currentProfileDocument); + return null; + } + Long companyId = currentProfileDocument.getCompanyId(); + if (companyId == null) { + log.error("companyId is null for profile_document {}", currentProfileDocument); + return null; + } + Company company = companyImdg.getSingleObjectByID(companyId); + if (company == null) { + log.error("Company for companyId={} is null", companyId); + return null; + } + String companyClearingCode = company.getClearingCode(); + if (StringUtils.isBlank(companyClearingCode)) { + log.error("Company.clearing_code for companyId={} is null", companyId); + return null; + } + + Map valuesForTemplate = new HashMap<>(); + fillHeaderValues(valuesForTemplate, notificationId); + valuesForTemplate.put("${validFromDate}", dateFormatter.format(validFromDate)); + + String outputFilename = "REX.%s.%s.docx".formatted(companyClearingCode, filenameDateTimeFormatter.format(LocalDateTime.now())); + outputFilename = normalizeFilenameForOS(outputFilename); + + File outputFile = new File(outputFilename); + try { + docxService.insertValues(outputFile, valuesForTemplate, true); + } catch (Exception e) { + log.error("Can't insert values into template.", e); + return null; + } + + return outputFile; + } + + @Override + protected String getTemplateResourceName() { + return "templates/REX_TEMPLATE.docx"; + } + +} diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/notifications/ROOT_ACTV_NotificationBuilder.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/notifications/ROOT_ACTV_NotificationBuilder.java new file mode 100644 index 000000000..b09813c5d --- /dev/null +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/notifications/ROOT_ACTV_NotificationBuilder.java @@ -0,0 +1,103 @@ +package ru.spcex.clearing.reports.notifications; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import ru.clearing.classes.objects.BusinessObject; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.company.CompanySymbols; +import ru.clearing.classes.statics.data.company.relation.Relation; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; + +import java.io.File; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.TextStyle; +import java.util.*; + +@Component +public class ROOT_ACTV_NotificationBuilder extends NotificationBuilder { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final Imdg companyImdg; + private final Imdg relationImdg; + private final Imdg companySymbolsImdg; + + public ROOT_ACTV_NotificationBuilder(ImdgProvider imdgProvider) { + super(null); + companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + relationImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); + companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + } + + @Override + public File buildNotification(Long consumerId) { + Company company = companyImdg.getSingleObjectByID(consumerId); + if (company == null) { + log.error("Company for companyId={} is null", consumerId); + return null; + } + String companyClearingCode = company.getClearingCode(); + if (StringUtils.isBlank(companyClearingCode)) { + log.error("Company.clearing_code for companyId={} is null", consumerId); + return null; + } + + String relationsSql = "consumerId = %d".formatted(consumerId); + Relation relation = null; + Collection relations = relationImdg.getCollectionObjectsBySQL(relationsSql); + if (relations.size() >= 1) { + Optional relationOptional = relations.stream().max(Comparator.comparing(BusinessObject::getUpdated)); + relation = relationOptional.get(); + } else { + log.warn("Relation with sql {} not found", relationsSql); + return null; + } + Long notificationId = relation.getId(); + Instant updatedAt = relation.getUpdated(); + if (updatedAt == null) { + log.error("updated_at is null for relation {}", relation); + return null; + } + + String companySymbolsSql = "companyId = %d AND companySymbol = INN"; + CompanySymbols companySymbols = null; + Collection companySymbolsCollection = companySymbolsImdg.getCollectionObjectsBySQL(companySymbolsSql); + if (companySymbolsCollection.size() >= 1) { + companySymbols = companySymbolsCollection.iterator().next(); + } else { + log.warn("CompanySymbols with sql {} not found", companySymbolsSql); + return null; + } + + Map valuesForTemplate = new HashMap<>(); + fillHeaderValues(valuesForTemplate, notificationId); + valuesForTemplate.put("${companyFullName}", company.getFullName()); + valuesForTemplate.put("${companySymbolsINN}", companySymbols.getCompanySymbolValue()); + valuesForTemplate.put("${companyClearingCode}", companyClearingCode); + valuesForTemplate.put("${relationUpdatedAt}", dateFormatter.format(updatedAt.atZone(ZoneId.systemDefault()).toLocalDate())); + + String outputFilename = "ROOT.ACTV.%s.%s.docx".formatted(companyClearingCode, filenameDateTimeFormatter.format(LocalDateTime.now())); + outputFilename = normalizeFilenameForOS(outputFilename); + + File outputFile = new File(outputFilename); + try { + docxService.insertValues(outputFile, valuesForTemplate, true); + } catch (Exception e) { + log.error("Can't insert values into template.", e); + return null; + } + + return outputFile; + } + + @Override + protected String getTemplateResourceName() { + return "templates/ROOT.ACTV_TEMPLATE.docx"; + } + +} diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/notifications/ROOT_BLKD_NotificationBuilder.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/notifications/ROOT_BLKD_NotificationBuilder.java new file mode 100644 index 000000000..f16848526 --- /dev/null +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/notifications/ROOT_BLKD_NotificationBuilder.java @@ -0,0 +1,103 @@ +package ru.spcex.clearing.reports.notifications; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import ru.clearing.classes.objects.BusinessObject; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.company.CompanySymbols; +import ru.clearing.classes.statics.data.company.relation.Relation; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; + +import java.io.File; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.TextStyle; +import java.util.*; + +@Component +public class ROOT_BLKD_NotificationBuilder extends NotificationBuilder { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final Imdg companyImdg; + private final Imdg relationImdg; + private final Imdg companySymbolsImdg; + + public ROOT_BLKD_NotificationBuilder(ImdgProvider imdgProvider) { + super(null); + companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + relationImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); + companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + } + + @Override + public File buildNotification(Long consumerId) { + Company company = companyImdg.getSingleObjectByID(consumerId); + if (company == null) { + log.error("Company for companyId={} is null", consumerId); + return null; + } + String companyClearingCode = company.getClearingCode(); + if (StringUtils.isBlank(companyClearingCode)) { + log.error("Company.clearing_code for companyId={} is null", consumerId); + return null; + } + + String relationsSql = "consumerId = %d".formatted(consumerId); + Relation relation = null; + Collection relations = relationImdg.getCollectionObjectsBySQL(relationsSql); + if (relations.size() >= 1) { + Optional relationOptional = relations.stream().max(Comparator.comparing(BusinessObject::getUpdated)); + relation = relationOptional.get(); + } else { + log.warn("Relation with sql {} not found", relationsSql); + return null; + } + Long notificationId = relation.getId(); + Instant updatedAt = relation.getUpdated(); + if (updatedAt == null) { + log.error("updated_at is null for relation {}", relation); + return null; + } + + String companySymbolsSql = "companyId = %d AND companySymbol = INN"; + CompanySymbols companySymbols = null; + Collection companySymbolsCollection = companySymbolsImdg.getCollectionObjectsBySQL(companySymbolsSql); + if (companySymbolsCollection.size() >= 1) { + companySymbols = companySymbolsCollection.iterator().next(); + } else { + log.warn("CompanySymbols with sql {} not found", companySymbolsSql); + return null; + } + + Map valuesForTemplate = new HashMap<>(); + fillHeaderValues(valuesForTemplate, notificationId); + valuesForTemplate.put("${companyFullName}", company.getFullName()); + valuesForTemplate.put("${companySymbolsINN}", companySymbols.getCompanySymbolValue()); + valuesForTemplate.put("${companyClearingCode}", companyClearingCode); + valuesForTemplate.put("${relationUpdatedAt}", dateFormatter.format(updatedAt.atZone(ZoneId.systemDefault()).toLocalDate())); + + String outputFilename = "ROOT.BLKD.%s.%s.docx".formatted(companyClearingCode, filenameDateTimeFormatter.format(LocalDateTime.now())); + outputFilename = normalizeFilenameForOS(outputFilename); + + File outputFile = new File(outputFilename); + try { + docxService.insertValues(outputFile, valuesForTemplate, true); + } catch (Exception e) { + log.error("Can't insert values into template.", e); + return null; + } + + return outputFile; + } + + @Override + protected String getTemplateResourceName() { + return "templates/ROOT.BLKD_TEMPLATE.docx"; + } + +} diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/notifications/ROOT_CLOS_NotificationBuilder.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/notifications/ROOT_CLOS_NotificationBuilder.java new file mode 100644 index 000000000..2ac7b9083 --- /dev/null +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/notifications/ROOT_CLOS_NotificationBuilder.java @@ -0,0 +1,112 @@ +package ru.spcex.clearing.reports.notifications; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.company.CompanySymbols; +import ru.clearing.classes.statics.data.profile.ProfileDocument; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; + +import java.io.File; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.TextStyle; +import java.util.*; + +@Component +public class ROOT_CLOS_NotificationBuilder extends NotificationBuilder { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final Imdg profileDocumentImdg; + private final Imdg companyImdg; + private final Imdg companySymbolsImdg; + + public ROOT_CLOS_NotificationBuilder(ImdgProvider imdgProvider) { + super(null); + profileDocumentImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ProfileDocument, ProfileDocument.class); + companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + } + + @Override + public File buildNotification(Long consumerId) { + String sql = "companyId = %d AND documentType = 'CNTR'".formatted(consumerId); + Collection profileDocuments = profileDocumentImdg.getCollectionObjectsBySQL(sql); + ProfileDocument currentProfileDocument = null; + if (profileDocuments.size() >= 1) { + Optional profileDocumentOptional = profileDocuments.stream().max((o1, o2) -> { + LocalDate o1ValidFromDate = o1.getValidFromDate(); + LocalDate o2ValidFromDate = o2.getValidFromDate(); + o1ValidFromDate = o1ValidFromDate == null ? LocalDate.MIN : o1ValidFromDate; + o2ValidFromDate = o2ValidFromDate == null ? LocalDate.MIN : o2ValidFromDate; + return o1ValidFromDate.compareTo(o2ValidFromDate); + }); + currentProfileDocument = profileDocumentOptional.get(); + } else { + log.warn("Profile_document with sql {} not found", sql); + return null; + } + + Long notificationId = currentProfileDocument.getId(); + LocalDate validFromDate = currentProfileDocument.getValidFromDate(); + if (validFromDate == null) { + log.error("validFromDate is null for profile_document {}", currentProfileDocument); + return null; + } + Long companyId = currentProfileDocument.getCompanyId(); + if (companyId == null) { + log.error("companyId is null for profile_document {}", currentProfileDocument); + return null; + } + Company company = companyImdg.getSingleObjectByID(companyId); + if (company == null) { + log.error("Company for companyId={} is null", companyId); + return null; + } + String companyClearingCode = company.getClearingCode(); + if (StringUtils.isBlank(companyClearingCode)) { + log.error("Company.clearing_code for companyId={} is null", companyId); + return null; + } + + String companySymbolsSql = "companyId = %d AND companySymbol = INN"; + CompanySymbols companySymbols = null; + Collection companySymbolsCollection = companySymbolsImdg.getCollectionObjectsBySQL(companySymbolsSql); + if (companySymbolsCollection.size() >= 1) { + companySymbols = companySymbolsCollection.iterator().next(); + } else { + log.warn("CompanySymbols with sql {} not found", companySymbolsSql); + return null; + } + + Map valuesForTemplate = new HashMap<>(); + fillHeaderValues(valuesForTemplate, notificationId); + valuesForTemplate.put("${companyFullName}", company.getFullName()); + valuesForTemplate.put("${companySymbolsINN}", companySymbols.getCompanySymbolValue()); + valuesForTemplate.put("${companyClearingCode}", companyClearingCode); + valuesForTemplate.put("${profileDocumentNumber}", currentProfileDocument.getNumber()); + valuesForTemplate.put("${validFromDate}", dateFormatter.format(validFromDate)); + + String outputFilename = "ROOT.CLOS.%s.%s.docx".formatted(companyClearingCode, filenameDateTimeFormatter.format(LocalDateTime.now())); + outputFilename = normalizeFilenameForOS(outputFilename); + + File outputFile = new File(outputFilename); + try { + docxService.insertValues(outputFile, valuesForTemplate, true); + } catch (Exception e) { + log.error("Can't insert values into template.", e); + return null; + } + + return outputFile; + } + + @Override + protected String getTemplateResourceName() { + return "templates/ROOT.CLOS_TEMPLATE.docx"; + } + +} diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/notifications/ROOT_NEW_NotificationBuilder.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/notifications/ROOT_NEW_NotificationBuilder.java new file mode 100644 index 000000000..abcfcdd01 --- /dev/null +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/notifications/ROOT_NEW_NotificationBuilder.java @@ -0,0 +1,112 @@ +package ru.spcex.clearing.reports.notifications; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.company.CompanySymbols; +import ru.clearing.classes.statics.data.profile.ProfileDocument; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; + +import java.io.File; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.TextStyle; +import java.util.*; + +@Component +public class ROOT_NEW_NotificationBuilder extends NotificationBuilder { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final Imdg profileDocumentImdg; + private final Imdg companyImdg; + private final Imdg companySymbolsImdg; + + public ROOT_NEW_NotificationBuilder(ImdgProvider imdgProvider) { + super(null); + profileDocumentImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ProfileDocument, ProfileDocument.class); + companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + } + + @Override + public File buildNotification(Long consumerId) { + String sql = "companyId = %d AND documentType = 'CNTR'".formatted(consumerId); + Collection profileDocuments = profileDocumentImdg.getCollectionObjectsBySQL(sql); + ProfileDocument currentProfileDocument = null; + if (profileDocuments.size() >= 1) { + Optional profileDocumentOptional = profileDocuments.stream().max((o1, o2) -> { + LocalDate o1ValidFromDate = o1.getValidFromDate(); + LocalDate o2ValidFromDate = o2.getValidFromDate(); + o1ValidFromDate = o1ValidFromDate == null ? LocalDate.MIN : o1ValidFromDate; + o2ValidFromDate = o2ValidFromDate == null ? LocalDate.MIN : o2ValidFromDate; + return o1ValidFromDate.compareTo(o2ValidFromDate); + }); + currentProfileDocument = profileDocumentOptional.get(); + } else { + log.warn("Profile_document with sql {} not found", sql); + return null; + } + + Long notificationId = currentProfileDocument.getId(); + LocalDate validFromDate = currentProfileDocument.getValidFromDate(); + if (validFromDate == null) { + log.error("validFromDate is null for profile_document {}", currentProfileDocument); + return null; + } + Long companyId = currentProfileDocument.getCompanyId(); + if (companyId == null) { + log.error("companyId is null for profile_document {}", currentProfileDocument); + return null; + } + Company company = companyImdg.getSingleObjectByID(companyId); + if (company == null) { + log.error("Company for companyId={} is null", companyId); + return null; + } + String companyClearingCode = company.getClearingCode(); + if (StringUtils.isBlank(companyClearingCode)) { + log.error("Company.clearing_code for companyId={} is null", companyId); + return null; + } + + String companySymbolsSql = "companyId = %d AND companySymbol = INN"; + CompanySymbols companySymbols = null; + Collection companySymbolsCollection = companySymbolsImdg.getCollectionObjectsBySQL(companySymbolsSql); + if (companySymbolsCollection.size() >= 1) { + companySymbols = companySymbolsCollection.iterator().next(); + } else { + log.warn("CompanySymbols with sql {} not found", companySymbolsSql); + return null; + } + + Map valuesForTemplate = new HashMap<>(); + fillHeaderValues(valuesForTemplate, notificationId); + valuesForTemplate.put("${companyFullName}", company.getFullName()); + valuesForTemplate.put("${companySymbolsINN}", companySymbols.getCompanySymbolValue()); + valuesForTemplate.put("${companyClearingCode}", companyClearingCode); + valuesForTemplate.put("${profileDocumentNumber}", currentProfileDocument.getNumber()); + valuesForTemplate.put("${validFromDate}", dateFormatter.format(validFromDate)); + + String outputFilename = "ROOT.NEW.%s.%s.docx".formatted(companyClearingCode, filenameDateTimeFormatter.format(LocalDateTime.now())); + outputFilename = normalizeFilenameForOS(outputFilename); + + File outputFile = new File(outputFilename); + try { + docxService.insertValues(outputFile, valuesForTemplate, true); + } catch (Exception e) { + log.error("Can't insert values into template.", e); + return null; + } + + return outputFile; + } + + @Override + protected String getTemplateResourceName() { + return "templates/ROOT.NEW_TEMPLATE.docx"; + } + +} diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/notifications/ROOT_SSPD_NotificationBuilder.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/notifications/ROOT_SSPD_NotificationBuilder.java new file mode 100644 index 000000000..eb009a49b --- /dev/null +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/notifications/ROOT_SSPD_NotificationBuilder.java @@ -0,0 +1,102 @@ +package ru.spcex.clearing.reports.notifications; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import ru.clearing.classes.objects.BusinessObject; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.company.CompanySymbols; +import ru.clearing.classes.statics.data.company.relation.Relation; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; + +import java.io.File; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.TextStyle; +import java.util.*; + +@Component +public class ROOT_SSPD_NotificationBuilder extends NotificationBuilder { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final Imdg companyImdg; + private final Imdg relationImdg; + private final Imdg companySymbolsImdg; + + public ROOT_SSPD_NotificationBuilder(ImdgProvider imdgProvider) { + super(null); + companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + relationImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); + companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + } + + @Override + public File buildNotification(Long consumerId) { + Company company = companyImdg.getSingleObjectByID(consumerId); + if (company == null) { + log.error("Company for companyId={} is null", consumerId); + return null; + } + String companyClearingCode = company.getClearingCode(); + if (StringUtils.isBlank(companyClearingCode)) { + log.error("Company.clearing_code for companyId={} is null", consumerId); + return null; + } + + String relationsSql = "consumerId = %d".formatted(consumerId); + Relation relation = null; + Collection relations = relationImdg.getCollectionObjectsBySQL(relationsSql); + if (relations.size() >= 1) { + Optional relationOptional = relations.stream().max(Comparator.comparing(BusinessObject::getUpdated)); + relation = relationOptional.get(); + } else { + log.warn("Relation with sql {} not found", relationsSql); + return null; + } + Long notificationId = relation.getId(); + Instant updatedAt = relation.getUpdated(); + if (updatedAt == null) { + log.error("updated_at is null for relation {}", relation); + return null; + } + + String companySymbolsSql = "companyId = %d AND companySymbol = INN"; + CompanySymbols companySymbols = null; + Collection companySymbolsCollection = companySymbolsImdg.getCollectionObjectsBySQL(companySymbolsSql); + if (companySymbolsCollection.size() >= 1) { + companySymbols = companySymbolsCollection.iterator().next(); + } else { + log.warn("CompanySymbols with sql {} not found", companySymbolsSql); + return null; + } + + Map valuesForTemplate = new HashMap<>(); + fillHeaderValues(valuesForTemplate, notificationId); + valuesForTemplate.put("${companyFullName}", company.getFullName()); + valuesForTemplate.put("${companySymbolsINN}", companySymbols.getCompanySymbolValue()); + valuesForTemplate.put("${companyClearingCode}", companyClearingCode); + valuesForTemplate.put("${relationUpdatedAt}", dateFormatter.format(updatedAt.atZone(ZoneId.systemDefault()).toLocalDate())); + + String outputFilename = "ROOT.SSPD.%s.%s.docx".formatted(companyClearingCode, filenameDateTimeFormatter.format(LocalDateTime.now())); + outputFilename = normalizeFilenameForOS(outputFilename); + + File outputFile = new File(outputFilename); + try { + docxService.insertValues(outputFile, valuesForTemplate, true); + } catch (Exception e) { + log.error("Can't insert values into template.", e); + return null; + } + + return outputFile; + } + + @Override + protected String getTemplateResourceName() { + return "templates/ROOT.SSPD_TEMPLATE.docx"; + } + +} diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/notifications/RRPCNotificationBuilder.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/notifications/RRPCNotificationBuilder.java new file mode 100644 index 000000000..797d6cbfb --- /dev/null +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/notifications/RRPCNotificationBuilder.java @@ -0,0 +1,104 @@ +package ru.spcex.clearing.reports.notifications; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import ru.clearing.classes.objects.BusinessObject; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.company.CompanySymbols; +import ru.clearing.classes.statics.data.company.relation.Relation; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; + +import java.io.File; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.TextStyle; +import java.util.*; + +@Component +public class RRPCNotificationBuilder extends NotificationBuilder { + private final Logger log = LoggerFactory.getLogger(getClass()); + private final Imdg companyImdg; + private final Imdg relationImdg; + private final Imdg companySymbolsImdg; + + public RRPCNotificationBuilder(ImdgProvider imdgProvider) { + super(null); + companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + relationImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Relation, Relation.class); + companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + } + + @Override + public File buildNotification(Long consumerId) { + Company company = companyImdg.getSingleObjectByID(consumerId); + if (company == null) { + log.error("Company for companyId={} is null", consumerId); + return null; + } + String companyClearingCode = company.getClearingCode(); + if (StringUtils.isBlank(companyClearingCode)) { + log.error("Company.clearing_code for companyId={} is null", consumerId); + return null; + } + + String relationsSql = "consumerId = %d".formatted(consumerId); + Relation relation = null; + Collection relations = relationImdg.getCollectionObjectsBySQL(relationsSql); + if (relations.size() >= 1) { + Optional relationOptional = relations.stream().max(Comparator.comparing(BusinessObject::getUpdated)); + relation = relationOptional.get(); + } else { + log.warn("Relation with sql {} not found", relationsSql); + return null; + } + Long notificationId = relation.getId(); + Instant updatedAt = relation.getUpdated(); + if (updatedAt == null) { + log.error("updated_at is null for relation {}", relation); + return null; + } + + String companySymbolsSql = "companyId = %d AND companySymbol = INN"; + CompanySymbols companySymbols = null; + Collection companySymbolsCollection = companySymbolsImdg.getCollectionObjectsBySQL(companySymbolsSql); + if (companySymbolsCollection.size() >= 1) { + companySymbols = companySymbolsCollection.iterator().next(); + } else { + log.warn("CompanySymbols with sql {} not found", companySymbolsSql); + return null; + } + + Map valuesForTemplate = new HashMap<>(); + fillHeaderValues(valuesForTemplate, notificationId); + + valuesForTemplate.put("${relationUpdatedAt}", dateFormatter.format(updatedAt.atZone(ZoneId.systemDefault()).toLocalDate())); + valuesForTemplate.put("${companyFullName}", company.getFullName()); + valuesForTemplate.put("${companyShortName}", company.getShortName()); + valuesForTemplate.put("${companySymbolsINN}", companySymbols.getCompanySymbolValue()); + valuesForTemplate.put("${companyClearingCode}", companyClearingCode); + + String outputFilename = "RRPC.%s.%s.docx".formatted(companyClearingCode, filenameDateTimeFormatter.format(LocalDateTime.now())); + outputFilename = normalizeFilenameForOS(outputFilename); + + File outputFile = new File(outputFilename); + try { + docxService.insertValues(outputFile, valuesForTemplate, true); + } catch (Exception e) { + log.error("Can't insert values into template.", e); + return null; + } + + return outputFile; + } + + @Override + protected String getTemplateResourceName() { + return "templates/RRPC_TEMPLATE.docx"; + } + +} diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/AbstractReport.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/AbstractReport.java index 7f82058a3..8a1293fb1 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/AbstractReport.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/AbstractReport.java @@ -2,6 +2,7 @@ package ru.spcex.clearing.reports.reports; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; +import com.thoughtworks.xstream.annotations.XStreamOmitField; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @@ -13,6 +14,9 @@ public abstract class AbstractReport { protected static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("dd.MM.yyyy"); protected static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("dd.MM.yyyy'T'HH:mm:ss"); + @XStreamOmitField + protected ReportId reportId; + @XStreamAsAttribute @XStreamAlias("version") protected String version; @@ -25,9 +29,11 @@ public abstract class AbstractReport { @XStreamAlias("name") protected String name; - public AbstractReport(String version, + public AbstractReport(ReportId reportId, + String version, String code, String name) { + this.reportId = reportId; this.version = version; this.code = code; this.name = name; diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/ReportId.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/ReportId.java new file mode 100644 index 000000000..d2ac8e468 --- /dev/null +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/ReportId.java @@ -0,0 +1,24 @@ +package ru.spcex.clearing.reports.reports; + +/** + * Идентификаторы отчётов + */ +public enum ReportId {//todo переименовать в соответствии с именами файлов () + PA_BT2_B, PA_BT2_IV, + + BT13_11, BT13_12, + + BT16_5, + + BR_0420315_P1, BR_0420315_P2, + + BR_0420317, + + BR_0420318, + + BR_0420314_P1, BR_0420314_P2, + + BR_0420312_P1, BR_0420312_P2, BR_0420312_P3, BR_0420312_P4, + BR_0420312_P5, BR_0420312_P6, BR_0420312_P7, BR_0420312_P8, + BR_0420312_P9, BR_0420312_P10, +} diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/ReportWithClearingStatus.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/ReportWithClearingStatus.java index e211edeea..e86e5007c 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/ReportWithClearingStatus.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/ReportWithClearingStatus.java @@ -2,7 +2,6 @@ package ru.spcex.clearing.reports.reports; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; -import ru.spcex.clearing.reports.ReportWithPeriod; import java.time.LocalDate; @@ -11,13 +10,14 @@ public abstract class ReportWithClearingStatus extends ReportWithPeriod { @XStreamAlias("clearingStatus") protected String clearingStatus; - public ReportWithClearingStatus(String version, + public ReportWithClearingStatus(ReportId reportId, + String version, String code, String name, LocalDate startDate, LocalDate endDate, String clearingStatus) { - super(version, code, name, startDate, endDate); + super(reportId, version, code, name, startDate, endDate); this.clearingStatus = clearingStatus; } diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/ReportWithPeriod.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/ReportWithPeriod.java similarity index 85% rename from clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/ReportWithPeriod.java rename to clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/ReportWithPeriod.java index 77a00ec6e..2895b8b4b 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/ReportWithPeriod.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/ReportWithPeriod.java @@ -1,9 +1,8 @@ -package ru.spcex.clearing.reports; +package ru.spcex.clearing.reports.reports; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; import com.thoughtworks.xstream.annotations.XStreamConverter; -import ru.spcex.clearing.reports.reports.AbstractReport; import ru.spcex.clearing.reports.xml_test.FormattedLocalDateConverter; import java.time.LocalDate; @@ -24,12 +23,13 @@ public abstract class ReportWithPeriod extends AbstractReport { protected LocalDate endDate; - public ReportWithPeriod(String version, + public ReportWithPeriod(ReportId reportId, + String version, String code, String name, LocalDate startDate, LocalDate endDate) { - super(version, code, name); + super(reportId, version, code, name); this.startDate = startDate; this.endDate = endDate; } diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_12_2/ReportPA_BT2_B.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_12_2/ReportPA_BT2_B.java index ac062d5fb..ff587a3b4 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_12_2/ReportPA_BT2_B.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_12_2/ReportPA_BT2_B.java @@ -2,19 +2,18 @@ package ru.spcex.clearing.reports.reports.bt_12_2; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; -import ru.spcex.clearing.reports.ReportWithPeriod; +import ru.spcex.clearing.reports.reports.ReportId; +import ru.spcex.clearing.reports.reports.ReportWithPeriod; import java.time.LocalDate; import java.time.LocalDateTime; @XStreamAlias("netPositionBank") public class ReportPA_BT2_B extends ReportWithPeriod { - @XStreamAsAttribute @XStreamAlias("clearingMemberCategory") private String clearingMemberCategory; - @XStreamAlias("liabilitiesClaimsAssets_fullName") private String liabilitiesClaimsAssetsFullName; @@ -73,7 +72,8 @@ public class ReportPA_BT2_B extends ReportWithPeriod { String claimsAmount, String liabilitiesAmount, String paymentAmount) { - super("0.0.1", + super(ReportId.PA_BT2_B, + "0.0.1", "BT2", "Отчет по нетто-позиции участника клиринга в секции МКР (Уполномоченный банк)", startDate, diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_12_2/ReportPA_BT2_IV.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_12_2/ReportPA_BT2_IV.java index e10ac91bb..dfae151ed 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_12_2/ReportPA_BT2_IV.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_12_2/ReportPA_BT2_IV.java @@ -2,19 +2,18 @@ package ru.spcex.clearing.reports.reports.bt_12_2; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; -import ru.spcex.clearing.reports.ReportWithPeriod; +import ru.spcex.clearing.reports.reports.ReportId; +import ru.spcex.clearing.reports.reports.ReportWithPeriod; import java.time.LocalDate; import java.time.LocalDateTime; @XStreamAlias("netPositionInitiator") public class ReportPA_BT2_IV extends ReportWithPeriod { - @XStreamAsAttribute @XStreamAlias("clearingMemberCategory") private String clearingMemberCategory; - @XStreamAlias("liabilitiesClaimsAssets_fullName") private String liabilitiesClaimsAssetsFullName; @@ -73,7 +72,8 @@ public class ReportPA_BT2_IV extends ReportWithPeriod { String claimsAmount, String liabilitiesAmount, String paymentAmount) { - super("0.0.1", + super(ReportId.PA_BT2_IV, + "0.0.1", "BT2", "Отчет по нетто-позиции участника клиринга в секции МКР (Вкладчик)", startDate, diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_13/Report_BT13_11.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_13/Report_BT13_11.java index 893c204ab..c2e631be7 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_13/Report_BT13_11.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_13/Report_BT13_11.java @@ -3,6 +3,7 @@ package ru.spcex.clearing.reports.reports.bt_13; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; import ru.spcex.clearing.reports.reports.AbstractReport; +import ru.spcex.clearing.reports.reports.ReportId; import java.time.LocalDate; import java.time.LocalDateTime; @@ -18,7 +19,6 @@ public class Report_BT13_11 extends AbstractReport { @XStreamAlias("time") private LocalTime time; - @XStreamAlias("inDocumentJournal_registrationDate") private String inDocumentJournalRegistrationDate; @@ -74,7 +74,7 @@ public class Report_BT13_11 extends AbstractReport { String inDocumentJournalDossierNumber, String inDocumentJournalComment, String inDocumentJournalReceiptDate) { - super("0.0.1", "BT 13.11", "Журнал Входящих документов"); + super(ReportId.BT13_11, "0.0.1", "BT 13.11", "Журнал Входящих документов"); this.date = date; this.time = time; this.inDocumentJournalRegistrationDate = inDocumentJournalRegistrationDate; diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_13/Report_BT13_12.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_13/Report_BT13_12.java index de765fe63..34a98c0ac 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_13/Report_BT13_12.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_13/Report_BT13_12.java @@ -3,6 +3,7 @@ package ru.spcex.clearing.reports.reports.bt_13; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; import ru.spcex.clearing.reports.reports.AbstractReport; +import ru.spcex.clearing.reports.reports.ReportId; import java.time.LocalDate; import java.time.LocalDateTime; @@ -18,7 +19,6 @@ public class Report_BT13_12 extends AbstractReport { @XStreamAlias("time") private LocalTime time; - @XStreamAlias("outDocumentJournal_registrationDate") private String outDocumentJournalRegistrationDate; @@ -70,41 +70,7 @@ public class Report_BT13_12 extends AbstractReport { String outDocumentJournalAmount, String outDocumentJournalDossierNumber, String outDocumentJournalPostDate) { - super("0.0.1", "BT 13.12", "Журнал Исходящих документов"); - this.date = date; - this.time = time; - this.outDocumentJournalRegistrationDate = outDocumentJournalRegistrationDate; - this.outDocumentJournalRegistrationTime = outDocumentJournalRegistrationTime; - this.outDocumentJournalRegistrationNumber = outDocumentJournalRegistrationNumber; - this.outDocumentJournalDocumentName = outDocumentJournalDocumentName; - this.outDocumentJournalAddress = outDocumentJournalAddress; - this.outDocumentJournalQuantity = outDocumentJournalQuantity; - this.outDocumentJournalClearingCode = outDocumentJournalClearingCode; - this.outDocumentJournalCourierType = outDocumentJournalCourierType; - this.outDocumentJournal_emailDate = outDocumentJournal_emailDate; - this.outDocumentJournalAmount = outDocumentJournalAmount; - this.outDocumentJournalDossierNumber = outDocumentJournalDossierNumber; - this.outDocumentJournalPostDate = outDocumentJournalPostDate; - } - - public Report_BT13_12(String version, - String code, - String name, - LocalDate date, - LocalTime time, - String outDocumentJournalRegistrationDate, - String outDocumentJournalRegistrationTime, - String outDocumentJournalRegistrationNumber, - String outDocumentJournalDocumentName, - String outDocumentJournalAddress, - String outDocumentJournalQuantity, - String outDocumentJournalClearingCode, - String outDocumentJournalCourierType, - String outDocumentJournal_emailDate, - String outDocumentJournalAmount, - String outDocumentJournalDossierNumber, - String outDocumentJournalPostDate) { - super(version, code, name); + super(ReportId.BT13_12, "0.0.1", "BT 13.12", "Журнал Исходящих документов"); this.date = date; this.time = time; this.outDocumentJournalRegistrationDate = outDocumentJournalRegistrationDate; diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_16_5/Report_BT16_5.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_16_5/Report_BT16_5.java index 3dc1d5737..79424f6ed 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_16_5/Report_BT16_5.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_16_5/Report_BT16_5.java @@ -3,6 +3,7 @@ package ru.spcex.clearing.reports.reports.bt_16_5; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; import ru.spcex.clearing.reports.reports.AbstractReport; +import ru.spcex.clearing.reports.reports.ReportId; import java.time.LocalDate; import java.time.LocalDateTime; @@ -57,7 +58,10 @@ public class Report_BT16_5 extends AbstractReport { String accountBalanceDebitAmount, String accountBalanceCreditAmount, String accountBalanceCloseAmount) { - super("0.0.1", "BT 16.5", "Отчет о денежных средствах на счете внутреннего учета (клиринговом регистре) Участника клиринга"); + super(ReportId.BT16_5, + "0.0.1", + "BT 16.5", + "Отчет о денежных средствах на счете внутреннего учета (клиринговом регистре) Участника клиринга"); this.date = date; this.time = time; this.clearingHouse = clearingHouse; diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_1/ReportBR_0420315_P1.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_1/ReportBR_0420315_P1.java index 47600c673..4e39e10ff 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_1/ReportBR_0420315_P1.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_1/ReportBR_0420315_P1.java @@ -2,6 +2,7 @@ package ru.spcex.clearing.reports.reports.bt_17_1; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; +import ru.spcex.clearing.reports.reports.ReportId; import ru.spcex.clearing.reports.reports.ReportWithClearingStatus; import java.time.LocalDate; @@ -28,7 +29,8 @@ public class ReportBR_0420315_P1 extends ReportWithClearingStatus { String destination, String clearingMemberCategory, String clearingStatus) { - super("0.0.1", + super(ReportId.BR_0420315_P1, + "0.0.1", "0420315", "Сведения об исполненных обязательствах, допущенных к клирингу, за отчетный период, часть 1", startDate, diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_1/ReportBR_0420315_P2.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_1/ReportBR_0420315_P2.java index a7c87f98d..8fe84ff00 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_1/ReportBR_0420315_P2.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_1/ReportBR_0420315_P2.java @@ -2,7 +2,8 @@ package ru.spcex.clearing.reports.reports.bt_17_1; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; -import ru.spcex.clearing.reports.ReportWithPeriod; +import ru.spcex.clearing.reports.reports.ReportId; +import ru.spcex.clearing.reports.reports.ReportWithPeriod; import java.time.LocalDate; import java.time.LocalDateTime; @@ -21,7 +22,8 @@ public class ReportBR_0420315_P2 extends ReportWithPeriod { String destination, String contractQty, String liabilitiesAmount) { - super("0.0.1", + super(ReportId.BR_0420315_P2, + "0.0.1", "0420315", "Сведения об исполненных обязательствах, допущенных к клирингу, за отчетный период, часть 2", startDate, diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_2/ReportBR_0420317.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_2/ReportBR_0420317.java index 2357530a0..71ef299a7 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_2/ReportBR_0420317.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_2/ReportBR_0420317.java @@ -2,7 +2,8 @@ package ru.spcex.clearing.reports.reports.bt_17_2; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; -import ru.spcex.clearing.reports.ReportWithPeriod; +import ru.spcex.clearing.reports.reports.ReportId; +import ru.spcex.clearing.reports.reports.ReportWithPeriod; import java.time.LocalDate; import java.time.LocalDateTime; @@ -19,7 +20,8 @@ public class ReportBR_0420317 extends ReportWithPeriod { private final List rows = new ArrayList<>(); public ReportBR_0420317(LocalDate startDate, LocalDate endDate, String destination) { - super("0.0.1", + super(ReportId.BR_0420317, + "0.0.1", "0420317", "Сведения о предоставлении, прекращении, приостановке," + " возобновлении допуска к клиринговому обслуживанию", diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_3/ReportBR_0420318.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_3/ReportBR_0420318.java index 73dc19c81..507b07940 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_3/ReportBR_0420318.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_3/ReportBR_0420318.java @@ -2,6 +2,7 @@ package ru.spcex.clearing.reports.reports.bt_17_3; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; +import ru.spcex.clearing.reports.reports.ReportId; import ru.spcex.clearing.reports.reports.ReportWithClearingStatus; import java.time.LocalDate; @@ -19,7 +20,8 @@ public class ReportBR_0420318 extends ReportWithClearingStatus { private final List rows = new ArrayList<>(); public ReportBR_0420318(LocalDate startDate, LocalDate endDate, String clearingStatus, String destination) { - super("0.0.1", + super(ReportId.BR_0420318, + "0.0.1", "0420318", "Сведения о неисполненных обязательствах", startDate, diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_4/ReportBR_0420314_P1.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_4/ReportBR_0420314_P1.java index 0940041db..a83fb54e9 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_4/ReportBR_0420314_P1.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_4/ReportBR_0420314_P1.java @@ -2,7 +2,10 @@ package ru.spcex.clearing.reports.reports.bt_17_4; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import ru.spcex.clearing.reports.reports.ReportId; import ru.spcex.clearing.reports.reports.ReportWithClearingStatus; +import ru.spcex.clearing.reports.xml_test.FormattedLocalDateConverter; import java.time.LocalDate; import java.time.LocalDateTime; @@ -19,7 +22,8 @@ public class ReportBR_0420314_P1 extends ReportWithClearingStatus { private final List rows = new ArrayList<>(); public ReportBR_0420314_P1(LocalDate startDate, LocalDate endDate, String clearingStatus, String destination) { - super("0.0.1", + super(ReportId.BR_0420314_P1, + "0.0.1", "0420314", "Сведения об УК и операциях, проведенных по торговым счетам, часть 1", startDate, @@ -39,10 +43,6 @@ public class ReportBR_0420314_P1 extends ReportWithClearingStatus { @XStreamAlias("company_clearingCode") protected String companyClearingCode; - @XStreamAsAttribute - @XStreamAlias("paymentInstruction_senderId") - private String paymentInstructionSenderId; - @XStreamAsAttribute @XStreamAlias("profileDocument_id") private String profileDocumentId; @@ -64,31 +64,36 @@ public class ReportBR_0420314_P1 extends ReportWithClearingStatus { private String clearingMemberCategoryClearingMemberCategory; @XStreamAsAttribute - @XStreamAlias("profileDocument_documentTypeAndValidFromDate") - private String profileDocumentDocumentTypeAndValidFromDate; + @XStreamAlias("liabilitiesClaimsAssets_contract") + private String liabilitiesClaimsAssets_contract; @XStreamAsAttribute - @XStreamAlias("liabilitiesClaimsAssets_liabilitiesQuantity") - private String liabilitiesClaimsAssetsLiabilitiesQuantity; + @XStreamAlias("liabilitiesClaimsAssets_tradingDate") + @XStreamConverter(value = FormattedLocalDateConverter.class, strings = {"dd.MM.yyyy"}) + private LocalDate liabilitiesClaimsAssets_tradingDate; + + @XStreamAsAttribute + @XStreamAlias("liabilitiesClaimsAssests_liabilitiesQuantity") + private String liabilitiesClaimsAssests_liabilitiesQuantity; public Info_0420314_P1(String companyClearingCode, - String paymentInstructionSenderId, String profileDocumentId, String companyFullName, String companySymbolCode, String companySymbolValue, String clearingMemberCategoryClearingMemberCategory, - String profileDocumentDocumentTypeAndValidFromDate, - String liabilitiesClaimsAssetsLiabilitiesQuantity) { + String liabilitiesClaimsAssets_contract, + LocalDate liabilitiesClaimsAssets_tradingDate, + String liabilitiesClaimsAssets_comment) { this.companyClearingCode = companyClearingCode; - this.paymentInstructionSenderId = paymentInstructionSenderId; this.profileDocumentId = profileDocumentId; this.companyFullName = companyFullName; this.companySymbolCode = companySymbolCode; this.companySymbolValue = companySymbolValue; this.clearingMemberCategoryClearingMemberCategory = clearingMemberCategoryClearingMemberCategory; - this.profileDocumentDocumentTypeAndValidFromDate = profileDocumentDocumentTypeAndValidFromDate; - this.liabilitiesClaimsAssetsLiabilitiesQuantity = liabilitiesClaimsAssetsLiabilitiesQuantity; + this.liabilitiesClaimsAssets_contract = liabilitiesClaimsAssets_contract; + this.liabilitiesClaimsAssets_tradingDate = liabilitiesClaimsAssets_tradingDate; + this.liabilitiesClaimsAssests_liabilitiesQuantity = liabilitiesClaimsAssests_liabilitiesQuantity; } } diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_4/ReportBR_0420314_P2.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_4/ReportBR_0420314_P2.java index 478698b15..c52189434 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_4/ReportBR_0420314_P2.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_4/ReportBR_0420314_P2.java @@ -2,7 +2,8 @@ package ru.spcex.clearing.reports.reports.bt_17_4; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; -import ru.spcex.clearing.reports.ReportWithPeriod; +import ru.spcex.clearing.reports.reports.ReportId; +import ru.spcex.clearing.reports.reports.ReportWithPeriod; import java.time.LocalDate; import java.time.LocalDateTime; @@ -23,7 +24,8 @@ public class ReportBR_0420314_P2 extends ReportWithPeriod { private final List rows = new ArrayList<>(); public ReportBR_0420314_P2(LocalDate startDate, LocalDate endDate, String transactionStatus, String destination) { - super("0.0.1", + super(ReportId.BR_0420314_P2, + "0.0.1", "0420314", "Сведения об УК и операциях, проведенных по торговым счетам, часть 2", startDate, @@ -43,10 +45,6 @@ public class ReportBR_0420314_P2 extends ReportWithPeriod { @XStreamAlias("company_clearingCode") protected String companyClearingCode; - @XStreamAsAttribute - @XStreamAlias("paymentInstruction_senderId") - private String paymentInstructionSenderId; - @XStreamAsAttribute @XStreamAlias("profileDocument_id") private String profileDocumentId; @@ -68,14 +66,12 @@ public class ReportBR_0420314_P2 extends ReportWithPeriod { private String accountBalanceCloseBalanceAmount; public Info_0420314_P2(String companyClearingCode, - String paymentInstructionSenderId, String profileDocumentId, String accountBalanceOpenBalanceAmount, String paymentInstructionCreditLegAmount, String paymentInstructionDebitLegAmount, String accountBalanceCloseBalanceAmount) { this.companyClearingCode = companyClearingCode; - this.paymentInstructionSenderId = paymentInstructionSenderId; this.profileDocumentId = profileDocumentId; this.accountBalanceOpenBalanceAmount = accountBalanceOpenBalanceAmount; this.paymentInstructionCreditLegAmount = paymentInstructionCreditLegAmount; diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P1.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P1.java index dce10d12a..69be76846 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P1.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P1.java @@ -2,7 +2,8 @@ package ru.spcex.clearing.reports.reports.bt_17_5; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; -import ru.spcex.clearing.reports.ReportWithPeriod; +import ru.spcex.clearing.reports.reports.ReportId; +import ru.spcex.clearing.reports.reports.ReportWithPeriod; import java.time.LocalDate; import java.time.LocalDateTime; @@ -15,14 +16,14 @@ public class ReportBR_0420312_P1 extends ReportWithPeriod { @XStreamAlias("destination") private String destination; - @XStreamAlias("rows") private final List rows = new ArrayList<>(); public ReportBR_0420312_P1(LocalDate startDate, LocalDate endDate, String destination) { - super("0.0.1", + super(ReportId.BR_0420312_P1, + "0.0.1", "0420312", "Сведения о клиринговом обеспечении, часть 1", startDate, @@ -56,6 +57,7 @@ public class ReportBR_0420312_P1 extends ReportWithPeriod { clearingMemberCategoryClearingMemberCategory)); } + @XStreamAlias("rows") public static class Info_0420312_P1 { @XStreamAsAttribute @XStreamAlias("company_clearingCode") diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P10.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P10.java index 0f79fe269..04dc1bc7f 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P10.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P10.java @@ -2,7 +2,8 @@ package ru.spcex.clearing.reports.reports.bt_17_5; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; -import ru.spcex.clearing.reports.ReportWithPeriod; +import ru.spcex.clearing.reports.reports.ReportId; +import ru.spcex.clearing.reports.reports.ReportWithPeriod; import java.time.LocalDate; import java.time.LocalDateTime; @@ -20,7 +21,8 @@ public class ReportBR_0420312_P10 extends ReportWithPeriod { LocalDate endDate, String destination, String liabilitiesAmount) { - super("0.0.5", + super(ReportId.BR_0420312_P10, + "0.0.5", "0420312", "Сведения о клиринговом обеспечении, часть 10", startDate, diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P2.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P2.java index 84dbf562d..4623ebdcf 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P2.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P2.java @@ -2,7 +2,8 @@ package ru.spcex.clearing.reports.reports.bt_17_5; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; -import ru.spcex.clearing.reports.ReportWithPeriod; +import ru.spcex.clearing.reports.reports.ReportId; +import ru.spcex.clearing.reports.reports.ReportWithPeriod; import java.time.LocalDate; import java.time.LocalDateTime; @@ -21,7 +22,8 @@ public class ReportBR_0420312_P2 extends ReportWithPeriod { String destination, String liabilitiesClaimsAssetsCompanyId, String liabilitiesClaimsAssetsLiabilities) { - super("0.0.1", + super(ReportId.BR_0420312_P2, + "0.0.1", "0420312", "Сведения о клиринговом обеспечении, часть 2", startDate, diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P3.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P3.java index 97442b1a9..466573a88 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P3.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P3.java @@ -2,7 +2,8 @@ package ru.spcex.clearing.reports.reports.bt_17_5; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; -import ru.spcex.clearing.reports.ReportWithPeriod; +import ru.spcex.clearing.reports.reports.ReportId; +import ru.spcex.clearing.reports.reports.ReportWithPeriod; import java.time.LocalDate; import java.time.LocalDateTime; @@ -21,7 +22,8 @@ public class ReportBR_0420312_P3 extends ReportWithPeriod { String destination, String liabilitiesClaimsAssetsCompanyId, String liabilitiesClaimsAssetsLiabilities) { - super("0.0.5", + super(ReportId.BR_0420312_P3, + "0.0.5", "0420312", "Сведения о клиринговом обеспечении, часть 3", startDate, diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P4.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P4.java index d4725b978..89aeb0761 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P4.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P4.java @@ -2,7 +2,8 @@ package ru.spcex.clearing.reports.reports.bt_17_5; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; -import ru.spcex.clearing.reports.ReportWithPeriod; +import ru.spcex.clearing.reports.reports.ReportId; +import ru.spcex.clearing.reports.reports.ReportWithPeriod; import java.time.LocalDate; import java.time.LocalDateTime; @@ -20,7 +21,8 @@ public class ReportBR_0420312_P4 extends ReportWithPeriod { LocalDate endDate, String destination, String liabilitiesAmount) { - super("0.0.5", + super(ReportId.BR_0420312_P4, + "0.0.5", "0420312", "Сведения о клиринговом обеспечении, часть 4", startDate, diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P5.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P5.java index 1af1850eb..e3117b3b9 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P5.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P5.java @@ -2,7 +2,8 @@ package ru.spcex.clearing.reports.reports.bt_17_5; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; -import ru.spcex.clearing.reports.ReportWithPeriod; +import ru.spcex.clearing.reports.reports.ReportId; +import ru.spcex.clearing.reports.reports.ReportWithPeriod; import java.time.LocalDate; import java.time.LocalDateTime; @@ -20,7 +21,8 @@ public class ReportBR_0420312_P5 extends ReportWithPeriod { LocalDate endDate, String destination, String liabilitiesAmount) { - super("0.0.5", + super(ReportId.BR_0420312_P5, + "0.0.5", "0420312", "Сведения о клиринговом обеспечении, часть 5", startDate, diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P6.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P6.java index 6b5126f7e..997a7243b 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P6.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P6.java @@ -2,7 +2,8 @@ package ru.spcex.clearing.reports.reports.bt_17_5; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; -import ru.spcex.clearing.reports.ReportWithPeriod; +import ru.spcex.clearing.reports.reports.ReportId; +import ru.spcex.clearing.reports.reports.ReportWithPeriod; import java.time.LocalDate; import java.time.LocalDateTime; @@ -20,7 +21,8 @@ public class ReportBR_0420312_P6 extends ReportWithPeriod { LocalDate endDate, String destination, String liabilitiesAmount) { - super("0.0.5", + super(ReportId.BR_0420312_P6, + "0.0.5", "0420312", "Сведения о клиринговом обеспечении, часть 6", startDate, diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P7.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P7.java index 81b539868..5c7e6523b 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P7.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P7.java @@ -2,7 +2,8 @@ package ru.spcex.clearing.reports.reports.bt_17_5; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; -import ru.spcex.clearing.reports.ReportWithPeriod; +import ru.spcex.clearing.reports.reports.ReportId; +import ru.spcex.clearing.reports.reports.ReportWithPeriod; import java.time.LocalDate; import java.time.LocalDateTime; @@ -20,7 +21,8 @@ public class ReportBR_0420312_P7 extends ReportWithPeriod { LocalDate endDate, String destination, String liabilitiesAmount) { - super("0.0.5", + super(ReportId.BR_0420312_P7, + "0.0.5", "0420312", "Сведения о клиринговом обеспечении, часть 7", startDate, diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P8.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P8.java index 563ffc599..686540b2f 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P8.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P8.java @@ -2,7 +2,8 @@ package ru.spcex.clearing.reports.reports.bt_17_5; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; -import ru.spcex.clearing.reports.ReportWithPeriod; +import ru.spcex.clearing.reports.reports.ReportId; +import ru.spcex.clearing.reports.reports.ReportWithPeriod; import java.time.LocalDate; import java.time.LocalDateTime; @@ -26,7 +27,8 @@ public class ReportBR_0420312_P8 extends ReportWithPeriod { String companySymbolValue, String companyInfoCountryCode, String clearingMemberCategoryClearingMemberCategory) { - super("0.0.5", + super(ReportId.BR_0420312_P8, + "0.0.5", "0420312", "Сведения о клиринговом обеспечении, часть 8", startDate, diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P9.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P9.java index 3438b9d05..5973b8bbc 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P9.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/reports/bt_17_5/ReportBR_0420312_P9.java @@ -2,7 +2,8 @@ package ru.spcex.clearing.reports.reports.bt_17_5; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAsAttribute; -import ru.spcex.clearing.reports.ReportWithPeriod; +import ru.spcex.clearing.reports.reports.ReportId; +import ru.spcex.clearing.reports.reports.ReportWithPeriod; import java.time.LocalDate; import java.time.LocalDateTime; @@ -23,7 +24,8 @@ public class ReportBR_0420312_P9 extends ReportWithPeriod { String liabilitiesClaimsAssetsCompanyId, String liabilitiesClaimsMoneyCurrencyCode, String liabilitiesClaimsAssetsLiabilities) { - super("0.0.5", + super(ReportId.BR_0420312_P9, + "0.0.5", "0420312", "Сведения о клиринговом обеспечении, часть 9", startDate, diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/DOCXService.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/DOCXService.java index 86483a38b..02e1813eb 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/DOCXService.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/DOCXService.java @@ -2,6 +2,7 @@ package ru.spcex.clearing.reports.services; import org.apache.poi.xwpf.usermodel.*; import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.*; import java.util.LinkedList; @@ -10,6 +11,7 @@ import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; import java.util.stream.Collectors; /** @@ -22,58 +24,86 @@ import java.util.stream.Collectors; * идентификатору потом можно установить стиль, который будет применён к вставляемой строке. */ public class DOCXService { + private final Logger log = LoggerFactory.getLogger(getClass()); /** * При инициализации сохраняет все имеющиеся ключи (ищет по маске keyPattern), найденные в текстовых элементах документа */ private List keyPositions = new LinkedList<>(); + /** + * Паттерн поиска ключей в файле по умолчанию + */ + private final Pattern DEFAULT_KEY_PATTERN = Pattern.compile("\\$\\{.*?}"); + /** * Паттерн поиска ключей в файле */ - private Pattern KEY_PATTERN = Pattern.compile("\\$\\{.*?}"); + private Pattern keyPattern = DEFAULT_KEY_PATTERN; + + /** + * Файл шаблона + */ + private File templateFile; + + /** + * Флаг инициализации + */ + private boolean initialized = false; /** * (ре)Инициализация сервиса */ - public void init(String keyPattern) { - KEY_PATTERN = Pattern.compile(keyPattern); + public boolean init(File templateFile, String keyPattern) { + initialized = false; + if (templateFile == null || !templateFile.exists() || !templateFile.isFile()) { + log.warn("Invalid templateFile"); + return false; + } + this.templateFile = templateFile; + if (keyPattern != null) { + try { + this.keyPattern = Pattern.compile(keyPattern); + } catch (PatternSyntaxException e) { + log.warn("Invalid keyPattern"); + return false; + } + } else { + this.keyPattern = DEFAULT_KEY_PATTERN; + } keyPositions = new LinkedList<>(); + initialized = true; + return true; } /** * Вставка значений в шаблон. Шаблон может содержать любое количество ключей, при этом эти ключи должны содержаться в * valuesMap. * - * @param templateFile Файл шаблона * @param outputFile Выходной файл. Должен быть либо файлом (будет перезаписан), либо отсутствовать * @param valuesMap Мапа значений. В файле шаблона будут искаться ключи этой мапы и заменяться на соответствующие значения. - * @param log Если будет передан null, то метод будет выбрасывать исключения. В противном случае будет записан лог и возвращено false * @param checkKeys True - строгий режим, где будет проверено наличие всех ключей из файла в valuesMap. * False - мягкий режим, отсутствующие ключи будут пропущены * * @return true - если вставка прошла успешно */ - public boolean insertValues(File templateFile, - File outputFile, + public boolean insertValues(File outputFile, Map valuesMap, - Logger log, boolean checkKeys) throws Exception { - assert templateFile != null && templateFile.exists() && templateFile.isFile(); + if (!initialized) { + log.warn("DOCXService not initialized"); + return false; + } if (outputFile == null || outputFile.isDirectory()) { - String logMsg = "Can't open output file. Output file: %s".formatted(outputFile == null ? "null" : outputFile.getAbsolutePath()); - if (log == null) throw new Exception(logMsg); - log.error(logMsg); + log.error("Can't open output file. Output file: {}", outputFile == null ? "null" : outputFile.getAbsolutePath()); return false; } if (outputFile.exists()) { - if (log != null) log.warn("Output file {} exist and will be overwritten", outputFile.getAbsolutePath()); + log.warn("Output file {} exist and will be overwritten", outputFile.getAbsolutePath()); boolean deleteOk = outputFile.delete(); if (!deleteOk) { - String logMsg = "Can't delete file %s".formatted(outputFile.getAbsolutePath()); - if (log == null) throw new Exception(logMsg); - log.error(logMsg); + log.error("Can't delete file {}", outputFile.getAbsolutePath()); return false; } } @@ -94,11 +124,9 @@ public class DOCXService { List notPresentInMap = new LinkedList<>(); boolean checkOk = checkIntersection(valuesMap, notPresentInMap); if (!checkOk) { - String logMsg = "Can't insert values in file %s. Keys not in map: %s." - .formatted(templateFile.getAbsolutePath(), - String.join(", ", notPresentInMap)); - if (log == null) throw new Exception(logMsg); - log.error(logMsg); + log.error("Can't insert values in file {}. Keys not in map: {}.", + templateFile.getAbsolutePath(), + String.join(", ", notPresentInMap)); return false; } } @@ -178,7 +206,7 @@ public class DOCXService { for (int currPos = 0; currPos < MAX_POSITION; currPos++) { String currText = run.getText(currPos); if (currText == null) break; - Matcher matcher = KEY_PATTERN.matcher(currText); + Matcher matcher = keyPattern.matcher(currText); while (matcher.find()) { String key = matcher.group(); keyPositions.add(new KeyPositionInDoc(key, run, currPos)); diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/QCommandExecutor.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/QCommandExecutor.java index a093f6eec..3d5e55548 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/QCommandExecutor.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/QCommandExecutor.java @@ -1,27 +1,29 @@ package ru.spcex.clearing.reports.services; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.InitializingBean; -import ru.spcex.clearing.platform.messaging.service.QueueConsumer; - import org.apache.kafka.clients.consumer.Consumer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; import ru.spcex.clearing.platform.messaging.domain.BaseRequest; -import ru.spcex.clearing.platform.messaging.domain.Consts; -//import ru.spcex.clearing.platform.messaging.domain.cud.balance.ExportToFileRequest; todo use class? +import ru.spcex.clearing.platform.messaging.domain.cud.reports.ReportWithPeriodRequest; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; -import ru.spcex.clearing.platform.messaging.service.sender.KafkaSender; +import ru.spcex.clearing.reports.reports.AbstractReport; +import ru.spcex.clearing.reports.reports.ReportId; +import ru.spcex.clearing.reports.services.builders.XMLReportBuilder; import ru.spcex.platform.enumeration.Task; -import ru.spcex.platform.imdg.api.Imdg; -import ru.spcex.platform.imdg.api.ImdgId; import ru.spcex.platform.imdg.api.ImdgProvider; +import java.io.File; +import java.io.IOException; +import java.time.LocalDate; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class QCommandExecutor extends QueueConsumer implements InitializingBean { private final Logger log = LoggerFactory.getLogger(getClass()); + private final Map collectorForReport = new HashMap<>(); + // private final ImdgId idGenerator; // private final KafkaSender kafkaReqProducer; @@ -29,21 +31,46 @@ public class QCommandExecutor extends QueueConsumer implements InitializingBean public QCommandExecutor(Consumer kafkaQueue, ImdgProvider imdgProvider, List listOfCollectors) { super(kafkaQueue); -// todo constructor } @Override public void afterPropertiesSet() { log.debug("Init queue listener {}", getClass().getSimpleName()); -// callback(Object.class) -// .setConsumer(this::newReportDo) -// .forDestination(Task.getVerification!!!.topic(), callbacks::put); // todo здесь надо указать команду из ТЗ или согласовать с фронтэндом -// init(); + callback(ReportWithPeriodRequest.class) + .setConsumer(this::newReportWithPeriod) + .forDestination(Task.createReport.topic(), callbacks::put); } - private void newReportDo(BaseRequest userRequest) { - log.debug("newReportDo request received"); - // todo logic + private void newReportWithPeriod(BaseRequest reportRequest) { + log.debug("newReportWithPeriod request received"); + + ReportWithPeriodRequest request = reportRequest.getRequestPayload(); + + if (request.getReportId() == null || request.getReportId().isBlank()) + throw new IllegalStateException("ReportID is empty"); + ReportId reportId = ReportId.valueOf(request.getReportId()); + ReportDataCollector reportDataCollector = collectorForReport.get(reportId); + if (reportDataCollector == null) + throw new IllegalStateException("Collector for ReportID " + reportId + " not implemented yet"); + + if (request.getStartDate() == null || request.getEndDate() == null) + throw new IllegalStateException("StartDate or EndDate is null"); + LocalDate startDate = request.getStartDate(); + LocalDate endDate = request.getEndDate(); + if (startDate.isAfter(endDate)) throw new IllegalStateException("StartDate > EndDate"); + + XMLReportBuilder reportBuilder = new XMLReportBuilder(reportDataCollector.getReportClass()); + AbstractReport report = reportDataCollector.collectReportWithPeriod(startDate, endDate); + File reportFile = null; + try { + reportFile = reportBuilder.createReport(report); + } catch (IOException e) { + } + + if (reportFile != null) { + // put file in folder + } log.debug("successfully processed"); } + } diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/ReportDataCollector.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/ReportDataCollector.java index 82a8d0001..143ffe7dd 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/ReportDataCollector.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/ReportDataCollector.java @@ -3,7 +3,9 @@ package ru.spcex.clearing.reports.services; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ru.spcex.clearing.reports.reports.AbstractReport; +import ru.spcex.platform.utils.time.TimeUtil; +import java.math.BigDecimal; import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; @@ -20,6 +22,7 @@ public abstract class ReportDataCollector { /** * T extends ReportWithPeriod + * * @return */ abstract public T collectReportWithPeriod(LocalDate startDate, LocalDate endDate); @@ -40,13 +43,35 @@ public abstract class ReportDataCollector { } } + protected Instant toInstantStartDay(LocalDate date) { + return date.atStartOfDay(TimeUtil.zone).toInstant(); + } + protected Instant toInstantEndDay(LocalDate date) { + return date.plusDays(1).atStartOfDay(TimeUtil.zone).minusSeconds(1).toInstant(); + } + protected String toString(Long val) { if (val == null) return null; return val.toString(); } + protected String toString(BigDecimal val) { + if (val == null) return null; + return val.toString(); + } + protected String toString(Instant val) { if (val == null) return null; return DATE_TIME_FORMATTER.format(val.atZone(ZoneId.systemDefault())); } + + protected String toString(LocalDate date) { + if (date == null) return null; + return DATE_FORMATTER.format(date); + } + +// protected String formatToIMDGInstant(LocalDate date) { +// LocalDateTime ldt = date.atStartOfDay(); +// return DATE_TIME_FORMATTER.format(ldt); +// } } diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/ReportsService.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/ReportsService.java index 54f5b2277..f0ba2a4a7 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/ReportsService.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/ReportsService.java @@ -123,7 +123,7 @@ public class ReportsService { "companySymbolCode", "companySymbolValue", "clearingMemberCategoryClearingMemberCategory", - "profileDocumentDocumentTypeAndValidFromDate", + LocalDate.of(2022,11,10), "liabilitiesClaimsAssetsLiabilitiesQuantity" ); reportBR_0420314P1.getRows().add(info_0420314P1); @@ -133,7 +133,6 @@ public class ReportsService { ReportBR_0420314_P2 reportBR_0420314P2 = new ReportBR_0420314_P2(LocalDate.now(), LocalDate.now(), "transactionStatus", "BR"); ReportBR_0420314_P2.Info_0420314_P2 info_0420314P2 = new ReportBR_0420314_P2.Info_0420314_P2("companyClearingCode", - "paymentInstructionSenderId", "profileDocumentId", "accountBalanceOpenBalanceAmt", "paymentInstructionCreditLegAmount", diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/builders/DOCXReportBuilder.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/builders/DOCXReportBuilder.java index ebf56d43d..2788ca791 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/builders/DOCXReportBuilder.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/builders/DOCXReportBuilder.java @@ -7,10 +7,16 @@ import ru.spcex.clearing.reports.reports.AbstractReport; import java.io.File; import java.io.IOException; -public abstract class DOCXReportBuilder extends FileReportBuilder { +public class DOCXReportBuilder extends FileReportBuilder { private final Logger log = LoggerFactory.getLogger(getClass()); - protected DOCXReportBuilder(Class reportClass, File templateResource) throws IOException { + protected DOCXReportBuilder(Class reportClass, File templateResource) throws IOException { super(reportClass); } + + @Override + public File createReport(AbstractReport report) throws IOException { + // todo implement + return null; + } } diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/builders/FileReportBuilder.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/builders/FileReportBuilder.java index d22e38111..dcde34308 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/builders/FileReportBuilder.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/builders/FileReportBuilder.java @@ -2,10 +2,13 @@ package ru.spcex.clearing.reports.services.builders; import ru.spcex.clearing.reports.reports.AbstractReport; -public abstract class FileReportBuilder { - protected final Class reportClass; +import java.io.File; +import java.io.IOException; - protected FileReportBuilder(Class reportClass) { +public abstract class FileReportBuilder { + protected final Class reportClass; + + protected FileReportBuilder(Class reportClass) { this.reportClass = reportClass; } @@ -13,4 +16,6 @@ public abstract class FileReportBuilder { if (System.getProperty("os.name").toLowerCase().contains("windows")) reportName = reportName.replace(":", "_"); return reportName + extension; } + + public abstract File createReport(AbstractReport report) throws IOException; } diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/builders/XMLReportBuilder.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/builders/XMLReportBuilder.java index 0d25b8cf6..61995cab6 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/builders/XMLReportBuilder.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/builders/XMLReportBuilder.java @@ -6,30 +6,24 @@ import com.thoughtworks.xstream.io.xml.XppDriver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ru.spcex.clearing.reports.reports.AbstractReport; -import ru.spcex.clearing.reports.services.ReportDataCollector; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -import java.time.LocalDate; import java.time.LocalDateTime; -public class XMLReportBuilder extends FileReportBuilder { +public class XMLReportBuilder extends FileReportBuilder { private final Logger log = LoggerFactory.getLogger(getClass()); - protected final XStream xStream; - protected final ReportDataCollector collector; - - public XMLReportBuilder(Class reportClass, ReportDataCollector collector) { + public XMLReportBuilder(Class reportClass) { super(reportClass); - this.collector = collector; this.xStream = new XStream(new XppDriver(new NoNameCoder())); xStream.processAnnotations(reportClass); } - public File createReport(LocalDate startDate, LocalDate endDate) throws IOException { - R report = collector.collectReportWithPeriod(startDate, endDate); + @Override + public File createReport(AbstractReport report) throws IOException { String reportName = report.getReportName(LocalDateTime.now()); String reportFileName = makeFileName(reportName, ".xml"); diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/collector/Bt17_1_P1_collector.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/collector/Bt17_1_P1_collector.java index 824306394..7774d4b6d 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/collector/Bt17_1_P1_collector.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/collector/Bt17_1_P1_collector.java @@ -16,11 +16,13 @@ import ru.spcex.platform.enumeration.ClearingStatus; import ru.spcex.platform.enumeration.Market; 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.time.TimeUtil; +import java.time.Instant; import java.time.LocalDate; -import java.time.LocalDateTime; import java.util.*; -import java.util.stream.Collectors; @Component public class Bt17_1_P1_collector extends ReportDataCollector { @@ -54,6 +56,20 @@ public class Bt17_1_P1_collector extends ReportDataCollector searchLiabilitiesClaimsAssets(LocalDate startDate, LocalDate endDate, Long allowClearingStatusId) { + // String ql = String.format("'%s' <= refundDate and refundDate <= '%s' and clearingStatus=%s", +// formatToIMDGInstant(startDate), formatToIMDGInstant(endDate), allowClearingStatusId); +// Collection liabilities = liabilitiesClaimsAssetsImdg.getCollectionObjectsBySQL(ql); + + ImdgPredicateBuilder pb = liabilitiesClaimsAssetsImdg.predicateBuilder(); + Instant dateTimeLo = toInstantStartDay(startDate); + Instant dateTimeHi = toInstantStartDay(endDate); + ImdgPredicate p = pb.and(pb.greatEqual("refundDate", dateTimeLo), pb.lessEqual("refundDate", dateTimeHi), + pb.equals("clearingStatus", allowClearingStatusId)); + Collection liabilities = liabilitiesClaimsAssetsImdg.getCollectionObjectsByPredicate(p); + return liabilities; + } + @Override public ReportBR_0420315_P1 collectReportWithPeriod(LocalDate startDate, LocalDate endDate) { validateDateRange(startDate, endDate); @@ -63,29 +79,25 @@ public class Bt17_1_P1_collector extends ReportDataCollector liabilities = liabilitiesClaimsAssetsImdg.getCollectionObjectsBySQL(ql); + Collection liabilities = searchLiabilitiesClaimsAssets(startDate, endDate, allowClearingStatusId); Map> indexByCompany = MapUtil.indexList(liabilities, LiabilitiesClaimsAssets::getCompanyId); + company_for: for (Map.Entry> companyEntry : indexByCompany.entrySet()) { final Long companyId = companyEntry.getKey(); List liabilitiesOfCompany = companyEntry.getValue(); Company company = companyImdg.getSingleObjectByID(companyId); if (company != null) { - ClearingMemberCategory cmc = clearingMemberCategoryImdg.getSingleObjectByFieldValues(Map.of("companyId", companyId)); - String checkCategory = cmc == null ? null : cmc.getClearingMemberCategory(); - if (!ALLOW_CLEARING_MEMBER_CATEGORY.contains(checkCategory)) { + Collection cmcLst = clearingMemberCategoryImdg.getCollectionObjectsByFieldValues(Map.of("companyId", companyId)); + boolean checkCategory = cmcLst.stream() + .anyMatch(cmc -> ALLOW_CLEARING_MEMBER_CATEGORY.contains(cmc.getClearingMemberCategory())); + if (!checkCategory) { // фильтруются <> I, V - log.trace("Filtered company[{}] ClearingMemberCategory[{}].ClearingMemberCategory={}", - companyId, cmc == null ? null : cmc.getId(), checkCategory); - continue; + log.trace("Filtered company[{}] ClearingMemberCategory no match: {}", + companyId, cmcLst); + continue company_for; } HashSet onMarket = new HashSet<>(); @@ -103,7 +115,7 @@ public class Bt17_1_P1_collector extends ReportDataCollector searchLiabilitiesClaimsAssets(LocalDate startDate, LocalDate endDate) { +// String ql = String.format("'%s' <= refundDate and refundDate <= '%s'", formatToIMDGInstant(startDate), formatToIMDGInstant(endDate)); +// Collection liabilities = liabilitiesClaimsAssetsImdg.getCollectionObjectsBySQL(ql); + + ImdgPredicateBuilder pb = liabilitiesClaimsAssetsImdg.predicateBuilder(); + Instant dateTimeLo = toInstantStartDay(startDate); + Instant dateTimeHi = toInstantStartDay(endDate); + ImdgPredicate p = pb.and(pb.greatEqual("refundDate", dateTimeLo), pb.lessEqual("refundDate", dateTimeHi)); + Collection liabilities = liabilitiesClaimsAssetsImdg.getCollectionObjectsByPredicate(p); + return liabilities; + } + @Override public ReportBR_0420315_P2 collectReportWithPeriod(LocalDate startDate, LocalDate endDate) { validateDateRange(startDate, endDate); - String ql = String.format("'%s' <= refundDate and refundDate <= '%s'", startDate, endDate); - Collection liabilities = liabilitiesClaimsAssetsImdg.getCollectionObjectsBySQL(ql); + Collection liabilities = searchLiabilitiesClaimsAssets(startDate, endDate); long contractorQty; double liabilitiesAmount = 0; { HashSet collectedToSumm = new HashSet<>(); for (LiabilitiesClaimsAssets lContract : liabilities) { - if (lContract.getPrice() != null && StringUtils.isNotEmpty(lContract.getContract()) + if (lContract.getLiabilitiesQuantity() != null && StringUtils.isNotEmpty(lContract.getContract()) && !collectedToSumm.contains(lContract.getContract())) { collectedToSumm.add(lContract.getContract()); liabilitiesAmount += lContract.getLiabilitiesQuantity().doubleValue(); diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/collector/Bt17_2_collector.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/collector/Bt17_2_collector.java index b85eed586..272becd5d 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/collector/Bt17_2_collector.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/collector/Bt17_2_collector.java @@ -11,10 +11,11 @@ import ru.spcex.clearing.reports.services.ReportDataCollector; import ru.spcex.platform.enumeration.DocumentTypes; 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.Instant; import java.time.LocalDate; -import java.time.LocalDateTime; import java.util.*; @Component @@ -30,13 +31,24 @@ public class Bt17_2_collector extends ReportDataCollector { companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); } + Collection searchRelation(LocalDate startDate, LocalDate endDate, String service) { +// String ql = String.format("'%s' <= updated and updated <= '%s' and service='MKR'", startDate, endDate); +// Collection relations = relationImdg.getCollectionObjectsBySQL(ql); + + ImdgPredicateBuilder pb = relationImdg.predicateBuilder(); + Instant dateTimeLo = toInstantStartDay(startDate); + Instant dateTimeHi = toInstantStartDay(endDate); + ImdgPredicate p = pb.and(pb.greatEqual("updated", dateTimeLo), pb.lessEqual("updated", dateTimeHi), + pb.equals("service", service)); + Collection relations = relationImdg.getCollectionObjectsByPredicate(p); + return relations; + } + @Override public ReportBR_0420317 collectReportWithPeriod(LocalDate startDate, LocalDate endDate) { validateDateRange(startDate, endDate); - String ql = String.format("'%s' <= updated and updated <= '%s' and service='MKR'", startDate, endDate); - // todo обговорить про updatedAt updated, todo enum MKR - Collection relations = relationImdg.getCollectionObjectsBySQL(ql); + Collection relations = searchRelation(startDate, endDate, "MKR"); ReportBR_0420317 reportBR_0420317 = new ReportBR_0420317(startDate, endDate, "BR"); for (Relation relation: relations) { diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/collector/Bt17_5_P1_collector.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/collector/Bt17_5_P1_collector.java index 11ccb81d6..804ace657 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/collector/Bt17_5_P1_collector.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/collector/Bt17_5_P1_collector.java @@ -4,17 +4,18 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import ru.clearing.classes.statics.data.company.Company; import ru.clearing.classes.statics.data.company.CompanySymbols; -import ru.clearing.classes.statics.data.company.relation.Relation; import ru.clearing.classes.statics.data.generated.ClearingMemberCategory; import ru.clearing.classes.transaction.data.execution.LiabilitiesClaimsAssets; -import ru.clearing.platform.dictionary.CountryCodeDictionary; import ru.spcex.clearing.imdg.IMDGDistributedNames; import ru.spcex.clearing.reports.reports.bt_17_5.ReportBR_0420312_P1; import ru.spcex.clearing.reports.services.ReportDataCollector; import ru.spcex.platform.enumeration.DocumentTypes; 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.Instant; import java.time.LocalDate; import java.util.Collection; import java.util.List; @@ -23,9 +24,7 @@ import java.util.Map; @Component public class Bt17_5_P1_collector extends ReportDataCollector { private Imdg companyImdg; - // private Imdg relationImdg; private Imdg companySymbolsImdg; - private Imdg countryCodeDictionaryImdg; private Imdg clearingMemberCategoryImdg; private Imdg liabilitiesClaimsAssetsImdg; @@ -33,10 +32,8 @@ public class Bt17_5_P1_collector extends ReportDataCollector searchLiabilitiesClaimsAssets(LocalDate startDate, LocalDate endDate) { +// String ql = String.format("'%s' <= refundDate and refundDate <= '%s'", formatToIMDGInstant(startDate), formatToIMDGInstant(endDate)); +// Collection liabilities = liabilitiesClaimsAssetsImdg.getCollectionObjectsBySQL(ql); + + ImdgPredicateBuilder pb = liabilitiesClaimsAssetsImdg.predicateBuilder(); + Instant dateTimeLo = toInstantStartDay(startDate); + Instant dateTimeHi = toInstantStartDay(endDate); + ImdgPredicate p = pb.and(pb.greatEqual("refundDate", dateTimeLo), pb.lessEqual("refundDate", dateTimeHi)); + Collection liabilities = liabilitiesClaimsAssetsImdg.getCollectionObjectsByPredicate(p); + return liabilities; + } + @Override public ReportBR_0420312_P1 collectReportWithPeriod(LocalDate startDate, LocalDate endDate) { validateDateRange(startDate, endDate); ReportBR_0420312_P1 reportBR_0420312P1 = new ReportBR_0420312_P1(startDate, endDate, "BR"); - // todo обговорить про updatedAt updated, todo enum MKR - String ql = String.format("'%s' <= refundDate and refundDate <= '%s'", - startDate, endDate); - Collection liabilities = liabilitiesClaimsAssetsImdg.getCollectionObjectsBySQL(ql); + Collection liabilities = searchLiabilitiesClaimsAssets(startDate, endDate); Map> indexByCompany = MapUtil.indexList(liabilities, LiabilitiesClaimsAssets::getCompanyId); + for (Map.Entry> companyEntry : indexByCompany.entrySet()) { final Long companyId = companyEntry.getKey(); Company company = companyImdg.getSingleObjectByID(companyId); + if (company == null) { + log.warn("Company not found by LiabilitiesClaimsAssets.CompanyId={}", companyId); + continue; + } CompanySymbols companySymbolINN = findSymbol(DocumentTypes.inn, company.getId()); CompanySymbols companySymbolOGRN = findSymbol(DocumentTypes.ogrn, company.getId()); ClearingMemberCategory cmc = clearingMemberCategoryImdg.getSingleObjectByFieldValues(Map.of("companyId", companyId)); diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/collector/MapUtil.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/collector/MapUtil.java index 2b9216819..e49ff0ca6 100644 --- a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/collector/MapUtil.java +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/collector/MapUtil.java @@ -1,12 +1,26 @@ package ru.spcex.clearing.reports.services.collector; +import org.apache.commons.lang3.StringUtils; +import ru.clearing.platform.dictionary.AbstractDictionary; import ru.spcex.platform.classes.base.interfaces.WithId; +import ru.spcex.platform.imdg.api.Imdg; import java.util.*; import java.util.function.Function; public class MapUtil { + public static String joinMultiString(Collection from, Function stringFieldExtractor) { + ArrayList strToJoin = new ArrayList<>(from.size()); + for (V obj : from) { + String v = stringFieldExtractor.apply(obj); + if (v != null) { + strToJoin.add(v); + } + } + return StringUtils.join(strToJoin, ","); + } + public static Map index(Collection from, Function indexFieldExtractor) { Map index = new HashMap<>(); for (V obj : from) { @@ -30,4 +44,12 @@ public class MapUtil { } return index; } + + public static Long getDictionaryIdByCode(Imdg dImdg, String code) { + TD dictItem = dImdg.getSingleObjectByFieldValues(Map.of("code", code)); + if (dictItem == null) { + throw new IllegalStateException(dImdg.getMapName() + " with code=\"" + code + "\" not fount"); + } + return dictItem.getId(); + } } diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/collector/Repbr0420314_P1_bt_17_4_collector.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/collector/Repbr0420314_P1_bt_17_4_collector.java new file mode 100644 index 000000000..6dc1e1bfd --- /dev/null +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/collector/Repbr0420314_P1_bt_17_4_collector.java @@ -0,0 +1,123 @@ +package ru.spcex.clearing.reports.services.collector; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.company.CompanySymbols; +import ru.clearing.classes.statics.data.generated.ClearingMemberCategory; +import ru.clearing.classes.transaction.data.execution.LiabilitiesClaimsAssets; +import ru.clearing.platform.dictionary.ClearingStatusDictionary; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.reports.reports.bt_17_4.ReportBR_0420314_P1; +import ru.spcex.clearing.reports.services.ReportDataCollector; +import ru.spcex.platform.enumeration.ClearingStatus; +import ru.spcex.platform.enumeration.DocumentTypes; +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.time.TimeUtil; + +import java.time.Instant; +import java.time.LocalDate; +import java.util.Collection; +import java.util.Map; + +/** + * accountTransactionLiabilities + */ +@Component +public class Repbr0420314_P1_bt_17_4_collector extends ReportDataCollector { + private Imdg companyImdg; + private Imdg companySymbolsImdg; + private Imdg clearingMemberCategoryImdg; + private Imdg liabilitiesClaimsAssetsImdg; + private Imdg clearingStatusDictionaryImdg; + + protected static final String ALLOW_CLEARING_STATUS = ClearingStatus.OK.getKey(); + + @Autowired + public Repbr0420314_P1_bt_17_4_collector(ImdgProvider imdgProvider) { + companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + liabilitiesClaimsAssetsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_LiabilitiesClaimsAssets, LiabilitiesClaimsAssets.class); + companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class); + clearingMemberCategoryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class); + clearingStatusDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingStatusDictionary, ClearingStatusDictionary.class); + } + + protected CompanySymbols findSymbol(DocumentTypes docType, Long companyId) { + CompanySymbols companySymbol = companySymbolsImdg.getSingleObjectByFieldValues(Map.of( + "companySymbol", docType.getKey(), + "companyId", companyId + )); + return companySymbol; + } + + Collection searchLiabilitiesClaimsAssets(LocalDate startDate, LocalDate endDate, Long allowClearingStatusId) { + // String ql = String.format("'%s' <= refundDate and refundDate <= '%s' and clearingStatus=%s", +// formatToIMDGInstant(startDate), formatToIMDGInstant(endDate), allowClearingStatusId); +// Collection liabilities = liabilitiesClaimsAssetsImdg.getCollectionObjectsBySQL(ql); + + ImdgPredicateBuilder pb = liabilitiesClaimsAssetsImdg.predicateBuilder(); + Instant dateTimeLo = toInstantStartDay(startDate); + Instant dateTimeHi = toInstantStartDay(endDate); + ImdgPredicate p = pb.and(pb.greatEqual("refundDate", dateTimeLo), pb.lessEqual("refundDate", dateTimeHi), + pb.equals("clearingStatus", allowClearingStatusId)); + Collection liabilities = liabilitiesClaimsAssetsImdg.getCollectionObjectsByPredicate(p); + return liabilities; + } + + @Override + public ReportBR_0420314_P1 collectReportWithPeriod(LocalDate startDate, LocalDate endDate) { + validateDateRange(startDate, endDate); + + ReportBR_0420314_P1 reportBR_0420312P1 = new ReportBR_0420314_P1(startDate, endDate, "BR", + ALLOW_CLEARING_STATUS //clearingStatus.getCode() "OK" + ); + final Long allowClearingStatusId = MapUtil.getDictionaryIdByCode(clearingStatusDictionaryImdg, ALLOW_CLEARING_STATUS); // "OK" + + Collection liabilities = searchLiabilitiesClaimsAssets(startDate, endDate, allowClearingStatusId); + + for (LiabilitiesClaimsAssets liability: liabilities) { + final Long companyId = liability.getCompanyId(); + Company company = companyImdg.getSingleObjectByID(companyId); + if (company == null) { + log.warn("Company not found by LiabilitiesClaimsAssets.CompanyId={}", companyId); + continue; + } + Collection cmcLst = clearingMemberCategoryImdg.getCollectionObjectsByFieldValues(Map.of("companyId", companyId)); +// boolean checkCategory = cmcLst.stream().anyMatch(cmc -> ALLOW_CLEARING_MEMBER_CATEGORY.contains(cmc.getClearingMemberCategory())); +// if (!checkCategory) { +// // фильтруются <> I, V +// log.trace("Filtered company[{}] ClearingMemberCategory no match: {}", +// companyId, cmcLst); +// continue company_for; +// } + String cleanMemberCategories = MapUtil.joinMultiString(cmcLst, ClearingMemberCategory::getClearingMemberCategory); + + CompanySymbols companySymbolCntr = findSymbol(DocumentTypes.cntr, company.getId()); + CompanySymbols companySymbolINN = findSymbol(DocumentTypes.inn, company.getId()); + CompanySymbols companySymbolOGRN = findSymbol(DocumentTypes.ogrn, company.getId()); + + ReportBR_0420314_P1.Info_0420314_P1 info_0420314P1 = new ReportBR_0420314_P1.Info_0420314_P1( + company.getClearingCode(), + toString(companySymbolCntr == null? null : companySymbolCntr.getId()), + company.getFullName(), + (companySymbolINN == null ? null : companySymbolINN.getCompanySymbolValue()), + (companySymbolOGRN == null? null : companySymbolOGRN.getCompanySymbolValue()), + cleanMemberCategories, // может быть несколько, тогда через запятую перечислить + toString(liability.getRefundPaymentId()), + TimeUtil.toLocalDate(liability.getTradingDate()), + toString(liability.getLiabilitiesQuantity()) + ); + reportBR_0420312P1.getRows().add(info_0420314P1); + } + + return reportBR_0420312P1; + } + + @Override + public Class getReportClass() { + return ReportBR_0420314_P1.class; + } +} diff --git a/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/collector/Repbr0420314_P2_bt_17_4_collector.java b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/collector/Repbr0420314_P2_bt_17_4_collector.java new file mode 100644 index 000000000..9dd77e4c0 --- /dev/null +++ b/clearing-parent/reports-service/src/main/java/ru/spcex/clearing/reports/services/collector/Repbr0420314_P2_bt_17_4_collector.java @@ -0,0 +1,128 @@ +package ru.spcex.clearing.reports.services.collector; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import ru.clearing.classes.statics.data.account.AccountBalance; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.payment.PaymentInstruction; +import ru.clearing.classes.statics.data.profile.ProfileDocument; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.clearing.reports.reports.bt_17_4.ReportBR_0420314_P2; +import ru.spcex.clearing.reports.services.ReportDataCollector; +import ru.spcex.platform.enumeration.AccountType; +import ru.spcex.platform.enumeration.DocumentTypes; +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.Instant; +import java.time.LocalDate; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * accountTransactionLiabilities + */ +@Component +public class Repbr0420314_P2_bt_17_4_collector extends ReportDataCollector { + private Imdg companyImdg; + private Imdg paymentInstructionImdg; + private Imdg accountBalanceImdg; + private Imdg profileDocumentImdg; + + @Autowired + public Repbr0420314_P2_bt_17_4_collector(ImdgProvider imdgProvider) { + companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class); + paymentInstructionImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_PaymentInstruction, PaymentInstruction.class); + accountBalanceImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_AccountBalance, AccountBalance.class); + profileDocumentImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ProfileDocument, ProfileDocument.class); + } + + Collection searchPaymentInstruction(LocalDate startDate, LocalDate endDate) { +// String ql = String.format("'%s' <= created and created <= '%s'", +// formatToIMDGInstant(startDate), formatToIMDGInstant(endDate)); +// Collection paymentInstructionsAll = paymentInstructionImdg.getCollectionObjectsBySQL(ql); + + ImdgPredicateBuilder pb = paymentInstructionImdg.predicateBuilder(); + Instant dateTimeLo = toInstantStartDay(startDate); + Instant dateTimeHi = toInstantStartDay(endDate); + ImdgPredicate p = pb.and(pb.greatEqual("created", dateTimeLo), pb.lessEqual("created", dateTimeHi)); + Collection paymentInstructionsAll = paymentInstructionImdg.getCollectionObjectsByPredicate(p); + return paymentInstructionsAll; + } + + @Override + public ReportBR_0420314_P2 collectReportWithPeriod(LocalDate startDate, LocalDate endDate) { + validateDateRange(startDate, endDate); + + ReportBR_0420314_P2 reportBR_0420312P2 = new ReportBR_0420314_P2(startDate, endDate, + "", "BR" + ); + + Collection paymentInstructionsAll = searchPaymentInstruction(startDate, endDate); + + Map> companyIdPyPaymtInstruction = + MapUtil.indexList(paymentInstructionsAll, PaymentInstruction::getSenderId); + + for (Map.Entry> entry : companyIdPyPaymtInstruction.entrySet()) { + final Long companyId = entry.getKey(); + List paymentInstructionsByCompany = entry.getValue(); + Company company = companyImdg.getSingleObjectByID(companyId); + ProfileDocument profileDocumentCntr = profileDocumentImdg.getSingleObjectByFieldValues(Map.of( + "companyId", companyId, + "documentType", DocumentTypes.cntr.getKey() + )); + AccountBalance accountBalance = accountBalanceImdg.getSingleObjectByFieldValues(Map.of( + "accountType", AccountType.Clrn.getKey(), + "companyId", companyId + )); + + String documentTypeStr = null; + if (profileDocumentCntr != null) { + documentTypeStr = profileDocumentCntr.getNumber(); + if (profileDocumentCntr.getValidFromDate() != null) { + if (StringUtils.isEmpty(documentTypeStr)) { + documentTypeStr = ""; + } else { + documentTypeStr += " "; + } + documentTypeStr += toString(profileDocumentCntr.getValidFromDate()); + } + } + + Long paymentInstruction_creditLeg_amount = paymentInstructionsByCompany.stream() + .map(PaymentInstruction::getCreditLegAmount) + .filter(Objects::nonNull) + .reduce(Long::sum) + .orElse(0L); + Long paymentInstructiont_debitLeg_amount = paymentInstructionsByCompany.stream() + .map(PaymentInstruction::getDebitLegAmount) + .filter(Objects::nonNull) + .reduce(Long::sum) + .orElse(0L); + + + ReportBR_0420314_P2.Info_0420314_P2 info_0420314P2 = new ReportBR_0420314_P2.Info_0420314_P2( + company.getClearingCode(), + documentTypeStr, + accountBalance == null ? null : toString(accountBalance.getOpenBalanceAmount()), + toString(paymentInstruction_creditLeg_amount), + toString(paymentInstructiont_debitLeg_amount), + accountBalance == null ? null : toString(accountBalance.getCloseBalanceAmount()) + ); + + reportBR_0420312P2.getRows().add(info_0420314P2); + } + + return reportBR_0420312P2; + } + + @Override + public Class getReportClass() { + return ReportBR_0420314_P2.class; + } +} diff --git a/clearing-parent/reports-service/src/main/resources/application.properties b/clearing-parent/reports-service/src/main/resources/application.properties index c7765a7fe..ffa1ebe50 100644 --- a/clearing-parent/reports-service/src/main/resources/application.properties +++ b/clearing-parent/reports-service/src/main/resources/application.properties @@ -18,7 +18,8 @@ reports-service.kafka-consumer.buffer-memory=33554432 #reports-service.kafka-producer.linger-ms=1 #reports-service.kafka-producer.buffer-memory=33554432 -reports-service.hazelcast.cluster-members=127.0.0.1:5701,10.200.200.181:5701 +reports-service.hazelcast.cluster-members=127.0.0.1:5701 + #,10.200.200.181:5701 reports-service.hazelcast.login=dev reports-service.hazelcast.password=dev-pass diff --git a/clearing-parent/reports-service/src/main/resources/templates/REX_TEMPLATE.docx b/clearing-parent/reports-service/src/main/resources/templates/REX_TEMPLATE.docx new file mode 100644 index 000000000..6ddc9fad2 Binary files /dev/null and b/clearing-parent/reports-service/src/main/resources/templates/REX_TEMPLATE.docx differ diff --git a/clearing-parent/reports-service/src/main/resources/templates/ROOT.ACTV_TEMPLATE.docx b/clearing-parent/reports-service/src/main/resources/templates/ROOT.ACTV_TEMPLATE.docx new file mode 100644 index 000000000..54edd36f6 Binary files /dev/null and b/clearing-parent/reports-service/src/main/resources/templates/ROOT.ACTV_TEMPLATE.docx differ diff --git a/clearing-parent/reports-service/src/main/resources/templates/ROOT.BLKD_TEMPLATE.docx b/clearing-parent/reports-service/src/main/resources/templates/ROOT.BLKD_TEMPLATE.docx new file mode 100644 index 000000000..fbabbcffa Binary files /dev/null and b/clearing-parent/reports-service/src/main/resources/templates/ROOT.BLKD_TEMPLATE.docx differ diff --git a/clearing-parent/reports-service/src/main/resources/templates/ROOT.CLOS_TEMPLATE.docx b/clearing-parent/reports-service/src/main/resources/templates/ROOT.CLOS_TEMPLATE.docx new file mode 100644 index 000000000..6b3809572 Binary files /dev/null and b/clearing-parent/reports-service/src/main/resources/templates/ROOT.CLOS_TEMPLATE.docx differ diff --git a/clearing-parent/reports-service/src/main/resources/templates/ROOT.NEW_TEMPLATE.docx b/clearing-parent/reports-service/src/main/resources/templates/ROOT.NEW_TEMPLATE.docx new file mode 100644 index 000000000..d142c6bf0 Binary files /dev/null and b/clearing-parent/reports-service/src/main/resources/templates/ROOT.NEW_TEMPLATE.docx differ diff --git a/clearing-parent/reports-service/src/main/resources/templates/ROOT.SSPD_TEMPLATE.docx b/clearing-parent/reports-service/src/main/resources/templates/ROOT.SSPD_TEMPLATE.docx new file mode 100644 index 000000000..33ff2a80f Binary files /dev/null and b/clearing-parent/reports-service/src/main/resources/templates/ROOT.SSPD_TEMPLATE.docx differ diff --git a/clearing-parent/reports-service/src/main/resources/templates/RRPC_TEMPLATE.docx b/clearing-parent/reports-service/src/main/resources/templates/RRPC_TEMPLATE.docx new file mode 100644 index 000000000..2dcedee3c Binary files /dev/null and b/clearing-parent/reports-service/src/main/resources/templates/RRPC_TEMPLATE.docx differ diff --git a/clearing-parent/reports-service/src/test/java/ru/spcex/clearing/reports/notifications/NotificationBuilderTest.java b/clearing-parent/reports-service/src/test/java/ru/spcex/clearing/reports/notifications/NotificationBuilderTest.java new file mode 100644 index 000000000..b0a5f47f7 --- /dev/null +++ b/clearing-parent/reports-service/src/test/java/ru/spcex/clearing/reports/notifications/NotificationBuilderTest.java @@ -0,0 +1,143 @@ +package ru.spcex.clearing.reports.notifications; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import ru.clearing.classes.statics.data.company.Company; +import ru.clearing.classes.statics.data.company.CompanySymbols; +import ru.clearing.classes.statics.data.company.relation.Relation; +import ru.clearing.classes.statics.data.profile.ProfileDocument; +import ru.spcex.clearing.imdg.IMDGDistributedNames; +import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.ImdgProvider; + +import java.io.File; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.Arrays; +import java.util.Collections; + +import static org.mockito.Mockito.*; + +class NotificationBuilderTest { + static ImdgProvider imdgProviderMock; + static Imdg companyImdgMock; + static Company testCompany; + + static Imdg profileDocumentImdgMock; + static ProfileDocument testProfileDocument_1; + static ProfileDocument testProfileDocument_2; + + static Imdg relationImdgMock; + static Relation testRelation_1; + static Relation testRelation_2; + + static Imdg companySymbolsImdgMock; + static CompanySymbols testCompanySymbols_1; + static CompanySymbols testCompanySymbols_2; + + @BeforeAll + public static void initMocks() { + imdgProviderMock = mock(ImdgProvider.class); + + testCompany = new Company(); + testCompany.setFullName("== TEST FULL NAME =="); + testCompany.setShortName("== TEST SHORT NAME =="); + testCompany.setClearingCode("TEST_CLEARING_CODE"); + companyImdgMock = mock(Imdg.class); + when(companyImdgMock.getSingleObjectByID(any())).thenReturn(testCompany); + when(imdgProviderMock.getImdg(eq(IMDGDistributedNames.Map_Company), eq(Company.class))).thenReturn(companyImdgMock); + + testProfileDocument_1 = new ProfileDocument(); + testProfileDocument_1.setId(777L); + testProfileDocument_1.setCompanyId(777L); + testProfileDocument_1.setValidFromDate(LocalDate.of(2020, 1, 1)); + testProfileDocument_1.setNumber("TEST_NUMBER_1"); + testProfileDocument_2 = new ProfileDocument(); + testProfileDocument_2.setId(777L); + testProfileDocument_2.setCompanyId(777L); + testProfileDocument_2.setValidFromDate(LocalDate.of(2019, 1, 1)); + testProfileDocument_2.setNumber("TEST_NUMBER_2"); + profileDocumentImdgMock = mock(Imdg.class); + when(profileDocumentImdgMock.getCollectionObjectsBySQL(any())).thenReturn(Arrays.asList(testProfileDocument_1, testProfileDocument_2)); + when(imdgProviderMock.getImdg(eq(IMDGDistributedNames.Map_ProfileDocument), eq(ProfileDocument.class))).thenReturn(profileDocumentImdgMock); + + testRelation_1 = new Relation(); + testRelation_1.setId(777L); + testRelation_1.setConsumerId(777L); + testRelation_1.setUpdated(LocalDate.of(2020, 1, 1).atStartOfDay(ZoneId.systemDefault()).toInstant()); + testRelation_2 = new Relation(); + testRelation_2.setId(777L); + testRelation_2.setConsumerId(777L); + testRelation_2.setUpdated(LocalDate.of(2019, 1, 1).atStartOfDay(ZoneId.systemDefault()).toInstant()); + relationImdgMock = mock(Imdg.class); + when(relationImdgMock.getCollectionObjectsBySQL(any())).thenReturn(Arrays.asList(testRelation_1, testRelation_2)); + when(imdgProviderMock.getImdg(eq(IMDGDistributedNames.Map_Relation), eq(Relation.class))).thenReturn(relationImdgMock); + + testCompanySymbols_1 = new CompanySymbols(); + testCompanySymbols_1.setId(777L); + testCompanySymbols_1.setCompanyId(777L); + testCompanySymbols_1.setCompanySymbol("TEST_COMPANY_SYMBOL_1"); + testCompanySymbols_1.setCompanySymbolValue("TEST_COMPANY_SYMBOL_VALUE_1"); + testCompanySymbols_2 = new CompanySymbols(); + testCompanySymbols_2.setId(777L); + testCompanySymbols_2.setCompanyId(777L); + testCompanySymbols_2.setCompanySymbol("TEST_COMPANY_SYMBOL_2"); + testCompanySymbols_2.setCompanySymbolValue("TEST_COMPANY_SYMBOL_VALUE_2"); + companySymbolsImdgMock = mock(Imdg.class); + when(companySymbolsImdgMock.getCollectionObjectsBySQL(any())).thenReturn(Arrays.asList(testCompanySymbols_1, testCompanySymbols_2)); + when(imdgProviderMock.getImdg(eq(IMDGDistributedNames.Map_CompanySymbols), eq(CompanySymbols.class))).thenReturn(companySymbolsImdgMock); + + } + + @Test + public void testREX() { + REXNotificationBuilder rexNotificationBuilder = new REXNotificationBuilder(imdgProviderMock); + File outputFile = rexNotificationBuilder.buildNotification(777L); + outputFile.delete(); + } + + @Test + public void testRRPC() { + RRPCNotificationBuilder rrpcNotificationBuilder = new RRPCNotificationBuilder(imdgProviderMock); + File outputFile = rrpcNotificationBuilder.buildNotification(777L); + outputFile.delete(); + } + + @Test + public void testROOT_ACTV() { + ROOT_ACTV_NotificationBuilder root_actv_notificationBuilder = new ROOT_ACTV_NotificationBuilder(imdgProviderMock); + File outputFile = root_actv_notificationBuilder.buildNotification(777L); + outputFile.delete(); + } + + @Test + public void testROOT_BLKD() { + ROOT_BLKD_NotificationBuilder root_actv_notificationBuilder = new ROOT_BLKD_NotificationBuilder(imdgProviderMock); + File outputFile = root_actv_notificationBuilder.buildNotification(777L); + outputFile.delete(); + } + + @Test + public void testROOT_CLOS() { + ROOT_CLOS_NotificationBuilder root_actv_notificationBuilder = new ROOT_CLOS_NotificationBuilder(imdgProviderMock); + File outputFile = root_actv_notificationBuilder.buildNotification(777L); + outputFile.delete(); + } + + @Test + public void testROOT_NEW() { + ROOT_NEW_NotificationBuilder root_actv_notificationBuilder = new ROOT_NEW_NotificationBuilder(imdgProviderMock); + File outputFile = root_actv_notificationBuilder.buildNotification(777L); + outputFile.delete(); + } + + @Test + public void testROOT_SSPD() { + ROOT_SSPD_NotificationBuilder root_actv_notificationBuilder = new ROOT_SSPD_NotificationBuilder(imdgProviderMock); + File outputFile = root_actv_notificationBuilder.buildNotification(777L); + outputFile.delete(); + } + + +} \ No newline at end of file diff --git a/clearing-parent/reports-service/src/test/java/ru/spcex/clearing/reports/services/DOCXServiceTest.java b/clearing-parent/reports-service/src/test/java/ru/spcex/clearing/reports/services/DOCXServiceTest.java index 528d64be2..ffd640744 100644 --- a/clearing-parent/reports-service/src/test/java/ru/spcex/clearing/reports/services/DOCXServiceTest.java +++ b/clearing-parent/reports-service/src/test/java/ru/spcex/clearing/reports/services/DOCXServiceTest.java @@ -19,10 +19,9 @@ class DOCXServiceTest { valuesMap.put("${test3}", "======== TEST 3 ========="); DOCXService service = new DOCXService(); - service.insertValues(new File(getClass().getClassLoader().getResource("REC.ACTV_TEST.docx").getPath()), - new File("output.docx"), + service.init(new File(getClass().getClassLoader().getResource("REC.ACTV_TEST.docx").getPath()), null); + service.insertValues(new File("output.docx"), valuesMap, - null, false); File file = new File("output.docx"); diff --git a/clearing-parent/reports-service/src/test/java/ru/spcex/clearing/reports/services/ReportDataCollectorTest.java b/clearing-parent/reports-service/src/test/java/ru/spcex/clearing/reports/services/ReportDataCollectorTest.java index 0e730578b..7c16b767c 100644 --- a/clearing-parent/reports-service/src/test/java/ru/spcex/clearing/reports/services/ReportDataCollectorTest.java +++ b/clearing-parent/reports-service/src/test/java/ru/spcex/clearing/reports/services/ReportDataCollectorTest.java @@ -14,20 +14,27 @@ class ReportDataCollectorTest extends ReportDataCollector { @Test void testToString() { ReportDataCollectorTest instance = new ReportDataCollectorTest(); - assertEquals(null, instance.toString((Long)null)); - assertEquals("1", instance.toString((Long)1L)); - assertEquals("1230", instance.toString((Long)1230L)); + assertEquals(null, instance.toString((Long) null)); + assertEquals("1", instance.toString((Long) 1L)); + assertEquals("1230", instance.toString((Long) 1230L)); } @Test void testToString1() { ReportDataCollectorTest instance = new ReportDataCollectorTest(); - assertEquals(null, instance.toString((Instant)null)); + assertEquals(null, instance.toString((Instant) null)); Instant val = Instant.ofEpochMilli(1672058774338L); assertEquals("26.12.2022T15:46:14", instance.toString(val)); // msk timezone } + @Test + void testToString2() { + ReportDataCollectorTest instance = new ReportDataCollectorTest(); + LocalDate val = LocalDate.of(2022, 12, 26); + assertEquals("26.12.2022", instance.toString(val)); + } + @Override public AbstractReport collectReportWithPeriod(LocalDate startDate, LocalDate endDate) { throw new IllegalStateException("test"); diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/ResultStatuses.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/ResultStatuses.java new file mode 100644 index 000000000..54660b5ce --- /dev/null +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/ResultStatuses.java @@ -0,0 +1,22 @@ +package ru.spcex.platform.enumeration; + +import ru.spcex.platform.utils.enumeration.IEnumKey; + +/** + * ResultStatusDictionary + */ +public enum ResultStatuses implements IEnumKey { + notSuccess("NACK"), // Неуспешно + success("ACK"); // Успешно + + private final String key; + + ResultStatuses(String key) { + this.key = key; + } + + @Override + public String getKey() { + return key; + } +} diff --git a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/Task.java b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/Task.java index 8233a188e..3d5a6ddcd 100644 --- a/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/Task.java +++ b/platform-parent/platform-enum/src/main/java/ru/spcex/platform/enumeration/Task.java @@ -14,7 +14,8 @@ public enum Task implements IEnumKey { startPostClearing("SPOC"),// Запуск постклиринга createOrder("CORD"), createOrderConfirm("CORC"), - getAllBalance("GALB"); + getAllBalance("GALB"), + createReport("RPRT");// Создание отчёта (report-service) private final String key; diff --git a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java index 43aad9a39..c447524f6 100644 --- a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java +++ b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java @@ -11,6 +11,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.imdg.api.Imdg; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; +import ru.spcex.platform.imdg.iml.hazelcast.adapter.predicate.ImdgPredicateBuilderHazelcast; +import ru.spcex.platform.imdg.iml.hazelcast.adapter.predicate.ImdgPredicateHazelcast; import ru.spcex.platform.utils.log.ExceptionUtils; import java.util.*; @@ -181,4 +185,26 @@ public class ImdgHazelcast implements Imdg { public void setMapName(String mapName) { this.mapName = mapName; } + + + // Predicate API + @Override + public Collection getCollectionObjectsByPredicate(ImdgPredicate predicateImdg) { + Predicate hazelcastPredicate = ((ImdgPredicateHazelcast) predicateImdg).getRawPredicate(); + Set ids = map.keySet(hazelcastPredicate); + Iterator idIterator = ids.iterator(); + Collection searchResult = new ArrayList<>(); + while (idIterator.hasNext()) { + T element = map.get(idIterator.next()); + if (element != null) { + searchResult.add(element); + } + } + return searchResult; + } + + @Override + public ImdgPredicateBuilder predicateBuilder() { + return ImdgPredicateBuilderHazelcast.instance(); + } } diff --git a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/predicate/ImdgPredicateBuilderHazelcast.java b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/predicate/ImdgPredicateBuilderHazelcast.java new file mode 100644 index 000000000..0764ac47c --- /dev/null +++ b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/predicate/ImdgPredicateBuilderHazelcast.java @@ -0,0 +1,76 @@ +package ru.spcex.platform.imdg.iml.hazelcast.adapter.predicate; + +import com.hazelcast.query.Predicates; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; + +public class ImdgPredicateBuilderHazelcast implements ImdgPredicateBuilder { + protected static final ImdgPredicateBuilderHazelcast instance = new ImdgPredicateBuilderHazelcast(); + + public static ImdgPredicateBuilderHazelcast instance() { + return instance; + } + + + @Override + public ImdgPredicate equals(String key, Object value) { + Comparable cmpValue = (Comparable) value; + return new ImdgPredicateHazelcast(Predicates.equal(key, cmpValue)); + } + + @Override + public ImdgPredicate greatEqual(String key, Comparable cmpValue) { + return new ImdgPredicateHazelcast(Predicates.greaterEqual(key, cmpValue)); + } + + @Override + public ImdgPredicate lessEqual(String key, Comparable cmpValue) { + return new ImdgPredicateHazelcast(Predicates.lessEqual(key, cmpValue)); + } + + @Override + public ImdgPredicate greater(String key, Comparable cmpValue) { + return new ImdgPredicateHazelcast(Predicates.greaterThan(key, cmpValue)); + } + + @Override + public ImdgPredicate less(String key, Comparable cmpValue) { + return new ImdgPredicateHazelcast(Predicates.lessThan(key, cmpValue)); + } + + @Override + public ImdgPredicate not(ImdgPredicate param) { + ImdgPredicateHazelcast paramMy = (ImdgPredicateHazelcast) param; + return new ImdgPredicateHazelcast(Predicates.not(paramMy.hazelcastPredicate)); + } + + @Override + public ImdgPredicate and(ImdgPredicate paramA, ImdgPredicate paramB) { + ImdgPredicateHazelcast paramAMy = (ImdgPredicateHazelcast) paramA; + ImdgPredicateHazelcast paramBMy = (ImdgPredicateHazelcast) paramB; + return new ImdgPredicateHazelcast(Predicates.and(paramAMy.hazelcastPredicate, paramBMy.hazelcastPredicate)); + } + + @Override + public ImdgPredicate and(ImdgPredicate paramA, ImdgPredicate paramB, ImdgPredicate paramC) { + ImdgPredicateHazelcast paramAMy = (ImdgPredicateHazelcast) paramA; + ImdgPredicateHazelcast paramBMy = (ImdgPredicateHazelcast) paramB; + ImdgPredicateHazelcast paramCMy = (ImdgPredicateHazelcast) paramB; + return new ImdgPredicateHazelcast(Predicates.and(paramAMy.hazelcastPredicate, paramBMy.hazelcastPredicate, paramCMy.hazelcastPredicate)); + } + + @Override + public ImdgPredicate or(ImdgPredicate paramA, ImdgPredicate paramB) { + ImdgPredicateHazelcast paramAMy = (ImdgPredicateHazelcast) paramA; + ImdgPredicateHazelcast paramBMy = (ImdgPredicateHazelcast) paramB; + return new ImdgPredicateHazelcast(Predicates.or(paramAMy.hazelcastPredicate, paramBMy.hazelcastPredicate)); + } + + @Override + public ImdgPredicate or(ImdgPredicate paramA, ImdgPredicate paramB, ImdgPredicate paramC) { + ImdgPredicateHazelcast paramAMy = (ImdgPredicateHazelcast) paramA; + ImdgPredicateHazelcast paramBMy = (ImdgPredicateHazelcast) paramB; + ImdgPredicateHazelcast paramCMy = (ImdgPredicateHazelcast) paramC; + return new ImdgPredicateHazelcast(Predicates.or(paramAMy.hazelcastPredicate, paramBMy.hazelcastPredicate, paramCMy.hazelcastPredicate)); + } +} diff --git a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/predicate/ImdgPredicateHazelcast.java b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/predicate/ImdgPredicateHazelcast.java new file mode 100644 index 000000000..e2ee78c25 --- /dev/null +++ b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/predicate/ImdgPredicateHazelcast.java @@ -0,0 +1,24 @@ +package ru.spcex.platform.imdg.iml.hazelcast.adapter.predicate; + +import com.hazelcast.query.Predicate; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; + +import java.util.Objects; + +public class ImdgPredicateHazelcast implements ImdgPredicate { + protected final Predicate hazelcastPredicate; + + protected ImdgPredicateHazelcast(Predicate hazelcastPredicate) { + Objects.requireNonNull(hazelcastPredicate); + this.hazelcastPredicate = hazelcastPredicate; + } + + public Predicate getRawPredicate() { + return hazelcastPredicate; + } + + @Override + public String toString() { + return hazelcastPredicate.toString(); + } +} diff --git a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/Imdg.java b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/Imdg.java index 2784cc2dd..bc4adb9c1 100644 --- a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/Imdg.java +++ b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/Imdg.java @@ -1,6 +1,8 @@ package ru.spcex.platform.imdg.api; import ru.spcex.platform.classes.base.SpcexObjectBase; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicate; +import ru.spcex.platform.imdg.api.predicate.ImdgPredicateBuilder; import java.util.Collection; import java.util.Map; @@ -65,4 +67,13 @@ public interface Imdg { default Integer size() { throw new UnsupportedOperationException("not implemented size"); } + + // Predicate API + default Collection getCollectionObjectsByPredicate(ImdgPredicate predicate) { + throw new UnsupportedOperationException("not implemented getCollectionObjectsByPredicate"); + } + + default ImdgPredicateBuilder predicateBuilder() { + throw new UnsupportedOperationException("not implemented predicateBuilder API"); + } } diff --git a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/predicate/ImdgPredicate.java b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/predicate/ImdgPredicate.java new file mode 100644 index 000000000..922245086 --- /dev/null +++ b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/predicate/ImdgPredicate.java @@ -0,0 +1,4 @@ +package ru.spcex.platform.imdg.api.predicate; + +public interface ImdgPredicate { +} diff --git a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/predicate/ImdgPredicateBuilder.java b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/predicate/ImdgPredicateBuilder.java new file mode 100644 index 000000000..09b135a35 --- /dev/null +++ b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/predicate/ImdgPredicateBuilder.java @@ -0,0 +1,15 @@ +package ru.spcex.platform.imdg.api.predicate; + +public interface ImdgPredicateBuilder { + ImdgPredicate equals(String key, Object value); + ImdgPredicate greatEqual(String key, Comparable value); + ImdgPredicate lessEqual(String key, Comparable value); + ImdgPredicate greater(String key, Comparable value); + ImdgPredicate less(String key, Comparable value); + + ImdgPredicate not(ImdgPredicate param); + ImdgPredicate and(ImdgPredicate paramA, ImdgPredicate paramB); + ImdgPredicate and(ImdgPredicate paramA, ImdgPredicate paramB, ImdgPredicate paramC); + ImdgPredicate or(ImdgPredicate paramA, ImdgPredicate paramB); + ImdgPredicate or(ImdgPredicate paramA, ImdgPredicate paramB, ImdgPredicate paramC); +} diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/reports/NotificationRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/reports/NotificationRequest.java new file mode 100644 index 000000000..f09103e1d --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/reports/NotificationRequest.java @@ -0,0 +1,23 @@ +package ru.spcex.clearing.platform.messaging.domain.cud.reports; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Запрос на формирование уведомления + */ +public class NotificationRequest { + /** + * Идентификатор участника клиринга + */ + @JsonProperty + protected String consumerId; + + + public String getConsumerId() { + return consumerId; + } + + public void setConsumerId(String consumerId) { + this.consumerId = consumerId; + } +} diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/reports/ReportRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/reports/ReportRequest.java new file mode 100644 index 000000000..17952def1 --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/reports/ReportRequest.java @@ -0,0 +1,23 @@ +package ru.spcex.clearing.platform.messaging.domain.cud.reports; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Запрос отчёта (без параметров) report-service + */ +public class ReportRequest { + /** + * Идентификатор отчёта + * см. {@link ru.spcex.clearing.reports.reports.ReportsEnum} + */ + @JsonProperty + protected String reportId; + + public String getReportId() { + return reportId; + } + + public void setReportId(String reportId) { + this.reportId = reportId; + } +} diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/reports/ReportWithPeriodRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/reports/ReportWithPeriodRequest.java new file mode 100644 index 000000000..4f4c80c75 --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/reports/ReportWithPeriodRequest.java @@ -0,0 +1,40 @@ +package ru.spcex.clearing.platform.messaging.domain.cud.reports; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import ru.spcex.clearing.platform.messaging.domain.json.deserialize.LocalDateDeserializer; +import ru.spcex.clearing.platform.messaging.domain.json.serialize.LocalDateSerializer; + +import java.time.LocalDate; + +/** + * Запрос отчёта с периодом report-service + */ +public class ReportWithPeriodRequest extends ReportRequest { + @JsonSerialize(using = LocalDateSerializer.class) + @JsonDeserialize(using = LocalDateDeserializer.class) + @JsonProperty + protected LocalDate startDate; + + @JsonSerialize(using = LocalDateSerializer.class) + @JsonDeserialize(using = LocalDateDeserializer.class) + @JsonProperty + protected 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/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/time/TimeUtil.java b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/time/TimeUtil.java index d3fcf9119..bd7bc0f90 100644 --- a/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/time/TimeUtil.java +++ b/platform-parent/platform-utils/src/main/java/ru/spcex/platform/utils/time/TimeUtil.java @@ -59,4 +59,9 @@ public class TimeUtil { public static Instant strToInstant(String date) { return localDateToInstant(Objects.requireNonNull(strToLocalDate(date))); } + + public static LocalDate toLocalDate(Instant date) { + if (date == null) return null; + return LocalDate.ofInstant(date, ZoneId.systemDefault()); + } } diff --git a/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/time/TimeUtilTest.java b/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/time/TimeUtilTest.java new file mode 100644 index 000000000..ee5bff21b --- /dev/null +++ b/platform-parent/platform-utils/src/test/java/ru/spcex/platform/utils/time/TimeUtilTest.java @@ -0,0 +1,18 @@ +package ru.spcex.platform.utils.time; + +import org.junit.jupiter.api.Test; + +import java.time.Instant; +import java.time.LocalDate; + +import static org.junit.jupiter.api.Assertions.*; + +class TimeUtilTest { + + @Test + void toLocalDate() { + Instant date1 = Instant.ofEpochMilli(1234567890123L); + LocalDate date2 = TimeUtil.toLocalDate(date1); + assertEquals("2009-02-14", date2.toString()); + } +} \ No newline at end of file