gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libeufin] branch master updated: Including more details into C52 and C5


From: gnunet
Subject: [libeufin] branch master updated: Including more details into C52 and C53 responses.
Date: Wed, 15 Jan 2020 11:05:52 +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 cbb6871  Including more details into C52 and C53 responses.
cbb6871 is described below

commit cbb687136fbefc4871a996b6b14a8d4d0528b533
Author: Marcello Stanisci <address@hidden>
AuthorDate: Wed Jan 15 11:03:22 2020 +0100

    Including more details into C52 and C53 responses.
---
 .../tech/libeufin/sandbox/EbicsProtocolBackend.kt  | 245 +++++++++++++++++++--
 sandbox/src/test/kotlin/XmlCombinatorsTest.kt      |  32 +++
 util/src/main/kotlin/XmlCombinators.kt             |  11 +-
 3 files changed, 265 insertions(+), 23 deletions(-)

diff --git 
a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt 
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
index 6166d08..012cfbc 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
@@ -41,6 +41,8 @@ import tech.libeufin.util.CryptoUtil
 import tech.libeufin.util.EbicsOrderUtil
 import tech.libeufin.util.XMLUtil
 import tech.libeufin.util.*
+import java.awt.List
+import java.math.BigDecimal
 import java.security.interfaces.RSAPrivateCrtKey
 import java.util.*
 import java.util.zip.DeflaterInputStream
@@ -111,7 +113,153 @@ private suspend fun 
ApplicationCall.respondEbicsKeyManagement(
     respondText(text, ContentType.Application.Xml, HttpStatusCode.OK)
 }
 
-/* intra-day account traffic */
+/**
+ * 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.
+ *
+ */
+private fun iterHistory(customerId: Int, request: EbicsRequest, base: 
XmlElementBuilder) {
+
+    extractHistoryForEach(
+        customerId,
+        try {
+            (request.header.static.orderDetails?.orderParams as 
EbicsRequest.StandardOrderParams).dateRange?.start.toString()
+        } catch (e: Exception) {
+            getGregorianDate().toString()
+        },
+        try {
+            (request.header.static.orderDetails?.orderParams as 
EbicsRequest.StandardOrderParams).dateRange?.end.toString()
+        } catch (e: Exception) {
+            getGregorianDate().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, request: 
EbicsRequest): String {
+
+    val camt = constructXml(indent = true) {
+
+        namespace("foo", "bar") // FIXME: set right namespace!
+        root("foo: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, request, this)
+            }
+        }
+    }
+
+  return camt
+}
+
 private fun ApplicationCall.handleEbicsC52(header: EbicsRequest.Header): 
ByteArray {
 
     val userId = header.static.userID!!
@@ -124,39 +272,100 @@ private fun ApplicationCall.handleEbicsC52(header: 
EbicsRequest.Header): ByteArr
         }
     }.firstOrNull() ?: throw Exception("Unknown subscriber")
 
-    val history = extractHistoryForEach(
-        subscriber.bankCustomer.id.value,
-        try {
-            (op as 
EbicsRequest.StandardOrderParams).dateRange?.start.toString()
-        } catch (e: Exception) {
-            getGregorianDate().toString()
-        },
-        try {
-            (op as EbicsRequest.StandardOrderParams).dateRange?.end.toString()
-        } catch (e: Exception) {
-            getGregorianDate().toString()
-        }
-    ) { println(it) }
+    // call history builder here
 
     val ret = constructXml(indent = true) {
         namespace("foo", "bar")
         root("foo:BkToCstmrAcctRpt") {
             element("GrpHdr") {
-
                 element("MsgId") {
+                    // unique identifier for a message
                     text("id under group header")
                 }
-                element("CreDtTm") {
-                    text("now")
-                }
             }
+            /*
+             * NOTE: Rpt elements can be 1 or more
+             */
             element("Rpt") {
                 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")
+                        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
+                         */
+                    }
+                }
+                element("Ntry") {
+                    /* FIXME: one statement 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.
+                         */
+                    }
+                }
             }
         }
     }
diff --git a/sandbox/src/test/kotlin/XmlCombinatorsTest.kt 
b/sandbox/src/test/kotlin/XmlCombinatorsTest.kt
index f2b2148..f55dc70 100644
--- a/sandbox/src/test/kotlin/XmlCombinatorsTest.kt
+++ b/sandbox/src/test/kotlin/XmlCombinatorsTest.kt
@@ -20,10 +20,42 @@
 package tech.libeufin.sandbox
 
 import org.junit.Test
+import tech.libeufin.util.XmlElementBuilder
 import tech.libeufin.util.constructXml
 
 class XmlCombinatorsTest {
 
+    @Test
+    fun testWithModularity() {
+        fun module(base: XmlElementBuilder) {
+            base.element("module")
+        }
+        val s = constructXml {
+            root("root") {
+                module(this)
+            }
+        }
+        println(s)
+    }
+
+    @Test
+    fun testWithIterable() {
+        val s = constructXml(indent = true) {
+            namespace("iter", "able")
+            root("iterable") {
+                element("endOfDocument") {
+                    for (i in 1..10)
+                        element("$i") {
+                            element("$i$i") {
+                                text("$i$i$i")
+                            }
+                        }
+                }
+            }
+        }
+        println(s)
+    }
+
     @Test
     fun testBasicXmlBuilding() {
         val s = constructXml(indent = true) {
diff --git a/util/src/main/kotlin/XmlCombinators.kt 
b/util/src/main/kotlin/XmlCombinators.kt
index 1ef44e8..9a812d6 100644
--- a/util/src/main/kotlin/XmlCombinators.kt
+++ b/util/src/main/kotlin/XmlCombinators.kt
@@ -7,17 +7,18 @@ import javax.xml.stream.XMLStreamWriter
 
 class XmlElementBuilder(val w: XMLStreamWriter) {
 
+    /**
+     * First consumes all the path's components, and _then_ starts applying f.
+     */
     fun element(path: MutableList<String>, f: XmlElementBuilder.() -> Unit = 
{}) {
-
+        /* the wanted path got constructed, go on with f's logic now.  */
         if (path.isEmpty()) {
-            f(this)
+            f()
             return
         }
-
         w.writeStartElement(path.removeAt(0))
         this.element(path, f)
         w.writeEndElement()
-
     }
 
     fun element(path: String, f: XmlElementBuilder.() -> Unit = {}) {
@@ -59,7 +60,7 @@ class XmlDocumentBuilder {
     fun root(name: String, f: XmlElementBuilder.() -> Unit) {
         val elementBuilder = XmlElementBuilder(writer)
         writer.writeStartElement(name)
-        f(elementBuilder)
+        elementBuilder.f()
         writer.writeEndElement()
     }
 }

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]