summaryrefslogtreecommitdiff
path: root/src/web_frontend
diff options
context:
space:
mode:
Diffstat (limited to 'src/web_frontend')
-rw-r--r--src/web_frontend/chart.rs33
-rw-r--r--src/web_frontend/transactions.rs69
-rw-r--r--src/web_frontend/util.rs67
3 files changed, 88 insertions, 81 deletions
diff --git a/src/web_frontend/chart.rs b/src/web_frontend/chart.rs
index 0992e99..a6b387a 100644
--- a/src/web_frontend/chart.rs
+++ b/src/web_frontend/chart.rs
@@ -64,16 +64,17 @@ pub fn chart_handler(account : &RawStr, start : Option<&RawStr>, end : Option<&R
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() && x.date.year() == date.year()).collect();
- t_filtered.append(& mut tmp);
+ let tc = t.clone();
+ let mut tmp : Vec<_> = tc.into_iter().filter(|x| x.date.month() == date.month() && x.date.year() == date.year()).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();
+ // 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();
println!("total sum: {}", total_sum);
let mut total_chart = 0.0;
for (section_name, entries) in ini_file.sections {
@@ -81,24 +82,22 @@ pub fn chart_handler(account : &RawStr, start : Option<&RawStr>, end : Option<&R
let mut complete = 0.0;
for (key, values) in entries {
for val in values {
- filter_string.push_str(&key);
- filter_string.push_str("-");
- filter_string.push_str(&val);
- filter_string.push_str(".");
- let mut t_filtered_cloned = t_filtered.clone();
if val.is_empty() || val.is_empty() {
continue
}
- 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();
+ 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());
+ println!("for filter: {}: transactions: {}", filter_string, t_filtered_cloned.len());
+ 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;
- // ALSO INSERT OTHER, AKA THE REST
}
let context = ChartContext { account_name : account_name,
groups : groups, total_sum : total_sum, total_chart : total_chart,
diff --git a/src/web_frontend/transactions.rs b/src/web_frontend/transactions.rs
index f6d65af..6e5ae8c 100644
--- a/src/web_frontend/transactions.rs
+++ b/src/web_frontend/transactions.rs
@@ -8,15 +8,12 @@ use rocket::response::NamedFile;
use std::path::{PathBuf, Path};
use rocket::request::Form;
use rocket::http::RawStr;
+use rocket::http::uri::Uri;
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!
@@ -30,65 +27,6 @@ struct TransactionContext {
date_end : String
}
-struct TransactionFilter {
- sender_name_filter : Vec<String>,
- reference_filter : Vec<String>
-}
-
-/*
- * files syntax: . seperates different search critereas
- * a search crietera is a key value pair, with key as fiter type, e.g.
- * sender name of transation. The value is what is should be and can be a regex
- * key value pair is split by -
- */
-fn apply_transaction_filter(filter : String, transactions : Vec<crate::banking::account::Transaction>) -> Vec<crate::banking::account::Transaction> {
- let mut tmp = transactions.clone();
- // special case if for general search
- if !filter.to_string().contains(".") {
- println!("in special case");
- let re = Regex::new(&filter).unwrap();
- tmp = transactions.into_iter().filter(|transaction| re.is_match(&transaction.sender_name) || re.is_match(&transaction.reference) ).collect();
- return tmp;
- }
-
- // parse filter string and construct TransactionFilter struct
- let mut sender_name_vec = Vec::new();
- let mut reference_vec = Vec::new();
- for entry in filter.to_string().split(".") {
- let v : Vec<_> = entry.split("-").collect();
- println!("{:?}", v);
- if v.len() > 1 {
- if v[0] == "sender" {
- println!("Filter for sender_name");
- sender_name_vec.push(v[1].to_string());
- }
- else if v[0] == "reference" {
- println!("filter for reference");
- reference_vec.push(v[1].to_string());
- }
- }
-
- }
- tmp = transactions.clone().into_iter().filter(|transaction| {
- let mut sender_match = false;
- let mut reference_match = false;
- for sender in &sender_name_vec {
- let re_sender = Regex::new(&sender).unwrap();
- if re_sender.is_match(&transaction.sender_name) {
- sender_match = true;
- }
- }
- for reference in &reference_vec {
- let re = Regex::new(&reference).unwrap();
- if re.is_match(&transaction.reference) {
- reference_match = true;
- }
- }
- sender_match || reference_match
- }).collect();
- tmp
-
-}
#[get("/transactions/<account>?<start>&<end>&<filter>")]
pub fn transaction_handler(account : &RawStr, start : Option<&RawStr>, end : Option<&RawStr>,
@@ -110,6 +48,9 @@ pub fn transaction_handler(account : &RawStr, start : Option<&RawStr>, end : Opt
Some(s) => s.to_string(),
None => String::from("")
};
+ let tf_c = transaction_filter.clone();
+ let test = Uri::percent_decode_lossy(tf_c.as_bytes());
+ let transaction_filter = test.to_string();
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(&account_name);
@@ -130,7 +71,7 @@ pub fn transaction_handler(account : &RawStr, start : Option<&RawStr>, end : Opt
}
// apply filter
- let ft = apply_transaction_filter(transaction_filter.clone(), t_filtered);
+ let ft = crate::web_frontend::util::apply_transaction_filter(transaction_filter.clone(), t_filtered);
let context = TransactionContext { transactions: ft, account_name : account_name,
filter : transaction_filter, date_start : date_start.to_string()[0..7].to_string(),
diff --git a/src/web_frontend/util.rs b/src/web_frontend/util.rs
index 208b5b9..8c24465 100644
--- a/src/web_frontend/util.rs
+++ b/src/web_frontend/util.rs
@@ -1,5 +1,6 @@
use chrono::{NaiveDate, Utc};
use chrono::Datelike;
+use regex::Regex;
#[derive(Debug)]
pub struct DateRange {
@@ -49,3 +50,69 @@ impl Iterator for DateRange {
return Some(chrono::NaiveDate::parse_from_str(&tmp, "%Y-%m-%d").unwrap())
}
}
+
+
+
+/*
+ This files contains the code to handle the /transactions requests
+*/
+
+struct TransactionFilter {
+ sender_name_filter : Vec<String>,
+ reference_filter : Vec<String>
+}
+
+/*
+ * files syntax: . seperates different search critereas
+ * a search crietera is a key value pair, with key as fiter type, e.g.
+ * sender name of transation. The value is what is should be and can be a regex
+ * key value pair is split by -
+ */
+pub fn apply_transaction_filter(filter : String, transactions : Vec<crate::banking::account::Transaction>) -> Vec<crate::banking::account::Transaction> {
+ let mut tmp = transactions.clone();
+ // special case if for general search
+ if !filter.to_string().contains(";") {
+ println!("in special case");
+ let re = Regex::new(&filter).unwrap();
+ tmp = transactions.into_iter().filter(|transaction| re.is_match(&transaction.sender_name) || re.is_match(&transaction.reference) ).collect();
+ return tmp;
+ }
+
+ // parse filter string and construct TransactionFilter struct
+ let mut sender_name_vec = Vec::new();
+ let mut reference_vec = Vec::new();
+ for entry in filter.to_string().split(";") {
+ let v : Vec<_> = entry.split("-").collect();
+ println!("{:?}", v);
+ if v.len() > 1 {
+ if v[0] == "sender" {
+ println!("Filter for sender_name");
+ sender_name_vec.push(v[1].to_string());
+ }
+ else if v[0] == "reference" {
+ println!("filter for reference");
+ reference_vec.push(v[1].to_string());
+ }
+ }
+
+ }
+ tmp = transactions.clone().into_iter().filter(|transaction| {
+ let mut sender_match = false;
+ let mut reference_match = false;
+ for sender in &sender_name_vec {
+ let re_sender = Regex::new(&sender).unwrap();
+ if re_sender.is_match(&transaction.sender_name) {
+ sender_match = true;
+ }
+ }
+ for reference in &reference_vec {
+ let re = Regex::new(&reference).unwrap();
+ if re.is_match(&transaction.reference) {
+ reference_match = true;
+ }
+ }
+ sender_match || reference_match
+ }).collect();
+ tmp
+
+}