[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libeufin] branch master updated: Camt generation.
From: |
gnunet |
Subject: |
[libeufin] branch master updated: Camt generation. |
Date: |
Tue, 17 Mar 2020 17:07:02 +0100 |
This is an automated email from the git hooks/post-receive script.
marcello pushed a commit to branch master
in repository libeufin.
The following commit(s) were added to refs/heads/master by this push:
new bc1b7a3 Camt generation.
bc1b7a3 is described below
commit bc1b7a3ee37698bcac5979b180062886feeb626d
Author: Marcello Stanisci <address@hidden>
AuthorDate: Tue Mar 17 17:05:27 2020 +0100
Camt generation.
Avoid spreading the logic through multiple helper
functions. And also, separaing the data retrieval
from database and the actual (CAMT) string construction.
---
.../tech/libeufin/sandbox/EbicsProtocolBackend.kt | 240 ++++++++++-----------
.../src/main/kotlin/tech/libeufin/sandbox/Main.kt | 26 +--
2 files changed, 120 insertions(+), 146 deletions(-)
diff --git
a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
index 1c3a894..0b79c81 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
@@ -136,19 +136,118 @@ private suspend fun
ApplicationCall.respondEbicsKeyManagement(
respondText(text, ContentType.Application.Xml, HttpStatusCode.OK)
}
+private fun buildCamtString(history: SizedIterable<BankTransactionEntity>,
type: Int): String {
+
+ return constructXml(indent = true) {
+ root("Document") {
+ attribute("xmlns",
"urn:iso:std:iso:20022:tech:xsd:camt.053.001.08")
+ attribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
+ attribute("xmlns:schemaLocation",
"urn:iso:std:iso:20022:tech:xsd:camt.053.001.02 camt.053.001.02.xsd")
+ element("BkToCstmrStmt") {
+ element("GrpHdr") {
+ element("MsgId") {
+ // unique identifier for a message
+ text("id under group header")
+ }
+ element("CreDtTm")
+ }
+ element(if (type == 52) "Rpt" else "Stmt") {
+ element("Id") {
+ // unique identificator for a report.
+ text("id under report")
+ }
+ element("Acct") {
+ // mandatory account identifier
+ text("account identifier")
+ }
+ element("Bal") {
+ element("Tp") {
+ // FIXME: type
+ element("CdOrPrTry") {
+ /**
+ * FIXME: code-or-proprietary
+ * This section specifies the 'balance type',
either in a
+ * 'coded' format or in a proprietary one.
+ */
+ }
+ }
+ element("Amt") {
+ /**
+ * FIXME: Amount
+ */
+ attribute("Ccy", "EUR")
+ text(Amount("0.99").toPlainString())
+ }
+ element("CdtDbtInd") {
+ /**
+ * FIXME: credit-debit-indicator
+ * Indicates whether the balance is a 'credit'
("CRDT") or a 'debit' ("DBIT") balance.
+ */
+ }
+ element("Dt") {
+ /**
+ * FIXME: date, in YYYY-MM-DD format
+ */
+ }
+ }
+
+ history.forEach {
+ element("Ntry") {
+ /* FIXME: one entry in an account history.
+ * NOTE: this element can appear from 0 to unbounded
number of times.
+ * */
+ element("Amt") {
+ /* FIXME: amount of this entry */
+ }
+ element("CdtDbtInd") {
+ /* FIXME: as above, whether the entry
witnesses debit or credit */
+ }
+ element("Sts") {
+ /* FIXME: 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"
+ */
+ }
+ element("BkTxCd") {
+ /* FIXME: Bank-transaction-code, see section
2.4.2.15.10.
+ * From the original text:
+ *
+ * "Set of elements used to fully identify the
type of underlying
+ * transaction resulting in an entry"
+ */
+ }
+ element("BookgDt") {
+ /**
+ * FIXME, Booking-date: when the entry was
posted on the books
+ * of the account servicer; do not necessarily
implies that assets
+ * become available. NOTE: this element is
optional.
+ */
+ }
+ element("ValDt") {
+ /**
+ * FIXME, Value-date: when the asset
corresponding to one entry
+ * becomes available (or unavailable, in case
of debit type entry)
+ * to the account owner. NOTE: this element
is optional.
+ */
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
/**
- * This function populates the "history" content of both a CAMT.052 and
CAMT.053.
- * FIXME: There might be needed some filter to exclude non-booked entries from
a
- * query-set (as CAMT.053 should do, see #6046)
- *
- * @param cusromerId unique identifier of a bank's customer: not
EBICS-relevant.
- * @param request the EBICS request carrying a "history" message.
- * @param base the sub-node where to start attaching history elements.
+ * Builds CAMT response.
*
+ * @param history the list of all the history elements
+ * @param type 52 or 53.
*/
-private fun iterHistory(customerId: Int, header: EbicsRequest.Header, base:
XmlElementBuilder) {
+private fun constructCamtResponse(type: Int, customerId: Int, header:
EbicsRequest.Header): String {
- extractHistoryForEach(
+ val history = extractHistory(
customerId,
try {
(header.static.orderDetails?.orderParams as
EbicsRequest.StandardOrderParams).dateRange!!.start.toString()
@@ -162,125 +261,8 @@ private fun iterHistory(customerId: Int, header:
EbicsRequest.Header, base: XmlE
LOGGER.debug("Asked to iterate over history with NO end date;
default to now")
DatatypeFactory.newInstance().newXMLGregorianCalendar(GregorianCalendar()).toString()
}
- ) {
-
- base.element("Ntry") {
- /* FIXME: one entry in an account history.
- * NOTE: this element can appear from 0 to unbounded number of
times.
- * */
- element("Amt") {
- /* FIXME: amount of this entry */
- }
- element("CdtDbtInd") {
- /* FIXME: as above, whether the entry witnesses debit or
credit */
- }
- element("Sts") {
- /* FIXME: 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"
- */
- }
- element("BkTxCd") {
- /* FIXME: Bank-transaction-code, see section 2.4.2.15.10.
- * From the original text:
- *
- * "Set of elements used to fully identify the type of
underlying
- * transaction resulting in an entry"
- */
- }
- element("BookgDt") {
- /**
- * FIXME, Booking-date: when the entry was posted on the books
- * of the account servicer; do not necessarily implies that
assets
- * become available. NOTE: this element is optional.
- */
- }
- element("ValDt") {
- /**
- * FIXME, Value-date: when the asset corresponding to one entry
- * becomes available (or unavailable, in case of debit type
entry)
- * to the account owner. NOTE: this element is optional.
- */
- }
- }
- }
-}
-
-/**
- * This function populates the content under "Rpt" or "Stmt" nodes,
- * therefore is valid for generating both C52 and C53 responses.
- *
- * @param base the sub-node where starting to append content.
- */
-private fun balance(base: XmlElementBuilder) {
-
- base.element("Id") {
- // unique identificator for a report.
- text("id under report")
- }
- base.element("Acct") {
- // mandatory account identifier
- text("account identifier")
- }
- base.element("Bal") {
- element("Tp") {
- // FIXME: type
- element("CdOrPrTry") {
- /**
- * FIXME: code-or-proprietary
- * This section specifies the 'balance type', either in a
- * 'coded' format or in a proprietary one.
- */
- }
- }
- element("Amt") {
- /**
- * FIXME: Amount
- */
- attribute("Ccy", "EUR")
- BigDecimal("1.00")
- }
- element("CdtDbtInd") {
- /**
- * FIXME: credit-debit-indicator
- * Indicates whether the balance is a 'credit' ("CRDT") or a
'debit' ("DBIT") balance.
- */
- }
- element("Dt") {
- /**
- * FIXME: date, in YYYY-MM-DD format
- */
- }
- }
-}
-
-/**
- * Builds CAMT response.
- *
- * @param history the list of all the history elements
- * @param type 52 or 53.
- */
-private fun constructCamtResponse(type: Int, customerId: Int, header:
EbicsRequest.Header): String {
- val camt = constructXml(indent = true) {
- root("Document") {
- attribute("xmlns",
"urn:iso:std:iso:20022:tech:xsd:camt.053.001.08")
- element("BkToCstmrAcctRpt") {
- element("GrpHdr") {
- element("MsgId") {
- // unique identifier for a message
- text("id under group header")
- }
- }
- element(if (type == 52) "Rpt" else "Stmt") {
-
- balance(this)
- iterHistory(customerId, header, this)
- }
- }
- }
- }
- return camt
+ )
+ return buildCamtString(history, type)
}
@@ -299,7 +281,7 @@ private fun handleEbicsC52(requestContext: RequestContext):
ByteArray {
val baos = ByteArrayOutputStream()
val asf =
ArchiveStreamFactory().createArchiveOutputStream(ArchiveStreamFactory.ZIP, baos)
- val zae = ZipArchiveEntry("Singleton C53 Entry")
+ val zae = ZipArchiveEntry("Singleton C5{2,3} Entry")
asf.putArchiveEntry(zae)
val bais = ByteArrayInputStream(camt.toByteArray())
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
index 333bb2a..a2a60a1 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
@@ -38,10 +38,7 @@ import io.ktor.routing.post
import io.ktor.routing.routing
import io.ktor.server.engine.embeddedServer
import io.ktor.server.netty.Netty
-import org.jetbrains.exposed.sql.Date
-import org.jetbrains.exposed.sql.StdOutSqlLogger
-import org.jetbrains.exposed.sql.addLogger
-import org.jetbrains.exposed.sql.and
+import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.transactions.transaction
import org.joda.time.DateTime
import org.slf4j.Logger
@@ -163,29 +160,23 @@ fun sampleData() {
}
/**
- * Finds the history for a customer, given dates of 'value'. This date
- * specifies the point in time where a operation settled. The other type
- * of date is 'operation', that indicates the point in time where the
- * transaction was created in the bank's system.
- *
* @param id the customer whose history must be returned. This
* id is local to the bank and is not reused/encoded into other
* EBICS id values.
- * @param builder lambda function that will loop over all the results.
+ *
+ * @return result set of all the operations related to the customer
+ * identified by @p id.
*/
-fun extractHistoryForEach(id: Int, start: String?, end: String?, builder:
(BankTransactionEntity) -> Any) {
+fun extractHistory(id: Int, start: String?, end: String?):
SizedIterable<BankTransactionEntity> {
val s = if (start != null) DateTime.parse(start) else DateTime(0)
val e = if (end != null) DateTime.parse(end) else DateTime.now()
LOGGER.debug("Fetching history from $s to $e")
- transaction {
+ return transaction {
addLogger(StdOutSqlLogger)
BankTransactionEntity.find {
BankTransactionsTable.localCustomer eq id and
BankTransactionsTable.valueDate.between(s.millis, e.millis)
- }.forEach {
- LOGGER.debug("Found history element: $it")
- builder(it)
}
}
}
@@ -244,8 +235,9 @@ fun main() {
val req = call.receive<CustomerHistoryRequest>()
val customer = findCustomer(call.parameters["id"])
val ret = CustomerHistoryResponse()
-
- extractHistoryForEach(customer.id.value, req.start, req.end) {
+ val history = extractHistory(customer.id.value, req.start,
req.end)
+
+ history.forEach {
ret.history.add(
CustomerHistoryResponseElement(
subject = it.subject,
--
To stop receiving notification emails like this one, please contact
address@hidden.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [libeufin] branch master updated: Camt generation.,
gnunet <=