Make number of days configurable for transactions

This commit is contained in:
2026-05-25 23:15:20 +02:00
parent da0d80f4f4
commit 415a1f8684
3 changed files with 27 additions and 9 deletions
+3
View File
@@ -24,6 +24,9 @@ pub enum Error {
AmountEmpty, AmountEmpty,
#[error("bank format not found: {0}")] #[error("bank format not found: {0}")]
BankFormat(String), BankFormat(String),
#[error("API error {status}: {message}")]
ApiError { status: u16, message: String },
/// Errors I've been too lazy to give a type yet /// Errors I've been too lazy to give a type yet
#[error("{0}")] #[error("{0}")]
Text(String), Text(String),
+12 -6
View File
@@ -26,10 +26,11 @@ enum Command {
#[arg(short = 'P', long, group = "planref")] #[arg(short = 'P', long, group = "planref")]
plan_id: Option<String>, plan_id: Option<String>,
}, },
// List transactions in the last 30 days /// List transactions
// ///
// You have to give a plan to list transactions from. You can optionally /// You have to give a plan to list transactions from. You can optionally
// also give an account to show only transactions from that account. /// also give an account to show only transactions from that account. You can specify the
/// number of days, the default is 30.
Transactions { Transactions {
/// Your YNAB token, available from developer settings in YNAB /// Your YNAB token, available from developer settings in YNAB
#[arg(short, long, env = "YNAB_API_TOKEN", hide_env_values = true)] #[arg(short, long, env = "YNAB_API_TOKEN", hide_env_values = true)]
@@ -50,6 +51,10 @@ enum Command {
/// Alternatively, give the YNAB account ID directly /// Alternatively, give the YNAB account ID directly
#[arg(short = 'A', long, group = "accountref")] #[arg(short = 'A', long, group = "accountref")]
account_id: Option<String>, account_id: Option<String>,
/// The number of days to look back for transactions
#[arg(short, long, default_value_t = 30)]
days: i64,
}, },
/// Convert from a bank export to a CSV you can import manually to YNAB /// Convert from a bank export to a CSV you can import manually to YNAB
Convert { Convert {
@@ -135,6 +140,7 @@ async fn main() -> anyhow::Result<()> {
plan_id, plan_id,
account, account,
account_id, account_id,
days,
} => { } => {
let client = Client::new(&token); let client = Client::new(&token);
let plan = match (plan, plan_id) { let plan = match (plan, plan_id) {
@@ -151,8 +157,8 @@ async fn main() -> anyhow::Result<()> {
}; };
let transactions = match account { let transactions = match account {
Some(account) => account.list_transactions().await?, Some(account) => account.list_transactions(days).await?,
None => plan.list_transactions(None).await?, None => plan.list_transactions(None, days).await?,
}; };
println!("Transactions{} in the last 30 days:", accountstr); println!("Transactions{} in the last 30 days:", accountstr);
for t in transactions { for t in transactions {
+12 -3
View File
@@ -26,6 +26,14 @@ impl Client {
.bearer_auth(&self.token) .bearer_auth(&self.token)
.send() .send()
.await?; .await?;
if !res.status().is_success() {
let code = res.status().as_u16();
let message = res.status().canonical_reason().unwrap_or("unknown");
return Err(Error::ApiError {
status: code,
message: message.to_string(),
});
}
let text = res.text().await?; let text = res.text().await?;
Ok(text) Ok(text)
} }
@@ -121,8 +129,9 @@ impl Plan {
pub async fn list_transactions( pub async fn list_transactions(
&self, &self,
account_id: Option<&str>, account_id: Option<&str>,
days: i64,
) -> Result<Vec<Transaction>, Error> { ) -> Result<Vec<Transaction>, Error> {
let since_date = chrono::Local::now().date_naive() - chrono::Duration::days(30); let since_date = chrono::Local::now().date_naive() - chrono::Duration::days(days);
let since_date = since_date.format("%Y-%m-%d"); let since_date = since_date.format("%Y-%m-%d");
let url = format!("plans/{}/transactions?since_date={}", self.id, since_date); let url = format!("plans/{}/transactions?since_date={}", self.id, since_date);
let raw = self.client.get(&url).await?; let raw = self.client.get(&url).await?;
@@ -166,8 +175,8 @@ impl Account {
}) })
} }
pub async fn list_transactions(&self) -> Result<Vec<Transaction>, Error> { pub async fn list_transactions(&self, days: i64) -> Result<Vec<Transaction>, Error> {
self.plan.list_transactions(Some(&self.id)).await self.plan.list_transactions(Some(&self.id), days).await
} }
pub async fn upload(&self, transactions: &[Transaction]) -> Result<(), Error> { pub async fn upload(&self, transactions: &[Transaction]) -> Result<(), Error> {