aboutsummaryrefslogtreecommitdiffstats
path: root/src/ynab/budget.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/ynab/budget.rs')
-rw-r--r--src/ynab/budget.rs103
1 files changed, 69 insertions, 34 deletions
diff --git a/src/ynab/budget.rs b/src/ynab/budget.rs
index 85eab22..d31b803 100644
--- a/src/ynab/budget.rs
+++ b/src/ynab/budget.rs
@@ -1,14 +1,10 @@
-pub struct Budget<'a> {
- api: &'a ynab_api::apis::client::APIClient,
+pub struct Budget {
budget: ynab_api::models::BudgetDetail,
}
-impl<'a> Budget<'a> {
- pub fn new(
- api: &'a ynab_api::apis::client::APIClient,
- budget: ynab_api::models::BudgetDetail,
- ) -> Self {
- Self { api, budget }
+impl Budget {
+ pub fn new(budget: ynab_api::models::BudgetDetail) -> Self {
+ Self { budget }
}
pub fn name(&self) -> String {
@@ -20,35 +16,30 @@ impl<'a> Budget<'a> {
}
pub fn reimbursables(&self) -> Vec<super::transaction::Transaction> {
- let reimbursables_id = self
- .api
- .categories_api()
- .get_categories(&self.budget.id, 0)
- .unwrap()
- .data
- .category_groups
- .iter()
- .map(|group| {
- group
- .categories
+ let reimbursables_id =
+ if let Some(categories) = &self.budget.categories {
+ categories
.iter()
- .map(|c| (c.id.clone(), c.name.clone()))
- })
- .flat_map(|cs| cs)
- .find(|(_, name)| name == "Reimbursables")
- .map(|(id, _)| id)
- .unwrap();
+ .find(|c| c.name == "Reimbursables")
+ .map(|c| c.id.clone())
+ .unwrap()
+ } else {
+ panic!("no categories found")
+ };
let mut reimbursables = vec![];
- if let Some(transactions) = &self.budget.transactions {
- if let Some(payees) = &self.budget.payees {
- let mut payee_map = std::collections::HashMap::new();
- for p in payees {
- payee_map.insert(p.id.clone(), p.name.clone());
- }
- let payee_map = payee_map;
+ if let Some(payees) = &self.budget.payees {
+ let mut payee_map = std::collections::HashMap::new();
+ for p in payees {
+ payee_map.insert(p.id.clone(), p.name.clone());
+ }
+ let payee_map = payee_map;
+ let mut transaction_map = std::collections::HashMap::new();
+ if let Some(transactions) = &self.budget.transactions {
for t in transactions {
+ transaction_map.insert(t.id.clone(), t);
+
if let Some(category_id) = &t.category_id {
if category_id != &reimbursables_id {
continue;
@@ -73,14 +64,58 @@ impl<'a> Budget<'a> {
date: t.date.clone(),
payee,
amount: t.amount,
+ total_amount: t.amount,
+ reimbursed,
+ })
+ }
+ }
+ let transaction_map = transaction_map;
+
+ if let Some(subtransactions) = &self.budget.subtransactions {
+ for st in subtransactions {
+ if let Some(category_id) = &st.category_id {
+ if category_id != &reimbursables_id {
+ continue;
+ }
+ } else {
+ continue;
+ }
+
+ let t = transaction_map[&st.transaction_id];
+ let payee = st
+ .payee_id
+ .iter()
+ .flat_map(|payee_id| payee_map.get(payee_id).cloned())
+ .next()
+ .unwrap_or_else(|| {
+ t.payee_id
+ .iter()
+ .flat_map(|payee_id| {
+ payee_map.get(payee_id).cloned()
+ })
+ .next()
+ .unwrap_or_else(|| "(none)".to_string())
+ });
+ let reimbursed = if let Some(color) = &t.flag_color {
+ color == "green"
+ } else {
+ false
+ };
+
+ reimbursables.push(super::transaction::Transaction {
+ date: t.date.clone(),
+ payee,
+ amount: st.amount,
+ total_amount: t.amount,
reimbursed,
})
}
- } else {
- panic!("no payees?");
}
+ } else {
+ panic!("no payees?");
}
+ reimbursables.sort_by_cached_key(|t| t.date.clone());
reimbursables
}
}