001package io.konik.csv.pdf;
002
003import io.konik.PdfHandler;
004import io.konik.csv.mapper.CsvInvoicesReader;
005import io.konik.csv.model.Row;
006import org.slf4j.Logger;
007import org.slf4j.LoggerFactory;
008
009import java.io.*;
010
011import static io.konik.csv.mapper.CsvInvoicesReader.ConvertedRow;
012import static io.konik.csv.mapper.CsvInvoicesReader.Result;
013
014public class CsvToZUGFeRDConverter {
015
016        private static final Logger log = LoggerFactory.getLogger(CsvToZUGFeRDConverter.class);
017        private static final String DEFAULT_SUFFIX = "_zugferd.pdf";
018
019        private final CsvInvoicesReader csvInvoicesReader;
020        private final PdfHandler pdfHandler;
021
022        public CsvToZUGFeRDConverter() {
023                this.csvInvoicesReader = new CsvInvoicesReader();
024                this.pdfHandler = new PdfHandler();
025        }
026
027        public CsvToZUGFeRDConverter(CsvInvoicesReader csvInvoicesReader, PdfHandler pdfHandler) {
028                this.csvInvoicesReader = csvInvoicesReader;
029                this.pdfHandler = pdfHandler;
030        }
031
032        public void convert(File csvFile, String inputPath, String outputPath) {
033                Result result = csvInvoicesReader.read(csvFile);
034
035                if (result != null) {
036                        log.info("CSV file contains {} rows, {} errors", result.getConvertedRows().size(), result.getRowErrors().size());
037
038                        for (final ConvertedRow convertedRow : result.getConvertedRows()) {
039                                InputStream input = null;
040                                OutputStream output = null;
041
042                                log.info("Processing row {}", convertedRow.getRowNumber());
043
044                                try {
045                                        final Row row = convertedRow.getRow();
046
047                                        if (isInputFilePresent(row)) {
048                                                log.info("Input file for given row present...");
049
050                                                String inputFile = getFilePath(inputPath, row.getFile().getInput());
051                                                input = new FileInputStream(inputFile);
052                                                log.info("Input file: {}", inputFile);
053
054                                                String outputName = row.getFile().getOutput();
055                                                if (!(outputName != null && !outputName.isEmpty())) {
056                                                        outputName = row.getFile().getInput().replaceFirst(".pdf", DEFAULT_SUFFIX);
057                                                }
058                                                outputName = getFilePath(outputPath, outputName);
059                                                output = new FileOutputStream(outputName);
060                                                log.info("Output file: {}", outputName);
061
062                                                log.info("Starting append invoice process...");
063                                                pdfHandler.appendInvoice(convertedRow.getInvoice(), input, output);
064                                                log.info("Invoice appended to the output file");
065                                        }
066                                } catch (IOException e) {
067                                        log.warn("IOException caught: {}", e.getMessage());
068                                } finally {
069                                        closeStreams(input, output);
070                                }
071                        }
072                }
073        }
074
075        private static String getFilePath(final String inputPath, final String inputFile) {
076                String result = inputFile;
077
078                if (inputPath != null && !inputPath.isEmpty()) {
079                        String path = inputPath;
080                        String file = inputFile;
081
082                        if (!path.endsWith("/")) {
083                                path = String.format("%s/", path);
084                        }
085                        if (file.startsWith("/")) {
086                                file = file.substring(1, file.length() - 1);
087                        }
088
089                        result = String.format("%s%s", path, file);
090                }
091
092                return result;
093        }
094
095        public void convert(File csvFile) {
096                convert(csvFile, null, null);
097        }
098
099        private boolean isInputFilePresent(Row row) {
100                return row != null && row.getFile().getInput() != null;
101        }
102
103        private void closeStreams(InputStream input, OutputStream output) {
104                try {
105                        if (input != null) {
106                                input.close();
107                        }
108
109                        if (output != null) {
110                                output.close();
111                        }
112                } catch (IOException e) {
113                        log.warn("IOException caught while closing input or output: {}", e.getMessage());
114                }
115        }
116
117        public static void main(String[] args) {
118                String inputPath = System.getProperty("inputPath");
119                String outputPath = System.getProperty("outputPath");
120                String csvFileName = args[0];
121
122                File csvFile = new File(csvFileName);
123
124                if (!csvFile.exists()) {
125                        throw new IllegalArgumentException(String.format("Csv file with name %s does not exist", csvFileName));
126                }
127
128                log.info("----------------------------------------------------------");
129                log.info("CSV file:\t\t{}", csvFile.getAbsolutePath());
130                log.info("Input path:\t{}", inputPath);
131                log.info("Output path:\t{}", outputPath);
132                log.info("----------------------------------------------------------");
133
134                CsvToZUGFeRDConverter converter = new CsvToZUGFeRDConverter();
135                converter.convert(csvFile, inputPath, outputPath);
136        }
137}