Introduced Amount to be able to remove Ionspin BigDecimal dependency
This commit is contained in:
parent
9ea9095e8b
commit
03bdb19668
|
@ -53,8 +53,6 @@ kotlin {
|
|||
|
||||
api "com.soywiz.korlibs.klock:klock:$klockVersion"
|
||||
|
||||
api "com.ionspin.kotlin:bignum:$bigNumVersion"
|
||||
|
||||
implementation "com.benasher44:uuid:$uuidVersion"
|
||||
}
|
||||
}
|
||||
|
@ -129,8 +127,6 @@ kotlin {
|
|||
|
||||
|
||||
implementation "com.soywiz.korlibs.klock:klock-js:$klockVersion"
|
||||
|
||||
implementation "com.ionspin.kotlin:bignum-js:$bigNumVersion"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ open class SepaBankTransferBase(
|
|||
"CreditorName" to messageCreator.convertDiacriticsAndReservedXmlCharacters(data.creditorName),
|
||||
"CreditorIban" to data.creditorIban.replace(" ", ""),
|
||||
"CreditorBic" to data.creditorBic.replace(" ", ""),
|
||||
"Amount" to data.amount.toStringExpanded(), // TODO: check if ',' or '.' should be used as decimal separator
|
||||
"Amount" to data.amount.amount.string.replace(',', '.'), // TODO: check if ',' or '.' should be used as decimal separator
|
||||
"Usage" to if (data.usage.isEmpty()) " " else messageCreator.convertDiacriticsAndReservedXmlCharacters(data.usage),
|
||||
"RequestedExecutionDate" to RequestedExecutionDateValueForNotScheduledTransfers
|
||||
),
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package net.dankito.banking.fints.model
|
||||
|
||||
import com.ionspin.kotlin.bignum.decimal.BigDecimal
|
||||
import com.soywiz.klock.Date
|
||||
import com.soywiz.klock.DateTime
|
||||
|
||||
|
@ -46,7 +45,7 @@ open class AccountTransaction(
|
|||
) {
|
||||
|
||||
// for object deserializers
|
||||
internal constructor() : this(AccountData(), Money(BigDecimal.ZERO, ""), false, "", DateTime.EPOCH.date, null, null, null, null, DateTime.EPOCH.date, 0, null, null, null,
|
||||
internal constructor() : this(AccountData(), Money(Amount.Zero, ""), false, "", DateTime.EPOCH.date, null, null, null, null, DateTime.EPOCH.date, 0, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null, null, null, null,
|
||||
null, "", "", null, null, "", null)
|
||||
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
package net.dankito.banking.fints.model
|
||||
|
||||
|
||||
open class Amount(
|
||||
val string: String
|
||||
) {
|
||||
|
||||
companion object {
|
||||
val Zero = Amount("0,")
|
||||
}
|
||||
|
||||
|
||||
internal constructor() : this("") // for object deserializers
|
||||
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is Amount) return false
|
||||
|
||||
if (string != other.string) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return string.hashCode()
|
||||
}
|
||||
|
||||
|
||||
override fun toString(): String {
|
||||
return string
|
||||
}
|
||||
|
||||
}
|
|
@ -1,13 +1,11 @@
|
|||
package net.dankito.banking.fints.model
|
||||
|
||||
import com.ionspin.kotlin.bignum.decimal.BigDecimal
|
||||
|
||||
|
||||
open class BankTransferData(
|
||||
val creditorName: String,
|
||||
val creditorIban: String,
|
||||
val creditorBic: String,
|
||||
val amount: BigDecimal, // TODO: use Money
|
||||
val amount: Money,
|
||||
val usage: String,
|
||||
val instantPayment: Boolean = false
|
||||
)
|
|
@ -1,16 +1,15 @@
|
|||
package net.dankito.banking.fints.model
|
||||
|
||||
import com.ionspin.kotlin.bignum.decimal.BigDecimal
|
||||
|
||||
|
||||
open class Money(
|
||||
val amount: BigDecimal,
|
||||
val amount: Amount,
|
||||
val currency: Currency
|
||||
) {
|
||||
|
||||
constructor(amount: BigDecimal, currencyCode: String) : this(amount, Currency(currencyCode))
|
||||
|
||||
internal constructor() : this(BigDecimal.ZERO, "") // for object deserializers
|
||||
constructor(amount: Amount, currencyCode: String) : this(amount, Currency(currencyCode))
|
||||
|
||||
internal constructor() : this(Amount.Zero, "") // for object deserializers
|
||||
|
||||
|
||||
open val displayString: String
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package net.dankito.banking.fints.response
|
||||
|
||||
import com.ionspin.kotlin.bignum.decimal.BigDecimal
|
||||
import com.ionspin.kotlin.bignum.decimal.toBigDecimal
|
||||
import com.soywiz.klock.Date
|
||||
import com.soywiz.klock.DateTime
|
||||
import com.soywiz.klock.Time
|
||||
|
@ -19,6 +17,7 @@ import net.dankito.banking.fints.messages.datenelementgruppen.implementierte.Kre
|
|||
import net.dankito.banking.fints.messages.datenelementgruppen.implementierte.account.KontoverbindungInternational
|
||||
import net.dankito.banking.fints.messages.datenelementgruppen.implementierte.signatur.Sicherheitsprofil
|
||||
import net.dankito.banking.fints.messages.segmente.id.MessageSegmentId
|
||||
import net.dankito.banking.fints.model.Amount
|
||||
import net.dankito.banking.fints.response.segments.*
|
||||
import net.dankito.banking.fints.util.MessageUtils
|
||||
import net.dankito.banking.fints.util.log.LoggerFactory
|
||||
|
@ -618,7 +617,7 @@ open class ResponseParser(
|
|||
|
||||
val parsedBalance = parseBalance(dataElementGroup)
|
||||
|
||||
if (BigDecimal.ZERO.equals(parsedBalance.amount)) {
|
||||
if (Amount.Zero.equals(parsedBalance.amount)) {
|
||||
return null
|
||||
}
|
||||
|
||||
|
@ -830,16 +829,14 @@ open class ResponseParser(
|
|||
return null
|
||||
}
|
||||
|
||||
protected open fun parseAmount(amountString: String, isPositive: Boolean = true): BigDecimal {
|
||||
val adjustedAmountString = amountString.replace(',', '.') // Hbci amount format uses comma instead dot as decimal separator
|
||||
|
||||
val amount = adjustedAmountString.toBigDecimal()
|
||||
protected open fun parseAmount(amountString: String, isPositive: Boolean = true): Amount {
|
||||
var adjustedAmountString = amountString // Hbci amount format uses comma instead dot as decimal separator
|
||||
|
||||
if (isPositive == false) {
|
||||
return amount.negate()
|
||||
adjustedAmountString = "-" + adjustedAmountString
|
||||
}
|
||||
|
||||
return amount
|
||||
return Amount(adjustedAmountString)
|
||||
}
|
||||
|
||||
protected open fun parseNullableDateTime(dataElementGroup: String): DateTime? {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package net.dankito.banking.fints.response.client
|
||||
|
||||
import com.ionspin.kotlin.bignum.decimal.BigDecimal
|
||||
import net.dankito.banking.fints.model.*
|
||||
import net.dankito.banking.fints.response.Response
|
||||
|
||||
|
@ -15,4 +14,4 @@ open class AddAccountResponse(
|
|||
val balances: Map<AccountData, Money> = mapOf()
|
||||
)
|
||||
: GetTransactionsResponse(response, bookedTransactionsOfLast90Days, unbookedTransactionsOfLast90Days,
|
||||
Money(balances.values.fold(BigDecimal.ZERO) { acc, e -> acc + e.amount }, balances.values.firstOrNull()?.currency?.code ?: "EUR"))
|
||||
Money(Amount.Zero, balances.values.firstOrNull()?.currency?.code ?: "EUR")) // TODO: sum balances
|
|
@ -1,12 +1,12 @@
|
|||
package net.dankito.banking.fints.response.segments
|
||||
|
||||
import com.ionspin.kotlin.bignum.decimal.BigDecimal
|
||||
import com.soywiz.klock.Date
|
||||
import com.soywiz.klock.Time
|
||||
import net.dankito.banking.fints.model.Amount
|
||||
|
||||
|
||||
open class Balance(
|
||||
val amount: BigDecimal,
|
||||
val amount: Amount,
|
||||
val date: Date,
|
||||
val time: Time?
|
||||
) {
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
package net.dankito.banking.fints.response.segments
|
||||
|
||||
import com.ionspin.kotlin.bignum.decimal.BigDecimal
|
||||
import com.soywiz.klock.Date
|
||||
import net.dankito.banking.fints.model.Amount
|
||||
|
||||
|
||||
open class BalanceSegment(
|
||||
val balance: BigDecimal,
|
||||
val balance: Amount,
|
||||
val currency: String,
|
||||
val date: Date,
|
||||
val accountProductName: String,
|
||||
val balanceOfPreBookedTransactions: BigDecimal?,
|
||||
val balanceOfPreBookedTransactions: Amount?,
|
||||
segmentString: String
|
||||
)
|
||||
: ReceivedSegment(segmentString)
|
|
@ -1,8 +1,8 @@
|
|||
package net.dankito.banking.fints.transactions
|
||||
|
||||
import com.ionspin.kotlin.bignum.decimal.BigDecimal
|
||||
import net.dankito.banking.fints.model.AccountData
|
||||
import net.dankito.banking.fints.model.AccountTransaction
|
||||
import net.dankito.banking.fints.model.Amount
|
||||
import net.dankito.banking.fints.model.Money
|
||||
import net.dankito.banking.fints.transactions.mt940.IMt940Parser
|
||||
import net.dankito.banking.fints.transactions.mt940.Mt940Parser
|
||||
|
@ -91,23 +91,23 @@ open class Mt940AccountTransactionsParser(
|
|||
/**
|
||||
* In MT940 amounts are always stated as a positive number and flag isCredit decides if it's a credit or debit.
|
||||
*/
|
||||
protected open fun mapAmount(balance: Balance): BigDecimal {
|
||||
protected open fun mapAmount(balance: Balance): Amount {
|
||||
return mapAmount(balance.amount, balance.isCredit)
|
||||
}
|
||||
|
||||
/**
|
||||
* In MT940 amounts are always stated as a positive number and flag isCredit decides if it's a credit or debit.
|
||||
*/
|
||||
protected open fun mapAmount(statementLine: StatementLine): BigDecimal {
|
||||
protected open fun mapAmount(statementLine: StatementLine): Amount {
|
||||
return mapAmount(statementLine.amount, statementLine.isCredit)
|
||||
}
|
||||
|
||||
/**
|
||||
* In MT940 amounts are always stated as a positive number and flag isCredit decides if it's a credit or debit.
|
||||
*/
|
||||
protected open fun mapAmount(positiveAmount: BigDecimal, isCredit: Boolean): BigDecimal {
|
||||
if (isCredit == false) {
|
||||
return positiveAmount.negate()
|
||||
protected open fun mapAmount(positiveAmount: Amount, isCredit: Boolean): Amount {
|
||||
if (isCredit == false && positiveAmount.string.startsWith('-') == false) {
|
||||
return Amount("-" + positiveAmount)
|
||||
}
|
||||
|
||||
return positiveAmount
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
package net.dankito.banking.fints.transactions.mt940
|
||||
|
||||
import com.ionspin.kotlin.bignum.decimal.BigDecimal
|
||||
import com.ionspin.kotlin.bignum.decimal.toBigDecimal
|
||||
import com.soywiz.klock.*
|
||||
import net.dankito.banking.fints.model.Amount
|
||||
import net.dankito.banking.fints.transactions.mt940.model.*
|
||||
import net.dankito.banking.fints.util.log.LoggerFactory
|
||||
|
||||
|
@ -460,8 +459,8 @@ open class Mt940Parser : IMt940Parser {
|
|||
return bookingDate
|
||||
}
|
||||
|
||||
protected open fun parseAmount(amountString: String): BigDecimal {
|
||||
return amountString.replace(',', '.').toBigDecimal()
|
||||
protected open fun parseAmount(amountString: String): Amount {
|
||||
return Amount(amountString)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
package net.dankito.banking.fints.transactions.mt940.model
|
||||
|
||||
import com.ionspin.kotlin.bignum.decimal.BigDecimal
|
||||
import com.soywiz.klock.Date
|
||||
import com.soywiz.klock.DateTime
|
||||
import net.dankito.banking.fints.model.Amount
|
||||
|
||||
|
||||
open class Balance(
|
||||
|
@ -38,11 +38,11 @@ open class Balance(
|
|||
*
|
||||
* Max Length = 15
|
||||
*/
|
||||
val amount: BigDecimal
|
||||
val amount: Amount
|
||||
|
||||
) {
|
||||
|
||||
internal constructor() : this(false, false, DateTime.EPOCH.date, "", BigDecimal.ZERO) // for object deserializers
|
||||
internal constructor() : this(false, false, DateTime.EPOCH.date, "", Amount.Zero) // for object deserializers
|
||||
|
||||
|
||||
override fun toString(): String {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package net.dankito.banking.fints.transactions.mt940.model
|
||||
|
||||
import com.ionspin.kotlin.bignum.decimal.BigDecimal
|
||||
import com.soywiz.klock.Date
|
||||
import net.dankito.banking.fints.model.Amount
|
||||
|
||||
|
||||
open class StatementLine(
|
||||
|
@ -48,7 +48,7 @@ open class StatementLine(
|
|||
*
|
||||
* Max length = 15
|
||||
*/
|
||||
val amount: BigDecimal,
|
||||
val amount: Amount,
|
||||
|
||||
/**
|
||||
* in Kontowährung
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package net.dankito.banking.fints
|
||||
|
||||
import com.benasher44.uuid.uuid4
|
||||
import com.ionspin.kotlin.bignum.decimal.BigDecimal
|
||||
import com.soywiz.klock.Date
|
||||
import net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate.Datum
|
||||
import net.dankito.banking.fints.messages.datenelemente.abgeleiteteformate.Laenderkennzeichen
|
||||
|
@ -68,10 +67,6 @@ abstract class FinTsTestBase {
|
|||
return uuid4().toString().replace("-", "")
|
||||
}
|
||||
|
||||
protected open fun convertAmount(amount: BigDecimal): String {
|
||||
return amount.toStringExpanded().replace('.', ',')
|
||||
}
|
||||
|
||||
protected open fun convertDate(date: Date): String {
|
||||
return Datum.format(date)
|
||||
}
|
||||
|
|
|
@ -2,11 +2,8 @@ package net.dankito.banking.fints.messages.segmente.implementierte.sepa
|
|||
|
||||
import ch.tutteli.atrium.api.fluent.en_GB.contains
|
||||
import ch.tutteli.atrium.api.verbs.expect
|
||||
import com.ionspin.kotlin.bignum.decimal.toBigDecimal
|
||||
import net.dankito.banking.fints.messages.segmente.id.CustomerSegmentId
|
||||
import net.dankito.banking.fints.model.AccountData
|
||||
import net.dankito.banking.fints.model.BankTransferData
|
||||
import net.dankito.banking.fints.model.CustomerData
|
||||
import net.dankito.banking.fints.model.*
|
||||
import kotlin.test.Test
|
||||
|
||||
|
||||
|
@ -21,7 +18,7 @@ class SepaBankTransferBaseTest {
|
|||
val creditorName = "Mahatma Gandhi"
|
||||
val creditorIban = "IN123456780987654321"
|
||||
val creditorBic = "ABCDINEFXXX"
|
||||
val amount = 1234.56.toBigDecimal()
|
||||
val amount = Amount("1234,56")
|
||||
val usage = "What should Mahatma Gandhi want with money?"
|
||||
|
||||
}
|
||||
|
@ -36,7 +33,7 @@ class SepaBankTransferBaseTest {
|
|||
CustomerData("", "", "", debitorName),
|
||||
AccountData("", null, 0, "", debitorIban, "", null, null, "", null, null, listOf()),
|
||||
debitorBic,
|
||||
BankTransferData(creditorName, creditorIban, creditorBic, amount, usage)
|
||||
BankTransferData(creditorName, creditorIban, creditorBic, Money(amount, "EUR"), usage)
|
||||
)
|
||||
|
||||
|
||||
|
@ -46,7 +43,7 @@ class SepaBankTransferBaseTest {
|
|||
|
||||
// then
|
||||
expect(result).contains(debitorName, debitorIban, debitorBic, creditorName, creditorIban, creditorBic,
|
||||
amount.toString(), usage, "urn?:iso?:std?:iso?:20022?:tech?:xsd?:pain.001.001.03")
|
||||
amount.toString().replace(',', '.'), usage, "urn?:iso?:std?:iso?:20022?:tech?:xsd?:pain.001.001.03")
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -58,7 +55,7 @@ class SepaBankTransferBaseTest {
|
|||
CustomerData("", "", "", debitorName),
|
||||
AccountData("", null, 0, "", debitorIban, "", null, null, "", null, null, listOf()),
|
||||
debitorBic,
|
||||
BankTransferData(creditorName, creditorIban, creditorBic, amount, usage)
|
||||
BankTransferData(creditorName, creditorIban, creditorBic, Money(amount, "EUR"), usage)
|
||||
)
|
||||
|
||||
|
||||
|
@ -68,7 +65,7 @@ class SepaBankTransferBaseTest {
|
|||
|
||||
// then
|
||||
expect(result).contains(debitorName, debitorIban, debitorBic, creditorName, creditorIban, creditorBic,
|
||||
amount.toString(), usage, "urn?:iso?:std?:iso?:20022?:tech?:xsd?:pain.001.003.03")
|
||||
amount.toString().replace(',', '.'), usage, "urn?:iso?:std?:iso?:20022?:tech?:xsd?:pain.001.003.03")
|
||||
}
|
||||
|
||||
}
|
|
@ -13,10 +13,9 @@ import net.dankito.banking.fints.messages.segmente.id.ISegmentId
|
|||
import net.dankito.banking.fints.messages.segmente.id.MessageSegmentId
|
||||
import net.dankito.banking.fints.response.segments.*
|
||||
import ch.tutteli.atrium.api.verbs.expect
|
||||
import com.ionspin.kotlin.bignum.decimal.BigDecimal
|
||||
import com.ionspin.kotlin.bignum.decimal.toBigDecimal
|
||||
import net.dankito.banking.fints.extensions.isFalse
|
||||
import net.dankito.banking.fints.extensions.isTrue
|
||||
import net.dankito.banking.fints.model.Amount
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.fail
|
||||
|
||||
|
@ -965,7 +964,7 @@ class ResponseParserTest : FinTsTestBase() {
|
|||
fun parseBalance() {
|
||||
|
||||
// given
|
||||
val balance = 1234.56.toBigDecimal()
|
||||
val balance = "1234,56"
|
||||
val date = com.soywiz.klock.Date(1988, 3, 27)
|
||||
val bankCode = "12345678"
|
||||
val accountId = "0987654321"
|
||||
|
@ -973,13 +972,13 @@ class ResponseParserTest : FinTsTestBase() {
|
|||
|
||||
// when
|
||||
val result = underTest.parse("HISAL:8:5:3+$accountId::280:$bankCode+$accountProductName+EUR+" +
|
||||
"C:${convertAmount(balance)}:EUR:${convertDate(date)}+C:0,:EUR:20191006++${convertAmount(balance)}:EUR")
|
||||
"C:$balance:EUR:${convertDate(date)}+C:0,:EUR:20191006++$balance:EUR")
|
||||
|
||||
// then
|
||||
assertSuccessfullyParsedSegment(result, InstituteSegmentId.Balance, 8, 5, 3)
|
||||
|
||||
result.getFirstSegmentById<BalanceSegment>(InstituteSegmentId.Balance)?.let { segment ->
|
||||
expect(segment.balance).toBe(balance)
|
||||
expect(segment.balance).toBe(Amount(balance))
|
||||
expect(segment.currency).toBe("EUR")
|
||||
expect(segment.date).toBe(date)
|
||||
expect(segment.accountProductName).toBe(accountProductName)
|
||||
|
@ -992,7 +991,7 @@ class ResponseParserTest : FinTsTestBase() {
|
|||
fun parseBalance_BalanceOfPreBookedTransactionsIsZero() {
|
||||
|
||||
// given
|
||||
val balance = BigDecimal.ZERO
|
||||
val balance = Amount.Zero
|
||||
val date = com.soywiz.klock.Date(2020, 6, 11)
|
||||
val bankCode = "12345678"
|
||||
val accountId = "0987654321"
|
||||
|
@ -1000,7 +999,7 @@ class ResponseParserTest : FinTsTestBase() {
|
|||
|
||||
// when
|
||||
// "HISAL:7:5:3+0987654321:Girokonto:280:12345678+Girokonto+EUR+C:0,:EUR:20200511:204204'"
|
||||
val result = underTest.parse("HISAL:7:5:3+$accountId:$accountProductName:280:$bankCode+$accountProductName+EUR+C:0,:EUR:${convertDate(date)}:204204'")
|
||||
val result = underTest.parse("HISAL:7:5:3+$accountId:$accountProductName:280:$bankCode+$accountProductName+EUR+C:$balance:EUR:${convertDate(date)}:204204'")
|
||||
|
||||
// then
|
||||
assertSuccessfullyParsedSegment(result, InstituteSegmentId.Balance, 7, 5, 3)
|
||||
|
@ -1019,7 +1018,7 @@ class ResponseParserTest : FinTsTestBase() {
|
|||
fun parseBalance_BalanceOfPreBookedTransactionsIsEmpty() {
|
||||
|
||||
// given
|
||||
val balance = BigDecimal.ZERO
|
||||
val balance = Amount.Zero
|
||||
val date = com.soywiz.klock.Date(2020, 6, 11)
|
||||
val bankCode = "12345678"
|
||||
val accountId = "0987654321"
|
||||
|
@ -1027,7 +1026,7 @@ class ResponseParserTest : FinTsTestBase() {
|
|||
|
||||
// when
|
||||
// "HISAL:7:5:3+0987654321:Girokonto:280:12345678+Girokonto+EUR++0,:EUR'"
|
||||
val result = underTest.parse("HISAL:7:5:3+$accountId:$accountProductName:280:$bankCode+$accountProductName+EUR+C:0,:EUR:${convertDate(date)}:204204++0,:EUR'")
|
||||
val result = underTest.parse("HISAL:7:5:3+$accountId:$accountProductName:280:$bankCode+$accountProductName+EUR+C:0,:EUR:${convertDate(date)}:204204++$balance:EUR'")
|
||||
|
||||
// then
|
||||
assertSuccessfullyParsedSegment(result, InstituteSegmentId.Balance, 7, 5, 3)
|
||||
|
|
|
@ -9,12 +9,11 @@ import net.dankito.banking.fints.transactions.mt940.model.Balance
|
|||
import net.dankito.banking.fints.transactions.mt940.model.InformationToAccountOwner
|
||||
import net.dankito.banking.fints.transactions.mt940.model.StatementLine
|
||||
import ch.tutteli.atrium.api.verbs.expect
|
||||
import com.ionspin.kotlin.bignum.decimal.BigDecimal
|
||||
import com.ionspin.kotlin.bignum.decimal.toBigDecimal
|
||||
import kotlin.test.Test
|
||||
import com.soywiz.klock.Date
|
||||
import com.soywiz.klock.DateFormat
|
||||
import net.dankito.banking.fints.extensions.isFalse
|
||||
import net.dankito.banking.fints.model.Amount
|
||||
|
||||
|
||||
class Mt940ParserTest : FinTsTestBase() {
|
||||
|
@ -26,20 +25,20 @@ class Mt940ParserTest : FinTsTestBase() {
|
|||
val AccountStatement1PreviousStatementBookingDate = Date(1988, 2, 26)
|
||||
val AccountStatement1BookingDate = Date(1988, 2, 27)
|
||||
|
||||
val AccountStatement1OpeningBalanceAmount = 12345.67.toBigDecimal()
|
||||
val AccountStatement1OpeningBalanceAmount = Amount("12345,67")
|
||||
|
||||
val AccountStatement1Transaction1Amount = 1234.56.toBigDecimal()
|
||||
val AccountStatement1Transaction1Amount = Amount("1234,56")
|
||||
val AccountStatement1Transaction1OtherPartyName = "Sender1"
|
||||
val AccountStatement1Transaction1OtherPartyBankCode = "AAAADE12"
|
||||
val AccountStatement1Transaction1OtherPartyAccountId = "DE99876543210987654321"
|
||||
|
||||
val AccountStatement1Transaction2Amount = 432.10.toBigDecimal()
|
||||
val AccountStatement1Transaction2Amount = Amount("432,10")
|
||||
val AccountStatement1Transaction2OtherPartyName = "Receiver2"
|
||||
val AccountStatement1Transaction2OtherPartyBankCode = "BBBBDE56"
|
||||
val AccountStatement1Transaction2OtherPartyAccountId = "DE77987654321234567890"
|
||||
|
||||
val AccountStatement1ClosingBalanceAmount = AccountStatement1OpeningBalanceAmount + AccountStatement1Transaction1Amount
|
||||
val AccountStatement1With2TransactionsClosingBalanceAmount = AccountStatement1OpeningBalanceAmount + AccountStatement1Transaction1Amount - AccountStatement1Transaction2Amount
|
||||
val AccountStatement1ClosingBalanceAmount = Amount("13580,23")
|
||||
val AccountStatement1With2TransactionsClosingBalanceAmount = Amount("13148,13")
|
||||
}
|
||||
|
||||
private val underTest = Mt940Parser()
|
||||
|
@ -74,7 +73,7 @@ class Mt940ParserTest : FinTsTestBase() {
|
|||
fun accountStatementWithSingleTransaction_SheetNumberOmitted() {
|
||||
|
||||
// given
|
||||
val amount = BigDecimal.parseString("15.00")
|
||||
val amount = Amount("15,00")
|
||||
val isCredit = false
|
||||
val bookingDate = Date(2020, 5, 11)
|
||||
|
||||
|
@ -92,7 +91,7 @@ class Mt940ParserTest : FinTsTestBase() {
|
|||
expect(statement.statementNumber).toBe(0)
|
||||
expect(statement.sequenceNumber).toBe(null)
|
||||
|
||||
assertBalance(statement.openingBalance, true, bookingDate, BigDecimal.parseString("0.00"))
|
||||
assertBalance(statement.openingBalance, true, bookingDate, Amount("0,00"))
|
||||
assertBalance(statement.closingBalance, isCredit, bookingDate, amount)
|
||||
|
||||
expect(statement.transactions).hasSize(1)
|
||||
|
@ -276,14 +275,14 @@ class Mt940ParserTest : FinTsTestBase() {
|
|||
}
|
||||
|
||||
|
||||
private fun assertBalance(balance: Balance, isCredit: Boolean, bookingDate: Date, amount: BigDecimal) {
|
||||
private fun assertBalance(balance: Balance, isCredit: Boolean, bookingDate: Date, amount: Amount) {
|
||||
expect(balance.isCredit).toBe(isCredit)
|
||||
expect(balance.bookingDate).toBe(bookingDate)
|
||||
expect(balance.amount).toBe(amount)
|
||||
expect(balance.currency).toBe(Currency)
|
||||
}
|
||||
|
||||
private fun assertTurnover(statementLine: StatementLine, valueDate: Date, amount: BigDecimal, isCredit: Boolean = true,
|
||||
private fun assertTurnover(statementLine: StatementLine, valueDate: Date, amount: Amount, isCredit: Boolean = true,
|
||||
bookingDate: Date? = valueDate) {
|
||||
|
||||
expect(statementLine.isCredit).toBe(isCredit)
|
||||
|
@ -308,12 +307,12 @@ class Mt940ParserTest : FinTsTestBase() {
|
|||
:20:STARTUMSE
|
||||
:25:$BankCode/$CustomerId
|
||||
:28C:00000/001
|
||||
:60F:C${convertMt940Date(AccountStatement1PreviousStatementBookingDate)}EUR${convertAmount(AccountStatement1OpeningBalanceAmount)}
|
||||
:61:${convertMt940Date(AccountStatement1BookingDate)}${convertToShortBookingDate(AccountStatement1BookingDate)}CR${convertAmount(AccountStatement1Transaction1Amount)}N062NONREF
|
||||
:60F:C${convertMt940Date(AccountStatement1PreviousStatementBookingDate)}EUR$AccountStatement1OpeningBalanceAmount
|
||||
:61:${convertMt940Date(AccountStatement1BookingDate)}${convertToShortBookingDate(AccountStatement1BookingDate)}CR${AccountStatement1Transaction1Amount}N062NONREF
|
||||
:86:166?00GUTSCHR. UEBERWEISUNG?109249?20EREF+674?21SVWZ+1908301/
|
||||
EUR ${convertAmount(AccountStatement1Transaction1Amount)}/20?2219-10-02/...?30$AccountStatement1Transaction1OtherPartyBankCode?31$AccountStatement1Transaction1OtherPartyAccountId
|
||||
EUR ${AccountStatement1Transaction1Amount}/20?2219-10-02/...?30$AccountStatement1Transaction1OtherPartyBankCode?31$AccountStatement1Transaction1OtherPartyAccountId
|
||||
?32$AccountStatement1Transaction1OtherPartyName
|
||||
:62F:C${convertMt940Date(AccountStatement1BookingDate)}EUR${convertAmount(AccountStatement1ClosingBalanceAmount)}
|
||||
:62F:C${convertMt940Date(AccountStatement1BookingDate)}EUR$AccountStatement1ClosingBalanceAmount
|
||||
-
|
||||
""".trimIndent()
|
||||
|
||||
|
@ -321,16 +320,16 @@ class Mt940ParserTest : FinTsTestBase() {
|
|||
:20:STARTUMSE
|
||||
:25:$BankCode/$CustomerId
|
||||
:28C:00000/001
|
||||
:60F:C${convertMt940Date(AccountStatement1PreviousStatementBookingDate)}EUR${convertAmount(AccountStatement1OpeningBalanceAmount)}
|
||||
:61:${convertMt940Date(AccountStatement1BookingDate)}${convertToShortBookingDate(AccountStatement1BookingDate)}CR${convertAmount(AccountStatement1Transaction1Amount)}N062NONREF
|
||||
:60F:C${convertMt940Date(AccountStatement1PreviousStatementBookingDate)}EUR$AccountStatement1OpeningBalanceAmount
|
||||
:61:${convertMt940Date(AccountStatement1BookingDate)}${convertToShortBookingDate(AccountStatement1BookingDate)}CR${AccountStatement1Transaction1Amount}N062NONREF
|
||||
:86:166?00GUTSCHR. UEBERWEISUNG?109249?20EREF+674?21SVWZ+1908301/
|
||||
EUR ${convertAmount(AccountStatement1Transaction1Amount)}/20?2219-10-02/...?30$AccountStatement1Transaction1OtherPartyBankCode?31$AccountStatement1Transaction1OtherPartyAccountId
|
||||
EUR ${AccountStatement1Transaction1Amount}/20?2219-10-02/...?30$AccountStatement1Transaction1OtherPartyBankCode?31$AccountStatement1Transaction1OtherPartyAccountId
|
||||
?32$AccountStatement1Transaction1OtherPartyName
|
||||
:61:${convertMt940Date(AccountStatement1BookingDate)}${convertToShortBookingDate(AccountStatement1BookingDate)}DR${convertAmount(AccountStatement1Transaction2Amount)}N062NONREF
|
||||
:61:${convertMt940Date(AccountStatement1BookingDate)}${convertToShortBookingDate(AccountStatement1BookingDate)}DR${AccountStatement1Transaction2Amount}N062NONREF
|
||||
:86:166?00ONLINE-UEBERWEISUNG?109249?20EREF+674?21SVWZ+1908301/
|
||||
EUR ${convertAmount(AccountStatement1Transaction2Amount)}/20?2219-10-02/...?30$AccountStatement1Transaction2OtherPartyBankCode?31$AccountStatement1Transaction2OtherPartyAccountId
|
||||
EUR ${AccountStatement1Transaction2Amount}/20?2219-10-02/...?30$AccountStatement1Transaction2OtherPartyBankCode?31$AccountStatement1Transaction2OtherPartyAccountId
|
||||
?32$AccountStatement1Transaction2OtherPartyName
|
||||
:62F:C${convertMt940Date(AccountStatement1BookingDate)}EUR${convertAmount(AccountStatement1With2TransactionsClosingBalanceAmount)}
|
||||
:62F:C${convertMt940Date(AccountStatement1BookingDate)}EUR${AccountStatement1With2TransactionsClosingBalanceAmount}
|
||||
-
|
||||
""".trimIndent()
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package net.dankito.banking.extensions
|
||||
|
||||
import net.dankito.banking.fints.model.Amount
|
||||
import net.dankito.banking.fints.model.Money
|
||||
import java.math.BigDecimal
|
||||
|
||||
|
||||
fun BigDecimal.toAmount(): Amount {
|
||||
return Amount(this.toString())
|
||||
}
|
||||
|
||||
fun BigDecimal.toMoney(): Money {
|
||||
return Money(this.toAmount(), "EUR")
|
||||
}
|
||||
|
||||
fun Amount.toJavaBigDecimal(): BigDecimal {
|
||||
return BigDecimal(this.string)
|
||||
}
|
||||
|
||||
fun Money.toJavaBigDecimal(): BigDecimal {
|
||||
return this.amount.toJavaBigDecimal()
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package net.dankito.banking.extensions
|
||||
|
||||
import com.ionspin.kotlin.bignum.integer.Sign
|
||||
import net.dankito.banking.fints.model.Money
|
||||
import java.math.BigDecimal
|
||||
|
||||
|
||||
fun BigDecimal.toIonspinBigDecimal(): com.ionspin.kotlin.bignum.decimal.BigDecimal {
|
||||
return com.ionspin.kotlin.bignum.decimal.BigDecimal.parseString(this.toString()) // TODO: couldn't figure out how to create BigDecimal from unscaledValue and scale
|
||||
}
|
||||
|
||||
fun com.ionspin.kotlin.bignum.decimal.BigDecimal.toJavaBigDecimal(): BigDecimal {
|
||||
val converted = BigDecimal.valueOf(this.significand.longValue(), (this.precision - this.exponent - 1).toInt())
|
||||
|
||||
if (this.significand.sign == Sign.NEGATIVE) {
|
||||
return converted.negate()
|
||||
}
|
||||
|
||||
return converted
|
||||
}
|
||||
|
||||
fun Money.toJavaBigDecimal(): BigDecimal {
|
||||
return this.amount.toJavaBigDecimal()
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
package net.dankito.banking
|
||||
|
||||
import net.dankito.banking.extensions.toIonspinBigDecimal
|
||||
import net.dankito.banking.extensions.toJavaBigDecimal
|
||||
import com.soywiz.klock.jvm.toDate
|
||||
import net.dankito.banking.extensions.toKlockDate
|
||||
import net.dankito.banking.ui.BankingClientCallback
|
||||
|
@ -25,8 +23,11 @@ import net.dankito.utils.serialization.JacksonJsonSerializer
|
|||
import net.dankito.banking.fints.webclient.IWebClient
|
||||
import net.dankito.banking.fints.webclient.KtorWebClient
|
||||
import net.dankito.banking.bankfinder.BankInfo
|
||||
import net.dankito.banking.extensions.toAmount
|
||||
import net.dankito.banking.extensions.toMoney
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.io.File
|
||||
import java.math.BigDecimal
|
||||
|
||||
|
||||
open class fints4kBankingClient(
|
||||
|
@ -133,7 +134,7 @@ open class fints4kBankingClient(
|
|||
callback(BankingClientResponse(false, "Cannot find account for ${bankAccount.identifier}")) // TODO: translate
|
||||
}
|
||||
else {
|
||||
val mappedData = BankTransferData(data.creditorName, data.creditorIban, data.creditorBic, data.amount.toIonspinBigDecimal(), data.usage, data.instantPayment)
|
||||
val mappedData = BankTransferData(data.creditorName, data.creditorIban, data.creditorBic, data.amount.toMoney(), data.usage, data.instantPayment)
|
||||
|
||||
client.doBankTransferAsync(mappedData, account) { response ->
|
||||
saveData()
|
||||
|
|
Loading…
Reference in New Issue