Extracted class Row
This commit is contained in:
parent
1b6e753f3c
commit
18f819d86c
|
@ -4,6 +4,7 @@ import net.codinux.invoicing.model.codes.InvoiceTypeUseFor
|
||||||
import net.codinux.invoicing.parser.genericode.CodeList
|
import net.codinux.invoicing.parser.genericode.CodeList
|
||||||
import net.codinux.invoicing.parser.model.CodeListType
|
import net.codinux.invoicing.parser.model.CodeListType
|
||||||
import net.codinux.invoicing.parser.model.Column
|
import net.codinux.invoicing.parser.model.Column
|
||||||
|
import net.codinux.invoicing.parser.model.Row
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.Currency
|
import java.util.Currency
|
||||||
|
|
||||||
|
@ -15,9 +16,9 @@ class CodeGenerator {
|
||||||
|
|
||||||
matchedCodeLists.forEach { (type, codeLists) ->
|
matchedCodeLists.forEach { (type, codeLists) ->
|
||||||
val (columns, rows) = if (type == CodeListType.IsoCurrencyCodes) mergeCurrencyData(codeLists.first, codeLists.second!!) else {
|
val (columns, rows) = if (type == CodeListType.IsoCurrencyCodes) mergeCurrencyData(codeLists.first, codeLists.second!!) else {
|
||||||
// Factur-X has the better column names and often also a Description column
|
|
||||||
reorder(map(filter(
|
reorder(map(filter(
|
||||||
if (codeLists.second != null) codeLists.second!!.columns to codeLists.second!!.rows
|
// Factur-X (= codeLists.second) has the better column names and often also a Description column
|
||||||
|
if (codeLists.second != null) codeLists.second!!.columns to codeLists.second!!.rows
|
||||||
else codeLists.first.columns to codeLists.first.rows
|
else codeLists.first.columns to codeLists.first.rows
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
@ -29,7 +30,7 @@ class CodeGenerator {
|
||||||
writer.appendLine("enum class ${type.className}(${columns.joinToString(", ") { "val ${getPropertyName(it)}: ${getDataType(it, columns, rows)}" } }) {")
|
writer.appendLine("enum class ${type.className}(${columns.joinToString(", ") { "val ${getPropertyName(it)}: ${getDataType(it, columns, rows)}" } }) {")
|
||||||
|
|
||||||
rows.forEach { row ->
|
rows.forEach { row ->
|
||||||
writer.appendLine("\t${getEnumName(columns, row)}(${row.joinToString(", ") { getPropertyValue(it) } }),")
|
writer.appendLine("\t${getEnumName(columns, row.values)}(${row.values.joinToString(", ") { getPropertyValue(it) } }),")
|
||||||
}
|
}
|
||||||
writer.append("}")
|
writer.append("}")
|
||||||
}
|
}
|
||||||
|
@ -42,7 +43,7 @@ class CodeGenerator {
|
||||||
// ElectronicAddressScheme: ignore Source
|
// ElectronicAddressScheme: ignore Source
|
||||||
// Unit: ignore Source
|
// Unit: ignore Source
|
||||||
// PaymentMeansCodeFacturX: ignore Sens
|
// PaymentMeansCodeFacturX: ignore Sens
|
||||||
private fun filter(columnsAndRows: Pair<List<Column>, List<List<Any?>>>): Pair<List<Column>, List<List<Any?>>> {
|
private fun filter(columnsAndRows: Pair<List<Column>, List<Row>>): Pair<List<Column>, List<Row>> {
|
||||||
val (columns, rows) = columnsAndRows
|
val (columns, rows) = columnsAndRows
|
||||||
val columnToIgnore = columns.firstOrNull { it.name == "Source" || it.name == "Comment" || it.name == "Sens" || it.name == "French Name" }
|
val columnToIgnore = columns.firstOrNull { it.name == "Source" || it.name == "Comment" || it.name == "Sens" || it.name == "French Name" }
|
||||||
|
|
||||||
|
@ -51,10 +52,10 @@ class CodeGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
val indexToIgnore = columns.indexOf(columnToIgnore)
|
val indexToIgnore = columns.indexOf(columnToIgnore)
|
||||||
return columns.filterIndexed { index, _ -> index != indexToIgnore } to rows.map { it.filterIndexed { index, _ -> index != indexToIgnore } }
|
return columns.filterIndexed { index, _ -> index != indexToIgnore } to rows.onEach { it.removeValueAtIndex(indexToIgnore) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun map(columnsAndRows: Pair<List<Column>, List<List<Any?>>>): Pair<List<Column>, List<List<Any?>>> {
|
private fun map(columnsAndRows: Pair<List<Column>, List<Row>>): Pair<List<Column>, List<Row>> {
|
||||||
val (columns, rows) = columnsAndRows
|
val (columns, rows) = columnsAndRows
|
||||||
val useForColumn = columns.firstOrNull { it.name == "EN16931 interpretation" }
|
val useForColumn = columns.firstOrNull { it.name == "EN16931 interpretation" }
|
||||||
|
|
||||||
|
@ -64,10 +65,10 @@ class CodeGenerator {
|
||||||
removeAt(index)
|
removeAt(index)
|
||||||
add(Column(columns.last().index + 1, "UseFor", "InvoiceTypeUseFor", "UseFor"))
|
add(Column(columns.last().index + 1, "UseFor", "InvoiceTypeUseFor", "UseFor"))
|
||||||
}
|
}
|
||||||
val modifiedRows = rows.map { it.toMutableList().apply {
|
val modifiedRows = rows.onEach {
|
||||||
val useFor = removeAt(index)?.toString()
|
val useFor = it.removeValueAtIndex(index)?.toString()
|
||||||
add(if (useFor == "Credit Note") InvoiceTypeUseFor.CreditNote else InvoiceTypeUseFor.Invoice)
|
it.addValue(if (useFor == "Credit Note") InvoiceTypeUseFor.CreditNote else InvoiceTypeUseFor.Invoice)
|
||||||
}}
|
}
|
||||||
|
|
||||||
return modifiedColumns to modifiedRows
|
return modifiedColumns to modifiedRows
|
||||||
}
|
}
|
||||||
|
@ -79,7 +80,7 @@ class CodeGenerator {
|
||||||
* For Countries move englishNames column to the end, so that alpha2Code and alpha3Code are the first and second column.
|
* For Countries move englishNames column to the end, so that alpha2Code and alpha3Code are the first and second column.
|
||||||
* For SchemeIdentifier move the schemeId column, which in most cases is null, to the end, so that the code is the first column.
|
* For SchemeIdentifier move the schemeId column, which in most cases is null, to the end, so that the code is the first column.
|
||||||
*/
|
*/
|
||||||
private fun reorder(columnsAndRows: Pair<List<Column>, List<List<Any?>>>): Pair<List<Column>, List<List<Any?>>> {
|
private fun reorder(columnsAndRows: Pair<List<Column>, List<Row>>): Pair<List<Column>, List<Row>> {
|
||||||
val (columns, rows) = columnsAndRows
|
val (columns, rows) = columnsAndRows
|
||||||
val reorderFirstColumn = columns.first().name in listOf("English Name", "Scheme ID")
|
val reorderFirstColumn = columns.first().name in listOf("English Name", "Scheme ID")
|
||||||
|
|
||||||
|
@ -89,10 +90,10 @@ class CodeGenerator {
|
||||||
this.add(reorderedColumn)
|
this.add(reorderedColumn)
|
||||||
}
|
}
|
||||||
|
|
||||||
val reorderedRows = rows.map { it.toMutableList().apply {
|
val reorderedRows = rows.onEach {
|
||||||
val reorderedRow = this.removeAt(0)
|
val reorderedRow = it.removeValueAtIndex(0)
|
||||||
this.add(reorderedRow)
|
it.addValue(reorderedRow)
|
||||||
}}
|
}
|
||||||
|
|
||||||
return reorderedColumns to reorderedRows
|
return reorderedColumns to reorderedRows
|
||||||
}
|
}
|
||||||
|
@ -100,7 +101,7 @@ class CodeGenerator {
|
||||||
return columnsAndRows
|
return columnsAndRows
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mergeCurrencyData(cefCodeList: CodeList, zugferdCodeList: net.codinux.invoicing.parser.excel.CodeList): Pair<List<Column>, List<List<Any?>>> {
|
private fun mergeCurrencyData(cefCodeList: CodeList, zugferdCodeList: net.codinux.invoicing.parser.excel.CodeList): Pair<List<Column>, List<Row>> {
|
||||||
val columns = listOf(
|
val columns = listOf(
|
||||||
Column(0, "alpha3Code", "String", "alpha3Code"),
|
Column(0, "alpha3Code", "String", "alpha3Code"),
|
||||||
Column(1, "currencySymbol", "String", "currencySymbol"),
|
Column(1, "currencySymbol", "String", "currencySymbol"),
|
||||||
|
@ -108,13 +109,13 @@ class CodeGenerator {
|
||||||
Column(3, "countries", "Set<String>", "countries")
|
Column(3, "countries", "Set<String>", "countries")
|
||||||
)
|
)
|
||||||
|
|
||||||
val cefByIsoCode = cefCodeList.rows.associateBy { it[0] }
|
val cefByIsoCode = cefCodeList.rows.associateBy { it.values[0] }
|
||||||
val zugferdByIsoCode = zugferdCodeList.rows.groupBy { it[2] }
|
val zugferdByIsoCode = zugferdCodeList.rows.groupBy { it.values[2] }
|
||||||
val availableCurrencies = Currency.getAvailableCurrencies().associateBy { it.currencyCode } // TODO: there are 52 currencies in availableCurrencies that are not in CEF and Zugferd list
|
val availableCurrencies = Currency.getAvailableCurrencies().associateBy { it.currencyCode } // TODO: there are 52 currencies in availableCurrencies that are not in CEF and Zugferd list
|
||||||
|
|
||||||
val rows = cefByIsoCode.map { (isoCode, cefRow) ->
|
val rows = cefByIsoCode.map { (isoCode, cefRow) ->
|
||||||
val zugferdRows = zugferdByIsoCode[isoCode] ?: emptyList()
|
val zugferdRows = zugferdByIsoCode[isoCode] ?: emptyList()
|
||||||
listOf(isoCode, availableCurrencies[isoCode]?.symbol, cefRow[1], zugferdRows.map { it[0] }.toSet())
|
Row(listOf(isoCode, availableCurrencies[isoCode]?.symbol, cefRow.values[1], zugferdRows.map { it.values[0] }.toSet()))
|
||||||
}
|
}
|
||||||
|
|
||||||
return columns to rows
|
return columns to rows
|
||||||
|
@ -151,9 +152,9 @@ class CodeGenerator {
|
||||||
return "\"${value.toString().replace("\n", "").replace('"', '\'')}\""
|
return "\"${value.toString().replace("\n", "").replace('"', '\'')}\""
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getDataType(column: Column, columns: List<Column>, rows: List<List<Any?>>): String {
|
private fun getDataType(column: Column, columns: List<Column>, rows: List<Row>): String {
|
||||||
val index = columns.indexOf(column)
|
val index = columns.indexOf(column)
|
||||||
val containsNullValues = rows.any { it[index] == null }
|
val containsNullValues = rows.any { it.values[index] == null }
|
||||||
|
|
||||||
return when (column.dataType) {
|
return when (column.dataType) {
|
||||||
"string" -> "String" + (if (containsNullValues) "?" else "")
|
"string" -> "String" + (if (containsNullValues) "?" else "")
|
||||||
|
|
|
@ -2,6 +2,7 @@ package net.codinux.invoicing.parser.excel
|
||||||
|
|
||||||
import net.codinux.invoicing.parser.model.CodeListType
|
import net.codinux.invoicing.parser.model.CodeListType
|
||||||
import net.codinux.invoicing.parser.model.Column
|
import net.codinux.invoicing.parser.model.Column
|
||||||
|
import net.codinux.invoicing.parser.model.Row
|
||||||
|
|
||||||
data class CodeList(
|
data class CodeList(
|
||||||
val type: CodeListType,
|
val type: CodeListType,
|
||||||
|
@ -10,7 +11,7 @@ data class CodeList(
|
||||||
val usedInInvoiceFields: String?,
|
val usedInInvoiceFields: String?,
|
||||||
val additionalUsedInInvoiceFields: String?,
|
val additionalUsedInInvoiceFields: String?,
|
||||||
val columns: List<Column>,
|
val columns: List<Column>,
|
||||||
val rows: List<List<Any?>>
|
val rows: List<Row>
|
||||||
) {
|
) {
|
||||||
override fun toString() = "$name${usedInInvoiceFields?.let { ", $it" } ?: ""}"
|
override fun toString() = "$name${usedInInvoiceFields?.let { ", $it" } ?: ""}"
|
||||||
}
|
}
|
|
@ -76,9 +76,10 @@ class ZugferdExcelCodeListsParser {
|
||||||
|
|
||||||
// if this Code List has a description, ignore every second row, as in the second row is the description
|
// if this Code List has a description, ignore every second row, as in the second row is the description
|
||||||
val rows = allRows.drop(5).filterIndexed { index, _ -> isTypeWithDescription == false || index % 2 == 0 }.map { row ->
|
val rows = allRows.drop(5).filterIndexed { index, _ -> isTypeWithDescription == false || index % 2 == 0 }.map { row ->
|
||||||
columnIndices.map { getCellValue(row.getCell(it)) } +
|
val values = columnIndices.map { getCellValue(row.getCell(it)) } +
|
||||||
( if (isTypeWithDescription) listOf(getCellValue(allRows.get(row.rowNum + 1).getCell(descriptionColumnIndex))) else emptyList())
|
( if (isTypeWithDescription) listOf(getCellValue(allRows.get(row.rowNum + 1).getCell(descriptionColumnIndex))) else emptyList())
|
||||||
}.filterNot { it.all { it == null } } // filter out empty rows
|
net.codinux.invoicing.parser.model.Row(values)
|
||||||
|
}.filterNot { it.values.all { it == null } } // filter out empty rows
|
||||||
|
|
||||||
if (isTypeWithDescription) {
|
if (isTypeWithDescription) {
|
||||||
columns.add(Column(indexOfNextEmptyCell!! - 1, "Description", "String", "Description"))
|
columns.add(Column(indexOfNextEmptyCell!! - 1, "Description", "String", "Description"))
|
||||||
|
|
|
@ -4,6 +4,7 @@ import com.helger.genericode.Genericode10CodeListMarshaller
|
||||||
import com.helger.xml.serialize.read.DOMReader
|
import com.helger.xml.serialize.read.DOMReader
|
||||||
import net.codinux.invoicing.parser.model.CodeListType
|
import net.codinux.invoicing.parser.model.CodeListType
|
||||||
import net.codinux.invoicing.parser.model.Column
|
import net.codinux.invoicing.parser.model.Column
|
||||||
|
import net.codinux.invoicing.parser.model.Row
|
||||||
import net.codinux.log.logger
|
import net.codinux.log.logger
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
|
@ -44,7 +45,7 @@ class CefGenericodeCodelistsParser {
|
||||||
val columns = columnSet?.columnChoice.orEmpty().filterIsInstance<com.helger.genericode.v10.Column>().mapIndexed { index, col -> Column(index, col.id!!, col.data?.type!!, col.shortNameValue!!) }
|
val columns = columnSet?.columnChoice.orEmpty().filterIsInstance<com.helger.genericode.v10.Column>().mapIndexed { index, col -> Column(index, col.id!!, col.data?.type!!, col.shortNameValue!!) }
|
||||||
val rows = simpleCodeList?.row.orEmpty().map { row -> columns.map { column -> row.value.firstOrNull { (it.columnRef as? com.helger.genericode.v10.Column)?.id == column.id }?.simpleValueValue } }
|
val rows = simpleCodeList?.row.orEmpty().map { row -> columns.map { column -> row.value.firstOrNull { (it.columnRef as? com.helger.genericode.v10.Column)?.id == column.id }?.simpleValueValue } }
|
||||||
|
|
||||||
return CodeList(getType(name), name, version, canonicalUri, canonicalVersionUri, columns, rows)
|
return CodeList(getType(name), name, version, canonicalUri, canonicalVersionUri, columns, rows.map { Row(it) })
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getType(name: String): CodeListType = when (name) {
|
private fun getType(name: String): CodeListType = when (name) {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package net.codinux.invoicing.parser.genericode
|
||||||
|
|
||||||
import net.codinux.invoicing.parser.model.CodeListType
|
import net.codinux.invoicing.parser.model.CodeListType
|
||||||
import net.codinux.invoicing.parser.model.Column
|
import net.codinux.invoicing.parser.model.Column
|
||||||
|
import net.codinux.invoicing.parser.model.Row
|
||||||
|
|
||||||
class CodeList(
|
class CodeList(
|
||||||
val type: CodeListType,
|
val type: CodeListType,
|
||||||
|
@ -10,7 +11,7 @@ class CodeList(
|
||||||
val canonicalUri: String?,
|
val canonicalUri: String?,
|
||||||
val canonicalVersionUri: String?,
|
val canonicalVersionUri: String?,
|
||||||
val columns: List<Column>,
|
val columns: List<Column>,
|
||||||
val rows: List<List<String?>>
|
val rows: List<Row>
|
||||||
) {
|
) {
|
||||||
override fun toString() = "$name ${columns.joinToString { it.name }}, ${rows.size} rows"
|
override fun toString() = "$name ${columns.joinToString { it.name }}, ${rows.size} rows"
|
||||||
}
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package net.codinux.invoicing.parser.model
|
||||||
|
|
||||||
|
class Row(
|
||||||
|
values: List<Any?>
|
||||||
|
) {
|
||||||
|
|
||||||
|
val values: List<Any?> = values.toMutableList()
|
||||||
|
|
||||||
|
fun addValue(value: Any?) {
|
||||||
|
(values as? MutableList<Any?>)?.add(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeValueAtIndex(index: Int): Any? =
|
||||||
|
(values as? MutableList<Any?>)?.removeAt(index)
|
||||||
|
|
||||||
|
|
||||||
|
override fun toString() = values.joinToString()
|
||||||
|
}
|
Loading…
Reference in New Issue