summaryrefslogtreecommitdiff
path: root/src/web_frontend/balance.rs
blob: 2cbebec702036413948b0b8ad2da3f92594ccea4 (plain)
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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)
}