libeufin

Integration and sandbox testing for FinTech APIs and data formats
Log | Files | Refs | Submodules | README | LICENSE

commit d01734374a4e8ed261295a23b909f2d942fd50d8
parent ebf6da1073887634da0fbb2117db625f62274f1f
Author: Antoine A <>
Date:   Wed,  5 Mar 2025 15:25:14 +0100

nexus: more generic camt parser

Diffstat:
Mnexus/src/main/kotlin/tech/libeufin/nexus/iso20022/camt.kt | 39++++++++++-----------------------------
1 file changed, 10 insertions(+), 29 deletions(-)

diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/iso20022/camt.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/iso20022/camt.kt @@ -230,7 +230,7 @@ private enum class Kind { /** Parse a payto */ private fun XmlDestructor.payto(prefix: String): IbanPayto? { return opt("RltdPties") { - val iban = opt("${prefix}Acct")?.one("Id")?.one("IBAN")?.text() + val iban = opt("${prefix}Acct")?.one("Id")?.opt("IBAN")?.text() if (iban != null) { val name = opt(prefix) { opt("Nm")?.text() ?: opt("Pty")?.one("Nm")?.text() } // TODO more performant option @@ -514,10 +514,9 @@ fun parseTx(notifXml: InputStream, dialect: Dialect): List<AccountTransactions> val batches = each("Ntry") { if (!isBooked()) return@each val entryCode = bankTransactionCode() - if (!entryCode.isPayment()) return@each val reversal = opt("RvslInd")?.text() == "true" val entryKind = opt("CdtDbtInd")?.enum<Kind>(); - val tmp = one("NtryDtls").map("TxDtls") { this } + val tmp = opt("NtryDtls")?.map("TxDtls") { this } ?: return@each val unique = tmp.size == 1 val entryRef = opt("AcctSvcrRef")?.text() val bookDate = executionDate() @@ -627,32 +626,14 @@ fun parseTx(notifXml: InputStream, dialect: Dialect): List<AccountTransactions> } accountTxs.add(AccountTransactions.fromParts(iban, currency, txInfos)) } - XmlDestructor.fromStream(notifXml, "Document") { when (dialect) { - Dialect.gls -> { - // Camt.053 All transactions appear here the day after they are booked - opt("BkToCstmrStmt")?.each("Stmt") { parseInner() } - // Camt.052 Transactions might appear here first before the end of the day - opt("BkToCstmrAcctRpt")?.each("Rpt") { parseInner() } - // Camt.054 Instant transactions appear here a few seconds after being booked - opt("BkToCstmrDbtCdtNtfctn")?.each("Ntfctn") { parseInner() } - } - Dialect.postfinance -> { - /* - Camt.053 - All transactions appear here on the day following their booking. Alas, some - necessary metadata is missing, which is only present in camt.054. However, - this file contains the structured return reasons that are missing from the - camt.054 files. That's why we only use this file for this purpose. - */ - opt("BkToCstmrStmt")?.each("Stmt") { parseInner() } - // Camt.054 Instant transactions appear here a moment after being booked - opt("BkToCstmrDbtCdtNtfctn")?.each("Ntfctn") { parseInner() } - } - Dialect.maerki_baumann -> { - // Camt.053 All transactions appear here the day after they are booked - opt("BkToCstmrStmt")?.each("Stmt") { parseInner() } - } - }} + XmlDestructor.fromStream(notifXml, "Document") { + // Camt.053 + opt("BkToCstmrStmt")?.each("Stmt") { parseInner() } + // Camt.052 + opt("BkToCstmrAcctRpt")?.each("Rpt") { parseInner() } + // Camt.054 + opt("BkToCstmrDbtCdtNtfctn")?.each("Ntfctn") { parseInner() } + } return accountTxs }