summaryrefslogtreecommitdiff
path: root/src/web_frontend/util.rs
blob: 7a291732f022a162938b73187c90a2226a8dcf3c (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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
use chrono::{NaiveDate, Utc};
use chrono::Datelike;
use regex::{Regex, RegexBuilder};

#[derive(Debug)]
pub struct DateRange {
	start_year : i32,
	start_month : u32,
	end_year : i32,
	end_month : u32,
	last : bool,
}

impl DateRange {
	pub 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(),
			last : false,
		}
	}
}

impl Iterator for DateRange {
	type Item = chrono::NaiveDate;

	fn next(&mut self) -> Option<Self::Item> {
		if self.last {
			return None
		}
		if self.start_year == self.end_year && self.start_month == self.end_month {
			self.last = true;	
		}
		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 < 12 {
			self.start_month = self.start_month + 1;
		} else {
			self.start_month = 1;
			self.start_year = self.start_year + 1;
		}
		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 mut re_sender = RegexBuilder::new(&sender)
				.case_insensitive(true)
				.build()
				.expect("invalid regex");
			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

}

pub fn apply_date_filter(transactions : Vec<crate::banking::account::Transaction>, date_start : chrono::NaiveDate, date_end : chrono::NaiveDate) -> Vec<crate::banking::account::Transaction> {
	let date_range = DateRange::new(date_start, date_end);	
	let mut t_filtered = Vec::new();
	for date in date_range {
		let tc = transactions.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);
	}
	t_filtered
}