Fixed that ?, got treated as field code leading to that parsing whole information to account owner failed

This commit is contained in:
dankito 2020-11-19 20:03:47 +01:00
parent 664195c495
commit b16390d0eb
2 changed files with 51 additions and 14 deletions

View File

@ -58,6 +58,8 @@ open class Mt940Parser : IMt940Parser {
val ReferenceTypeRegex = Regex("[A-Z]{4}\\+")
val InformationToAccountOwnerSubFieldRegex = Regex("\\?\\d\\d")
const val EndToEndReferenceKey = "EREF+"
const val CustomerReferenceKey = "KREF+"
@ -318,10 +320,11 @@ open class Mt940Parser : IMt940Parser {
var primaNotaNumber: String? = null
var textKeySupplement: String? = null
informationToAccountOwnerString.substring(3).split('?').forEach { subField ->
if (subField.isNotEmpty()) {
val fieldCode = subField.substring(0, 2).toInt()
val fieldValue = subField.substring(2)
val subFieldMatches = InformationToAccountOwnerSubFieldRegex.findAll(informationToAccountOwnerString).toList()
subFieldMatches.forEachIndexed { index, matchResult ->
val fieldCode = matchResult.value.substring(1, 3).toInt()
val endIndex = if (index + 1 < subFieldMatches.size) subFieldMatches[index + 1].range.start else informationToAccountOwnerString.length
val fieldValue = informationToAccountOwnerString.substring(matchResult.range.last + 1, endIndex)
when (fieldCode) {
0 -> bookingText = fieldValue
@ -334,7 +337,6 @@ open class Mt940Parser : IMt940Parser {
in 60..63 -> referenceParts.add(fieldValue)
}
}
}
val reference = if (isFormattedReference(referenceParts)) joinReferenceParts(referenceParts)
else referenceParts.joinToString(" ")

View File

@ -11,6 +11,7 @@ import net.dankito.banking.fints.transactions.mt940.model.StatementLine
import ch.tutteli.atrium.api.verbs.expect
import kotlin.test.Test
import net.dankito.banking.fints.extensions.isFalse
import net.dankito.banking.fints.extensions.isTrue
import net.dankito.banking.fints.model.Amount
import net.dankito.utils.multiplatform.Date
import net.dankito.utils.multiplatform.DateFormatter
@ -277,6 +278,40 @@ class Mt940ParserTest : FinTsTestBase() {
}
}
@Test
fun `Fix that ?, gets detected as field code`() {
val transactionsString = """
:20:STARTUMS
:25:$BankCode/$CustomerId
:28C:0
:60F:C200511EUR0,00
:61:200511D15,00NMSCNONREF
:86:105?00BASISLASTSCHRIFT?10931?20EREF+6MKL2OT30QENNLIU
?21MREF+?,3SQNdUbxm9z7dB)+gKYD?22JAKzCM0G?23CRED+DE94ZZZ00000123456
?24SVWZ+306-4991422-2405949 NI?25LE Mktp DE 6MKL2OT30QENNLIU?26
EREF: 6MKL2OT30QENNLIU MRE?27F: ?,3SQNdUbxm9z7dB)+gKYDJA?28KzCM0G
CRED: DE94ZZZ0000012?293456 IBAN: DE87300308801234?30TUBDDEDD?31DE87300308801234567890?32NILE PAYMENTS EUROPE S.C.?33A.?34992?60567890 BIC: TUBDDEDD
:62F:D200511EUR15,00
-
""".trimIndent()
// when
val result = underTest.parseMt940String(transactionsString)
// then
expect(result).hasSize(1)
expect(result.first().transactions).hasSize(1)
expect(result.first().transactions[0].information?.bookingText).toBe("BASISLASTSCHRIFT")
expect(result.first().transactions[0].information?.otherPartyBankCode).toBe("TUBDDEDD")
expect(result.first().transactions[0].information?.otherPartyAccountId).toBe("DE87300308801234567890")
expect(result.first().transactions[0].information?.endToEndReference).toBe("6MKL2OT30QENNLIU")
expect(result.first().transactions[0].information?.mandateReference).toBe("?,3SQNdUbxm9z7dB)+gKYDJAKzCM0G")
expect(result.first().transactions[0].information?.sepaReference?.contains("IBAN: DE87300308801234567890 BIC: TUBDDEDD") ?: false).isTrue()
}
private fun assertBalance(balance: Balance, isCredit: Boolean, bookingDate: Date, amount: Amount) {
expect(balance.isCredit).toBe(isCredit)