diff options
| author | Benedict Börger <benedict@0xb8000.de> | 2019-04-14 19:12:21 +0200 |
|---|---|---|
| committer | Benedict Börger <benedict@0xb8000.de> | 2019-04-14 19:12:21 +0200 |
| commit | f28e8a59c781f24ed9399268cc2536aad0cf534d (patch) | |
| tree | 5678dd6c12b5849ab15f9d63a49c9424d222390b /src/web_frontend | |
| parent | 7e8656cb6d086f364baeeb79a69a04555a6fd4f6 (diff) | |
[global] update all files
Diffstat (limited to 'src/web_frontend')
| -rw-r--r-- | src/web_frontend/asset.rs | 61 | ||||
| -rw-r--r-- | src/web_frontend/balance.rs | 56 | ||||
| -rw-r--r-- | src/web_frontend/chart.rs | 79 | ||||
| -rw-r--r-- | src/web_frontend/mod.rs | 24 | ||||
| -rw-r--r-- | src/web_frontend/transactions.rs | 22 | ||||
| -rw-r--r-- | src/web_frontend/util.rs | 50 |
6 files changed, 192 insertions, 100 deletions
diff --git a/src/web_frontend/asset.rs b/src/web_frontend/asset.rs new file mode 100644 index 0000000..f69f184 --- /dev/null +++ b/src/web_frontend/asset.rs @@ -0,0 +1,61 @@ +use std::collections::HashMap; +use rocket_contrib::templates::Template; +use crate::parsers::ini::IniFile; +use crate::parsers::csv::CsvFile; + + +#[derive(Serialize)] +pub struct AssetContext { + accounts : Vec<Account> +} + +#[derive(Serialize)] +pub struct Account { + name : String, + category : String, + balance : f32 +} + +#[get("/asset")] +pub fn asset_handler() -> rocket_contrib::templates::Template { + let asset_file = "data/asset.ini"; + let asset_config = IniFile::from_file(asset_file); + let ini_file; + match asset_config { + Ok(file) => ini_file = file, + Err(e) => panic!("could not read asset file") + } + + let mut acc = Vec::new(); + + for (account_name, config) in ini_file.sections { + let mut category = String::from(""); + if let Some(cat) = config.get("Category") { + if let Some(c) = cat.get(0) { + category = c.to_string(); + } + } + let mut all_trans = Vec::new(); + if let Some(transaction_files) = config.get("TransactionFile") { + for file in transaction_files { + let transactions = CsvFile::from_file(file, ";", true); + let mut t : Vec<crate::banking::account::Transaction> ; + match transactions { + Ok(trans) => t = crate::banking::account::Transaction::from_sparkasse_csv_file(trans), + Err(e) => panic!("could not read file {:?}", e) + } + all_trans.append(& mut t); + } + } + let balance = all_trans.iter().fold(0.0, |acc, x| acc + x.amount).abs(); + let tmp = Account { + name : account_name, + category : category.to_string(), + balance : balance + }; + acc.push(tmp); + } + + let context = AssetContext { accounts : acc }; + Template::render("asset", context) +} diff --git a/src/web_frontend/balance.rs b/src/web_frontend/balance.rs index 2cbebec..77311b0 100644 --- a/src/web_frontend/balance.rs +++ b/src/web_frontend/balance.rs @@ -1,5 +1,5 @@ use parsers::csv::CsvFile; -use banking::Account; +use banking::account::Account; //use parsers::ini::IniFile; use std::collections::HashMap; use rocket_contrib::templates::Template; @@ -10,6 +10,7 @@ use rocket::http::RawStr; use regex::Regex; use chrono::{NaiveDate, Utc}; use chrono::Datelike; +use crate::web_frontend::util; #[derive(Serialize)] struct MonthEarnSpend { @@ -27,53 +28,6 @@ struct BalanceContext { date_end : String } -#[derive(Debug)] -struct DateRange { - start_year : i32, - start_month : u32, - end_year : i32, - end_month : u32, -} - -impl DateRange { - fn new(start : chrono::NaiveDate, end : chrono::NaiveDate) -> DateRange { - DateRange { - start_year : start.year(), - start_month : start.month(), - end_year : end.year(), - end_month : end.month(), - } - } -} - -impl Iterator for DateRange { - type Item = chrono::NaiveDate; - - fn next(&mut self) -> Option<Self::Item> { - println!("next called"); - if (self.start_year <= self.end_year) { - if(self.start_month <= self.end_month) { - let mut tmp = self.start_year.to_string(); - if self.start_month < 10 { - tmp.push_str("-0"); - } else { - tmp.push_str("-"); - } - tmp.push_str(&self.start_month.to_string()); - tmp.push_str("-01"); - if self.start_month < 13 { - self.start_month = self.start_month + 1; - } else { - self.start_month = 1; - self.start_year = self.start_year + 1; - } - println!("{}", tmp); - return Some(chrono::NaiveDate::parse_from_str(&tmp, "%Y-%m-%d").unwrap()) - } - } - None - } -} #[get("/balance?<start>&<end>")] pub fn balance_handler(start : Option<&RawStr>, end : Option<&RawStr>) -> rocket_contrib::templates::Template { @@ -89,14 +43,14 @@ pub fn balance_handler(start : Option<&RawStr>, end : Option<&RawStr>) -> rocket chrono::NaiveDate::parse_from_str(&tmp, "%Y-%m-%d").unwrap() }, None => Utc::today().naive_utc() }; - let date_range = DateRange::new(date_start, date_end); + let date_range = crate::web_frontend::util::DateRange::new(date_start, date_end); let mut earn_spend_v = Vec::new(); for date in date_range { let transactions = CsvFile::from_file("data/t.csv", ";", true); - let t : Vec<crate::banking::Transaction> ; + let t : Vec<crate::banking::account::Transaction> ; match transactions { - Ok(trans) => t = crate::banking::Transaction::from_sparkasse_csv_file(trans), + Ok(trans) => t = crate::banking::account::Transaction::from_sparkasse_csv_file(trans), Err(e) => panic!("could not read file {:?}", e) } let result : Vec<_> = t.iter().filter(|x| x.date.month() == date.month()).collect(); diff --git a/src/web_frontend/chart.rs b/src/web_frontend/chart.rs index c5948fe..7065c6d 100644 --- a/src/web_frontend/chart.rs +++ b/src/web_frontend/chart.rs @@ -1,6 +1,7 @@ -use parsers::csv::CsvFile; -use banking::Account; -//use parsers::ini::IniFile; +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; @@ -14,12 +15,29 @@ use chrono::Datelike; #[derive(Serialize)] struct ChartContext { account_name : String, - groups : HashMap<String, f32> + groups : HashMap<String, f32>, + total_sum : f32, + total_chart : f32, + date_start : String, + date_end : String } -#[get("/chart")] -fn chart_handler() -> rocket_contrib::templates::Template { +#[get("/chart?<start>&<end>")] +pub fn chart_handler(start : Option<&RawStr>, end : Option<&RawStr>) -> rocket_contrib::templates::Template { + 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 date_range = crate::web_frontend::util::DateRange::new(date_start, date_end); // read group config let chart_file = "data/giro"; let chart_config = IniFile::from_file(chart_file); @@ -29,33 +47,52 @@ fn chart_handler() -> rocket_contrib::templates::Template { Err(e) => panic!("could not read group file {:?}", e) } let mut groups = HashMap::new(); + + let asset_ini = "data/asset.ini"; + let asset = crate::banking::asset::Asset::from_ini_file(asset_ini); + let transactions = asset.get_account_by_name("Girokonto"); + let acc; + match transactions { + Some(trans) => acc = trans, + None => panic!("could not read file") + } + let t = acc.transactions; + // filter transaction to match only the specified timeframe + println!("unfiltered number: {}", t.len()); + let mut t_filtered = Vec::new(); + for date in date_range { + let mut tmp : Vec<_> = t.iter().filter(|x| x.date.month() == date.month()).collect(); + t_filtered.append(& mut tmp); + + } + println!("filtered number: {}", t_filtered.len()); + let total_sum = t_filtered.iter().filter(|t| t.amount < 0.0 ) + .fold(0.0, |acc, x| acc + x.amount).abs(); + println!("total sum: {}", total_sum); + let mut total_chart = 0.0; for (section_name, entries) in ini_file.sections { let mut complete = 0.0; - println!("section name: {}", section_name); - for entrie in entries { - for val in entrie.values { - if entrie.name.is_empty() || val.is_empty() { + for (key, values) in entries { + for val in values { + let mut t_filtered_cloned = t_filtered.clone(); + if val.is_empty() || val.is_empty() { continue } - println!("entrie is : {}", entrie.name); - let transactions = CsvFile::from_file("data/t.csv", ";", true); - let t : Vec<banking::Transaction> ; - match transactions { - Ok(trans) => t = banking::Transaction::from_sparkasse_csv_file(trans), - Err(e) => panic!("could not read file {:?}", e) - } - let re = Regex::new(&val).unwrap(); - let tmp = t.into_iter().filter(|transaction| + let re = Regex::new(&val).unwrap(); + let tmp = t_filtered_cloned.into_iter().filter(|transaction| re.is_match(&transaction.sender_name) ) .fold(0.0, |acc, x| acc + x.amount); - complete = complete + tmp.abs(); + complete = complete + tmp.abs(); } } groups.insert(section_name, complete); + total_chart = total_chart + complete; // ALSO INSERT OTHER, AKA THE REST } let context = ChartContext { account_name : String::from("Girokonto"), - groups : groups }; + 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) } diff --git a/src/web_frontend/mod.rs b/src/web_frontend/mod.rs index 8577065..3f58227 100644 --- a/src/web_frontend/mod.rs +++ b/src/web_frontend/mod.rs @@ -1,27 +1,13 @@ pub mod transactions; pub mod balance; -use parsers::csv::CsvFile; -use crate::banking::Account; -//use parsers::ini::IniFile; -use std::collections::HashMap; -use rocket_contrib::templates::Template; +pub mod chart; +pub mod asset; +mod util; 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; -/* - * Overview over all accounts, complete asset overview? - */ -#[get("/")] -pub fn account_handler() -> rocket_contrib::templates::Template { - let context : HashMap<u32, u32> = HashMap::new(); - Template::render("account", context) -} -// allow always access + +// allow always access to static files #[get("/static/<file..>")] pub fn static_handler(file: PathBuf) -> Option<NamedFile> { NamedFile::open(Path::new("static/").join(file)).ok() diff --git a/src/web_frontend/transactions.rs b/src/web_frontend/transactions.rs index 417ca96..28e2dd1 100644 --- a/src/web_frontend/transactions.rs +++ b/src/web_frontend/transactions.rs @@ -1,5 +1,6 @@ use parsers::csv::CsvFile; -use crate::banking::Account; +use crate::banking::account::Account; +use crate::banking::asset::Asset; //use parsers::ini::IniFile; use std::collections::HashMap; use rocket_contrib::templates::Template; @@ -22,7 +23,7 @@ use chrono::Datelike; */ #[derive(Serialize)] struct TransactionContext { - transactions : Vec<crate::banking::Transaction>, + transactions : Vec<crate::banking::account::Transaction>, account_name : String, filter : String, date_start : String, @@ -35,13 +36,16 @@ pub struct TransactionFilter { } impl TransactionFilter { - pub fn apply_filter(&self, transactions : Vec<crate::banking::Transaction>) -> Vec<crate::banking::Transaction> { - let transactions = CsvFile::from_file("data/t.csv", ";", true); - let t : Vec<crate::banking::Transaction> ; + pub fn apply_filter(&self, transactions : Vec<crate::banking::account::Transaction>) -> Vec<crate::banking::account::Transaction> { + let asset_ini = "data/asset.ini"; + let asset : Asset = crate::banking::asset::Asset::from_ini_file(asset_ini); + let transactions = asset.get_account_by_name("Girokonto"); + let acc; match transactions { - Ok(trans) => t = crate::banking::Transaction::from_sparkasse_csv_file(trans), - Err(e) => panic!("could not read file {:?}", e) + Some(trans) => acc = trans, + None => panic!("could not read file") } + let t = acc.transactions; //self.filter.split("=").collect::<Vec<&str>>(); let re = Regex::new(&self.filter).unwrap(); let tmp = t.into_iter().filter(|transaction| re.is_match(&transaction.sender_name) || re.is_match(&transaction.reference) ).collect(); @@ -89,9 +93,9 @@ pub fn transaction_handler(start : Option<&RawStr>, end : Option<&RawStr>) -> ro None => Utc::today().naive_utc() }; let transactions = CsvFile::from_file("data/t.csv", ";", true); - let t : Vec<crate::banking::Transaction> ; + let t : Vec<crate::banking::account::Transaction> ; match transactions { - Ok(trans) => t = crate::banking::Transaction::from_sparkasse_csv_file(trans), + Ok(trans) => t = crate::banking::account::Transaction::from_sparkasse_csv_file(trans), Err(e) => panic!("could not read file {:?}", e) } let context = TransactionContext { transactions: t, account_name : String::from("Girokonto"), diff --git a/src/web_frontend/util.rs b/src/web_frontend/util.rs new file mode 100644 index 0000000..cffef0e --- /dev/null +++ b/src/web_frontend/util.rs @@ -0,0 +1,50 @@ +use chrono::{NaiveDate, Utc}; +use chrono::Datelike; + +#[derive(Debug)] +pub struct DateRange { + start_year : i32, + start_month : u32, + end_year : i32, + end_month : u32, +} + +impl DateRange { + pub fn new(start : chrono::NaiveDate, end : chrono::NaiveDate) -> DateRange { + DateRange { + start_year : start.year(), + start_month : start.month(), + end_year : end.year(), + end_month : end.month(), + } + } +} + +impl Iterator for DateRange { + type Item = chrono::NaiveDate; + + fn next(&mut self) -> Option<Self::Item> { + println!("next called"); + if (self.start_year <= self.end_year) { + if(self.start_month <= self.end_month) { + let mut tmp = self.start_year.to_string(); + if self.start_month < 10 { + tmp.push_str("-0"); + } else { + tmp.push_str("-"); + } + tmp.push_str(&self.start_month.to_string()); + tmp.push_str("-01"); + if self.start_month < 13 { + self.start_month = self.start_month + 1; + } else { + self.start_month = 1; + self.start_year = self.start_year + 1; + } + println!("{}", tmp); + return Some(chrono::NaiveDate::parse_from_str(&tmp, "%Y-%m-%d").unwrap()) + } + } + None + } +} |
