use parsers::csv::CsvFile; use crate::banking::account::Account; use crate::banking::asset::Asset; //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, account_name : String, filter : String, date_start : String, date_end : String } struct TransactionFilter { sender_name_filter : Vec, reference_filter : Vec } /* * 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) -> Vec { 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/?&&")] pub fn transaction_handler(account : &RawStr, start : Option<&RawStr>, end : Option<&RawStr>, filter : 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 transaction_filter = match filter { Some(s) => s.to_string(), None => String::from("") }; 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); let acc; match transactions { Some(trans) => acc = trans, None => panic!("could not read file") } let t = acc.transactions; // apply parameters // apply date filters let date_range = crate::web_frontend::util::DateRange::new(date_start, date_end); let mut t_filtered = Vec::new(); for date in date_range { 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); } // apply filter let ft = 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(), date_end : date_end.to_string()[0..7].to_string()}; Template::render("transaction", context) }