diff --git a/src/main/java/ru/dmitriymx/corrector1s/Corrector1S.java b/src/main/java/ru/dmitriymx/corrector1s/Corrector1S.java index afe9b54..b2c54bb 100644 --- a/src/main/java/ru/dmitriymx/corrector1s/Corrector1S.java +++ b/src/main/java/ru/dmitriymx/corrector1s/Corrector1S.java @@ -12,7 +12,9 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; @Slf4j @@ -21,7 +23,15 @@ public class Corrector1S { private class ExcelRecord { private String name; private Integer addition; - private Double data; + private List dataList; + + ExcelRecord(int capacity) { + dataList = new ArrayList<>(capacity); + } + + boolean isEmptyDataList() { + return dataList.stream().mapToDouble(Double::doubleValue).sum() == 0.0d; + } } @Setter @@ -30,14 +40,19 @@ public class Corrector1S { private File targetFile; @Setter private double honorarium; + @Setter + private double fss; private Map mapRecords; private Workbook workbook; private Sheet sheet; + /** номер колонки "Итого начислено" */ private int cellNumSum = 0; + /** номер колонки с больничными */ private int cellBol = 0; private int lastColumn = 0; private CellStyle cellStyle1, cellStyle2; + private int maxLines = 0; private String getFileExtension(File file) { int i = file.getAbsolutePath().lastIndexOf('.'); @@ -48,8 +63,14 @@ public class Corrector1S { } } + private String buildSumFormula(int column, int startLine, int endLine) { + String columnChar = CellReference.convertNumToColString(column); + return String.format("SUM(%s%d:%s%d)", columnChar, startLine, columnChar, endLine); + } + public void check() throws Exception { if (honorarium == 0.0d) throw new AssertionError("Honorarium not be 0.0%!"); + if (fss == 0.0d) throw new AssertionError("FSS not be 0.0%!"); if (sourceFile == null) throw new AssertionError("Source file not be null!"); else if (!sourceFile.exists()) throw new FileNotFoundException(sourceFile.getAbsolutePath()); @@ -64,37 +85,47 @@ public class Corrector1S { sheet.getRow(6).getCell(8); sheet.getRow(7).getCell(8); sheet.getRow(8).getCell(8); - sheet.getRow(9).getCell(8); } catch (Exception e) { - throw new FormatFileException(e); - } finally { workbook.close(); + throw new FormatFileException(e); } + + // get max lines + for (int line = 8; true; line++) { + if (sheet.getRow(line) == null) { + this.maxLines = line - 2; + break; + } + } + + workbook.close(); } public void createSnapshotData() throws IOException, InvalidFormatException { workbook = WorkbookFactory.create(sourceFile); sheet = workbook.getSheetAt(0); - mapRecords = new HashMap<>(19); // ожидается 19 записей для сохранения + mapRecords = new HashMap<>(20); Cell cell; loop: - for (int c = 8; true; c++) { - ExcelRecord record = new ExcelRecord(); + for (int column = 8; true; column++) { + ExcelRecord record = new ExcelRecord(this.maxLines); - for (int r = 6; r < 9; r++) { - cell = sheet.getRow(r).getCell(c); + for (int line = 6; line <= this.maxLines; line++) { + cell = sheet.getRow(line).getCell(column); if (cell == null) break loop; - if (r == 6) record.name = cell.getStringCellValue(); - else if (r == 7) { + if (line == 6) { + record.name = cell.getStringCellValue(); + } else if (line == 7) { if (cell.getCellTypeEnum().equals(CellType.NUMERIC)) { record.addition = (int) cell.getNumericCellValue(); } else { record.addition = 0; } + } else { + record.dataList.add(cell.getNumericCellValue()); } - else record.data = cell.getNumericCellValue(); } String key = (record.addition == 0 ? record.name.trim() : record.name.trim() + "_" + record.addition); @@ -115,10 +146,12 @@ public class Corrector1S { } private void setCellRecord(ExcelRecord record, int column) { + // NAME Cell cell = sheet.getRow(6).getCell(column, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK); cell.setCellType(CellType.STRING); cell.setCellValue(record.name); + // ADDITION cell = sheet.getRow(7).getCell(column, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK); if (record.addition == 0) { cell.setCellType(CellType.BLANK); @@ -127,62 +160,68 @@ public class Corrector1S { cell.setCellValue(record.addition); } - cell = sheet.getRow(8).getCell(column, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK); - if (record.data == 0) { - cell.setCellType(CellType.BLANK); - } else { - cell.setCellType(CellType.NUMERIC); - cell.setCellValue(record.data); + // DATA + for (int line = 8; line <= this.maxLines; line++) { + cell = sheet.getRow(line).getCell(column, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK); + double data = record.dataList.get(line-8); + if (data == 0) { + cell.setCellType(CellType.BLANK); + } else { + cell.setCellType(CellType.NUMERIC); + cell.setCellValue(data); + } } - cell = sheet.getRow(9).getCell(column, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK); - if (record.data == 0) { + // SUM + cell = sheet.getRow(this.maxLines+1).getCell(column, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK); + if (record.isEmptyDataList()) { cell.setCellType(CellType.BLANK); } else { - cell.setCellType(CellType.NUMERIC); - cell.setCellValue(record.data); + cell.setCellType(CellType.FORMULA); + cell.setCellFormula(buildSumFormula(column, 8, this.maxLines)); } } public void replaceData() { - int c = 8; + int column = 8; ExcelRecord record; + if ((record = mapRecords.remove("Отпуск очередной_104")) != null) setCellRecord(record, column++); if ((record = mapRecords.remove("Больничный за счет работодателя_105")) != null) { - setCellRecord(record, c++); - this.cellBol = c-1; + setCellRecord(record, column++); + this.cellBol = column-1; } - if ((record = mapRecords.remove("Дневные")) != null) setCellRecord(record, c++); - if ((record = mapRecords.remove("Ночные")) != null) setCellRecord(record, c++); - if ((record = mapRecords.remove("Ночные_123")) != null) setCellRecord(record, c++); - if ((record = mapRecords.remove("питание_124")) != null) setCellRecord(record, c++); - if ((record = mapRecords.remove("Выходные")) != null) setCellRecord(record, c++); - if ((record = mapRecords.remove("выходные_135")) != null) setCellRecord(record, c++); - if ((record = mapRecords.remove("пересчет за прошлый месяц_141")) != null) setCellRecord(record, c++); - if ((record = mapRecords.remove("вредность_145")) != null) setCellRecord(record, c++); - if ((record = mapRecords.remove("Материальная помощь при рождении ребенка_148")) != null) setCellRecord(record, c++); - if ((record = mapRecords.remove("компенсация за задержку зарплаты_169")) != null) setCellRecord(record, c++); - if ((record = mapRecords.remove("Оплата по среднему (донорство, посещение врача)_174")) != null) setCellRecord(record, c++); - if ((record = mapRecords.remove("Компенсация проезда при использовании личного транспорта_176")) != null) setCellRecord(record, c++); - if ((record = mapRecords.remove("сверхурочные_133")) != null) setCellRecord(record, c++); - if ((record = mapRecords.remove("Сверхурочные 1.5 ставки")) != null) setCellRecord(record, c++); - if ((record = mapRecords.remove("сверхурочные 1,5_180")) != null) setCellRecord(record, c++); - if ((record = mapRecords.remove("Сверхурочные 2 ставки")) != null) setCellRecord(record, c++); - if ((record = mapRecords.remove("сверхурочные 2_181")) != null) setCellRecord(record, c++); - if ((record = mapRecords.remove("Компенсация за неиспользованный отпуск (с декабря 2017)_184")) != null) setCellRecord(record, c++); - if ((record = mapRecords.remove("Месячная премия 2018_186")) != null) setCellRecord(record, c++); + if ((record = mapRecords.remove("Дневные")) != null) setCellRecord(record, column++); + if ((record = mapRecords.remove("Ночные")) != null) setCellRecord(record, column++); + if ((record = mapRecords.remove("Ночные_123")) != null) setCellRecord(record, column++); + if ((record = mapRecords.remove("питание_124")) != null) setCellRecord(record, column++); + if ((record = mapRecords.remove("Выходные")) != null) setCellRecord(record, column++); + if ((record = mapRecords.remove("выходные_135")) != null) setCellRecord(record, column++); + if ((record = mapRecords.remove("пересчет за прошлый месяц_141")) != null) setCellRecord(record, column++); + if ((record = mapRecords.remove("вредность_145")) != null) setCellRecord(record, column++); + if ((record = mapRecords.remove("Материальная помощь при рождении ребенка_148")) != null) setCellRecord(record, column++); + if ((record = mapRecords.remove("компенсация за задержку зарплаты_169")) != null) setCellRecord(record, column++); + if ((record = mapRecords.remove("Оплата по среднему (донорство, посещение врача)_174")) != null) setCellRecord(record, column++); + if ((record = mapRecords.remove("Компенсация проезда при использовании личного транспорта_176")) != null) setCellRecord(record, column++); + if ((record = mapRecords.remove("сверхурочные_133")) != null) setCellRecord(record, column++); + if ((record = mapRecords.remove("Сверхурочные 1.5 ставки")) != null) setCellRecord(record, column++); + if ((record = mapRecords.remove("сверхурочные 1,5_180")) != null) setCellRecord(record, column++); + if ((record = mapRecords.remove("Сверхурочные 2 ставки")) != null) setCellRecord(record, column++); + if ((record = mapRecords.remove("сверхурочные 2_181")) != null) setCellRecord(record, column++); + if ((record = mapRecords.remove("Компенсация за неиспользованный отпуск (с декабря 2017)_184")) != null) setCellRecord(record, column++); + if ((record = mapRecords.remove("Месячная премия 2018_186")) != null) setCellRecord(record, column++); if (mapRecords.size() > 1) { for (ExcelRecord rec : mapRecords.values()) { if (!rec.name.equalsIgnoreCase("Итого начислено")) { - setCellRecord(rec, c++); + setCellRecord(rec, column++); } } } - if ((record = mapRecords.remove("Итого начислено")) != null) setCellRecord(record, c++); - cellNumSum = c-1; + if ((record = mapRecords.remove("Итого начислено")) != null) setCellRecord(record, column++); + cellNumSum = column-1; - this.lastColumn = c; + this.lastColumn = column; } private void initStyle() { @@ -208,89 +247,99 @@ public class Corrector1S { cellStyle2.setBorderRight(BorderStyle.THIN); } - private void insertCell(String title, String addition, String formula1, String formula2, int columnNumber) { - Cell cell = sheet.getRow(6).createCell(columnNumber); + private void insertCell(String title, String addition, String formulaTemplate, String formulaSum, int column) { + // NAME + Cell cell = sheet.getRow(6).createCell(column); cell.setCellType(CellType.STRING); cell.setCellValue(title); cell.setCellStyle(cellStyle1); - cell = sheet.getRow(7).createCell(columnNumber); + // ADDITION + cell = sheet.getRow(7).createCell(column); cell.setCellType(CellType.STRING); cell.setCellValue(addition); cell.setCellStyle(cellStyle1); - cell = sheet.getRow(8).createCell(columnNumber); - cell.setCellStyle(cellStyle2); - cell.setCellType(CellType.FORMULA); - cell.setCellFormula(formula1); + // DATA + for (int line = 8; line <= this.maxLines; line++) { + cell = sheet.getRow(line).createCell(column); + cell.setCellStyle(cellStyle2); + cell.setCellType(CellType.FORMULA); + cell.setCellFormula(formulaTemplate.replace("{L}", String.valueOf(line+1)).replace(',','.')); + } - cell = sheet.getRow(9).createCell(columnNumber); + // SUM + cell = sheet.getRow(this.maxLines+1).createCell(column); cell.setCellStyle(cellStyle2); cell.setCellType(CellType.FORMULA); - cell.setCellFormula(formula2); + cell.setCellFormula(formulaSum); } public void insertNewCols() { initStyle(); - int column = lastColumn; - String form1, form2; + + // FSS + String formulaTemplate; if (cellBol == 0) { - form1 = String.format("(%s9)*31%%", CellReference.convertNumToColString(cellNumSum)); - form2 = String.format("(%s10)*31%%", CellReference.convertNumToColString(cellNumSum)); + formulaTemplate = String.format( + "(%s{L})*%.2f%%", + CellReference.convertNumToColString(cellNumSum), + this.fss + ); } else { - form1 = String.format("(%s9-%s9)*31%%", + formulaTemplate = String.format( + "(%s{L}-%s{L})*%.2f%%", CellReference.convertNumToColString(cellNumSum), - CellReference.convertNumToColString(cellBol)); - form2 = String.format("(%s10-%s10)*31%%", - CellReference.convertNumToColString(cellNumSum), - CellReference.convertNumToColString(cellBol)); + CellReference.convertNumToColString(cellBol), + this.fss + ); } insertCell( - "Страховые взносы + ФСС НС (31%)", + String.format("Страховые взносы + ФСС НС (%.2f%%)", this.fss), "Начислено", - form1, - form2, + formulaTemplate, + buildSumFormula(column, 8, this.maxLines), column++ ); + + // BASE insertCell( "БАЗА", "для начисления стоимости услуг", - String.format("%s9+%s9", - CellReference.convertNumToColString(cellNumSum), - CellReference.convertNumToColString(column-1)), - String.format("%s10+%s10", + String.format("%s{L}+%s{L}", CellReference.convertNumToColString(cellNumSum), CellReference.convertNumToColString(column-1)), + buildSumFormula(column, 8, this.maxLines), column++ ); + + // HONORARIUM insertCell( "Гонорар", - (int)this.honorarium + "%", - String.format("%s9*%d%%", + String.format("%.2f%%", this.honorarium), + String.format("%s{L}*%.2f%%", CellReference.convertNumToColString(column-1), - (int)this.honorarium), - String.format("%s10*%d%%", - CellReference.convertNumToColString(column-1), - (int)this.honorarium), + this.honorarium), + buildSumFormula(column, 8, this.maxLines), column++ ); + + // SUM ALL insertCell( "Итого, для счета", "Результат", - String.format("%s9+%s9", - CellReference.convertNumToColString(column-2), - CellReference.convertNumToColString(column-1)), - String.format("%s10+%s10", + String.format("%s{L}+%s{L}", CellReference.convertNumToColString(column-2), CellReference.convertNumToColString(column-1)), + buildSumFormula(column, 8, this.maxLines), column ); - - workbook.getCreationHelper().createFormulaEvaluator().evaluateAll(); } public void saveFile() throws IOException { + workbook.getCreationHelper().createFormulaEvaluator().evaluateAll(); + try (FileOutputStream fos = new FileOutputStream(targetFile)) { workbook.write(fos); workbook.close(); diff --git a/src/main/java/ru/dmitriymx/corrector1s/Main.java b/src/main/java/ru/dmitriymx/corrector1s/Main.java index 2146180..003aa1f 100644 --- a/src/main/java/ru/dmitriymx/corrector1s/Main.java +++ b/src/main/java/ru/dmitriymx/corrector1s/Main.java @@ -24,10 +24,14 @@ public class Main { optionParser.acceptsAll(Arrays.asList("t", "target"), "Target Excel file (default: target = source)") .withRequiredArg() .ofType(File.class); - optionParser.acceptsAll(Arrays.asList("f", "fee"), "Honorarium (in percentages)") + optionParser.acceptsAll(Arrays.asList("h", "honorarium"), "Honorarium (in percentages)") .withRequiredArg() .ofType(Double.class) .defaultsTo(9.0d); + optionParser.acceptsAll(Arrays.asList("f", "fss"), "FSS (in percentages)") + .withRequiredArg() + .ofType(Double.class) + .defaultsTo(31.0d); optionParser.acceptsAll(Arrays.asList("h", "help"), "Help page. Display this message") .forHelp(); optionParser.acceptsAll(Arrays.asList("v", "version"), "Version") @@ -72,12 +76,15 @@ public class Main { log.debug("Source file: {} (exists: {})", sourceFile.getAbsolutePath(), Files.exists(sourceFile.toPath())); log.debug("Target file: {}", targetFile.getAbsolutePath()); - log.debug("Honorarium: {}%", optionSet.valueOf("fee")); + log.debug("Honorarium: {}%", optionSet.valueOf("honorarium")); + log.debug("FSS: {}%", optionSet.valueOf("fss")); Corrector1S corrector1S = new Corrector1S(); corrector1S.setSourceFile(sourceFile); corrector1S.setTargetFile(targetFile); - corrector1S.setHonorarium((Double) optionSet.valueOf("fee")); + corrector1S.setHonorarium((Double) optionSet.valueOf("honorarium")); + corrector1S.setFss((Double) optionSet.valueOf("fss")); + corrector1S.check(); corrector1S.createSnapshotData(); corrector1S.removeMergedCells();