tktax_histogram/
histogram_builder.rs

1// ---------------- [ File: tktax-histogram/src/histogram_builder.rs ]
2crate::ix!();
3
4#[derive(Getters)]
5#[getset(get="pub")]
6pub struct AccountHistogramBuilder<'a> {
7    account: &'a Account,
8    bins:    Vec<MonetaryAmount>,
9}
10
11impl<'a> AccountHistogramBuilder<'a> {
12
13    pub fn new(account: &'a Account, bins: Vec<MonetaryAmount>) -> Self {
14        Self { account, bins }
15    }
16
17    pub fn build_histogram(&self, strategy: &HistogramDisplayStrategy) -> AccountHistogram {
18
19        let mut histogram = AccountHistogram::new(strategy);
20
21        let full_data = self.organize_histogram_data();
22
23        // Collect and sort the months
24        let mut months: Vec<NaiveDate> = full_data.keys().cloned().collect();
25
26        months.sort();
27
28        for month in &months {
29
30            let bins = full_data.get(month).unwrap();
31
32            let month_number = month.month();
33
34            let mut histogram_month = HistogramMonth::new(month_number);
35
36            for (i, bin) in bins.iter().enumerate()
37                //.filter(|(i,bin)| bin.len() > 0) 
38            {
39                let month_txns: Vec<_> = bin.iter().sorted().rev().map(
40                    |tx| HistogramMonthBinTxnBuilder::default()
41                        .date(*tx.transaction_date())
42                        .amount(tx.amount())
43                        .description(tx.description())
44                        .build()
45                        .unwrap()
46                ).collect();
47
48                histogram_month.push(
49                    HistogramMonthBinBuilder::default()
50                        .price_range(self.bins[i] .. self.bins[i + 1])
51                        .txns(month_txns)
52                        .build()
53                        .unwrap()
54                );
55            }
56
57            histogram.push(histogram_month);
58        }
59
60        histogram
61    }
62
63    fn organize_histogram_data(&self) -> HashMap<NaiveDate, Vec<Vec<&'a Transaction>>> {
64
65        let mut histograms: HashMap<NaiveDate, Vec<Vec<&'a Transaction>>> = HashMap::new();
66
67        for tx in self.account.txns().iter() {
68
69            let month_start = tx.transaction_date().with_day0(0).unwrap();
70
71            let histogram = histograms.entry(month_start).or_insert_with(|| {
72                let mut bin_vec = Vec::new();
73                for _ in 0..self.bins.len() - 1 {
74                    bin_vec.push(Vec::new());
75                }
76                bin_vec
77            });
78
79            for i in 0..self.bins.len() - 1 {
80                if tx.amount() >= self.bins[i] && tx.amount() < self.bins[i + 1] {
81                    histogram[i].push(tx);
82                    break;
83                }
84            }
85        }
86
87        histograms
88    }
89}