1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
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<String, GroupValues>,
total_sum : f32,
total_chart : f32,
date_start : String,
date_end : String
}
#[get("/chart/<account>?<start>&<end>")]
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, &t_final);
let tmp = t_filtered_cloned.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)
}
|