revenue.rs (3566B)
1 /* 2 * This file is part of LibEuFin. 3 * Copyright (C) 2026 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 use std::sync::Arc; 21 22 use axum::{ 23 Json, Router, 24 extract::State, 25 response::{IntoResponse, NoContent}, 26 routing::get, 27 }; 28 use taler_api::{constants::REVENUE_API_VERSION, error::ApiResult, extract::Query}; 29 use taler_common::api::{ 30 params::HistoryParams, 31 revenue::{RevenueConfig, RevenueIncomingHistory}, 32 }; 33 34 use crate::{ 35 api::{BankState, IMPLEMENTATION}, 36 auth::RevenueAuth, 37 db::tx::revenue_history, 38 }; 39 40 pub fn revenue_api() -> Router<Arc<BankState>> { 41 Router::new() 42 .route( 43 "/accounts/{username}/taler-revenue/config", 44 get(async |State(state): State<Arc<BankState>>| { 45 Json(RevenueConfig { 46 name: (), 47 version: REVENUE_API_VERSION, 48 implementation: Some(IMPLEMENTATION), 49 currency: state.cfg.regional_currency, 50 }) 51 }), 52 ) 53 .route( 54 "/accounts/{USERNAME}/taler-revenue/history", 55 get( 56 async |mut auth: RevenueAuth, 57 Query(params): Query<HistoryParams>, 58 State(state): State<Arc<BankState>>| { 59 let params = params.check()?; 60 let info = auth.bank_info(&state.db, &state.cfg.ctx).await?; 61 let incoming_transactions = revenue_history( 62 &state.db, 63 &state.cfg.ctx, 64 &state.cfg.regional_currency, 65 &state.revenue_channel, 66 ¶ms, 67 info.bank_account_id, 68 ) 69 .await?; 70 if incoming_transactions.is_empty() { 71 ApiResult::Ok(NoContent.into_response()) 72 } else { 73 Ok(Json(RevenueIncomingHistory { 74 incoming_transactions, 75 credit_account: info.payto.as_uri(), 76 }) 77 .into_response()) 78 } 79 }, 80 ), 81 ) 82 } 83 84 #[cfg(test)] 85 mod test { 86 use sqlx::postgres::PgConnectOptions; 87 use taler_macros::db_test; 88 use taler_test_utils::{routine::revenue_routine, server::TestServer, tasks}; 89 90 use crate::api::test::bank_setup; 91 92 #[db_test(raw)] 93 async fn revenue(db: PgConnectOptions) { 94 let ctx = bank_setup(db).await; 95 ctx.set_max_debt("customer", "1000").await; 96 let admin = ctx.admin_router().await; 97 revenue_routine( 98 &admin.prefix("/accounts/exchange/taler-wire-gateway"), 99 &admin.prefix("/accounts/exchange/taler-revenue"), 100 &ctx.customer_payto.as_uri(), 101 tasks!(), 102 tasks!(), 103 ) 104 .await; 105 } 106 }