Skip to content

Commit

Permalink
refactor AbstractBrokerReport
Browse files Browse the repository at this point in the history
  • Loading branch information
vananiev committed Oct 22, 2024
1 parent 9d4c7c9 commit 70d0265
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 146 deletions.
60 changes: 38 additions & 22 deletions src/main/java/ru/investbook/parser/AbstractBrokerReport.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,47 +18,62 @@

package ru.investbook.parser;

import lombok.AccessLevel;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.spacious_team.table_wrapper.api.ReportPage;

import java.nio.file.Path;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;

@RequiredArgsConstructor
@EqualsAndHashCode(of = "path")
@ToString(of = "reportName")
@EqualsAndHashCode(of = "reportName")
public abstract class AbstractBrokerReport implements SingleBrokerReport {

protected static final int LAST_TRADE_HOUR = 19;
@Getter
private final SecurityRegistrar securityRegistrar;
@Setter(AccessLevel.PROTECTED)
private DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy");
@Setter(AccessLevel.PROTECTED)
private DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss");
protected static final ZoneId MOSCOW_ZONEID = ZoneId.of("Europe/Moscow");
private static final DateTimeFormatter RUSSIAN_DATE_FORMATTER = DateTimeFormatter.ofPattern("dd.MM.yyyy");
private static final DateTimeFormatter RUSSIAN_DATETIME_FORMATTER = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss");

@Setter(AccessLevel.PROTECTED)
private Path path;
private final DateTimeFormatter dateFormatter = RUSSIAN_DATE_FORMATTER;
private final DateTimeFormatter dateTimeFormatter = RUSSIAN_DATETIME_FORMATTER;
@Getter
private final ZoneId reportZoneId = MOSCOW_ZONEID;
@Getter
@Setter(AccessLevel.PROTECTED)
private String portfolio;
private final ReportPage reportPage;
private final String reportName;
@Getter
@Setter(AccessLevel.PROTECTED)
private ReportPage reportPage;
private final Instant reportEndDateTime;
@Getter
@Setter(AccessLevel.PROTECTED)
private Instant reportEndDateTime;
private final String portfolio;
@Getter
private final ZoneId reportZoneId = ZoneId.of("Europe/Moscow");
private final SecurityRegistrar securityRegistrar;

public AbstractBrokerReport(Attributes attributes, SecurityRegistrar securityRegistrar) {
this.reportPage = attributes.reportPage();
this.reportName = attributes.reportName();
this.reportEndDateTime = attributes.reportEndDateTime();
this.portfolio = attributes.portfolio();
this.securityRegistrar = securityRegistrar;
}

public Instant convertToInstant(String value) {
return convertToInstant(value, dateFormatter, dateTimeFormatter, reportZoneId);
}

protected static Instant convertToInstantWithRussianFormatAndMoscowZoneId(String value) {
return convertToInstant(value, RUSSIAN_DATE_FORMATTER, RUSSIAN_DATETIME_FORMATTER, MOSCOW_ZONEID);
}

protected static Instant convertToInstant(String value,
DateTimeFormatter dateFormatter,
DateTimeFormatter dateTimeFormatter,
ZoneId reportZoneId) {
value = value.trim();
if (value.contains(":")) {
return LocalDateTime.parse(value, dateTimeFormatter).atZone(reportZoneId).toInstant();
Expand All @@ -67,8 +82,9 @@ public Instant convertToInstant(String value) {
}
}

@Override
public String toString() {
return path.getFileName().toString();
public record Attributes(ReportPage reportPage,
String reportName,
Instant reportEndDateTime,
String portfolio) {
}
}
14 changes: 12 additions & 2 deletions src/main/java/ru/investbook/parser/AbstractExcelBrokerReport.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@

public abstract class AbstractExcelBrokerReport extends AbstractBrokerReport {

public AbstractExcelBrokerReport(SecurityRegistrar securityRegistrar) {
super(securityRegistrar);
private final Workbook workbook;

public AbstractExcelBrokerReport(ExcelAttributes attributes, SecurityRegistrar securityRegistrar) {
super(attributes.attributes(), securityRegistrar);
this.workbook = attributes.workbook();
}

public static Workbook getWorkBook(String excelFileName, InputStream is) {
Expand All @@ -45,4 +48,11 @@ public static Workbook getWorkBook(String excelFileName, InputStream is) {
}
}

@Override
public void close() throws IOException {
workbook.close();
}

public record ExcelAttributes(Workbook workbook, Attributes attributes) {
}
}
43 changes: 24 additions & 19 deletions src/main/java/ru/investbook/parser/psb/PsbBrokerReport.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,33 +32,42 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Instant;
import java.time.temporal.ChronoUnit;

import static java.time.temporal.ChronoUnit.HOURS;

@EqualsAndHashCode(callSuper = true)
public class PsbBrokerReport extends AbstractExcelBrokerReport {
public static final String UNIQ_TEXT = "Брокер: ПАО \"Промсвязьбанк\"";
private static final String PORTFOLIO_MARKER = "Договор №:";
private static final String REPORT_DATE_MARKER = "ОТЧЕТ БРОКЕРА";

private final Workbook book;

public PsbBrokerReport(String excelFileName, SecurityRegistrar securityRegistrar) throws IOException {
this(Paths.get(excelFileName), securityRegistrar);
}

public PsbBrokerReport(Path report, SecurityRegistrar securityRegistrar) throws IOException {
this(report.getFileName().toString(), Files.newInputStream(report), securityRegistrar);
this(getFileName(report), Files.newInputStream(report), securityRegistrar);
}

public PsbBrokerReport(String excelFileName, InputStream is, SecurityRegistrar securityRegistrar) {
super(securityRegistrar);
this.book = getWorkBook(excelFileName, is);
ReportPage reportPage = new ExcelSheet(book.getSheetAt(0));
super(getBrokerReportAttributes(excelFileName, is), securityRegistrar);
}

@SuppressWarnings("nullness")
private static String getFileName(Path path) {
return path.getFileName().toString();
}

private static ExcelAttributes getBrokerReportAttributes(String excelFileName, InputStream is) {
Workbook workbook = getWorkBook(excelFileName, is);
ReportPage reportPage = new ExcelSheet(workbook.getSheetAt(0));
checkReportFormat(excelFileName, reportPage);
setPath(Paths.get(excelFileName));
setReportPage(reportPage);
setPortfolio(getPortfolio(reportPage));
setReportEndDateTime(getReportEndDateTime(reportPage));
Attributes attributes = new Attributes(
reportPage,
excelFileName,
getReportEndDateTime(reportPage),
getPortfolio(reportPage));
return new ExcelAttributes(workbook, attributes);
}

public static void checkReportFormat(String excelFileName, ReportPage reportPage) {
Expand All @@ -77,19 +86,15 @@ private static String getPortfolio(ReportPage reportPage) {
}
}

private Instant getReportEndDateTime(ReportPage reportPage) {
private static Instant getReportEndDateTime(ReportPage reportPage) {
try {
String value = String.valueOf(reportPage.getNextColumnValue(REPORT_DATE_MARKER));
return convertToInstant(value.split(" ")[3])
.plus(LAST_TRADE_HOUR, ChronoUnit.HOURS);
String date = value.split(" ")[3];
return convertToInstantWithRussianFormatAndMoscowZoneId(date)
.plus(LAST_TRADE_HOUR, HOURS);
} catch (Exception e) {
throw new IllegalArgumentException(
"Не найдена дата отчета по заданному шаблону '" + REPORT_DATE_MARKER + " XXX'");
}
}

@Override
public void close() throws IOException {
this.book.close();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Paths;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.function.Function;

import static java.time.temporal.ChronoUnit.HOURS;

@EqualsAndHashCode(callSuper = true)
public class PsbBrokerForeignMarketReport extends AbstractBrokerReport {
Expand All @@ -47,14 +49,18 @@ public class PsbBrokerForeignMarketReport extends AbstractBrokerReport {
private static final String REPORT_DATE_MARKER = "ОТЧЕТ БРОКЕРА";

public PsbBrokerForeignMarketReport(String excelFileName, InputStream is, SecurityRegistrar securityRegistrar) {
super(securityRegistrar);
super(getBrokerReportAttributes(excelFileName, is), securityRegistrar);
}

private static Attributes getBrokerReportAttributes(String excelFileName, InputStream is) {
Workbook book = getWorkbook(is);
ReportPage reportPage = new XmlReportPage(book.getWorksheetAt(0));
PsbBrokerReport.checkReportFormat(excelFileName, reportPage);
setPath(Paths.get(excelFileName));
setReportPage(reportPage);
setPortfolio(getPortfolio(reportPage));
setReportEndDateTime(getReportEndDateTime(reportPage));
return new Attributes(
reportPage,
excelFileName,
getReportEndDateTime(reportPage),
getPortfolio(reportPage));
}

private static Workbook getWorkbook(InputStream is) {
Expand Down Expand Up @@ -88,11 +94,12 @@ private static String getPortfolio(ReportPage reportPage) {
}
}

private Instant getReportEndDateTime(ReportPage reportPage) {
private static Instant getReportEndDateTime(ReportPage reportPage) {
try {
String value = String.valueOf(reportPage.getNextColumnValue(REPORT_DATE_MARKER));
return convertToInstant(value.split(" ")[3])
.plus(LAST_TRADE_HOUR, ChronoUnit.HOURS);
String date = value.split(" ")[3];
return convertToInstantWithRussianFormatAndMoscowZoneId(date)
.plus(LAST_TRADE_HOUR, HOURS);
} catch (Exception e) {
throw new IllegalArgumentException(
"Не найдена дата отчета по заданному шаблону '" + REPORT_DATE_MARKER + " XXX'");
Expand All @@ -101,14 +108,26 @@ private Instant getReportEndDateTime(ReportPage reportPage) {

@Override
public Instant convertToInstant(String value) {
return convertXmlDateTimeToInstant(value, getReportZoneId(), super::convertToInstant);
}

protected static Instant convertToInstantWithRussianFormatAndMoscowZoneId(String value) {
return convertXmlDateTimeToInstant(value,
MOSCOW_ZONEID,
AbstractBrokerReport::convertToInstantWithRussianFormatAndMoscowZoneId);
}

private static Instant convertXmlDateTimeToInstant(String value,
ZoneId zoneId,
Function<String, Instant> defaultConverter) {
value = value.trim();
if (value.contains("/")) {
return LocalDate.parse(value, PsbBrokerForeignMarketReport.dateFormatterWithSlash)
.atStartOfDay(getReportZoneId()).toInstant();
.atStartOfDay(zoneId).toInstant();
} else if (value.contains(":") && value.length() == 16) {
return LocalDateTime.parse(value, dateTimeFormatter).atZone(getReportZoneId()).toInstant();
return LocalDateTime.parse(value, dateTimeFormatter).atZone(zoneId).toInstant();
} else {
return super.convertToInstant(value);
return defaultConverter.apply(value);
}
}

Expand Down
39 changes: 19 additions & 20 deletions src/main/java/ru/investbook/parser/tinkoff/TinkoffBrokerReport.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,12 @@
import ru.investbook.parser.AbstractExcelBrokerReport;
import ru.investbook.parser.SecurityRegistrar;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Paths;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.function.Predicate;
import java.util.regex.Pattern;

import static java.time.temporal.ChronoUnit.HOURS;
import static java.util.regex.Pattern.UNICODE_CHARACTER_CLASS;
import static ru.investbook.parser.tinkoff.TinkoffBrokerReportHelper.removePageNumRows;

Expand All @@ -48,18 +46,21 @@ public class TinkoffBrokerReport extends AbstractExcelBrokerReport {
private static final Predicate<Object> dateMarkerPredicate = cell ->
(cell instanceof String) && ((String) cell).contains("за период");

private final Workbook book;

public TinkoffBrokerReport(String excelFileName, InputStream is, SecurityRegistrar securityRegistrar) {
super(securityRegistrar);
this.book = getWorkBook(excelFileName, is);
ExcelSheet reportPage = new ExcelSheet(book.getSheetAt(0));
super(getBrokerReportAttributes(excelFileName, is), securityRegistrar);
}

private static ExcelAttributes getBrokerReportAttributes(String excelFileName, InputStream is) {
Workbook workbook = getWorkBook(excelFileName, is);
ExcelSheet reportPage = new ExcelSheet(workbook.getSheetAt(0));
checkReportFormat(excelFileName, reportPage);
setPath(Paths.get(excelFileName));
setReportPage(reportPage);
setPortfolio(getPortfolio(reportPage));
setReportEndDateTime(getReportEndDateTime(reportPage));
removePageNumRows(reportPage);
Attributes attributes = new Attributes(
reportPage,
excelFileName,
getReportEndDateTime(reportPage),
getPortfolio(reportPage));
return new ExcelAttributes(workbook, attributes);
}

public static void checkReportFormat(String excelFileName, ReportPage reportPage) {
Expand All @@ -69,34 +70,32 @@ public static void checkReportFormat(String excelFileName, ReportPage reportPage
}
}

@SuppressWarnings({"nullness", "DataFlowIssue"})
private static String getPortfolio(ReportPage reportPage) {
try {
return reportPage.getCell(reportPage.findByPrefix(PORTFOLIO_MARKER))
.getStringValue()
.split("/")[1]
.trim()
.split("\s+")[0];
.split("\\s+")[0];
} catch (Exception e) {
throw new IllegalArgumentException(
"В отчете не найден номер договора по заданному шаблону '" + PORTFOLIO_MARKER);
}
}

private Instant getReportEndDateTime(ReportPage reportPage) {
private static Instant getReportEndDateTime(ReportPage reportPage) {
try {
TableCellAddress address = reportPage.find(0, 10, dateMarkerPredicate);
@SuppressWarnings({"nullness", "DataFlowIssue"})
String[] words = reportPage.getCell(address)
.getStringValue()
.split("-");
String value = words[words.length - 1].trim();
return convertToInstant(value).plus(LAST_TRADE_HOUR, ChronoUnit.HOURS);
return convertToInstantWithRussianFormatAndMoscowZoneId(value)
.plus(LAST_TRADE_HOUR, HOURS);
} catch (Exception e) {
throw new IllegalArgumentException("Не найдена дата отчета по заданному шаблону");
}
}

@Override
public void close() throws IOException {
this.book.close();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spacious_team.table_wrapper.api.ReportPage;
import org.spacious_team.table_wrapper.excel.ExcelSheet;
import org.springframework.util.StringUtils;
Expand Down Expand Up @@ -66,7 +67,7 @@ private static boolean isTableHeader(ReportPage reportPage, int rowNum) {
TinkoffBrokerReportHelper::isCellContainsTableName) != NOT_FOUND;
}

private static boolean isCellContainsTableName(Object cell) {
private static boolean isCellContainsTableName(@Nullable Object cell) {
return (cell instanceof String) &&
!cell.toString().isEmpty() &&
tableNamePattern.matcher(cell.toString()).lookingAt();
Expand Down
Loading

0 comments on commit 70d0265

Please sign in to comment.