Compare commits

...

10 Commits

8 changed files with 60 additions and 10 deletions

View File

@ -1,6 +1,6 @@
// TODO: move to versions.gradle
ext {
appVersionName = '1.0.0-Alpha-12-SNAPSHOT'
appVersionName = '1.0.0-Alpha-13-SNAPSHOT'
/* Test */

View File

@ -8,7 +8,7 @@ plugins {
kotlin {
jvmToolchain(8)
jvmToolchain(11)
compilerOptions {
// suppresses compiler warning: [EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING] 'expect'/'actual' classes (including interfaces, objects, annotations, enums, and 'actual' typealiases) are in Beta.
@ -73,7 +73,7 @@ kotlin {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:$kotlinxSerializationVersion")
implementation("net.codinux.log:kmp-log:$klfVersion")
implementation("net.codinux.log:klf:$klfVersion")
}
}

View File

@ -307,6 +307,7 @@ open class FinTsJobExecutor(
bank.selectedTanMedium = preferredTanMedium?.let { bank.tanMedia.firstOrNull { it.mediumName == preferredTanMedium } }
?: bank.selectedTanMedium?.let { selected -> bank.tanMedia.firstOrNull { it.mediumName == selected.mediumName } } // try to find selectedTanMedium in new TanMedia instances
?: bank.tanMedia.firstOrNull { it.status == TanMediumStatus.Aktiv && it.mediumName != null }
?: bank.tanMedia.firstOrNull { it.mediumName != null }
}

View File

@ -24,6 +24,15 @@ open class BankParameters(
*
* Maximale Anzahl aller Geschäftsvorfallsarten pro Nachricht: Anzahl Geschäftsvorfallsarten (BPA, also dieser Wert hier).
* Maximale Anzahl eines bestimmten Segments pro Nachricht: Maximale Anzahl Aufträge (JobParameter des jeweiligen Segments).
*
* Jedoch, 07 PINTAN, S. 60:
* "Desweiteren ist vom Kundenprodukt sicherzustellen, dass eine Nachricht entweder nur einen einzelnen Geschäftsvorfall enthält,
* für den eine TAN erforderlich ist, oder nur solche Geschäftsvorfälle, für die keine TAN erforderlich ist. Andernfalls ist
* die eindeutige Zuordnung der übergebenen TAN zu den Geschäftsvorfällen nicht sichergestellt.
* Eine Mischung von Geschäftsvorfällen, die eine TAN erfordern, mit solchen, die keine erfordern, ist generell nicht zulässig."
*
* -> ist praktisch nutzlos, da allenfalls nur mehr als ein nicht-TAN pflichtiger Geschäftsvorall pro Nachricht
* gesendent werden kann, jedoch nicht mehrere TAN-pflichtige und damit 99 % aller Geschäftsvorfälle.
*/
val countMaxJobsPerMessage: Int,

View File

@ -53,7 +53,7 @@ open class Mt940Parser(
val DateFormatter = DateFormatter("yyMMdd") // TODO: replace with LocalDate.Format { }
val CurrentYearTwoDigit = LocalDate.todayAtEuropeBerlin().year - 2000
val CurrentYearTwoDigit = LocalDate.todayAtEuropeBerlin().year
val CreditDebitCancellationRegex = Regex("C|D|RC|RD")
@ -455,7 +455,7 @@ open class Mt940Parser(
// this really simple date format on my own
if (dateString.length == 6) {
try {
var year = dateString.substring(0, 2).toInt()
var year = dateString.substring(0, 2).toInt() + 2000
val month = dateString.substring(2, 4).toInt()
val day = dateString.substring(4, 6).toInt()
@ -463,7 +463,14 @@ open class Mt940Parser(
year -= 100
}
return LocalDate(year + 2000, month, day) // java.util.Date years start at 1900 at month at 0 not at 1
// ah, here we go, banks (in Germany) calculate with 30 days each month, so yes, it can happen that dates
// like 30th of February or 29th of February in non-leap years occur, see:
// https://de.m.wikipedia.org/wiki/30._Februar#30._Februar_in_der_Zinsberechnung
if (month == 2 && (day > 29 || (day > 28 && year % 4 != 0))) { // fix that for banks each month has 30 days
return LocalDate(year, 3, 1)
}
return LocalDate(year , month, day)
} catch (e: Exception) {
logError("Could not parse dateString '$dateString'", e)
}

View File

@ -18,7 +18,7 @@ open class KtorWebClient(
private val log by logger()
protected val client = HttpClient {
protected open val client = HttpClient {
install(HttpTimeout) {
this.connectTimeoutMillis = connectTimeoutMillis
this.requestTimeoutMillis = requestTimeoutMillis
@ -37,7 +37,7 @@ open class KtorWebClient(
}
suspend fun get(url: String): WebClientResponse {
open suspend fun get(url: String): WebClientResponse {
val clientResponse = client.get(url)
val responseBody = clientResponse.bodyAsText()

View File

@ -38,7 +38,11 @@ class Mt940ParserTest : FinTsTestBase() {
val AccountStatement1With2TransactionsClosingBalanceAmount = Amount("13148,13")
}
private val underTest = Mt940Parser()
private val underTest = object : Mt940Parser() {
public override fun parseMt940Date(dateString: String): LocalDate {
return super.parseMt940Date(dateString)
}
}
@Test
@ -312,6 +316,35 @@ class Mt940ParserTest : FinTsTestBase() {
}
@Test
fun parseDate() {
val result = underTest.parseMt940Date("240507")
assertEquals(LocalDate(2024, 5, 7), result)
}
@Test
fun parseDateBeforeYear2000() {
val result = underTest.parseMt940Date("990507")
assertEquals(LocalDate(1999, 5, 7), result)
}
@Test
fun parseDate_FixSparkasse29thOFFebruaryInNonLeapYearBug() {
val result = underTest.parseMt940Date("230229")
assertEquals(LocalDate(2023, 3, 1), result)
}
@Test
fun parseDate_FixSparkasse30thOfFebruaryBug() {
val result = underTest.parseMt940Date("230229")
assertEquals(LocalDate(2023, 3, 1), result)
}
private fun assertBalance(balance: Balance, isCredit: Boolean, bookingDate: LocalDate, amount: Amount) {
assertEquals(isCredit, balance.isCredit)
assertEquals(bookingDate, balance.bookingDate)

View File

@ -15,7 +15,7 @@ kotlinxDateTimeVersion=0.5.0
kotlinxSerializationVersion=1.7.1
atomicfuVersion=0.25.0
klfVersion=1.5.1
klfVersion=1.6.0
android.useAndroidX=true
android.enableJetifier=true