commit e3b58a2ca0b59045d2c5d754828be78eef9ce883
parent 65dd58fc819562255679db601b950044732a3a79
Author: Florian Dold <florian.dold@gmail.com>
Date: Thu, 11 Jun 2020 23:04:14 +0530
further camt parsing improvements
Diffstat:
2 files changed, 52 insertions(+), 5 deletions(-)
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Iso20022.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/Iso20022.kt
@@ -36,6 +36,19 @@ enum class TransactionStatus {
BOOK, PENDING
}
+/**
+ * Schemes to identify a transaction within an account.
+ * An identifier from such a scheme will be used to reconcile transactions
+ * from multiple sources.
+ * (LibEuFin-specific, not defined by ISO 20022)
+ */
+enum class TransactionIdentifierSchemes {
+ /**
+ * Reconcile based on the account servicer reference.
+ */
+ AcctSvcrRef
+}
+
data class TransactionDetails(
/**
* Related parties as JSON.
@@ -53,9 +66,14 @@ data class TransactionDetails(
data class BankTransaction(
val accountIdentifier: String,
/**
+ * Identifier for the transaction that should be unique within an account.
+ * Prefix by the identifier scheme name followed by a colon.
+ */
+ val transactionIdentifier: String,
+ /**
* Scheme used for the account identifier.
*/
- val accountScheme: String,
+ val accountIdentifierScheme: String,
val currency: String,
val amount: String,
/**
@@ -76,7 +94,10 @@ data class BankTransaction(
* Is this a batch booking?
*/
val isBatch: Boolean,
- val details: List<TransactionDetails>
+ val details: List<TransactionDetails>,
+ val valueDate: DateOrDateTime?,
+ val bookingDate: DateOrDateTime?,
+ val accountServicerReference: String
)
abstract class TypedEntity(val type: String)
@@ -97,6 +118,16 @@ class Account(
val iban: String?
) : TypedEntity("party")
+abstract class DateOrDateTime(type: String) : TypedEntity(type)
+
+class Date(
+ val date: String
+) : DateOrDateTime("date")
+
+class DateTime(
+ val date: String
+) : DateOrDateTime("datetime")
+
@JsonInclude(JsonInclude.Include.NON_NULL)
data class BankTransactionCode(
@@ -143,6 +174,16 @@ data class RelatedParties(
class CamtParsingError(msg: String) : Exception(msg)
+private fun XmlElementDestructor.extractDateOrDateTime(): DateOrDateTime {
+ return requireOnlyChild {
+ when (it.localName) {
+ "Dt" -> Date(e.textContent)
+ "DtTm" -> DateTime(e.textContent)
+ else -> throw Exception("Invalid date / time: ${e.localName}")
+ }
+ }
+}
+
private fun XmlElementDestructor.extractAgent(): Agent {
return Agent(
name = maybeUniqueChildNamed("FinInstnId") {
@@ -277,17 +318,24 @@ private fun XmlElementDestructor.extractInnerTransactions(): List<BankTransactio
}
)
}
+ val acctSvcrRef = maybeUniqueChildNamed("AcctSvcrRef") { it.textContent }
+ // For now, only support account servicer reference as id
+ val txId = "AcctSvcrRef:" + (acctSvcrRef ?: throw Exception("currently, AcctSvcrRef is mandatory in LibEuFin"))
val details = extractTransactionDetails()
BankTransaction(
accountIdentifier = iban,
- accountScheme = "iban",
+ accountIdentifierScheme = "iban",
amount = amount,
currency = currency,
status = status,
creditDebitIndicator = creditDebitIndicator,
bankTransactionCode = btc,
details = details,
- isBatch = details.size > 1
+ isBatch = details.size > 1,
+ bookingDate = maybeUniqueChildNamed("BookgDt") { extractDateOrDateTime() },
+ valueDate = maybeUniqueChildNamed("ValDt") { extractDateOrDateTime() },
+ accountServicerReference = acctSvcrRef,
+ transactionIdentifier = txId
)
}
}
diff --git a/util/src/main/kotlin/XmlCombinators.kt b/util/src/main/kotlin/XmlCombinators.kt
@@ -145,7 +145,6 @@ class XmlElementDestructor internal constructor(val d: Document, val e: Element)
if (cl.size == 1) {
val el = cl[0]
val destr = XmlElementDestructor(d, el)
- println("found child $s")
return f(destr, el)
}
return null