summaryrefslogtreecommitdiff
path: root/src/web_frontend
diff options
context:
space:
mode:
authorBenedict Börger <benedict@0xb8000.de>2019-03-23 15:40:35 +0100
committerBenedict Börger <benedict@0xb8000.de>2019-03-23 15:41:11 +0100
commit2e0a6909cbfb2479edd7fba78fa4d0135a79ae3f (patch)
tree83070d9e1489faaea9a94609e7ff5bccedeb66d5 /src/web_frontend
parent7fcdc3ecc0f077ff7ff4ec57c912beae4f974fdb (diff)
[global] refactoring code base
Diffstat (limited to 'src/web_frontend')
-rw-r--r--src/web_frontend/balance.rs118
-rw-r--r--src/web_frontend/chart.rs61
-rw-r--r--src/web_frontend/mod.rs29
-rw-r--r--src/web_frontend/transactions.rs101
4 files changed, 309 insertions, 0 deletions
diff --git a/src/web_frontend/balance.rs b/src/web_frontend/balance.rs
new file mode 100644
index 0000000..2cbebec
--- /dev/null
+++ b/src/web_frontend/balance.rs
@@ -0,0 +1,118 @@
+use parsers::csv::CsvFile;
+use banking::Account;
+//use 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 MonthEarnSpend {
+ name : String,
+ earned : f32,
+ spent : f32,
+}
+
+
+#[derive(Serialize)]
+struct BalanceContext {
+ account_name : String,
+ months : Vec<MonthEarnSpend>,
+ date_start : String,
+ 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 {
+ 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 = 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> ;
+ match transactions {
+ Ok(trans) => t = crate::banking::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();
+ let mut earn = 0.0;
+ let mut spend = 0.0;
+ for r in &result {
+ if r.amount > 0.0 {
+ earn = earn + r.amount;
+ } else {
+ spend = spend + r.amount.abs();
+ }
+ }
+ earn_spend_v.push(MonthEarnSpend { name : date.to_string(), earned : earn, spent : spend});
+ }
+ let context = BalanceContext { account_name : String::from("Girokonto"),
+ months : earn_spend_v , date_start : date_start.to_string()[0..7].to_string(),
+ date_end : date_end.to_string()[0..7].to_string()};
+ Template::render("balance", context)
+}
diff --git a/src/web_frontend/chart.rs b/src/web_frontend/chart.rs
new file mode 100644
index 0000000..c5948fe
--- /dev/null
+++ b/src/web_frontend/chart.rs
@@ -0,0 +1,61 @@
+use parsers::csv::CsvFile;
+use banking::Account;
+//use 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 ChartContext {
+ account_name : String,
+ groups : HashMap<String, f32>
+}
+
+
+#[get("/chart")]
+fn chart_handler() -> rocket_contrib::templates::Template {
+ // read group config
+ let chart_file = "data/giro";
+ let chart_config = IniFile::from_file(chart_file);
+ 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();
+ 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() {
+ 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|
+ re.is_match(&transaction.sender_name) )
+ .fold(0.0, |acc, x| acc + x.amount);
+ complete = complete + tmp.abs();
+ }
+ }
+ groups.insert(section_name, complete);
+ // ALSO INSERT OTHER, AKA THE REST
+ }
+ let context = ChartContext { account_name : String::from("Girokonto"),
+ groups : groups };
+ Template::render("chart", context)
+}
+
diff --git a/src/web_frontend/mod.rs b/src/web_frontend/mod.rs
new file mode 100644
index 0000000..8577065
--- /dev/null
+++ b/src/web_frontend/mod.rs
@@ -0,0 +1,29 @@
+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;
+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
+#[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
new file mode 100644
index 0000000..417ca96
--- /dev/null
+++ b/src/web_frontend/transactions.rs
@@ -0,0 +1,101 @@
+use parsers::csv::CsvFile;
+use crate::banking::Account;
+//use 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;
+
+/*
+ This files contains the code to handle the /transactions requests
+*/
+
+/*
+ * This context is passed to the template rendering engine
+ * If you modify this structure, adapt also the template to include the
+ * changes!
+ */
+#[derive(Serialize)]
+struct TransactionContext {
+ transactions : Vec<crate::banking::Transaction>,
+ account_name : String,
+ filter : String,
+ date_start : String,
+ date_end : String
+}
+
+#[derive(FromForm)]
+pub struct TransactionFilter {
+ filter : String
+}
+
+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> ;
+ match transactions {
+ Ok(trans) => t = crate::banking::Transaction::from_sparkasse_csv_file(trans),
+ Err(e) => panic!("could not read file {:?}", e)
+ }
+ //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();
+ tmp
+
+ }
+}
+
+#[post("/transactions?<start>&<end>", data= "<transaction_filter>")]
+pub fn transaction_handler_post(start : Option<&RawStr>, end : Option<&RawStr>,
+ transaction_filter : Form<TransactionFilter>) -> 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 input : TransactionFilter = transaction_filter.into_inner();
+ let tmp = Vec::new();
+ let ft = input.apply_filter(tmp);
+ let context = TransactionContext { transactions : ft, account_name : String::from("TEST"),
+ filter : input.filter, date_start : date_start.to_string(),
+ date_end : date_end.to_string()};
+ Template::render("transaction", context)
+}
+
+#[get("/transactions?<start>&<end>")]
+pub fn transaction_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 transactions = CsvFile::from_file("data/t.csv", ";", true);
+ let t : Vec<crate::banking::Transaction> ;
+ match transactions {
+ Ok(trans) => t = crate::banking::Transaction::from_sparkasse_csv_file(trans),
+ Err(e) => panic!("could not read file {:?}", e)
+ }
+ let context = TransactionContext { transactions: t, account_name : String::from("Girokonto"),
+ filter : String::from(""), date_start : date_start.to_string()[0..7].to_string(),
+ date_end : date_end.to_string()[0..7].to_string()};
+ Template::render("transaction", context)
+}