summaryrefslogtreecommitdiff
path: root/backend/core/src/utils
diff options
context:
space:
mode:
Diffstat (limited to 'backend/core/src/utils')
-rw-r--r--backend/core/src/utils/calculate_budgets_accrual.rs155
-rw-r--r--backend/core/src/utils/calculate_category_balance.rs153
-rw-r--r--backend/core/src/utils/find_by_id_or.rs41
-rw-r--r--backend/core/src/utils/mod.rs7
4 files changed, 0 insertions, 356 deletions
diff --git a/backend/core/src/utils/calculate_budgets_accrual.rs b/backend/core/src/utils/calculate_budgets_accrual.rs
deleted file mode 100644
index 56171ca..0000000
--- a/backend/core/src/utils/calculate_budgets_accrual.rs
+++ /dev/null
@@ -1,155 +0,0 @@
-use anyhow::Result;
-use crate::{models::{
- budget_update::BudgetUpdate, category::Category, date_utc::DateUtc
-}, traits::nowlike::Nowlike};
-
-pub fn calculate_budgets_accrual(category: &Category, budget_updates: &[BudgetUpdate]) -> Result<i64> {
- let mut budget_updates = budget_updates
- .iter()
- .filter(|bu| bu.category_id == category.id)
- .collect::<Vec<&BudgetUpdate>>();
- budget_updates.sort_by_key(|bu| bu.date.clone());
- budget_updates.reverse();
-
- let mut budgets_accrual = 0.0_f64;
- let mut calculated_back_to_date = DateUtc::now();
-
- for budget_update in budget_updates {
- let days_on_this_budget = calculated_back_to_date.day_diff(&budget_update.date);
- if days_on_this_budget == 0_u32 {
- return Err(anyhow::Error::msg(format!(
- "failed to calculate budgets accrual since two budget updates had the same date ({})",
- budget_update.date,
- )));
- }
- let budget_per_day = budget_update.new_budget as f64 / budget_update.new_period as f64;
- budgets_accrual += days_on_this_budget as f64 * budget_per_day;
- calculated_back_to_date = budget_update.date.clone();
- }
-
- Ok(budgets_accrual.floor() as i64)
-}
-
-#[cfg(test)]
-mod test {
- use chrono::{Days, Utc};
-
- use crate::{
- models::{budget_update::BudgetUpdate, category::Category, date_utc::DateUtc}, traits::nowlike::Nowlike, utils::calculate_budgets_accrual
- };
-
- #[test]
- fn when_no_budget_updates_then_return_zero() {
- let category = Category {
- id: 0,
- name: String::from("Groceries"),
- };
- let budget_updates = [];
-
- let result = calculate_budgets_accrual(&category, &budget_updates);
-
- assert!(result.is_ok());
- assert_eq!(result.unwrap(), 0_i64);
- }
-
- #[test]
- fn when_one_budget_update_for_another_category_then_return_zero() {
- let category = Category {
- id: 0,
- name: String::from("Groceries"),
- };
- let budget_updates = [BudgetUpdate {
- id: 0,
- category_id: 1,
- date: DateUtc::now(),
- new_budget: 100,
- new_period: 1,
- }];
-
- let result = calculate_budgets_accrual(&category, &budget_updates);
-
- assert!(result.is_ok());
- assert_eq!(result.unwrap(), 0_i64);
- }
-
- #[test]
- fn when_one_budget_update_then_return_quantity_times_days_in_past() {
- let category = Category {
- id: 0,
- name: String::from("Groceries"),
- };
- let budget_updates = [BudgetUpdate {
- id: 0,
- category_id: 0,
- date: DateUtc::from(Utc::now().checked_sub_days(Days::new(120)).unwrap()),
- new_budget: 100,
- new_period: 1,
- }];
-
- let result = calculate_budgets_accrual(&category, &budget_updates);
-
- assert!(result.is_ok());
- assert_eq!(result.unwrap(), 12_000);
- }
-
- #[test]
- fn when_two_budget_updates_then_calculates_as_expected() {
- let category = Category {
- id: 0,
- name: String::from("Groceries"),
- };
- let budget_updates = [
- BudgetUpdate {
- id: 0,
- category_id: 0,
- date: DateUtc::from(&Utc::now().checked_sub_days(Days::new(60)).unwrap()),
- new_budget: 200,
- new_period: 1,
- },
- BudgetUpdate {
- id: 0,
- category_id: 0,
- date: DateUtc::from(&Utc::now().checked_sub_days(Days::new(120)).unwrap()),
- new_budget: 100,
- new_period: 1,
- },
- ];
-
- let result = calculate_budgets_accrual(&category, &budget_updates);
-
- assert!(result.is_ok());
- assert_eq!(result.unwrap(), 18_000);
- }
-
- #[test]
- fn when_two_budget_updates_on_same_day_then_returns_err() {
- let category = Category {
- id: 0,
- name: String::from("Groceries"),
- };
- let budget_updates = [
- BudgetUpdate {
- id: 0,
- category_id: 0,
- date: DateUtc::from_ymd(2020, 12, 25).unwrap(),
- new_budget: 200,
- new_period: 1,
- },
- BudgetUpdate {
- id: 0,
- category_id: 0,
- date: DateUtc::from_ymd(2020, 12, 25).unwrap(),
- new_budget: 100,
- new_period: 1,
- },
- ];
- let mut budget_updates_reversed = budget_updates.clone();
- budget_updates_reversed.reverse();
-
- let result_leftways = calculate_budgets_accrual(&category, &budget_updates);
- let result_rightways = calculate_budgets_accrual(&category, &budget_updates_reversed);
-
- assert!(result_leftways.is_err());
- assert!(result_rightways.is_err());
- }
-}
diff --git a/backend/core/src/utils/calculate_category_balance.rs b/backend/core/src/utils/calculate_category_balance.rs
deleted file mode 100644
index 61b94a8..0000000
--- a/backend/core/src/utils/calculate_category_balance.rs
+++ /dev/null
@@ -1,153 +0,0 @@
-use anyhow::Result;
-use crate::{
- models::{budget_update::BudgetUpdate, category::Category},
- utils::{calculate_budgets_accrual, find_by_id_or},
-};
-
-pub fn calculate_category_balance(
- category: &Category,
- transaction_sums: &[(i32, i64)],
- category_transfer_from_sums: &[(i32, i64)],
- category_transfer_to_sums: &[(i32, i64)],
- budget_updates: &[BudgetUpdate],
-) -> Result<i64> {
- let transaction_sum = find_by_id_or(transaction_sums, category.id, 0);
- let category_transfer_from_sum = find_by_id_or(category_transfer_from_sums, category.id, 0);
- let category_transfer_to_sum = find_by_id_or(category_transfer_to_sums, category.id, 0);
- let budget_accruals_sum = calculate_budgets_accrual(category, budget_updates)?;
-
- Ok(
- transaction_sum
- + budget_accruals_sum
- + category_transfer_to_sum
- - category_transfer_from_sum
- )
-}
-
-#[cfg(test)]
-mod test {
- use chrono::{Days, Utc};
-
- use crate::{
- models::{budget_update::BudgetUpdate, category::Category, date_utc::DateUtc},
- utils::calculate_category_balance
- };
-
- #[test]
- fn when_no_data_then_returns_zero() {
- let category = Category {
- id: 0,
- name: String::new(),
- };
-
- let result = calculate_category_balance(&category, &[], &[], &[], &[]);
-
- assert!(result.is_ok());
- assert_eq!(result.unwrap(), 0_i64);
- }
-
- #[test]
- fn when_data_only_for_another_category_then_returns_zero() {
- let category = Category {
- id: 0,
- name: String::new(),
- };
- let transaction_sums = [(1, 100)];
- let category_transfer_from_sums = [(1, 91)];
- let category_transfer_to_sums = [(2, 79)];
- let budget_updates = [BudgetUpdate {
- id: 0,
- category_id: 1,
- date: DateUtc::from(Utc::now().checked_sub_days(Days::new(120)).unwrap()),
- new_budget: 77,
- new_period: 1,
- }];
-
- let result = calculate_category_balance(
- &category,
- &transaction_sums,
- &category_transfer_from_sums,
- &category_transfer_to_sums,
- &budget_updates,
- );
-
- assert!(result.is_ok());
- assert_eq!(result.unwrap(), 0_i64);
- }
-
- #[test]
- fn when_transaction_sum_is_zero_then_returns_zero() {
- let category = Category {
- id: 0,
- name: String::new(),
- };
- let transaction_sums = [(0, 0)];
- let category_transfer_from_sums = [];
- let category_transfer_to_sums = [];
- let budget_updates = [];
-
- let result = calculate_category_balance(
- &category,
- &transaction_sums,
- &category_transfer_from_sums,
- &category_transfer_to_sums,
- &budget_updates,
- );
-
- assert!(result.is_ok());
- assert_eq!(result.unwrap(), 0_i64);
- }
-
- #[test]
- fn when_category_transfers_are_zero_then_returns_zero() {
- let category = Category {
- id: 0,
- name: String::new(),
- };
- let transaction_sums = [];
- let category_transfer_from_sums = [(0, 0)];
- let category_transfer_to_sums = [(0, 0)];
- let budget_updates = [];
-
- let result = calculate_category_balance(
- &category,
- &transaction_sums,
- &category_transfer_from_sums,
- &category_transfer_to_sums,
- &budget_updates,
- );
-
- assert!(result.is_ok());
- assert_eq!(result.unwrap(), 0_i64);
- }
-
- #[test]
- fn when_some_data_then_calculates_as_expected() {
- let category = Category {
- id: 0,
- name: String::new(),
- };
- let transaction_sums = [(0, 100)];
- let category_transfer_from_sums = [(0, 91)];
- let category_transfer_to_sums = [(0, 79)];
- let budget_updates = [BudgetUpdate {
- id: 0,
- category_id: 0,
- date: DateUtc::from(&Utc::now().checked_sub_days(Days::new(120)).unwrap()),
- new_budget: 77,
- new_period: 1,
- }];
-
- let result = calculate_category_balance(
- &category,
- &transaction_sums,
- &category_transfer_from_sums,
- &category_transfer_to_sums,
- &budget_updates,
- );
-
- let expected_result = 100 + (-91) + 79 + 77 * 120;
- assert!(result.is_ok());
- assert_eq!(result.unwrap(), expected_result);
- }
-}
diff --git a/backend/core/src/utils/find_by_id_or.rs b/backend/core/src/utils/find_by_id_or.rs
deleted file mode 100644
index 8335e5c..0000000
--- a/backend/core/src/utils/find_by_id_or.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-pub fn find_by_id_or<Id: PartialEq, Val: Copy>(
- arr: &[(Id, Val)],
- id: Id,
- default: Val,
-) -> Val {
- arr.iter()
- .find(|(elem_id, _)| *elem_id == id)
- .map_or(default, |row| row.1)
-}
-
-#[cfg(test)]
-mod test {
- use super::find_by_id_or;
-
- #[test]
- fn when_no_elements_then_return_default() {
- let arr = [];
-
- let result = find_by_id_or(&arr, 1, 42);
-
- assert_eq!(result, 42);
- }
-
- #[test]
- fn when_id_not_in_elements_then_return_default() {
- let arr = [(0, 100), (2, 200)];
-
- let result = find_by_id_or(&arr, 1, 42);
-
- assert_eq!(result, 42);
- }
-
- #[test]
- fn when_id_in_elements_then_return_value() {
- let arr = [(1, 67)];
-
- let result = find_by_id_or(&arr, 1, 42);
-
- assert_eq!(result, 67);
- }
-}
diff --git a/backend/core/src/utils/mod.rs b/backend/core/src/utils/mod.rs
deleted file mode 100644
index 84a27af..0000000
--- a/backend/core/src/utils/mod.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-mod calculate_budgets_accrual;
-mod calculate_category_balance;
-mod find_by_id_or;
-
-pub use calculate_budgets_accrual::calculate_budgets_accrual;
-pub use calculate_category_balance::calculate_category_balance;
-pub use find_by_id_or::find_by_id_or;