ledger_utils/
monthly_report.rs1use crate::balance::Balance;
2use crate::Ledger;
3use chrono::Datelike;
4
5#[derive(Debug, Clone)]
6pub struct MonthlyBalance {
7 pub year: i32,
8 pub month: u32,
9 pub monthly_change: Balance,
10 pub total: Balance,
11}
12
13impl MonthlyBalance {
14 pub fn new(year: i32, month: u32) -> MonthlyBalance {
15 MonthlyBalance {
16 year,
17 month,
18 monthly_change: Balance::new(),
19 total: Balance::new(),
20 }
21 }
22}
23
24#[derive(Debug, Clone)]
25pub struct MonthlyReport {
26 pub monthly_balances: Vec<MonthlyBalance>,
27}
28
29impl Default for MonthlyReport {
30 fn default() -> Self {
31 Self::new()
32 }
33}
34
35impl MonthlyReport {
36 pub fn new() -> MonthlyReport {
37 MonthlyReport {
38 monthly_balances: Vec::new(),
39 }
40 }
41}
42
43impl<'a> From<&'a Ledger> for MonthlyReport {
44 fn from(ledger: &'a Ledger) -> Self {
45 let mut report = MonthlyReport::new();
46
47 let mut current_year = 0;
48 let mut current_month = 0;
49 let mut current_monthly_balance: Option<MonthlyBalance> = None;
50 let mut monthly_balance = Balance::new();
51 let mut total_balance = Balance::new();
52
53 for transaction in &ledger.transactions {
54 if transaction.date.year() != current_year || transaction.date.month() != current_month
55 {
56 if let Some(mut b) = current_monthly_balance.take() {
59 b.monthly_change = monthly_balance.clone();
60 b.total = total_balance.clone();
61 report.monthly_balances.push(b);
62 }
63
64 current_year = transaction.date.year();
65 current_month = transaction.date.month();
66 monthly_balance = Balance::new();
67
68 current_monthly_balance = Some(MonthlyBalance::new(current_year, current_month));
69 }
70
71 monthly_balance.update_with_transaction(transaction);
72 total_balance.update_with_transaction(transaction);
73 }
74
75 if let Some(mut b) = current_monthly_balance.take() {
76 b.monthly_change = monthly_balance.clone();
77 b.total = total_balance.clone();
78 report.monthly_balances.push(b);
79 }
80
81 report
82 }
83}