dev.rs (4800B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2025 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or modify it under the 6 terms of the GNU Affero General Public License as published by the Free Software 7 Foundation; either version 3, or (at your option) any later version. 8 9 TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 12 13 You should have received a copy of the GNU Affero General Public License along with 14 TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 17 use anyhow::anyhow; 18 use clap::ValueEnum; 19 use jiff::Zoned; 20 use taler_common::{ 21 config::Config, 22 types::{amount::Amount, payto::PaytoImpl}, 23 }; 24 use tracing::info; 25 26 use crate::{ 27 HuIban, HuPayto, TransferHuPayto, 28 config::WorkerCfg, 29 magnet_api::{ 30 client::AuthClient, 31 types::{Direction, Order}, 32 }, 33 setup, 34 worker::{Tx, extract_tx_info}, 35 }; 36 37 #[derive(Debug, Clone, PartialEq, Eq, ValueEnum)] 38 pub enum DirArg { 39 #[value(alias("in"))] 40 Incoming, 41 #[value(alias("out"))] 42 Outgoing, 43 Both, 44 } 45 46 #[derive(clap::Subcommand, Debug)] 47 pub enum DevCmd { 48 /// Print account info 49 Accounts, 50 Tx { 51 account: HuIban, 52 #[clap(long, short, value_enum, default_value_t = DirArg::Both)] 53 direction: DirArg, 54 }, 55 Transfer { 56 #[clap(long)] 57 debtor: HuPayto, 58 #[clap(long)] 59 creditor: TransferHuPayto, 60 #[clap(long)] 61 amount: Option<Amount>, 62 #[clap(long)] 63 subject: Option<String>, 64 }, 65 } 66 67 pub async fn dev(cfg: &Config, cmd: DevCmd) -> anyhow::Result<()> { 68 let cfg = WorkerCfg::parse(cfg)?; 69 let keys = setup::load(&cfg)?; 70 let client = reqwest::Client::new(); 71 let client = AuthClient::new(&client, &cfg.api_url, &cfg.consumer).upgrade(&keys.access_token); 72 match cmd { 73 DevCmd::Accounts => { 74 let res = client.list_accounts().await?; 75 for partner in res.partners { 76 for account in partner.bank_accounts { 77 let payto = account.iban.as_full_payto(&partner.partner.name); 78 info!(target: "dev", "{} {} {}", account.code, account.currency.symbol, payto); 79 } 80 } 81 } 82 DevCmd::Tx { account, direction } => { 83 let dir = match direction { 84 DirArg::Incoming => Direction::Incoming, 85 DirArg::Outgoing => Direction::Outgoing, 86 DirArg::Both => Direction::Both, 87 }; 88 // Register incoming 89 let mut next = None; 90 loop { 91 let page = client 92 .page_tx( 93 dir, 94 Order::Ascending, 95 100, 96 account.bban(), 97 &next, 98 next.is_none(), 99 ) 100 .await?; 101 next = page.next; 102 for item in page.list { 103 let tx = extract_tx_info(item.tx); 104 match tx { 105 Tx::In(tx_in) => info!(target: "dev", "in {tx_in}"), 106 Tx::Out(tx_out) => info!(target: "dev", "out {tx_out}"), 107 } 108 } 109 if next.is_none() { 110 break; 111 } 112 } 113 } 114 DevCmd::Transfer { 115 debtor, 116 creditor, 117 amount, 118 subject, 119 } => { 120 let account = client.account(debtor.bban()).await?; 121 let amount = creditor 122 .amount 123 .clone() 124 .or(amount) 125 .ok_or_else(|| anyhow!("Missing amount"))?; 126 let subject = creditor 127 .subject 128 .clone() 129 .or(subject) 130 .ok_or_else(|| anyhow!("Missing subject"))?; 131 132 let now = Zoned::now(); 133 let date = now.date(); 134 135 let init = client 136 .init_tx( 137 account.code, 138 amount.val as f64, 139 &subject, 140 &date, 141 &creditor.name, 142 creditor.bban(), 143 ) 144 .await?; 145 client 146 .submit_tx( 147 &keys.signing_key, 148 &account.number, 149 init.code, 150 init.amount, 151 &date, 152 creditor.bban(), 153 ) 154 .await?; 155 } 156 } 157 Ok(()) 158 }