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 }