use crate::parsers::csv::CsvFile; use crate::banking::account::Account; use crate::banking::asset::Asset; use crate::parsers::ini::IniFile; use std::collections::HashMap; use rocket_contrib::templates::Template; use rocket::response::NamedFile; use std::path::{PathBuf, Path}; use rocket::request::Form; use rocket::http::RawStr; use regex::Regex; use chrono::{NaiveDate, Utc}; use chrono::Datelike; #[derive(Serialize)] struct GroupValues { amount : f32, filter : String } #[derive(Serialize)] struct ChartContext { account_name : String, groups : HashMap, total_sum : f32, total_chart : f32, date_start : String, date_end : String } #[get("/chart/?&")] pub fn chart_handler(account : &RawStr, start : Option<&RawStr>, end : Option<&RawStr>) -> rocket_contrib::templates::Template { let account_name = account.to_string(); let date_start = match start { Some(s) => { let mut tmp = s.to_string(); tmp.push_str("-01"); chrono::NaiveDate::parse_from_str(&tmp, "%Y-%m-%d").unwrap() }, None => Utc::today().naive_utc() }; let date_end = match end { Some(s) => { let mut tmp = s.to_string(); tmp.push_str("-01"); chrono::NaiveDate::parse_from_str(&tmp, "%Y-%m-%d").unwrap() }, None => Utc::today().naive_utc() }; let asset_ini = "data/asset.ini"; let asset = crate::banking::asset::Asset::from_ini_file(asset_ini); let account = asset.get_account_by_name(&account_name); let acc; match account { Some(trans) => acc = trans, None => panic!("could not read file") } // read group config let chart_config = IniFile::from_file(&acc.groupFile); let ini_file; match chart_config { Ok(file) => ini_file = file, Err(e) => panic!("could not read group file {:?}", e) } let mut groups = HashMap::new(); let t = acc.transactions; // filter transaction to match only the specified timeframe let t_filtered = crate::web_frontend::util::apply_date_filter(t, date_start, date_end); // spending chart, so do not consider income let t_final : Vec<_> = t_filtered.clone().into_iter().filter(|t| t.amount < 0.0 ).collect(); let total_sum = t_final.clone().into_iter().fold(0.0, |acc, x| acc + x.amount).abs(); let mut total_chart = 0.0; for (section_name, entries) in ini_file.sections { let mut filter_string = String::from(""); let mut complete = 0.0; for (key, values) in entries { for val in values { if val.is_empty() || val.is_empty() { continue } filter_string.push_str(&key); filter_string.push_str("-"); filter_string.push_str(&val); filter_string.push_str(";"); } } let t_filtered_cloned = crate::web_frontend::util::apply_transaction_filter(filter_string.clone(), t_final.clone()); let tmp = t_filtered_cloned.into_iter() .fold(0.0, |acc, x| acc + x.amount); complete = complete + tmp.abs(); groups.insert(section_name, GroupValues{ amount: complete, filter : filter_string } ); total_chart = total_chart + complete; } let context = ChartContext { account_name : account_name, groups : groups, total_sum : total_sum, total_chart : total_chart, date_start : date_start.to_string()[0..7].to_string(), date_end : date_end.to_string()[0..7].to_string() }; Template::render("chart", context) }