From ddd6e01f1fedf1715e592a7ee63c73a69187920f Mon Sep 17 00:00:00 2001 From: dankito Date: Mon, 18 Nov 2024 21:06:07 +0100 Subject: [PATCH] Implemented FilesystemInvoiceReader --- .../filesystem/FilesystemInvoiceReader.kt | 49 +++++++++++++++++++ .../filesystem/InvoiceOnFilesystem.kt | 12 +++++ .../filesystem/FilesystemInvoiceReaderTest.kt | 41 ++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 e-invoicing-domain/src/main/kotlin/net/codinux/invoicing/filesystem/FilesystemInvoiceReader.kt create mode 100644 e-invoicing-domain/src/main/kotlin/net/codinux/invoicing/filesystem/InvoiceOnFilesystem.kt create mode 100644 e-invoicing-domain/src/test/kotlin/net/codinux/invoicing/filesystem/FilesystemInvoiceReaderTest.kt diff --git a/e-invoicing-domain/src/main/kotlin/net/codinux/invoicing/filesystem/FilesystemInvoiceReader.kt b/e-invoicing-domain/src/main/kotlin/net/codinux/invoicing/filesystem/FilesystemInvoiceReader.kt new file mode 100644 index 0000000..99b0080 --- /dev/null +++ b/e-invoicing-domain/src/main/kotlin/net/codinux/invoicing/filesystem/FilesystemInvoiceReader.kt @@ -0,0 +1,49 @@ +package net.codinux.invoicing.filesystem + +import net.codinux.invoicing.model.Invoice +import net.codinux.invoicing.reader.EInvoiceReader +import net.codinux.log.logger +import java.nio.file.Path +import kotlin.io.path.* + +class FilesystemInvoiceReader( + private val eInvoiceReader: EInvoiceReader = EInvoiceReader() +) { + + private val log by logger() + + fun readAllInvoicesOfDirectory(directory: Path, recursive: Boolean = false) = + readInvoicesFromFiles(collectFiles(directory, recursive)) + + private fun collectFiles(directory: Path, recursive: Boolean): List = buildList { + directory.listDirectoryEntries().forEach { child -> + if (child.isRegularFile()) { + add(child) + } else if (recursive && child.isDirectory()) { + addAll(collectFiles(child, recursive)) + } + } + } + + fun readInvoicesFromFiles(vararg files: Path) = + readInvoicesFromFiles(files.toList()) + + fun readInvoicesFromFiles(files: List): List = + files.mapNotNull { file -> readInvoiceFromFile(file)?.let { InvoiceOnFilesystem(file, it) } } + + fun readInvoiceFromFile(file: Path): Invoice? = try { + val extension = file.extension.lowercase() + + if (extension == "pdf") { + eInvoiceReader.extractFromPdf(file.inputStream()) + } else if (extension == "xml") { + eInvoiceReader.readFromXml(file.inputStream()) + } else { + null + } + } catch (e: Throwable) { + log.debug(e) { "Could not extract invoices from $file" } + null + } + +} \ No newline at end of file diff --git a/e-invoicing-domain/src/main/kotlin/net/codinux/invoicing/filesystem/InvoiceOnFilesystem.kt b/e-invoicing-domain/src/main/kotlin/net/codinux/invoicing/filesystem/InvoiceOnFilesystem.kt new file mode 100644 index 0000000..5f0fb5e --- /dev/null +++ b/e-invoicing-domain/src/main/kotlin/net/codinux/invoicing/filesystem/InvoiceOnFilesystem.kt @@ -0,0 +1,12 @@ +package net.codinux.invoicing.filesystem + +import net.codinux.invoicing.model.Invoice +import java.nio.file.Path +import kotlin.io.path.name + +class InvoiceOnFilesystem( + val file: Path, + val invoice: Invoice +) { + override fun toString() = "${file.name} $invoice" +} \ No newline at end of file diff --git a/e-invoicing-domain/src/test/kotlin/net/codinux/invoicing/filesystem/FilesystemInvoiceReaderTest.kt b/e-invoicing-domain/src/test/kotlin/net/codinux/invoicing/filesystem/FilesystemInvoiceReaderTest.kt new file mode 100644 index 0000000..98c8d9f --- /dev/null +++ b/e-invoicing-domain/src/test/kotlin/net/codinux/invoicing/filesystem/FilesystemInvoiceReaderTest.kt @@ -0,0 +1,41 @@ +package net.codinux.invoicing.filesystem + +import assertk.assertThat +import assertk.assertions.hasSize +import net.codinux.invoicing.model.Invoice +import net.codinux.invoicing.test.InvoiceAsserter +import net.codinux.invoicing.test.TestUtils +import java.nio.file.Path +import kotlin.test.Test + +class FilesystemInvoiceReaderTest { + + private val underTest = FilesystemInvoiceReader() + + @Test + fun readAllInvoicesOfDirectory() { + val testDirectory = getTestFile("XRechnung.xml").parent + + val result = underTest.readAllInvoicesOfDirectory(testDirectory) + + assertThat(result).hasSize(3) + } + + @Test + fun readInvoiceFromFile() { + val xRechnung = getTestFile("XRechnung.xml") + + val result = underTest.readInvoiceFromFile(xRechnung) + + assertInvoice(result) + } + + + private fun getTestFile(filename: String): Path = + TestUtils.getTestFile(filename).toPath() + + private fun assertInvoice(invoice: Invoice?) { + InvoiceAsserter.assertInvoice(invoice) + } + +} \ No newline at end of file