Compare commits

...

4 Commits

Author SHA1 Message Date
dankito ddd6e01f1f Implemented FilesystemInvoiceReader 2024-11-18 21:06:07 +01:00
dankito af94ff2049 Extracted TestUtils 2024-11-18 20:04:55 +01:00
dankito f6a0022b24 Catching all errors 2024-11-18 20:00:17 +01:00
dankito 2cbe323e9b Removed internal debugging properties 2024-11-18 19:55:40 +01:00
7 changed files with 126 additions and 19 deletions

View File

@ -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<Path> = 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<Path>): List<InvoiceOnFilesystem> =
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
}
}

View File

@ -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"
}

View File

@ -17,10 +17,6 @@ class MailReader(
private val eInvoiceReader: EInvoiceReader = EInvoiceReader()
) {
private val extractionErrorMessages = mutableSetOf<String?>()
private val extractionErrors = mutableSetOf<Throwable>()
private val log by logger()
@ -105,23 +101,20 @@ class MailReader(
return null
}
private fun tryToReadEInvoice(part: BodyPart): Invoice? {
private fun tryToReadEInvoice(part: BodyPart): Invoice? = try {
val filename = part.fileName.lowercase()
val contentType = part.contentType.lowercase()
return if (filename.endsWith(".pdf") || contentType.startsWith("application/pdf") || contentType.startsWith("application/octet-stream")) {
try {
eInvoiceReader.extractFromPdf(part.inputStream)
} catch (e: Throwable) {
extractionErrorMessages.add(e.message)
extractionErrors.add(e)
null
}
if (filename.endsWith(".pdf") || contentType.startsWith("application/pdf") || contentType.startsWith("application/octet-stream")) {
eInvoiceReader.extractFromPdf(part.inputStream)
} else if (filename.endsWith(".xml") || contentType.startsWith("application/xml") || contentType.startsWith("text/xml")) {
eInvoiceReader.readFromXml(part.inputStream)
} else {
null
}
} catch (e: Throwable) {
log.debug(e) { "Could not extract invoices from ${part.fileName}" }
null
}
// TODO: same code as in MustangMapper

View File

@ -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)
}
}

View File

@ -2,7 +2,7 @@ package net.codinux.invoicing.reader
import net.codinux.invoicing.model.Invoice
import net.codinux.invoicing.test.InvoiceAsserter
import java.io.InputStream
import net.codinux.invoicing.test.TestUtils
import kotlin.test.Test
class EInvoiceReaderTest {
@ -32,8 +32,7 @@ class EInvoiceReaderTest {
}
private fun getTestFile(filename: String): InputStream =
this.javaClass.classLoader.getResourceAsStream("files/$filename")!!
private fun getTestFile(filename: String) = TestUtils.getTestFileAsStream(filename)
private fun assertInvoice(invoice: Invoice?) {
InvoiceAsserter.assertInvoice(invoice)

View File

@ -0,0 +1,14 @@
package net.codinux.invoicing.test
import java.io.File
import java.io.InputStream
object TestUtils {
fun getTestFileAsStream(filename: String): InputStream =
this.javaClass.classLoader.getResourceAsStream("files/$filename")!!
fun getTestFile(filename: String): File =
File(this.javaClass.classLoader.getResource("files/$filename")!!.toURI())
}

View File

@ -2,7 +2,7 @@ package net.codinux.invoicing.validation
import assertk.assertThat
import assertk.assertions.*
import java.io.File
import net.codinux.invoicing.test.TestUtils
import kotlin.test.Test
class EInvoiceValidatorTest {
@ -54,7 +54,6 @@ class EInvoiceValidatorTest {
}
private fun getTestFile(filename: String): File =
File(this.javaClass.classLoader.getResource("files/$filename")!!.toURI())
private fun getTestFile(filename: String) = TestUtils.getTestFile(filename)
}