summaryrefslogtreecommitdiff
path: root/nexus/src/main/kotlin
diff options
context:
space:
mode:
authorAntoine A <>2024-05-06 17:21:24 +0900
committerAntoine A <>2024-05-06 17:21:24 +0900
commitdaf79284cff57b8138c0efef5fe865ca6eb4509b (patch)
tree30c3dd7096cccc550477403cfaaaf0f1099893ae /nexus/src/main/kotlin
parent2bc9b85d82aabb656fc9894430eaad53ab22f2ce (diff)
downloadlibeufin-daf79284cff57b8138c0efef5fe865ca6eb4509b.tar.gz
libeufin-daf79284cff57b8138c0efef5fe865ca6eb4509b.tar.bz2
libeufin-daf79284cff57b8138c0efef5fe865ca6eb4509b.zip
nexus: parse GLS instant transaction notifications
Diffstat (limited to 'nexus/src/main/kotlin')
-rw-r--r--nexus/src/main/kotlin/tech/libeufin/nexus/Iso20022.kt42
-rw-r--r--nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsOrder.kt3
2 files changed, 39 insertions, 6 deletions
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Iso20022.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/Iso20022.kt
index 5eb9bfb1..e8cb5680 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/Iso20022.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/Iso20022.kt
@@ -343,8 +343,10 @@ fun parseTx(
}
}
- fun XmlDestructor.bookDate() =
- one("BookgDt").one("Dt").date().atStartOfDay().toInstant(ZoneOffset.UTC)
+ fun XmlDestructor.executionDate(): Instant {
+ // Value date if present else booking date
+ return (opt("ValDt") ?: one("BookgDt")).one("Dt").date().atStartOfDay().toInstant(ZoneOffset.UTC)
+ }
fun XmlDestructor.nexusId(): String? =
opt("Refs") { opt("EndToEndId")?.textProvided() ?: opt("MsgId")?.text() }
@@ -392,7 +394,7 @@ fun parseTx(
each("Ntry") {
val entryRef = opt("AcctSvcrRef")?.text()
assertBooked(entryRef)
- val bookDate = bookDate()
+ val bookDate = executionDate()
val kind = one("CdtDbtInd").enum<Kind>()
val amount = amount(acceptedCurrency)
one("NtryDtls").one("TxDtls") { // TODO handle batches
@@ -446,6 +448,36 @@ fun parseTx(
opt("BkToCstmrStmt")?.each("Stmt") { // Camt.053
parseGlsInner()
}
+ opt("BkToCstmrDbtCdtNtfctn")?.each("Ntfctn") { // Camt.054
+ opt("Acct") {
+ // Sanity check on currency and IBAN ?
+ }
+ each("Ntry") {
+ val entryRef = opt("AcctSvcrRef")?.text()
+ assertBooked(entryRef)
+ val bookDate = executionDate()
+ val kind = one("CdtDbtInd").enum<Kind>()
+ val amount = amount(acceptedCurrency)
+ if (!isReversalCode()) {
+ one("NtryDtls").one("TxDtls") {
+ val txRef = one("Refs").opt("AcctSvcrRef")?.text()
+ val subject = opt("RmtInf")?.map("Ustrd") { text() }?.joinToString("")
+ if (kind == Kind.CRDT) {
+ val bankId = one("Refs").opt("TxId")?.text()
+ val debtorPayto = opt("RltdPties") { payto("Dbtr") }
+ txsInfo.add(TxInfo.Credit(
+ ref = bankId ?: txRef ?: entryRef,
+ bookDate = bookDate,
+ bankId = bankId,
+ amount = amount,
+ subject = subject,
+ debtorPayto = debtorPayto
+ ))
+ }
+ }
+ }
+ }
+ }
}
Dialect.postfinance -> {
opt("BkToCstmrStmt")?.each("Stmt") { // Camt.053
@@ -455,7 +487,7 @@ fun parseTx(
each("Ntry") {
val entryRef = opt("AcctSvcrRef")?.text()
assertBooked(entryRef)
- val bookDate = bookDate()
+ val bookDate = executionDate()
if (isReversalCode()) {
one("NtryDtls").one("TxDtls") {
val kind = one("CdtDbtInd").enum<Kind>()
@@ -481,7 +513,7 @@ fun parseTx(
each("Ntry") {
val entryRef = opt("AcctSvcrRef")?.text()
assertBooked(entryRef)
- val bookDate = bookDate()
+ val bookDate = executionDate()
if (!isReversalCode()) {
one("NtryDtls").each("TxDtls") {
val kind = one("CdtDbtInd").enum<Kind>()
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsOrder.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsOrder.kt
index d6cced05..40830093 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsOrder.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsOrder.kt
@@ -62,11 +62,12 @@ enum class Dialect {
}
}
}
+ // TODO for GLS we might have to fetch the same kind of files from multiple orders
gls -> when (doc) {
SupportedDocument.PAIN_002 -> EbicsOrder.V3("BTD", "REP", "DE", "pain.002", null, "ZIP", "SCT")
SupportedDocument.CAMT_052 -> EbicsOrder.V3("BTD", "STM", "DE", "camt.052", null, "ZIP")
SupportedDocument.CAMT_053 -> EbicsOrder.V3("BTD", "EOP", "DE", "camt.053", null, "ZIP")
- SupportedDocument.CAMT_054 -> EbicsOrder.V3("BTD", "STM", "DE", "camt.054", null, "ZIP")
+ SupportedDocument.CAMT_054 -> EbicsOrder.V3("BTD", "STM", "DE", "camt.054", null, "ZIP", "SCI")
SupportedDocument.PAIN_002_LOGS -> EbicsOrder.V3("HAC")
}
}