crate::ix!();
#[derive(Getters)]
#[getset(get="pub")]
pub struct AccountHistogramBuilder<'a> {
account: &'a Account,
bins: Vec<MonetaryAmount>,
}
impl<'a> AccountHistogramBuilder<'a> {
pub fn new(account: &'a Account, bins: Vec<MonetaryAmount>) -> Self {
Self { account, bins }
}
pub fn build_histogram(&self, strategy: &HistogramDisplayStrategy) -> AccountHistogram {
let mut histogram = AccountHistogram::new(strategy);
let full_data = self.organize_histogram_data();
let mut months: Vec<NaiveDate> = full_data.keys().cloned().collect();
months.sort();
for month in &months {
let bins = full_data.get(month).unwrap();
let month_number = month.month();
let mut histogram_month = HistogramMonth::new(month_number);
for (i, bin) in bins.iter().enumerate()
{
let month_txns: Vec<_> = bin.iter().sorted().rev().map(
|tx| HistogramMonthBinTxnBuilder::default()
.date(*tx.transaction_date())
.amount(tx.amount())
.description(tx.description())
.build()
.unwrap()
).collect();
histogram_month.push(
HistogramMonthBinBuilder::default()
.price_range(self.bins[i] .. self.bins[i + 1])
.txns(month_txns)
.build()
.unwrap()
);
}
histogram.push(histogram_month);
}
histogram
}
fn organize_histogram_data(&self) -> HashMap<NaiveDate, Vec<Vec<&'a Transaction>>> {
let mut histograms: HashMap<NaiveDate, Vec<Vec<&'a Transaction>>> = HashMap::new();
for tx in self.account.txns().iter() {
let month_start = tx.transaction_date().with_day0(0).unwrap();
let histogram = histograms.entry(month_start).or_insert_with(|| {
let mut bin_vec = Vec::new();
for _ in 0..self.bins.len() - 1 {
bin_vec.push(Vec::new());
}
bin_vec
});
for i in 0..self.bins.len() - 1 {
if tx.amount() >= self.bins[i] && tx.amount() < self.bins[i + 1] {
histogram[i].push(tx);
break;
}
}
}
histograms
}
}