use crate::db::Database; use crate::models::{NewTransaction, TransactionType}; use std::path::Path; pub fn import_csv(db: &Database, path: &Path, merge: bool) -> Result> { 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) }