[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libeufin] 03/08: Refactoring Camt generation.
From: |
gnunet |
Subject: |
[libeufin] 03/08: Refactoring Camt generation. |
Date: |
Fri, 04 Dec 2020 15:00:06 +0100 |
This is an automated email from the git hooks/post-receive script.
ms pushed a commit to branch master
in repository libeufin.
commit 338960bbc8965df12e1e76d24f2a3103d792f134
Author: MS <ms@taler.net>
AuthorDate: Fri Dec 4 11:39:50 2020 +0100
Refactoring Camt generation.
---
.../tech/libeufin/sandbox/EbicsProtocolBackend.kt | 356 ++++++++++-----------
.../main/kotlin/tech/libeufin/sandbox/Helpers.kt | 4 +
.../src/main/kotlin/tech/libeufin/sandbox/Main.kt | 8 +-
3 files changed, 183 insertions(+), 185 deletions(-)
diff --git
a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
index 5ced5e1..321572b 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
@@ -197,13 +197,11 @@ private fun getRelatedParty(branch: XmlElementBuilder,
payment: RawPayment) {
}
}
-/**
- * Returns a list of camt strings. Note: each element in the
- * list accounts for only one payment in the history. In other
- * words, the camt constructor does create always only one "Ntry"
- * node.
- */
-fun buildCamtString(type: Int, subscriberIban: String, history:
List<RawPayment>): MutableList<String> {
+fun buildCamtString(
+ type: Int,
+ subscriberIban: String,
+ history: List<RawPayment>
+): String {
/**
* ID types required:
*
@@ -216,156 +214,190 @@ fun buildCamtString(type: Int, subscriberIban: String,
history: List<RawPayment>
* - Proprietary code of the bank transaction
* - Id of the servicer (Issuer and Code)
*/
- val ret = mutableListOf<String>()
- history.forEach {
- logger.debug(
- "Building CAMT over payment: ${it.debitorIban} =>
${it.creditorIban}, ${it.currency}:${it.amount}, ${it.subject}"
- )
- val dashedDate = expectNonNull(it.date)
- val now = LocalDateTime.now()
- val zonedDateTime = now.toZonedString()
- ret.add(
- constructXml(indent = true) {
- root("Document") {
- attribute("xmlns",
"urn:iso:std:iso:20022:tech:xsd:camt.053.001.02")
- attribute("xmlns:xsi",
"http://www.w3.org/2001/XMLSchema-instance")
- attribute(
- "xsi:schemaLocation",
- "urn:iso:std:iso:20022:tech:xsd:camt.053.001.02
camt.053.001.02.xsd"
- )
- element("BkToCstmrStmt") {
- element("GrpHdr") {
- element("MsgId") {
- text("sandbox-${now.millis()}")
- }
- element("CreDtTm") {
- text(zonedDateTime)
+ val now = LocalDateTime.now()
+ val dashedDate = now.toDashedDate()
+ val zonedDateTime = now.toZonedString()
+ return constructXml(indent = true) {
+ root("Document") {
+ attribute("xmlns",
"urn:iso:std:iso:20022:tech:xsd:camt.053.001.02")
+ attribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
+ attribute(
+ "xsi:schemaLocation",
+ "urn:iso:std:iso:20022:tech:xsd:camt.053.001.02
camt.053.001.02.xsd"
+ )
+ element("BkToCstmrStmt") {
+ element("GrpHdr") {
+ element("MsgId") {
+ text("sandbox-${now.millis()}")
+ }
+ element("CreDtTm") {
+ text(zonedDateTime)
+ }
+ element("MsgPgntn") {
+ element("PgNb") {
+ text("001")
+ }
+ element("LastPgInd") {
+ text("true")
+ }
+ }
+ }
+ element(if (type == 52) "Rpt" else "Stmt") {
+ element("Id") {
+ text("0")
+ }
+ element("ElctrncSeqNb") {
+ text("0")
+ }
+ element("LglSeqNb") {
+ text("0")
+ }
+ element("CreDtTm") {
+ text(zonedDateTime)
+ }
+ element("Acct") {
+ // mandatory account identifier
+ element("Id/IBAN") {
+ text(subscriberIban)
+ }
+ element("Ccy") {
+ text("EUR")
+ }
+ element("Ownr/Nm") {
+ text("Debitor/Owner Name")
+ }
+ element("Svcr/FinInstnId") {
+ element("Nm") {
+ text("Libeufin Bank")
}
- element("MsgPgntn") {
- element("PgNb") {
- text("001")
+ element("Othr") {
+ element("Id") {
+ text("0")
}
- element("LastPgInd") {
- text("true")
+ element("Issr") {
+ text("XY")
}
}
}
- element(if (type == 52) "Rpt" else "Stmt") {
- element("Id") {
- text("0")
- }
- element("ElctrncSeqNb") {
- text("0")
+ }
+ element("Bal") {
+ element("Tp/CdOrPrtry/Cd") {
+ /* Balance type, in a coded format. PRCD stands
+ for "Previously closed booked" and shows the
+ balance at the time _before_ all the entries
+ reported in this document were posted to the
+ involved bank account. */
+ text("PRCD")
+ }
+ element("Amt") {
+ attribute("Ccy", "EUR")
+ text(Amount(0).toPlainString())
+ }
+ element("CdtDbtInd") {
+ // a temporary value to get the camt to validate.
+ // Should be fixed along #6269
+ text("CRDT")
+ }
+ element("Dt/Dt") {
+ // date of this balance
+ text(dashedDate)
+ }
+ }
+ element("Bal") {
+ element("Tp/CdOrPrtry/Cd") {
+ /* CLBD stands for "Closing booked balance", and it
+ is calculated by summing the PRCD with all the
+ entries reported in this document */
+ text("CLBD")
+ }
+ element("Amt") {
+ attribute("Ccy", "EUR")
+ text(Amount(0).toPlainString())
+ }
+ element("CdtDbtInd") {
+ // a temporary value to get the camt to validate.
+ // Should be fixed along #6269
+ text("DBIT")
+ }
+ element("Dt/Dt") {
+ text(dashedDate)
+ }
+ }
+ history.forEach {
+ this.element("Ntry") {
+ element("Amt") {
+ attribute("Ccy", it.currency)
+ text(it.amount)
}
- element("LglSeqNb") {
- text("0")
+ element("CdtDbtInd") {
+ text(
+ if (subscriberIban.equals(it.creditorIban))
+ "CRDT" else "DBIT"
+ )
}
- element("CreDtTm") {
- text(zonedDateTime)
+ element("Sts") {
+ /* Status of the entry (see 2.4.2.15.5 from
the ISO20022 reference document.)
+ * From the original text:
+ * "Status of an entry on the books of the
account servicer" */
+ text("BOOK")
}
- element("Acct") {
- // mandatory account identifier
- element("Id/IBAN") {
- text(subscriberIban)
- }
- element("Ccy") {
- text("EUR")
- }
- element("Ownr/Nm") {
- text("Debitor/Owner Name")
+ element("BookgDt/Dt") {
+ text(dashedDate)
+ } // date of the booking
+ element("ValDt/Dt") {
+ text(dashedDate)
+ } // date of assets' actual (un)availability
+ element("AcctSvcrRef") {
+ val uid = if (it.uid != null)
it.uid.toString() else {
+ throw EbicsRequestError(
+ errorCode = "091116",
+ errorText = "EBICS_PROCESSING_ERROR"
+ )
}
- element("Svcr/FinInstnId") {
- element("Nm") {
- text("Libeufin Bank")
+ text(uid)
+ }
+ element("BkTxCd") {
+ /* "Set of elements used to fully identify
the type of underlying
+ * transaction resulting in an entry". */
+ element("Domn") {
+ element("Cd") {
+ text("PMNT")
}
- element("Othr") {
- element("Id") {
- text("0")
+ element("Fmly") {
+ element("Cd") {
+ text("ICDT")
}
- element("Issr") {
- text("XY")
+ element("SubFmlyCd") {
+ text("ESCT")
}
}
}
- }
- element("Bal") {
- element("Tp/CdOrPrtry/Cd") {
- /* Balance type, in a coded format. PRCD
stands
- for "Previously closed booked" and
shows the
- balance at the time _before_ all the
entries
- reported in this document were posted
to the
- involved bank account. */
- text("PRCD")
- }
- element("Amt") {
- attribute("Ccy", "EUR")
- text(Amount(0).toPlainString())
- }
- element("CdtDbtInd") {
- // a temporary value to get the camt to
validate.
- // Should be fixed along #6269
- text("CRDT")
- }
- element("Dt/Dt") {
- // date of this balance
- text(dashedDate)
+ element("Prtry") {
+ element("Cd") {
+ text("0")
+ }
+ element("Issr") {
+ text("XY")
+ }
}
}
- element("Bal") {
- element("Tp/CdOrPrtry/Cd") {
- /* CLBD stands for "Closing booked
balance", and it
- is calculated by summing the PRCD with
all the
- entries reported in this document */
- text("CLBD")
+ element("NtryDtls/TxDtls") {
+ element("Refs") {
+ element("MsgId") {
+ text("0")
+ }
+ element("PmtInfId") {
+ text("0")
+ }
+ element("EndToEndId") {
+ text("NOTPROVIDED")
+ }
}
- element("Amt") {
+ element("AmtDtls/TxAmt/Amt") {
attribute("Ccy", "EUR")
- text(Amount(0).toPlainString())
- }
- element("CdtDbtInd") {
- // a temporary value to get the camt to
validate.
- // Should be fixed along #6269
- text("DBIT")
- }
- element("Dt/Dt") {
- text(dashedDate)
- }
- }
- element("Ntry") {
- element("Amt") {
- attribute("Ccy", it.currency)
text(it.amount)
}
- element("CdtDbtInd") {
- text(
- if
(subscriberIban.equals(it.creditorIban))
- "CRDT" else "DBIT"
- )
- }
- element("Sts") {
- /* Status of the entry (see 2.4.2.15.5
from the ISO20022 reference document.)
- * From the original text:
- * "Status of an entry on the books of
the account servicer" */
- text("BOOK")
- }
- element("BookgDt/Dt") {
- text(dashedDate)
- } // date of the booking
- element("ValDt/Dt") {
- text(dashedDate)
- } // date of assets' actual (un)availability
- element("AcctSvcrRef") {
- val uid = if (it.uid != null)
it.uid.toString() else {
- throw EbicsRequestError(
- errorCode = "091116",
- errorText =
"EBICS_PROCESSING_ERROR"
- )
- }
- text(uid)
- }
element("BkTxCd") {
- /* "Set of elements used to fully
identify the type of underlying
- * transaction resulting in an entry".
*/
element("Domn") {
element("Cd") {
text("PMNT")
@@ -388,58 +420,17 @@ fun buildCamtString(type: Int, subscriberIban: String,
history: List<RawPayment>
}
}
}
- element("NtryDtls/TxDtls") {
- element("Refs") {
- element("MsgId") {
- text("0")
- }
- element("PmtInfId") {
- text("0")
- }
- element("EndToEndId") {
- text("NOTPROVIDED")
- }
- }
- element("AmtDtls/TxAmt/Amt") {
- attribute("Ccy", "EUR")
- text(it.amount)
- }
- element("BkTxCd") {
- element("Domn") {
- element("Cd") {
- text("PMNT")
- }
- element("Fmly") {
- element("Cd") {
- text("ICDT")
- }
- element("SubFmlyCd") {
- text("ESCT")
- }
- }
- }
- element("Prtry") {
- element("Cd") {
- text("0")
- }
- element("Issr") {
- text("XY")
- }
- }
- }
- getRelatedParty(this, it)
- element("RmtInf/Ustrd") {
- text(it.subject)
- }
+ getRelatedParty(this, it)
+ element("RmtInf/Ustrd") {
+ text(it.subject)
}
}
}
}
}
}
- )
+ }
}
- return ret
}
/**
@@ -460,9 +451,8 @@ private fun constructCamtResponse(
importDateFromMillis(dateRange.end.toGregorianCalendar().timeInMillis)
)
} else Pair(parseDashedDate("1970-01-01"), LocalDateTime.now())
- val history = mutableListOf<RawPayment>()
val bankAccount = getBankAccountFromSubscriber(subscriber)
- return buildCamtString(type, bankAccount.iban,
historyForAccount(bankAccount.iban))
+ return mutableListOf(buildCamtString(type, bankAccount.iban,
historyForAccount(bankAccount.iban)))
}
/**
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt
index 67d17a9..0ea1927 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt
@@ -24,6 +24,10 @@ import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.and
import org.jetbrains.exposed.sql.transactions.transaction
+fun SandboxAssert(condition: Boolean, reason: String) {
+ if (!condition) throw SandboxError(HttpStatusCode.InternalServerError,
reason)
+}
+
fun getOrderTypeFromTransactionId(transactionID: String): String {
val uploadTransaction = transaction {
EbicsUploadTransactionEntity.findById(transactionID)
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
index 7de0c95..ac88e97 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
@@ -233,9 +233,13 @@ fun serverMain(dbName: String) {
get("/") {
call.respondText("Hello, this is Sandbox\n",
ContentType.Text.Plain)
}
- // only reason for a post is to hide the iban to some degree.
- post("/admin/payments/camt53") {
+ // only reason for a post is to hide the iban (to some degree.)
+ post("/admin/payments/camt/53") {
val iban = call.receiveText()
+ val history = historyForAccount(iban)
+ val camt53 = buildCamtString(53, iban, history)
+ call.respondText(camt53, ContentType.Text.Xml,
HttpStatusCode.OK)
+ return@post
}
get("/admin/payments") {
val ret = PaymentsResponse()
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [libeufin] branch master updated (c8bcfc1 -> ae7897d), gnunet, 2020/12/04
- [libeufin] 02/08: more abstraction at sandbox, gnunet, 2020/12/04
- [libeufin] 01/08: evolving sandbox, gnunet, 2020/12/04
- [libeufin] 03/08: Refactoring Camt generation.,
gnunet <=
- [libeufin] 07/08: prefer wrapping lists into JSON field, gnunet, 2020/12/04
- [libeufin] 06/08: Get unit tests from Sandbox to pass., gnunet, 2020/12/04
- [libeufin] 08/08: abstract over Camt type, gnunet, 2020/12/04
- [libeufin] 04/08: sandbox payment API: ask the payment direction too, gnunet, 2020/12/04
- [libeufin] 05/08: address validation issues, gnunet, 2020/12/04