summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rust/actualbudget_queries/src/actualbudget_payees.rs13
-rw-r--r--rust/actualbudget_queries/src/lib.rs1
-rw-r--r--rust/actualbudget_queries/tests/actualbudget_payees.rs25
-rw-r--r--rust/actualbudget_queries/tests/common/mod.rs2
-rw-r--r--rust/actualbudget_queries/tests/common/payee_matchers.rs124
-rw-r--r--rust/actualbudget_queries/tests/common/payee_names.rs17
6 files changed, 182 insertions, 0 deletions
diff --git a/rust/actualbudget_queries/src/actualbudget_payees.rs b/rust/actualbudget_queries/src/actualbudget_payees.rs
new file mode 100644
index 0000000..d5b0c5f
--- /dev/null
+++ b/rust/actualbudget_queries/src/actualbudget_payees.rs
@@ -0,0 +1,13 @@
+use actualbudget_models::ActualbudgetPayee;
+use actualbudget_schema::actualbudget_schema::payees::dsl::payees;
+use anyhow::{Result, Context};
+use diesel::{QueryDsl, RunQueryDsl, SelectableHelper, SqliteConnection};
+
+pub fn get_all_actualbudget_payees(
+ connection: &mut SqliteConnection,
+) -> Result<Vec<ActualbudgetPayee>> {
+ payees
+ .select(ActualbudgetPayee::as_select())
+ .load(connection)
+ .with_context(|| "failed to get actualbudget payees")
+}
diff --git a/rust/actualbudget_queries/src/lib.rs b/rust/actualbudget_queries/src/lib.rs
index e16dafc..ca3f6ea 100644
--- a/rust/actualbudget_queries/src/lib.rs
+++ b/rust/actualbudget_queries/src/lib.rs
@@ -1,4 +1,5 @@
pub mod actualbudget_accounts;
pub mod actualbudget_categories;
+pub mod actualbudget_payees;
pub mod actualbudget_transactions;
pub mod actualbudget_zero_budgets;
diff --git a/rust/actualbudget_queries/tests/actualbudget_payees.rs b/rust/actualbudget_queries/tests/actualbudget_payees.rs
new file mode 100644
index 0000000..acf5c4e
--- /dev/null
+++ b/rust/actualbudget_queries/tests/actualbudget_payees.rs
@@ -0,0 +1,25 @@
+pub mod common;
+
+use actualbudget_queries::actualbudget_payees::get_all_actualbudget_payees;
+use common::{db_url::DB_URL, get_reference_data::get_accounts, payee_matchers::get_payee_matchers};
+use diesel::{Connection, SqliteConnection};
+
+#[test]
+fn given_test_database_when_get_all_payees_then_return_payees() {
+ let connection = &mut SqliteConnection::establish(DB_URL).unwrap();
+ let accounts = get_accounts(connection);
+
+ let payees = get_all_actualbudget_payees(connection);
+
+ assert!(payees.is_ok());
+ let payees = payees.unwrap();
+ let payee_matchers = get_payee_matchers();
+ assert_eq!(payee_matchers.len(), payees.len());
+ for payee in payees {
+ assert!(
+ payee_matchers.iter().any(|payee_matcher| payee_matcher(&payee, &accounts)),
+ "no match found for payee {:?}",
+ payee,
+ );
+ }
+}
diff --git a/rust/actualbudget_queries/tests/common/mod.rs b/rust/actualbudget_queries/tests/common/mod.rs
index 9c24578..b19b061 100644
--- a/rust/actualbudget_queries/tests/common/mod.rs
+++ b/rust/actualbudget_queries/tests/common/mod.rs
@@ -2,5 +2,7 @@ pub mod account_names;
pub mod category_names;
pub mod db_url;
pub mod get_reference_data;
+pub mod payee_matchers;
+pub mod payee_names;
pub mod transaction_matchers;
pub mod zero_budget_matchers;
diff --git a/rust/actualbudget_queries/tests/common/payee_matchers.rs b/rust/actualbudget_queries/tests/common/payee_matchers.rs
new file mode 100644
index 0000000..ccba204
--- /dev/null
+++ b/rust/actualbudget_queries/tests/common/payee_matchers.rs
@@ -0,0 +1,124 @@
+use std::collections::HashMap;
+
+use actualbudget_models::{ActualbudgetAccount, ActualbudgetPayee};
+use anyhow::Context;
+
+use super::{account_names::ACCOUNT_NAMES_DICT, payee_names::PAYEE_NAMES_DICT};
+
+pub fn get_payee_matchers(
+) -> Vec<Box<dyn Fn(&ActualbudgetPayee, &HashMap<String, ActualbudgetAccount>) -> bool>> {
+ vec![
+ Box::new(|p, a| matches_bank_account_transfer_account(p, a)),
+ Box::new(|p, a| matches_cash_account_transfer_account(p, a)),
+ Box::new(|p, a| matches_category_transfers_transfer_account(p, a)),
+ Box::new(|p, a| matches_starting_balances(p, a)),
+ Box::new(|p, a| matches_employer(p, a)),
+ Box::new(|p, a| matches_tesco(p, a)),
+ ]
+}
+
+fn matches_bank_account_transfer_account(
+ payee: &ActualbudgetPayee,
+ accounts: &HashMap<String, ActualbudgetAccount>,
+) -> bool {
+ let bank_account = accounts
+ .get(ACCOUNT_NAMES_DICT.bank_account)
+ .with_context(|| "failed to get bank account")
+ .unwrap();
+
+ match payee {
+ ActualbudgetPayee {
+ name,
+ transfer_account_id,
+ ..
+ } => name == ""
+ && transfer_account_id.clone().is_some_and(
+ |account_id| account_id == bank_account.id,
+ ),
+ }
+}
+
+fn matches_cash_account_transfer_account(
+ payee: &ActualbudgetPayee,
+ accounts: &HashMap<String, ActualbudgetAccount>,
+) -> bool {
+ let cash_account = accounts
+ .get(ACCOUNT_NAMES_DICT.cash_account)
+ .with_context(|| "failed to find cash account")
+ .unwrap();
+
+ match payee {
+ ActualbudgetPayee {
+ name,
+ transfer_account_id,
+ ..
+ } => name == ""
+ && transfer_account_id.clone().is_some_and(
+ |account_id| account_id == cash_account.id,
+ ),
+ }
+}
+
+fn matches_category_transfers_transfer_account(
+ payee: &ActualbudgetPayee,
+ accounts: &HashMap<String, ActualbudgetAccount>,
+) -> bool {
+ let category_transfers_account = accounts
+ .get(ACCOUNT_NAMES_DICT.transfers_account)
+ .with_context(|| "failed to find category transfers account")
+ .unwrap();
+
+ match payee {
+ ActualbudgetPayee {
+ name,
+ transfer_account_id,
+ ..
+ } => name == ""
+ && transfer_account_id.clone().is_some_and(
+ |account_id| account_id == category_transfers_account.id,
+ ),
+ }
+}
+
+fn matches_starting_balances(
+ payee: &ActualbudgetPayee,
+ _accounts: &HashMap<String, ActualbudgetAccount>,
+) -> bool {
+ match payee {
+ ActualbudgetPayee {
+ name,
+ transfer_account_id,
+ ..
+ } => transfer_account_id.is_none()
+ && name.clone() == PAYEE_NAMES_DICT.starting_balances,
+ }
+}
+
+fn matches_employer(
+ payee: &ActualbudgetPayee,
+ _accounts: &HashMap<String, ActualbudgetAccount>,
+) -> bool {
+ match payee {
+ ActualbudgetPayee {
+ name,
+ transfer_account_id,
+ ..
+ } => transfer_account_id.is_none()
+ && name == PAYEE_NAMES_DICT.employer,
+ }
+}
+
+
+fn matches_tesco(
+ payee: &ActualbudgetPayee,
+ _accounts: &HashMap<String, ActualbudgetAccount>,
+) -> bool {
+ match payee {
+ ActualbudgetPayee {
+ name,
+ transfer_account_id,
+ ..
+ } => transfer_account_id.is_none()
+ && name == PAYEE_NAMES_DICT.tesco,
+ }
+}
diff --git a/rust/actualbudget_queries/tests/common/payee_names.rs b/rust/actualbudget_queries/tests/common/payee_names.rs
new file mode 100644
index 0000000..42b6024
--- /dev/null
+++ b/rust/actualbudget_queries/tests/common/payee_names.rs
@@ -0,0 +1,17 @@
+pub const PAYEE_NAMES: &[&'static str] = &[
+ "Starting Balance",
+ "Employer Ltd",
+ "Tesco",
+];
+
+pub struct PayeeNamesDict {
+ pub starting_balances: &'static str,
+ pub employer: &'static str,
+ pub tesco: &'static str,
+}
+
+pub const PAYEE_NAMES_DICT: PayeeNamesDict = PayeeNamesDict {
+ starting_balances: PAYEE_NAMES[0],
+ employer: PAYEE_NAMES[1],
+ tesco: PAYEE_NAMES[2],
+};