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 chrono::{NaiveDate, Utc};
use chrono::Datelike;
use regex::Regex;
#[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 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
}
|