diff --git a/fints4k/src/main/kotlin/net/dankito/banking/fints/model/AccountTransaction.kt b/fints4k/src/main/kotlin/net/dankito/banking/fints/model/AccountTransaction.kt index cf61eff6..8ac24cf3 100644 --- a/fints4k/src/main/kotlin/net/dankito/banking/fints/model/AccountTransaction.kt +++ b/fints4k/src/main/kotlin/net/dankito/banking/fints/model/AccountTransaction.kt @@ -6,27 +6,54 @@ import java.util.* open class AccountTransaction( + val account: AccountData, val amount: BigDecimal, val currency: String, - val usage: String, + val isReversal: Boolean, + val unparsedUsage: String, val bookingDate: Date, val otherPartyName: String?, val otherPartyBankCode: String?, val otherPartyAccountId: String?, val bookingText: String?, - val valueDate: Date?, + val valueDate: Date, + val statementNumber: Int, + val sequenceNumber: Int?, val openingBalance: BigDecimal?, val closingBalance: BigDecimal?, - val account: AccountData - // TODO: may also add other values from parsed usage lines + + val endToEndReference: String?, + val customerReference: String?, + val mandateReference: String?, + val creditorIdentifier: String?, + val originatorsIdentificationCode: String?, + val compensationAmount: String?, + val originalAmount: String?, + val sepaUsage: String?, + val deviantOriginator: String?, + val deviantRecipient: String?, + val usageWithNoSpecialType: String?, + val primaNotaNumber: String?, + val textKeySupplement: String?, + + val currencyType: String?, + val bookingKey: String, + val referenceForTheAccountOwner: String, + val referenceOfTheAccountServicingInstitution: String?, + val supplementaryDetails: String?, + + val transactionReferenceNumber: String, + val relatedReferenceNumber: String? ) { // for object deserializers - internal constructor() : this(0.toBigDecimal(),"", "", Date(), null, null, null, null, null, null, null, AccountData()) + internal constructor() : this(AccountData(), 0.toBigDecimal(),"", false, "", Date(), null, null, null, null, Date(), 0, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, + null, "", "", null, null, "", null) override fun toString(): String { - return "${DateFormat.getDateInstance(DateFormat.MEDIUM).format(bookingDate)} $amount $otherPartyName: $usage" + return "${DateFormat.getDateInstance(DateFormat.MEDIUM).format(bookingDate)} $amount $otherPartyName: $unparsedUsage" } } \ No newline at end of file diff --git a/fints4k/src/main/kotlin/net/dankito/banking/fints/transactions/Mt940AccountTransactionsParser.kt b/fints4k/src/main/kotlin/net/dankito/banking/fints/transactions/Mt940AccountTransactionsParser.kt index 93591de3..d927fd58 100644 --- a/fints4k/src/main/kotlin/net/dankito/banking/fints/transactions/Mt940AccountTransactionsParser.kt +++ b/fints4k/src/main/kotlin/net/dankito/banking/fints/transactions/Mt940AccountTransactionsParser.kt @@ -45,18 +45,44 @@ open class Mt940AccountTransactionsParser @JvmOverloads constructor( protected open fun mapToAccountTransaction(statement: AccountStatement, transaction: Transaction, account: AccountData): AccountTransaction { return AccountTransaction( + account, mapAmount(transaction.statementLine), statement.closingBalance.currency, - transaction.information?.sepaUsage ?: transaction.information?.usage ?: "", + transaction.statementLine.isReversal, + transaction.information?.unparsedUsage ?: "", transaction.statementLine.bookingDate ?: statement.closingBalance.bookingDate, transaction.information?.otherPartyName, transaction.information?.otherPartyBankCode, transaction.information?.otherPartyAccountId, transaction.information?.bookingText, transaction.statementLine.valueDate, + statement.statementNumber, + statement.sequenceNumber, mapAmount(statement.openingBalance), // TODO: that's not true, these are the opening and closing balance of mapAmount(statement.closingBalance), // all transactions of this day, not this specific transaction's ones - account + + transaction.information?.endToEndReference, + transaction.information?.customerReference, + transaction.information?.mandateReference, + transaction.information?.creditorIdentifier, + transaction.information?.originatorsIdentificationCode, + transaction.information?.compensationAmount, + transaction.information?.originalAmount, + transaction.information?.sepaUsage, + transaction.information?.deviantOriginator, + transaction.information?.deviantRecipient, + transaction.information?.usageWithNoSpecialType, + transaction.information?.primaNotaNumber, + transaction.information?.textKeySupplement, + + transaction.statementLine.currencyType, + transaction.statementLine.bookingKey, + transaction.statementLine.referenceForTheAccountOwner, + transaction.statementLine.referenceOfTheAccountServicingInstitution, + transaction.statementLine.supplementaryDetails, + + statement.transactionReferenceNumber, + statement.relatedReferenceNumber ) } diff --git a/fints4k/src/main/kotlin/net/dankito/banking/fints/transactions/mt940/Mt940Parser.kt b/fints4k/src/main/kotlin/net/dankito/banking/fints/transactions/mt940/Mt940Parser.kt index 6065af91..1c1aed82 100644 --- a/fints4k/src/main/kotlin/net/dankito/banking/fints/transactions/mt940/Mt940Parser.kt +++ b/fints4k/src/main/kotlin/net/dankito/banking/fints/transactions/mt940/Mt940Parser.kt @@ -57,6 +57,18 @@ open class Mt940Parser : IMt940Parser { val UsageTypePattern = Pattern.compile("\\w{4}\\+") + const val EndToEndReferenceUsageKey = "EREF+" + const val CustomerReferenceUsageKey = "KREF+" + const val MandateReferenceUsageKey = "MREF+" + const val CreditorIdentifierUsageKey = "CRED+" + const val OriginatorsIdentificationCodeUsageKey = "DEBT+" + const val CompensationAmountUsageKey = "COAM+" + const val OriginalAmountUsageKey = "OAMT+" + const val SepaUsageUsageKey = "SVWZ+" + const val DeviantOriginatorUsageKey = "ABWA+" + const val DeviantRecipientUsageKey = "ABWE+" + + private val log = LoggerFactory.getLogger(Mt940Parser::class.java) } @@ -362,36 +374,35 @@ open class Mt940Parser : IMt940Parser { * Weitere 4 Verwendungszwecke können zu den Feldschlüsseln 60 bis 63 eingestellt werden. */ protected open fun mapUsage(information: InformationToAccountOwner) { - val usageParts = getUsageParts(information) + val usageParts = getUsageParts(information.unparsedUsage) - usageParts.forEach { pair -> - setUsageLineValue(information, pair.first, pair.second) + usageParts.forEach { entry -> + setUsageLineValue(information, entry.key, entry.value) } } - protected open fun getUsageParts(information: InformationToAccountOwner): MutableList> { - val usage = information.usage + open fun getUsageParts(unparsedUsage: String): Map { var previousMatchType = "" var previousMatchEnd = 0 - val usageParts = mutableListOf>() - val matcher = UsageTypePattern.matcher(information.usage) + val usageParts = mutableMapOf() + val matcher = UsageTypePattern.matcher(unparsedUsage) while (matcher.find()) { if (previousMatchEnd > 0) { - val typeValue = usage.substring(previousMatchEnd, matcher.start()) + val typeValue = unparsedUsage.substring(previousMatchEnd, matcher.start()) - usageParts.add(Pair(previousMatchType, typeValue)) + usageParts[previousMatchType] = typeValue } - previousMatchType = usage.substring(matcher.start(), matcher.end()) + previousMatchType = unparsedUsage.substring(matcher.start(), matcher.end()) previousMatchEnd = matcher.end() } if (previousMatchEnd > 0) { - val typeValue = usage.substring(previousMatchEnd, usage.length) + val typeValue = unparsedUsage.substring(previousMatchEnd, unparsedUsage.length) - usageParts.add(Pair(previousMatchType, typeValue)) + usageParts[previousMatchType] = typeValue } return usageParts @@ -399,16 +410,16 @@ open class Mt940Parser : IMt940Parser { protected open fun setUsageLineValue(information: InformationToAccountOwner, usageType: String, typeValue: String) { when (usageType) { - "EREF+" -> information.endToEndReference = typeValue - "KREF+" -> information.customerReference = typeValue - "MREF+" -> information.mandateReference = typeValue - "CRED+" -> information.creditorIdentifier = typeValue - "DEBT+" -> information.originatorsIdentificationCode = typeValue - "COAM+" -> information.compensationAmount = typeValue - "OAMT+" -> information.originalAmount = typeValue - "SVWZ+" -> information.sepaUsage = typeValue - "ABWA+" -> information.deviantOriginator = typeValue - "ABWE+" -> information.deviantRecipient = typeValue + EndToEndReferenceUsageKey -> information.endToEndReference = typeValue + CustomerReferenceUsageKey -> information.customerReference = typeValue + MandateReferenceUsageKey -> information.mandateReference = typeValue + CreditorIdentifierUsageKey -> information.creditorIdentifier = typeValue + OriginatorsIdentificationCodeUsageKey -> information.originatorsIdentificationCode = typeValue + CompensationAmountUsageKey -> information.compensationAmount = typeValue + OriginalAmountUsageKey -> information.originalAmount = typeValue + SepaUsageUsageKey -> information.sepaUsage = typeValue + DeviantOriginatorUsageKey -> information.deviantOriginator = typeValue + DeviantRecipientUsageKey -> information.deviantRecipient = typeValue else -> information.usageWithNoSpecialType = typeValue } } diff --git a/fints4k/src/main/kotlin/net/dankito/banking/fints/transactions/mt940/model/AccountStatement.kt b/fints4k/src/main/kotlin/net/dankito/banking/fints/transactions/mt940/model/AccountStatement.kt index 70c67c98..41f70777 100644 --- a/fints4k/src/main/kotlin/net/dankito/banking/fints/transactions/mt940/model/AccountStatement.kt +++ b/fints4k/src/main/kotlin/net/dankito/banking/fints/transactions/mt940/model/AccountStatement.kt @@ -20,7 +20,7 @@ open class AccountStatement( * * Max length = 16 */ - val referenceReferenceNumber: String?, + val relatedReferenceNumber: String?, /** * xxxxxxxxxxx/Konto-Nr. oder yyyyyyyy/Konto-Nr. diff --git a/fints4k/src/main/kotlin/net/dankito/banking/fints/transactions/mt940/model/InformationToAccountOwner.kt b/fints4k/src/main/kotlin/net/dankito/banking/fints/transactions/mt940/model/InformationToAccountOwner.kt index 6f7f995e..a30747ce 100644 --- a/fints4k/src/main/kotlin/net/dankito/banking/fints/transactions/mt940/model/InformationToAccountOwner.kt +++ b/fints4k/src/main/kotlin/net/dankito/banking/fints/transactions/mt940/model/InformationToAccountOwner.kt @@ -2,7 +2,7 @@ package net.dankito.banking.fints.transactions.mt940.model open class InformationToAccountOwner( - val usage: String, + val unparsedUsage: String, val otherPartyName: String?, val otherPartyBankCode: String?, val otherPartyAccountId: String?, @@ -35,7 +35,7 @@ open class InformationToAccountOwner( override fun toString(): String { - return "$otherPartyName $usage" + return "$otherPartyName $unparsedUsage" } } \ No newline at end of file diff --git a/fints4k/src/main/kotlin/net/dankito/banking/fints/transactions/mt940/model/StatementLine.kt b/fints4k/src/main/kotlin/net/dankito/banking/fints/transactions/mt940/model/StatementLine.kt index 9a3d1733..72a85932 100644 --- a/fints4k/src/main/kotlin/net/dankito/banking/fints/transactions/mt940/model/StatementLine.kt +++ b/fints4k/src/main/kotlin/net/dankito/banking/fints/transactions/mt940/model/StatementLine.kt @@ -19,7 +19,7 @@ open class StatementLine( */ val isCredit: Boolean, - val isCancellation: Boolean, + val isReversal: Boolean, /** * Valuta (JJMMTT) @@ -58,9 +58,9 @@ open class StatementLine( */ val bookingKey: String, - val customerReference: String, + val referenceForTheAccountOwner: String, - val bankReference: String?, + val referenceOfTheAccountServicingInstitution: String?, val supplementaryDetails: String? = null diff --git a/fints4k/src/test/kotlin/net/dankito/banking/fints/transactions/Mt940ParserTest.kt b/fints4k/src/test/kotlin/net/dankito/banking/fints/transactions/Mt940ParserTest.kt index b872d004..dd0f9541 100644 --- a/fints4k/src/test/kotlin/net/dankito/banking/fints/transactions/Mt940ParserTest.kt +++ b/fints4k/src/test/kotlin/net/dankito/banking/fints/transactions/Mt940ParserTest.kt @@ -249,7 +249,7 @@ class Mt940ParserTest : FinTsTestBase() { bookingDate: Date? = valueDate) { assertThat(statementLine.isCredit).isEqualTo(isCredit) - assertThat(statementLine.isCancellation).isFalse() + assertThat(statementLine.isReversal).isFalse() assertThat(statementLine.valueDate).isEqualTo(valueDate) assertThat(statementLine.bookingDate).isEqualTo(bookingDate) assertThat(statementLine.amount).isEqualTo(amount) diff --git a/persistence/LuceneBankingPersistence/src/main/kotlin/net/dankito/banking/persistence/LuceneBankingPersistence.kt b/persistence/LuceneBankingPersistence/src/main/kotlin/net/dankito/banking/persistence/LuceneBankingPersistence.kt index f14ae354..834fe869 100644 --- a/persistence/LuceneBankingPersistence/src/main/kotlin/net/dankito/banking/persistence/LuceneBankingPersistence.kt +++ b/persistence/LuceneBankingPersistence/src/main/kotlin/net/dankito/banking/persistence/LuceneBankingPersistence.kt @@ -72,9 +72,9 @@ open class LuceneBankingPersistence( fields.storedField(BookingDateFieldName, transaction.bookingDate), fields.storedField(AmountFieldName, transaction.amount), fields.storedField(CurrencyFieldName, transaction.currency), - fields.nullableStoredField(BalanceFieldName, transaction.balance), + fields.nullableStoredField(BalanceFieldName, transaction.closingBalance), // TODO: remove - fields.sortField(BookingDateSortFieldName, transaction.bookingDate) + fields.sortField(BookingDateSortFieldName, transaction.bookingDate) // TODO: sort by valueDate ) } diff --git a/persistence/LuceneBankingPersistence/src/test/kotlin/net/dankito/banking/search/LuceneRemitteeSearcherTest.kt b/persistence/LuceneBankingPersistence/src/test/kotlin/net/dankito/banking/search/LuceneRemitteeSearcherTest.kt index b7ecacca..85f1e75d 100644 --- a/persistence/LuceneBankingPersistence/src/test/kotlin/net/dankito/banking/search/LuceneRemitteeSearcherTest.kt +++ b/persistence/LuceneBankingPersistence/src/test/kotlin/net/dankito/banking/search/LuceneRemitteeSearcherTest.kt @@ -211,7 +211,7 @@ class LuceneRemitteeSearcherTest { otherPartyName: String = randomString(), otherPartyBankCode: String = randomString(), otherPartyAccountId: String = randomString(), usage: String = randomString()): AccountTransaction { - return AccountTransaction(amount, bookingDate, usage, otherPartyName, otherPartyBankCode, otherPartyAccountId, null, null, "EUR", bankAccount) + return AccountTransaction(bankAccount, amount, usage, bookingDate, otherPartyName, otherPartyBankCode, otherPartyAccountId, null, bookingDate) } private fun randomString(): String { diff --git a/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountTransactionsTable.kt b/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountTransactionsTable.kt index 222a3c25..ef12378c 100644 --- a/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountTransactionsTable.kt +++ b/ui/BankingJavaFxControls/src/main/kotlin/net/dankito/banking/ui/javafx/controls/AccountTransactionsTable.kt @@ -72,7 +72,7 @@ open class AccountTransactionsTable @JvmOverloads constructor( } } - label(it.usage ?: "") { + label(it.usage) { vboxConstraints { margin = LabelMargin } diff --git a/ui/BankingUiCommon/src/main/java/net/dankito/banking/ui/model/AccountTransaction.kt b/ui/BankingUiCommon/src/main/java/net/dankito/banking/ui/model/AccountTransaction.kt index d533beb3..dfb3c7a5 100644 --- a/ui/BankingUiCommon/src/main/java/net/dankito/banking/ui/model/AccountTransaction.kt +++ b/ui/BankingUiCommon/src/main/java/net/dankito/banking/ui/model/AccountTransaction.kt @@ -9,20 +9,57 @@ import java.util.* @JsonIdentityInfo(property = "id", generator = ObjectIdGenerators.PropertyGenerator::class) // to avoid stack overflow due to circular references open class AccountTransaction( + val bankAccount: BankAccount, val amount: BigDecimal, + val currency: String, + val isReversal: Boolean, + val unparsedUsage: String, val bookingDate: Date, - val usage: String, val otherPartyName: String?, val otherPartyBankCode: String?, val otherPartyAccountId: String?, val bookingText: String?, - val balance: BigDecimal?, - val currency: String, - val bankAccount: BankAccount + val valueDate: Date, + val statementNumber: Int, + val sequenceNumber: Int?, + val openingBalance: BigDecimal?, + val closingBalance: BigDecimal?, + + val endToEndReference: String?, + val customerReference: String?, + val mandateReference: String?, + val creditorIdentifier: String?, + val originatorsIdentificationCode: String?, + val compensationAmount: String?, + val originalAmount: String?, + val sepaUsage: String?, + val deviantOriginator: String?, + val deviantRecipient: String?, + val usageWithNoSpecialType: String?, + val primaNotaNumber: String?, + val textKeySupplement: String?, + + val currencyType: String?, + val bookingKey: String, + val referenceForTheAccountOwner: String, + val referenceOfTheAccountServicingInstitution: String?, + val supplementaryDetails: String?, + + val transactionReferenceNumber: String, + val relatedReferenceNumber: String? ) { + constructor(bankAccount: BankAccount, amount: BigDecimal, unparsedUsage: String, bookingDate: Date, + otherPartyName: String?, otherPartyBankCode: String?, otherPartyAccountId: String?, + bookingText: String?, valueDate: Date) + : this(bankAccount, amount, "EUR", false, unparsedUsage, bookingDate, + otherPartyName, otherPartyBankCode, otherPartyAccountId, bookingText, valueDate, + 0, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "", "", null, null, "", null) + // for object deserializers - internal constructor() : this(BigDecimal.ZERO, Date(),"", null, null, null, null, BigDecimal.ZERO, "", BankAccount()) + internal constructor() : this(BankAccount(), BigDecimal.ZERO, "", false,"", Date(), null, null, null, null, Date(), 0, null, BigDecimal.ZERO, BigDecimal.ZERO, + null, null, null, null, null, null, null, null, null, null, null, null, null, + null, "", "", null, null, "", null) var id: String = UUID.randomUUID().toString() @@ -32,6 +69,9 @@ open class AccountTransaction( val showOtherPartyName: Boolean get() = otherPartyName.isNullOrBlank() == false /* && type != "ENTGELTABSCHLUSS" && type != "AUSZAHLUNG" */ // TODO + val usage: String + get() = sepaUsage ?: unparsedUsage + override fun equals(other: Any?): Boolean { if (this === other) return true @@ -39,7 +79,7 @@ open class AccountTransaction( if (amount.compareTo(other.amount) != 0) return false if (currency != other.currency) return false - if (usage != other.usage) return false + if (unparsedUsage != other.unparsedUsage) return false if (bookingDate != other.bookingDate) return false if (otherPartyName != other.otherPartyName) return false if (otherPartyBankCode != other.otherPartyBankCode) return false @@ -53,7 +93,7 @@ open class AccountTransaction( override fun hashCode(): Int { var result = amount.hashCode() result = 31 * result + currency.hashCode() - result = 31 * result + usage.hashCode() + result = 31 * result + unparsedUsage.hashCode() result = 31 * result + bookingDate.hashCode() result = 31 * result + (otherPartyName?.hashCode() ?: 0) result = 31 * result + (otherPartyBankCode?.hashCode() ?: 0) diff --git a/ui/fints4kBankingClient/src/main/kotlin/net/dankito/banking/mapper/fints4kModelMapper.kt b/ui/fints4kBankingClient/src/main/kotlin/net/dankito/banking/mapper/fints4kModelMapper.kt index 05feaa17..d7e0b0e6 100644 --- a/ui/fints4kBankingClient/src/main/kotlin/net/dankito/banking/mapper/fints4kModelMapper.kt +++ b/ui/fints4kBankingClient/src/main/kotlin/net/dankito/banking/mapper/fints4kModelMapper.kt @@ -175,16 +175,44 @@ open class fints4kModelMapper { open fun mapTransaction(bankAccount: BankAccount, transaction: net.dankito.banking.fints.model.AccountTransaction): AccountTransaction { return AccountTransaction( + bankAccount, transaction.amount, + transaction.currency, + transaction.isReversal, + transaction.unparsedUsage, transaction.bookingDate, - transaction.usage, transaction.otherPartyName, transaction.otherPartyBankCode, transaction.otherPartyAccountId, transaction.bookingText, + transaction.valueDate, + transaction.statementNumber, + transaction.sequenceNumber, + transaction.openingBalance, transaction.closingBalance, - transaction.currency, - bankAccount + + transaction.endToEndReference, + transaction.customerReference, + transaction.mandateReference, + transaction.creditorIdentifier, + transaction.originatorsIdentificationCode, + transaction.compensationAmount, + transaction.originalAmount, + transaction.sepaUsage, + transaction.deviantOriginator, + transaction.deviantRecipient, + transaction.usageWithNoSpecialType, + transaction.primaNotaNumber, + transaction.textKeySupplement, + + transaction.currencyType, + transaction.bookingKey, + transaction.referenceForTheAccountOwner, + transaction.referenceOfTheAccountServicingInstitution, + transaction.supplementaryDetails, + + transaction.transactionReferenceNumber, + transaction.relatedReferenceNumber ) } diff --git a/ui/hbci4jBankingClient/src/main/kotlin/net/dankito/banking/util/AccountTransactionMapper.kt b/ui/hbci4jBankingClient/src/main/kotlin/net/dankito/banking/util/AccountTransactionMapper.kt index 3c824493..79cb56c6 100644 --- a/ui/hbci4jBankingClient/src/main/kotlin/net/dankito/banking/util/AccountTransactionMapper.kt +++ b/ui/hbci4jBankingClient/src/main/kotlin/net/dankito/banking/util/AccountTransactionMapper.kt @@ -1,8 +1,10 @@ package net.dankito.banking.util +import net.dankito.banking.fints.transactions.mt940.Mt940Parser import net.dankito.banking.ui.model.AccountTransaction import net.dankito.banking.ui.model.BankAccount import org.kapott.hbci.GV_Result.GVRKUms +import org.kapott.hbci.structures.Value import org.slf4j.LoggerFactory import java.math.BigDecimal import java.text.SimpleDateFormat @@ -25,8 +27,10 @@ open class AccountTransactionMapper { open fun mapAccountTransactions(bankAccount: BankAccount, result: GVRKUms): List { val entries = ArrayList() - result.flatData.forEach { transaction -> - entries.add(mapAccountingEntry(bankAccount, transaction)) + result.dataPerDay.forEach { btag -> + btag.lines.forEach { transaction -> + entries.add(mapAccountingEntry(bankAccount, btag, transaction)) + } } log.debug("Retrieved ${result.flatData.size} accounting entries") @@ -34,129 +38,50 @@ open class AccountTransactionMapper { return entries.sortedByDescending { it.bookingDate } } - protected open fun mapAccountingEntry(bankAccount: BankAccount, transaction: GVRKUms.UmsLine): AccountTransaction { + protected open fun mapAccountingEntry(bankAccount: BankAccount, btag: GVRKUms.BTag, transaction: GVRKUms.UmsLine): AccountTransaction { + val unparsedUsage = transaction.usage.joinToString("") + val parsedUsage = Mt940Parser().getUsageParts(unparsedUsage) + val statementAndMaySequenceNumber = btag.counter.split('/') - val result = AccountTransaction(BigDecimal.valueOf(transaction.value.longValue).divide(BigDecimal.valueOf(100)), transaction.bdate, transaction.usage.joinToString(""), - if (transaction.other.name2.isNullOrBlank() == false) transaction.other.name + " " + transaction.other.name2 else transaction.other.name, - if (transaction.other.bic != null) transaction.other.bic else transaction.other.blz, - if (transaction.other.iban != null) transaction.other.iban else transaction.other.number, - transaction.text, BigDecimal.valueOf(transaction.saldo.value.longValue), transaction.value.curr, bankAccount) + val result = AccountTransaction(bankAccount, + mapValue(transaction.value), transaction.value.curr, transaction.isStorno, unparsedUsage, transaction.bdate, + transaction.other.name + (transaction.other.name2 ?: ""), + transaction.other.bic ?: transaction.other.blz, + transaction.other.iban ?: transaction.other.number, + transaction.text, transaction.valuta, + statementAndMaySequenceNumber[0].toInt(), + if (statementAndMaySequenceNumber.size > 1) statementAndMaySequenceNumber[1].toInt() else null, + mapValue(btag.start.value), mapValue(btag.end.value), -// mapUsage(transaction, result) + parsedUsage[Mt940Parser.EndToEndReferenceUsageKey], + parsedUsage[Mt940Parser.CustomerReferenceUsageKey], + parsedUsage[Mt940Parser.MandateReferenceUsageKey], + parsedUsage[Mt940Parser.CreditorIdentifierUsageKey], + parsedUsage[Mt940Parser.OriginatorsIdentificationCodeUsageKey], + parsedUsage[Mt940Parser.CompensationAmountUsageKey], + parsedUsage[Mt940Parser.OriginalAmountUsageKey], + parsedUsage[Mt940Parser.SepaUsageUsageKey], + parsedUsage[Mt940Parser.DeviantOriginatorUsageKey], + parsedUsage[Mt940Parser.DeviantRecipientUsageKey], + parsedUsage[""], + transaction.primanota, + transaction.addkey, + + null, + "", + transaction.customerref, + transaction.instref, + transaction.additional, + + "", + null + ) return result } - /** - * From https://sites.google.com/a/crem-solutions.de/doku/version-2012-neu/buchhaltung/03-zahlungsverkehr/05-e-banking/technische-beschreibung-der-mt940-sta-datei: - * - * Weitere 4 Verwendungszwecke können zu den Feldschlüsseln 60 bis 63 eingestellt werden. - * Jeder Bezeichner [z.B. EREF+] muss am Anfang eines Subfeldes [z. B. ?21] stehen. - * Bei Längenüberschreitung wird im nachfolgenden Subfeld ohne Wiederholung des Bezeichners fortgesetzt. Bei Wechsel des Bezeichners ist ein neues Subfeld zu beginnen. - * Belegung in der nachfolgenden Reihenfolge, wenn vorhanden: - * EREF+[ Ende-zu-Ende Referenz ] (DD-AT10; CT-AT41 - Angabe verpflichtend; NOTPROVIDED wird nicht eingestellt.) - * KREF+[Kundenreferenz] - * MREF+[Mandatsreferenz] (DD-AT01 - Angabe verpflichtend) - * CRED+[Creditor Identifier] (DD-AT02 - Angabe verpflichtend bei SEPA-Lastschriften, nicht jedoch bei SEPA-Rücklastschriften) - * DEBT+[Originators Identification Code](CT-AT10- Angabe verpflichtend,) - * Entweder CRED oder DEBT - * - * optional zusätzlich zur Einstellung in Feld 61, Subfeld 9: - * - * COAM+ [Compensation Amount / Summe aus Auslagenersatz und Bearbeitungsprovision bei einer nationalen Rücklastschrift sowie optionalem Zinsausgleich.] - * OAMT+[Original Amount] Betrag der ursprünglichen Lastschrift - * - * SVWZ+[SEPA-Verwendungszweck] (DD-AT22; CT-AT05 -Angabe verpflichtend, nicht jedoch bei R-Transaktionen) - * ABWA+[Abweichender Überweisender] (CT-AT08) / Abweichender Zahlungsempfänger (DD-AT38) ] (optional) - * ABWE+[Abweichender Zahlungsemp-fänger (CT-AT28) / Abweichender Zahlungspflichtiger ((DD-AT15)] (optional) - */ -// protected open fun mapUsage(buchung: GVRKUms.UmsLine, entry: AccountingEntry) { -// var lastUsageLineType = UsageLineType.ContinuationFromLastLine -// var typeValue = "" -// -// buchung.usage.forEach { line -> -// val (type, adjustedString) = getUsageLineType(line, entry) -// -// if (type == UsageLineType.ContinuationFromLastLine) { -// typeValue += (if(adjustedString[0].isUpperCase()) " " else "") + adjustedString -// } -// else if (lastUsageLineType != type) { -// if (lastUsageLineType != UsageLineType.ContinuationFromLastLine) { -// setUsageLineValue(entry, lastUsageLineType, typeValue) -// } -// -// typeValue = adjustedString -// lastUsageLineType = type -// } -// -// tryToParseBookingDateFromUsageLine(entry, adjustedString, typeValue) -// } -// -// if(lastUsageLineType != UsageLineType.ContinuationFromLastLine) { -// setUsageLineValue(entry, lastUsageLineType, typeValue) -// } -// } -// -// protected open fun setUsageLineValue(entry: AccountingEntry, lastUsageLineType: UsageLineType, typeValue: String) { -// entry.parsedUsages.add(typeValue) -// -// when (lastUsageLineType) { -// UsageLineType.EREF -> entry.endToEndReference = typeValue -// UsageLineType.KREF -> entry.kundenreferenz = typeValue -// UsageLineType.MREF -> entry.mandatsreferenz = typeValue -// UsageLineType.CRED -> entry.creditorIdentifier = typeValue -// UsageLineType.DEBT -> entry.originatorsIdentificationCode = typeValue -// UsageLineType.COAM -> entry.compensationAmount = typeValue -// UsageLineType.OAMT -> entry.originalAmount = typeValue -// UsageLineType.SVWZ -> entry.sepaVerwendungszweck = typeValue -// UsageLineType.ABWA -> entry.abweichenderAuftraggeber = typeValue -// UsageLineType.ABWE -> entry.abweichenderZahlungsempfaenger = typeValue -// UsageLineType.NoSpecialType -> entry.usageWithNoSpecialType = typeValue -// } -// } -// -// protected open fun getUsageLineType(line: String, entry: AccountingEntry): Pair { -// return when { -// line.startsWith("EREF+") -> Pair(UsageLineType.EREF, line.substring(5)) -// line.startsWith("KREF+") -> Pair(UsageLineType.KREF, line.substring(5)) -// line.startsWith("MREF+") -> Pair(UsageLineType.MREF, line.substring(5)) -// line.startsWith("CRED+") -> Pair(UsageLineType.CRED, line.substring(5)) -// line.startsWith("DEBT+") -> Pair(UsageLineType.DEBT, line.substring(5)) -// line.startsWith("COAM+") -> Pair(UsageLineType.COAM, line.substring(5)) -// line.startsWith("OAMT+") -> Pair(UsageLineType.OAMT, line.substring(5)) -// line.startsWith("SVWZ+") -> Pair(UsageLineType.SVWZ, line.substring(5)) -// line.startsWith("ABWA+") -> Pair(UsageLineType.ABWA, line.substring(5)) -// line.startsWith("ABWE+") -> Pair(UsageLineType.ABWE, line.substring(5)) -// entry.usage.startsWith(line) -> Pair(UsageLineType.NoSpecialType, line) -// else -> Pair(UsageLineType.ContinuationFromLastLine, line) -// } -// } -// -// protected open fun tryToParseBookingDateFromUsageLine(entry: AccountingEntry, currentLine: String, typeLine: String) { -// if (currentLine.startsWith(DateStartString)) { -// tryToParseBookingDateFromUsageLine(entry, currentLine) -// } -// else if (typeLine.startsWith(DateStartString)) { -// tryToParseBookingDateFromUsageLine(entry, typeLine) -// } -// } -// -// protected open fun tryToParseBookingDateFromUsageLine(entry: AccountingEntry, line: String) { -// var dateString = line.replace(DateStartString, "") -// val index = dateString.indexOf(DateEndString) -// if (index > 0) { -// dateString = dateString.substring(0, index) -// } -// -// try { -// entry.bookingDate = DateTimeFormat.parse(dateString) -// } catch (e: Exception) { -// try { -// entry.bookingDate = DateFormat.parse(dateString) -// } catch (secondException: Exception) { -// log.debug("Could not parse '$dateString' from '$line' to a Date", e) -// } -// } -// } + protected open fun mapValue(value: Value): BigDecimal { + return BigDecimal.valueOf(value.longValue).divide(BigDecimal.valueOf(100)) + } } \ No newline at end of file