From 27b95c9186bd45edd4c982a7cc89cf69cf2c5d46 Mon Sep 17 00:00:00 2001 From: Joe Carstairs Date: Wed, 16 Oct 2024 12:51:21 +0100 Subject: All backend stuff lives in backend folder --- backend/src/utils/calculate_budgets_accrual.rs | 159 ------------------------ backend/src/utils/calculate_category_balance.rs | 141 --------------------- backend/src/utils/find_by_id_or.rs | 53 -------- backend/src/utils/mod.rs | 7 -- 4 files changed, 360 deletions(-) delete mode 100644 backend/src/utils/calculate_budgets_accrual.rs delete mode 100644 backend/src/utils/calculate_category_balance.rs delete mode 100644 backend/src/utils/find_by_id_or.rs delete mode 100644 backend/src/utils/mod.rs (limited to 'backend/src/utils') diff --git a/backend/src/utils/calculate_budgets_accrual.rs b/backend/src/utils/calculate_budgets_accrual.rs deleted file mode 100644 index f14260d..0000000 --- a/backend/src/utils/calculate_budgets_accrual.rs +++ /dev/null @@ -1,159 +0,0 @@ -use crate::models::{budget_update::BudgetUpdate, category::Category, date_time_utc::DateTimeUtc}; - -pub fn calculate_budgets_accrual(category: &Category, budget_updates: &[BudgetUpdate]) -> i64 { - let mut budget_updates = budget_updates - .iter() - .filter(|bu| bu.category_id == category.id) - .collect::>(); - budget_updates.sort_by_key(|bu| bu.date); - budget_updates.reverse(); - - let mut budgets_accrual = 0.0_f64; - let mut calculated_back_to_date = DateTimeUtc::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 { - continue; - } - 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; - } - - budgets_accrual.floor() as i64 -} - -#[cfg(test)] -mod test { - use chrono::{Days, Timelike, Utc}; - - use crate::models::{ - budget_update::BudgetUpdate, category::Category, date_time_utc::DateTimeUtc, - }; - - use super::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_eq!(result, 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: DateTimeUtc::now(), - new_budget: 100, - new_period: 1, - }]; - - let result = calculate_budgets_accrual(&category, &budget_updates); - - assert_eq!(result, 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: DateTimeUtc::new(Utc::now().checked_sub_days(Days::new(120)).unwrap()), - new_budget: 100, - new_period: 1, - }]; - - let result = calculate_budgets_accrual(&category, &budget_updates); - - assert_eq!(result, 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: DateTimeUtc::new(Utc::now().checked_sub_days(Days::new(60)).unwrap()), - new_budget: 200, - new_period: 1, - }, - BudgetUpdate { - id: 0, - category_id: 0, - date: DateTimeUtc::new(Utc::now().checked_sub_days(Days::new(120)).unwrap()), - new_budget: 100, - new_period: 1, - }, - ]; - - let result = calculate_budgets_accrual(&category, &budget_updates); - - assert_eq!(result, 18_000); - } - - #[test] - fn when_two_budget_updates_on_same_day_then_uses_latest_only() { - let category = Category { - id: 0, - name: String::from("Groceries"), - }; - let budget_updates = [ - BudgetUpdate { - id: 0, - category_id: 0, - date: DateTimeUtc::new( - Utc::now() - .checked_sub_days(Days::new(120)) - .unwrap() - .with_hour(13) - .unwrap(), - ), - new_budget: 200, - new_period: 1, - }, - BudgetUpdate { - id: 0, - category_id: 0, - date: DateTimeUtc::new( - Utc::now() - .checked_sub_days(Days::new(120)) - .unwrap() - .with_hour(12) - .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_eq!(result_leftways, 24_000); - assert_eq!(result_rightways, 24_000); - } -} diff --git a/backend/src/utils/calculate_category_balance.rs b/backend/src/utils/calculate_category_balance.rs deleted file mode 100644 index 3c1c62f..0000000 --- a/backend/src/utils/calculate_category_balance.rs +++ /dev/null @@ -1,141 +0,0 @@ -use crate::models::{budget_update::BudgetUpdate, category::Category}; - -use super::{calculate_budgets_accrual, find_by_id_or}; - -pub fn calculate_category_balance( - category: &Category, - transaction_sums: &[(i32, Option)], - category_transfer_from_sums: &[(i32, Option)], - category_transfer_to_sums: &[(i32, Option)], - budget_updates: &[BudgetUpdate], -) -> 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); - - 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_time_utc::DateTimeUtc}, - 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_eq!(result, 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, Some(100))]; - let category_transfer_from_sums = [(1, Some(91))]; - let category_transfer_to_sums = [(2, Some(79))]; - let budget_updates = [BudgetUpdate { - id: 0, - category_id: 1, - date: DateTimeUtc::new(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_eq!(result, 0_i64); - } - - #[test] - fn when_transaction_sum_is_none_then_returns_zero() { - let category = Category { - id: 0, - name: String::new(), - }; - let transaction_sums = [(0, None)]; - 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_eq!(result, 0_i64); - } - - #[test] - fn when_category_transfers_are_none_then_returns_zero() { - let category = Category { - id: 0, - name: String::new(), - }; - let transaction_sums = []; - let category_transfer_from_sums = [(0, None)]; - let category_transfer_to_sums = [(0, None)]; - let budget_updates = []; - - let result = calculate_category_balance( - &category, - &transaction_sums, - &category_transfer_from_sums, - &category_transfer_to_sums, - &budget_updates, - ); - - assert_eq!(result, 0_i64); - } - - #[test] - fn when_some_data_then_calculates_as_expected() { - let category = Category { - id: 0, - name: String::new(), - }; - let transaction_sums = [(0, Some(100))]; - let category_transfer_from_sums = [(0, Some(91))]; - let category_transfer_to_sums = [(0, Some(79))]; - let budget_updates = [BudgetUpdate { - id: 0, - category_id: 0, - date: DateTimeUtc::new(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_eq!(result, expected_result); - } -} diff --git a/backend/src/utils/find_by_id_or.rs b/backend/src/utils/find_by_id_or.rs deleted file mode 100644 index f5add30..0000000 --- a/backend/src/utils/find_by_id_or.rs +++ /dev/null @@ -1,53 +0,0 @@ -pub fn find_by_id_or( - arr: &[(Id, Option)], - id: Id, - default: Val, -) -> Val { - arr.iter() - .find(|(elem_id, _)| *elem_id == id) - .map_or(default, |row| match row { - (_, Some(quantity)) => *quantity, - (_, _) => default, - }) -} - -#[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, Some(100)), (2, Some(200))]; - - let result = find_by_id_or(&arr, 1, 42); - - assert_eq!(result, 42); - } - - #[test] - fn when_value_is_none_then_return_default() { - let arr = [(1, None)]; - - let result = find_by_id_or(&arr, 1, 42); - - assert_eq!(result, 42); - } - - #[test] - fn when_value_is_some_then_return_value() { - let arr = [(1, Some(67))]; - - let result = find_by_id_or(&arr, 1, 42); - - assert_eq!(result, 67); - } -} diff --git a/backend/src/utils/mod.rs b/backend/src/utils/mod.rs deleted file mode 100644 index 84a27af..0000000 --- a/backend/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; -- cgit v1.2.3