Implemented mapping all account transaction fields; Renamed usage to unparsedUsage, isCancellation to isReversal, customerReference to referenceForTheAccountOwner, bankReference to referenceOfTheAccountServicingInstitution and referenceReferenceNumber to relatedReferenceNumber
This commit is contained in:
parent
ac78758262
commit
a16cf630b4
|
@ -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"
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -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<Pair<String, String>> {
|
||||
val usage = information.usage
|
||||
open fun getUsageParts(unparsedUsage: String): Map<String, String> {
|
||||
var previousMatchType = ""
|
||||
var previousMatchEnd = 0
|
||||
|
||||
val usageParts = mutableListOf<Pair<String, String>>()
|
||||
val matcher = UsageTypePattern.matcher(information.usage)
|
||||
val usageParts = mutableMapOf<String, String>()
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ open class AccountStatement(
|
|||
*
|
||||
* Max length = 16
|
||||
*/
|
||||
val referenceReferenceNumber: String?,
|
||||
val relatedReferenceNumber: String?,
|
||||
|
||||
/**
|
||||
* xxxxxxxxxxx/Konto-Nr. oder yyyyyyyy/Konto-Nr.
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -72,7 +72,7 @@ open class AccountTransactionsTable @JvmOverloads constructor(
|
|||
}
|
||||
}
|
||||
|
||||
label(it.usage ?: "") {
|
||||
label(it.usage) {
|
||||
vboxConstraints {
|
||||
margin = LabelMargin
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -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<AccountTransaction> {
|
||||
val entries = ArrayList<AccountTransaction>()
|
||||
|
||||
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<UsageLineType, String> {
|
||||
// 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))
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue