Add feature batch 2, subscription/recurring sync, smooth charts, and app icon

This commit is contained in:
2026-03-03 21:18:37 +02:00
parent f9e293c30e
commit 577cd54a9e
10102 changed files with 107853 additions and 1318 deletions

View File

@@ -0,0 +1,75 @@
use crate::db::Database;
use crate::models::{NewTransaction, TransactionType};
use std::path::Path;
pub fn import_csv(db: &Database, path: &Path, merge: bool) -> Result<usize, Box<dyn std::error::Error>> {
if !merge {
db.reset_all_data()?;
}
let mut reader = csv::Reader::from_path(path)?;
let mut count = 0;
for result in reader.records() {
let record = result?;
if record.len() < 6 {
continue;
}
let date_str = &record[0];
let type_str = &record[1];
let category_name = &record[2];
let amount: f64 = match record[3].parse() {
Ok(v) => v,
Err(_) => continue,
};
let currency = &record[4];
let exchange_rate: f64 = match record[5].parse() {
Ok(v) => v,
Err(_) => 1.0,
};
let note = if record.len() > 6 && !record[6].is_empty() {
Some(record[6].to_string())
} else {
None
};
let payee = if record.len() > 7 && !record[7].is_empty() {
Some(record[7].to_string())
} else {
None
};
let txn_type = match type_str.to_lowercase().as_str() {
"expense" => TransactionType::Expense,
"income" => TransactionType::Income,
_ => continue,
};
let categories = db.list_categories(Some(txn_type))?;
let category_id = match categories.iter().find(|c| c.name == category_name) {
Some(c) => c.id,
None => continue,
};
let date = chrono::NaiveDate::parse_from_str(date_str, "%Y-%m-%d")?;
if merge && db.find_duplicate_transaction(amount, txn_type, category_id, date)? {
continue;
}
let new_txn = NewTransaction {
amount,
transaction_type: txn_type,
category_id,
currency: currency.to_string(),
exchange_rate,
note,
date,
recurring_id: None,
payee,
};
db.insert_transaction(&new_txn)?;
count += 1;
}
Ok(count)
}