libeufin

Integration and sandbox testing for FinTech APIs and data formats
Log | Files | Refs | Submodules | README | LICENSE

List.kt (6036B)


      1 /*
      2  * This file is part of LibEuFin.
      3  * Copyright (C) 2025 Taler Systems S.A.
      4 
      5  * LibEuFin is free software; you can redistribute it and/or modify
      6  * it under the terms of the GNU Affero General Public License as
      7  * published by the Free Software Foundation; either version 3, or
      8  * (at your option) any later version.
      9 
     10  * LibEuFin is distributed in the hope that it will be useful, but
     11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General
     13  * Public License for more details.
     14 
     15  * You should have received a copy of the GNU Affero General Public
     16  * License along with LibEuFin; see the file COPYING.  If not, see
     17  * <http://www.gnu.org/licenses/>
     18  */
     19 
     20 package tech.libeufin.nexus.cli
     21 
     22 import com.github.ajalt.clikt.core.CliktCommand
     23 import com.github.ajalt.clikt.core.Context
     24 import com.github.ajalt.clikt.core.subcommands
     25 import com.github.ajalt.clikt.parameters.arguments.*
     26 import com.github.ajalt.clikt.parameters.groups.provideDelegate
     27 import com.github.ajalt.clikt.parameters.options.convert
     28 import com.github.ajalt.clikt.parameters.options.default
     29 import com.github.ajalt.clikt.parameters.options.flag
     30 import com.github.ajalt.clikt.parameters.options.option
     31 import com.github.ajalt.clikt.parameters.types.*
     32 import com.github.ajalt.mordant.terminal.*
     33 import tech.libeufin.common.*
     34 import tech.libeufin.nexus.*
     35 import tech.libeufin.nexus.iso20022.*
     36 import java.util.zip.*
     37 import java.time.Instant
     38 import java.io.*
     39 
     40 private fun fmtPayto(payto: String): String {
     41     try {
     42         val parsed = Payto.parse(payto).expectIban()
     43         return buildString {
     44             append(parsed.iban.toString())
     45             if (parsed.bic != null) append(" ${parsed.bic}")
     46             if (parsed.receiverName != null) append(" ${parsed.receiverName}")
     47         }
     48     } catch (e: Exception) {
     49         return payto.removePrefix("payto://")
     50     }
     51 }
     52 
     53 
     54 class ListIncoming: TalerCmd("incoming") {
     55     override fun help(context: Context) = "List incoming transactions"
     56 
     57     override fun run() = cliCmd(logger) {
     58         nexusConfig(config).withDb { db, cfg ->
     59             val txs = db.list.incoming()
     60             for (tx in txs) {
     61                 println(buildString{
     62                     if (tx.creditFee.isZero()) {
     63                         append("${tx.date} ${tx.id} ${tx.amount}\n")
     64                     } else {
     65                         append("${tx.date} ${tx.id} ${tx.amount}-${tx.creditFee}\n")
     66                     }
     67                     if (tx.debtor != null) {
     68                         append("  debtor: ${fmtPayto(tx.debtor)}\n")
     69                     }
     70                     if (tx.subject != null) {
     71                         append("  subject: ${tx.subject}\n")
     72                     }
     73                     if (tx.talerable != null) {
     74                         append("  talerable: ${tx.talerable}\n")
     75                     }
     76                     if (tx.bounced != null) {
     77                         append("  bounced: ${tx.bounced}\n")
     78                     }
     79                 })
     80             }
     81         }
     82     }
     83 }
     84 
     85 class ListOutgoing: TalerCmd("outgoing") {
     86     override fun help(context: Context) = "List outgoing transactions"
     87 
     88     override fun run() = cliCmd(logger) {
     89         nexusConfig(config).withDb { db, cfg ->
     90             val txs = db.list.outgoing()
     91             for (tx in txs) {
     92                 println(buildString{
     93                     append("${tx.date} ${tx.id} ${tx.amount}\n")
     94                     if (tx.creditor != null) {
     95                         append("  creditor: ${fmtPayto(tx.creditor)}\n")
     96                     }
     97                     append("  subject: ${tx.subject}\n")
     98                     if (tx.wtid != null) {
     99                         append("  talerable: ${tx.wtid} ${tx.exchangeBaseUrl}\n")
    100                     }
    101                 })
    102             }
    103         }
    104     }
    105 }
    106 
    107 class ListInitiated: TalerCmd("initiated") {
    108     override fun help(context: Context) = "List initiated transactions"
    109 
    110     private val awaitingAck by option(
    111         "--ack", "--awaiting-ack",
    112         help = "Only list transactions awaiting manual acknowledgement",
    113     ).flag()
    114 
    115     override fun run() = cliCmd(logger) {
    116         nexusConfig(config).withDb { db, cfg ->
    117             if (awaitingAck) {
    118                 val txs = db.list.initiatedAck()
    119                 for (tx in txs) {
    120                     println(buildString{
    121                         append("${tx.date} ${tx.id} ${tx.amount}\n")
    122                         append("  creditor: ${fmtPayto(tx.creditor)}\n")
    123                         append("  subject: ${tx.subject}\n")
    124                         append("  ack: ${tx.dbId}")
    125                         append('\n')
    126                     })
    127                 }
    128             } else {
    129                 val txs = db.list.initiated()
    130                 for (tx in txs) {
    131                     println(buildString{
    132                         append("${tx.date} ${tx.id} ${tx.amount}\n")
    133                         append("  creditor: ${fmtPayto(tx.creditor)}\n")
    134                         append("  subject: ${tx.subject}\n")
    135                         if (tx.batch != null) {
    136                             append("  batch: ${tx.batch}")
    137                             if (tx.batchOrder != null)
    138                             append(" ${tx.batchOrder}")
    139                             append('\n')
    140                         }
    141                         if (tx.submissionCounter > 0) {
    142                             append("  submission: ${tx.submissionTime} ${tx.submissionCounter}\n")
    143                         }
    144                         append("  status: ${tx.status}")
    145                         if (tx.msg != null) {
    146                             append(" ${tx.msg}")
    147                         }
    148                         append('\n')
    149                     })
    150                 }
    151             }  
    152         }
    153     }
    154 }
    155 
    156 
    157 class ListCmd: CliktCommand("list") {
    158     override fun help(context: Context) = "List nexus transactions"
    159 
    160     init {
    161         subcommands(ListIncoming(), ListOutgoing(), ListInitiated())
    162     }
    163 
    164     override fun run() = Unit
    165 }