summaryrefslogtreecommitdiff
path: root/backend/actualbudget_importer/src
diff options
context:
space:
mode:
authorJoe Carstairs <me@joeac.net>2024-11-17 09:23:28 +0000
committerJoe Carstairs <me@joeac.net>2024-11-17 09:23:28 +0000
commit1ae19eb3315c40e3f9062592c27fa76c11cf626c (patch)
tree09d9ce380795971f4b50e1d4b0ca3c57c9e1db1a /backend/actualbudget_importer/src
parent1a494937021561595d0fb29e26fb707aef9e55de (diff)
Renames workspace folder
Diffstat (limited to 'backend/actualbudget_importer/src')
-rw-r--r--backend/actualbudget_importer/src/main.rs45
-rw-r--r--backend/actualbudget_importer/src/models/actualbudget_account.rs8
-rw-r--r--backend/actualbudget_importer/src/models/actualbudget_category.rs8
-rw-r--r--backend/actualbudget_importer/src/models/actualbudget_date.rs75
-rw-r--r--backend/actualbudget_importer/src/models/actualbudget_transaction.rs18
-rw-r--r--backend/actualbudget_importer/src/models/actualbudget_zero_budget.rs13
-rw-r--r--backend/actualbudget_importer/src/models/mod.rs5
-rw-r--r--backend/actualbudget_importer/src/queries/actualbudget_accounts/get_all.rs6
-rw-r--r--backend/actualbudget_importer/src/queries/actualbudget_accounts/get_category_transfers_account.rs13
-rw-r--r--backend/actualbudget_importer/src/queries/actualbudget_accounts/mod.rs5
-rw-r--r--backend/actualbudget_importer/src/queries/actualbudget_categories/get_all.rs6
-rw-r--r--backend/actualbudget_importer/src/queries/actualbudget_categories/mod.rs3
-rw-r--r--backend/actualbudget_importer/src/queries/actualbudget_transactions/get_all.rs6
-rw-r--r--backend/actualbudget_importer/src/queries/actualbudget_transactions/get_first_date.rs14
-rw-r--r--backend/actualbudget_importer/src/queries/actualbudget_transactions/mod.rs5
-rw-r--r--backend/actualbudget_importer/src/queries/actualbudget_zero_budgets/get_all.rs6
-rw-r--r--backend/actualbudget_importer/src/queries/actualbudget_zero_budgets/mod.rs3
-rw-r--r--backend/actualbudget_importer/src/queries/mod.rs4
-rw-r--r--backend/actualbudget_importer/src/schema.rs47
-rw-r--r--backend/actualbudget_importer/src/transformers.rs218
20 files changed, 0 insertions, 508 deletions
diff --git a/backend/actualbudget_importer/src/main.rs b/backend/actualbudget_importer/src/main.rs
deleted file mode 100644
index cb69bb5..0000000
--- a/backend/actualbudget_importer/src/main.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-pub mod models;
-pub mod queries;
-pub mod schema;
-pub mod transformers;
-
-use anyhow::Result;
-use budgeting_app_core::queries as budgeting_app_queries;
-use diesel::{Connection, SqliteConnection};
-use queries::{actualbudget_accounts::{get_all_actualbudget_accounts, get_category_transfers_account}, actualbudget_categories::get_all_actualbudget_categories, actualbudget_transactions::{get_all_actualbudget_transactions, get_first_actualbudget_transaction_date}, actualbudget_zero_budgets::get_all_actualbudget_zero_budgets};
-
-fn main() -> Result<()> {
- let connection_src = &mut SqliteConnection::establish("in.sqlite").unwrap();
- let connection_dest = &mut SqliteConnection::establish("out.sqlite").unwrap();
-
- let actualbudget_first_transaction_date = get_first_actualbudget_transaction_date(connection_src)?;
- let actualbudget_accounts = get_all_actualbudget_accounts(connection_src)?;
- let actualbudget_categories = get_all_actualbudget_categories(connection_src)?;
- let actualbudget_zero_budgets = get_all_actualbudget_zero_budgets(connection_src)?;
- let actualbudget_category_transfers_account = get_category_transfers_account(connection_src)?;
- let actualbudget_transactions = get_all_actualbudget_transactions(connection_src)?;
-
- let first_transaction_date = transformers::transform_date(&actualbudget_first_transaction_date)?;
- let accounts =
- transformers::transform_accounts(&actualbudget_accounts, &first_transaction_date);
- let categories = transformers::transform_categories(&actualbudget_categories);
- let budget_updates = transformers::transform_budget_updates(&actualbudget_zero_budgets)?;
- let (transactions, transaction_categorisations) = transformers::transform_transactions(
- &actualbudget_transactions,
- &actualbudget_category_transfers_account,
- )?;
- let category_transfers = transformers::transform_category_transfers(
- &actualbudget_transactions,
- &actualbudget_category_transfers_account,
- );
-
- budgeting_app_queries::clear::clear(connection_dest)?;
- budgeting_app_queries::accounts::insert_accounts(&accounts, connection_dest)?;
- budgeting_app_queries::categories::insert_categories(&categories, connection_dest)?;
- budgeting_app_queries::budget_updates::insert_budget_updates(&budget_updates, connection_dest)?;
- budgeting_app_queries::transactions::insert_transactions(&transactions, connection_dest)?;
- budgeting_app_queries::transaction_categorisations::insert_transaction_categorisations(&transaction_categorisations, connection_dest)?;
- budgeting_app_queries::category_transfers::insert_category_transfers(&category_transfers, connection_dest)?;
-
- Ok(())
-}
diff --git a/backend/actualbudget_importer/src/models/actualbudget_account.rs b/backend/actualbudget_importer/src/models/actualbudget_account.rs
deleted file mode 100644
index b3d00ac..0000000
--- a/backend/actualbudget_importer/src/models/actualbudget_account.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-use diesel::prelude::{Queryable, Selectable};
-
-#[derive(Queryable, Selectable)]
-#[diesel(table_name = crate::schema::accounts)]
-pub struct ActualbudgetAccount {
- pub id: String,
- pub name: String,
-}
diff --git a/backend/actualbudget_importer/src/models/actualbudget_category.rs b/backend/actualbudget_importer/src/models/actualbudget_category.rs
deleted file mode 100644
index cbea99b..0000000
--- a/backend/actualbudget_importer/src/models/actualbudget_category.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-use diesel::{prelude::Queryable, Selectable};
-
-#[derive(Queryable, Selectable)]
-#[diesel(table_name = crate::schema::categories)]
-pub struct ActualbudgetCategory {
- pub id: String,
- pub name: String,
-}
diff --git a/backend/actualbudget_importer/src/models/actualbudget_date.rs b/backend/actualbudget_importer/src/models/actualbudget_date.rs
deleted file mode 100644
index bef160c..0000000
--- a/backend/actualbudget_importer/src/models/actualbudget_date.rs
+++ /dev/null
@@ -1,75 +0,0 @@
-use diesel::{backend::Backend, deserialize::{FromSql, FromSqlRow}, expression::AsExpression, sql_types::Integer, sqlite::Sqlite};
-
-#[derive(Clone, PartialEq, Eq, Debug, AsExpression, FromSqlRow)]
-#[diesel(sql_type=Integer)]
-pub struct ActualbudgetDate(i32);
-
-#[derive(Clone, PartialOrd, PartialEq, Eq)]
-enum DatePart {
- MonthOfYear,
- DayOfMonth,
-}
-
-// actualbudget represents dates as numbers which "look like" the corresponding
-// ISO string when written in decimal. E.g. 20240901 represents 1 Sep 2024. It
-// also uses month specifiers, e.g. 202409 to represent Sep 2024. In this case,
-// we interpret this as the first day of the month, e.g. 2024-09-01.
-
-impl ActualbudgetDate {
- pub fn to_iso(&self) -> String {
- format!("{0}-{1}-{2}", self.year(), self.month(), self.day())
- }
-
- pub fn year(&self) -> String {
- self.0.to_string()[0..4].to_string()
- }
-
- pub fn month(&self) -> String {
- self.0.to_string()[4..6].to_string()
- }
-
- pub fn day(&self) -> String {
- match self.date_part() {
- DatePart::DayOfMonth => self.0.to_string()[6..8].to_string(),
- DatePart::MonthOfYear => String::from("01"),
- }
- }
-
- pub fn from_i32(i: i32) -> Self {
- ActualbudgetDate(i)
- }
-
- fn date_part(&self) -> DatePart {
- if self.0 < 10000000 {
- DatePart::MonthOfYear
- } else {
- DatePart::DayOfMonth
- }
- }
-
- fn dayified_value(&self) -> i32 {
- match self.date_part() {
- DatePart::DayOfMonth => self.0,
- DatePart::MonthOfYear => self.0 * 100 + 1,
- }
- }
-}
-
-impl Ord for ActualbudgetDate {
- fn cmp(&self, other: &Self) -> std::cmp::Ordering {
- self.dayified_value().cmp(&other.dayified_value())
- }
-}
-
-impl PartialOrd for ActualbudgetDate {
- fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
- Some(self.cmp(other))
- }
-}
-
-impl FromSql<Integer, Sqlite> for ActualbudgetDate {
- fn from_sql(bytes: <Sqlite as Backend>::RawValue<'_>) -> diesel::deserialize::Result<Self> {
- let int: i32 = FromSql::<Integer, Sqlite>::from_sql(bytes)?;
- Ok(ActualbudgetDate(int))
- }
-}
diff --git a/backend/actualbudget_importer/src/models/actualbudget_transaction.rs b/backend/actualbudget_importer/src/models/actualbudget_transaction.rs
deleted file mode 100644
index be2ca1a..0000000
--- a/backend/actualbudget_importer/src/models/actualbudget_transaction.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-use diesel::prelude::{Identifiable, Queryable, QueryableByName, Selectable};
-
-use crate::models::actualbudget_date::ActualbudgetDate;
-
-#[derive(Identifiable, QueryableByName, Queryable, Selectable, Clone)]
-#[diesel(table_name = crate::schema::transactions)]
-pub struct ActualbudgetTransaction {
- pub id: String,
- pub is_parent: bool,
- pub is_child: bool,
- pub account_id: String,
- pub category_id: String,
- pub amount: i32,
- pub payee: String,
- pub notes: String,
- pub date: ActualbudgetDate,
- pub parent_id: Option<String>,
-}
diff --git a/backend/actualbudget_importer/src/models/actualbudget_zero_budget.rs b/backend/actualbudget_importer/src/models/actualbudget_zero_budget.rs
deleted file mode 100644
index 6478d34..0000000
--- a/backend/actualbudget_importer/src/models/actualbudget_zero_budget.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-use crate::models::actualbudget_date::ActualbudgetDate;
-use diesel::{prelude::{Identifiable, Queryable, QueryableByName, Selectable}, sqlite::Sqlite};
-
-#[derive(Identifiable, QueryableByName, Queryable, Selectable, Clone)]
-#[diesel(table_name = crate::schema::zero_budgets)]
-#[diesel(check_for_backend(Sqlite))]
-pub struct ActualbudgetZeroBudget {
- pub id: String,
- pub month: ActualbudgetDate,
- pub category_id: String,
- pub amount: i32,
- pub do_carry_over: i32,
-}
diff --git a/backend/actualbudget_importer/src/models/mod.rs b/backend/actualbudget_importer/src/models/mod.rs
deleted file mode 100644
index 1c97c65..0000000
--- a/backend/actualbudget_importer/src/models/mod.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-pub mod actualbudget_account;
-pub mod actualbudget_category;
-pub mod actualbudget_date;
-pub mod actualbudget_transaction;
-pub mod actualbudget_zero_budget;
diff --git a/backend/actualbudget_importer/src/queries/actualbudget_accounts/get_all.rs b/backend/actualbudget_importer/src/queries/actualbudget_accounts/get_all.rs
deleted file mode 100644
index 6f667de..0000000
--- a/backend/actualbudget_importer/src/queries/actualbudget_accounts/get_all.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-use crate::{models::actualbudget_account::ActualbudgetAccount, schema::accounts::dsl::accounts};
-use diesel::{result::Error, QueryDsl, RunQueryDsl, SelectableHelper, SqliteConnection};
-
-pub fn get_all_actualbudget_accounts(connection: &mut SqliteConnection) -> Result<Vec<ActualbudgetAccount>, Error> {
- accounts.select(ActualbudgetAccount::as_select()).load(connection)
-}
diff --git a/backend/actualbudget_importer/src/queries/actualbudget_accounts/get_category_transfers_account.rs b/backend/actualbudget_importer/src/queries/actualbudget_accounts/get_category_transfers_account.rs
deleted file mode 100644
index f05dc78..0000000
--- a/backend/actualbudget_importer/src/queries/actualbudget_accounts/get_category_transfers_account.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-use diesel::{result::Error, ExpressionMethods, QueryDsl, RunQueryDsl, SelectableHelper, SqliteConnection};
-
-use crate::{models::actualbudget_account::ActualbudgetAccount, schema::accounts::{
- self as accounts_schema,
- dsl::accounts as accounts_table,
-}};
-
-pub fn get_category_transfers_account(connection: &mut SqliteConnection) -> Result<ActualbudgetAccount, Error> {
- accounts_table
- .filter(accounts_schema::name.eq("Category transfers"))
- .select(ActualbudgetAccount::as_select())
- .first(connection)
-}
diff --git a/backend/actualbudget_importer/src/queries/actualbudget_accounts/mod.rs b/backend/actualbudget_importer/src/queries/actualbudget_accounts/mod.rs
deleted file mode 100644
index c6d6015..0000000
--- a/backend/actualbudget_importer/src/queries/actualbudget_accounts/mod.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-mod get_all;
-mod get_category_transfers_account;
-
-pub use get_all::get_all_actualbudget_accounts;
-pub use get_category_transfers_account::get_category_transfers_account;
diff --git a/backend/actualbudget_importer/src/queries/actualbudget_categories/get_all.rs b/backend/actualbudget_importer/src/queries/actualbudget_categories/get_all.rs
deleted file mode 100644
index 4cb7ebc..0000000
--- a/backend/actualbudget_importer/src/queries/actualbudget_categories/get_all.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-use crate::{models::actualbudget_category::ActualbudgetCategory, schema::categories::dsl::categories};
-use diesel::{result::Error, QueryDsl, RunQueryDsl, SelectableHelper, SqliteConnection};
-
-pub fn get_all_actualbudget_categories(connection: &mut SqliteConnection) -> Result<Vec<ActualbudgetCategory>, Error> {
- categories.select(ActualbudgetCategory::as_select()).load(connection)
-}
diff --git a/backend/actualbudget_importer/src/queries/actualbudget_categories/mod.rs b/backend/actualbudget_importer/src/queries/actualbudget_categories/mod.rs
deleted file mode 100644
index 0c04e53..0000000
--- a/backend/actualbudget_importer/src/queries/actualbudget_categories/mod.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-mod get_all;
-
-pub use get_all::get_all_actualbudget_categories;
diff --git a/backend/actualbudget_importer/src/queries/actualbudget_transactions/get_all.rs b/backend/actualbudget_importer/src/queries/actualbudget_transactions/get_all.rs
deleted file mode 100644
index 84c8d08..0000000
--- a/backend/actualbudget_importer/src/queries/actualbudget_transactions/get_all.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-use crate::{models::actualbudget_transaction::ActualbudgetTransaction, schema::transactions::dsl::transactions};
-use diesel::{result::Error, QueryDsl, RunQueryDsl, SelectableHelper, SqliteConnection};
-
-pub fn get_all_actualbudget_transactions(connection: &mut SqliteConnection) -> Result<Vec<ActualbudgetTransaction>, Error> {
- transactions.select(ActualbudgetTransaction::as_select()).load(connection)
-}
diff --git a/backend/actualbudget_importer/src/queries/actualbudget_transactions/get_first_date.rs b/backend/actualbudget_importer/src/queries/actualbudget_transactions/get_first_date.rs
deleted file mode 100644
index b958c37..0000000
--- a/backend/actualbudget_importer/src/queries/actualbudget_transactions/get_first_date.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-use anyhow::Result;
-use crate::{models::actualbudget_date::ActualbudgetDate, schema::transactions::{
- self as transactions_schema,
- dsl::transactions as transactions_table,
-}};
-use diesel::{dsl::min, result::Error, QueryDsl, RunQueryDsl, SqliteConnection};
-
-pub fn get_first_actualbudget_transaction_date(connection: &mut SqliteConnection) -> Result<ActualbudgetDate> {
- let date_as_int = transactions_table
- .select(min(transactions_schema::date))
- .first::<Option<i32>>(connection)
- .map_or_else(|e| Err(e), |o| o.map_or_else(|| Err(Error::NotFound), |i| Ok(i)))?;
- Ok(ActualbudgetDate::from_i32(date_as_int))
-}
diff --git a/backend/actualbudget_importer/src/queries/actualbudget_transactions/mod.rs b/backend/actualbudget_importer/src/queries/actualbudget_transactions/mod.rs
deleted file mode 100644
index b4ed0dd..0000000
--- a/backend/actualbudget_importer/src/queries/actualbudget_transactions/mod.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-mod get_all;
-mod get_first_date;
-
-pub use get_all::get_all_actualbudget_transactions;
-pub use get_first_date::get_first_actualbudget_transaction_date;
diff --git a/backend/actualbudget_importer/src/queries/actualbudget_zero_budgets/get_all.rs b/backend/actualbudget_importer/src/queries/actualbudget_zero_budgets/get_all.rs
deleted file mode 100644
index 0c3f695..0000000
--- a/backend/actualbudget_importer/src/queries/actualbudget_zero_budgets/get_all.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-use crate::{models::actualbudget_zero_budget::ActualbudgetZeroBudget, schema::zero_budgets::dsl::zero_budgets};
-use diesel::{result::Error, QueryDsl, RunQueryDsl, SelectableHelper, SqliteConnection};
-
-pub fn get_all_actualbudget_zero_budgets(connection: &mut SqliteConnection) -> Result<Vec<ActualbudgetZeroBudget>, Error> {
- zero_budgets.select(ActualbudgetZeroBudget::as_select()).load(connection)
-}
diff --git a/backend/actualbudget_importer/src/queries/actualbudget_zero_budgets/mod.rs b/backend/actualbudget_importer/src/queries/actualbudget_zero_budgets/mod.rs
deleted file mode 100644
index ba7e21b..0000000
--- a/backend/actualbudget_importer/src/queries/actualbudget_zero_budgets/mod.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-mod get_all;
-
-pub use get_all::get_all_actualbudget_zero_budgets;
diff --git a/backend/actualbudget_importer/src/queries/mod.rs b/backend/actualbudget_importer/src/queries/mod.rs
deleted file mode 100644
index e16dafc..0000000
--- a/backend/actualbudget_importer/src/queries/mod.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-pub mod actualbudget_accounts;
-pub mod actualbudget_categories;
-pub mod actualbudget_transactions;
-pub mod actualbudget_zero_budgets;
diff --git a/backend/actualbudget_importer/src/schema.rs b/backend/actualbudget_importer/src/schema.rs
deleted file mode 100644
index a872231..0000000
--- a/backend/actualbudget_importer/src/schema.rs
+++ /dev/null
@@ -1,47 +0,0 @@
-diesel::table! {
- accounts (id) {
- id -> Text,
- name -> Text,
- }
-}
-
-diesel::table! {
- categories (id) {
- id -> Text,
- name -> Text,
- }
-}
-
-diesel::table! {
- transactions (id) {
- id -> Text,
- #[sql_name = "isParent"]
- is_parent -> Bool,
- #[sql_name = "isChild"]
- is_child -> Bool,
- #[sql_name = "acct"]
- account_id -> Text,
- #[sql_name = "category"]
- category_id -> Text,
- amount -> Integer,
- #[sql_name = "description"]
- payee -> Text,
- notes -> Text,
- date -> Integer,
- parent_id -> Nullable<Text>,
- }
-}
-
-diesel::table! {
- zero_budgets (id) {
- id -> Text,
- month -> Integer,
- #[sql_name = "category"]
- category_id -> Text,
- amount -> Integer,
- #[sql_name = "carryover"]
- do_carry_over -> Integer,
- // goal -> Integer,
- // long_goal -> Integer,
- }
-}
diff --git a/backend/actualbudget_importer/src/transformers.rs b/backend/actualbudget_importer/src/transformers.rs
deleted file mode 100644
index dd4d154..0000000
--- a/backend/actualbudget_importer/src/transformers.rs
+++ /dev/null
@@ -1,218 +0,0 @@
-use anyhow::Result;
-use budgeting_app_core::models::{
- account::Account, budget_update::BudgetUpdate, category::Category, category_transfer::CategoryTransfer, date_utc::DateUtc, datetime_utc::DatetimeUtc, transaction::Transaction, transaction_categorisation::TransactionCategorisation
-};
-use core::panic;
-use std::hash::{DefaultHasher, Hash, Hasher};
-
-use crate::models::{actualbudget_account::ActualbudgetAccount, actualbudget_category::ActualbudgetCategory, actualbudget_date::ActualbudgetDate, actualbudget_transaction::ActualbudgetTransaction, actualbudget_zero_budget::ActualbudgetZeroBudget};
-
-pub fn transform_date(actualbudget_date: &ActualbudgetDate) -> Result<DatetimeUtc> {
- actualbudget_date.to_iso().parse()
-}
-
-pub fn transform_accounts(
- actualbudget_accounts: &[ActualbudgetAccount],
- first_transaction_date: &DatetimeUtc,
-) -> Vec<Account> {
- let mut accounts = Vec::<Account>::new();
- for account in actualbudget_accounts {
- accounts.push(transform_account(account, first_transaction_date));
- }
- accounts
-}
-
-fn transform_account(
- actualbudget_account: &ActualbudgetAccount,
- opening_date: &DatetimeUtc,
-) -> Account {
- Account {
- id: transform_id(&actualbudget_account.id.clone()),
- name: actualbudget_account.name.clone(),
- opening_balance: 0,
- opening_date: opening_date.clone(),
- }
-}
-
-pub fn transform_categories(
- actualbudget_categories: &[ActualbudgetCategory],
-) -> Vec<Category> {
- let mut categories = Vec::<Category>::new();
- for actualbudget_category in actualbudget_categories {
- categories.push(Category {
- id: transform_id(&actualbudget_category.id.clone()),
- name: actualbudget_category.name.clone(),
- })
- }
- categories
-}
-
-fn transform_id(actualbudget_id: &str) -> i32 {
- let mut hasher = DefaultHasher::new();
- actualbudget_id.hash(&mut hasher);
- (hasher.finish() % std::convert::TryInto::<u64>::try_into(i32::MAX).unwrap())
- .try_into()
- .unwrap()
-}
-
-pub fn transform_budget_updates(
- actualbudget_zero_budgets: &[ActualbudgetZeroBudget],
-) -> Result<Vec<BudgetUpdate>> {
- let mut budget_updates = Vec::<BudgetUpdate>::new();
- for zero_budget in actualbudget_zero_budgets {
- let first_zero_budget_in_category = get_first_zero_budget_in_category(
- actualbudget_zero_budgets,
- &zero_budget.category_id.clone(),
- );
- if first_zero_budget_in_category.is_some_and(|zb| zb.id == zero_budget.id) {
- continue;
- }
- budget_updates.push(BudgetUpdate {
- id: transform_id(&zero_budget.id.clone()),
- category_id: transform_id(&zero_budget.category_id.clone()),
- date: DateUtc::from(transform_date(&zero_budget.month.clone())?),
- new_budget: zero_budget.amount.try_into().unwrap(),
- new_period: 30,
- })
- }
- Ok(budget_updates)
-}
-
-fn get_first_zero_budget_in_category(
- actualbudget_zero_budgets: &[ActualbudgetZeroBudget],
- actualbudget_category_id: &str,
-) -> Option<ActualbudgetZeroBudget> {
- let mut category_zero_budgets = actualbudget_zero_budgets.to_vec();
- category_zero_budgets.retain(|zb| zb.category_id == actualbudget_category_id);
- category_zero_budgets
- .iter()
- .min_by_key(|zb| zb.month.clone())
- .cloned()
-}
-
-pub fn transform_transactions(
- actualbudget_transactions: &[ActualbudgetTransaction],
- actualbudget_category_transfers_account: &ActualbudgetAccount,
-) -> Result<(Vec<Transaction>, Vec<TransactionCategorisation>)> {
- let mut transactions = Vec::<Transaction>::new();
- let mut transaction_categorisations = Vec::<TransactionCategorisation>::new();
-
- let mut actualbudget_transactions = actualbudget_transactions.to_vec();
- actualbudget_transactions
- .retain(|t| t.category_id.clone() != actualbudget_category_transfers_account.id.clone());
- let mut parent_actualbudget_transactions = actualbudget_transactions.to_vec();
- parent_actualbudget_transactions.retain(|t| t.is_parent);
- let mut child_actualbudget_transactions = actualbudget_transactions.to_vec();
- child_actualbudget_transactions.retain(|t| t.is_child);
- let mut atomic_actualbudget_transactions = actualbudget_transactions.to_vec();
- atomic_actualbudget_transactions.retain(|t| !t.is_parent && !t.is_child);
-
- for atomic_actualbudget_transaction in atomic_actualbudget_transactions {
- let transaction_id = transform_id(&atomic_actualbudget_transaction.id);
-
- transactions.push(Transaction {
- id: transaction_id,
- description: atomic_actualbudget_transaction.notes,
- payee: atomic_actualbudget_transaction.payee,
- quantity: atomic_actualbudget_transaction.amount.try_into().unwrap(),
- date: transform_date(&atomic_actualbudget_transaction.date)?,
- account_id: transform_id(&atomic_actualbudget_transaction.account_id),
- });
-
- transaction_categorisations.push(TransactionCategorisation {
- id: transaction_id,
- description: String::new(),
- quantity: atomic_actualbudget_transaction.amount.try_into().unwrap(),
- transaction_id,
- category_id: transform_id(&atomic_actualbudget_transaction.category_id),
- });
- }
-
- for parent_actualbudget_transaction in parent_actualbudget_transactions {
- let mut child_actualbudget_transactions = child_actualbudget_transactions.to_vec();
- child_actualbudget_transactions.retain(|t| {
- t.parent_id
- .clone()
- .is_some_and(|parent_id| parent_id == parent_actualbudget_transaction.id.clone())
- });
-
- let transaction_id = transform_id(&parent_actualbudget_transaction.id);
-
- transactions.push(Transaction {
- id: transaction_id,
- description: parent_actualbudget_transaction.notes,
- payee: parent_actualbudget_transaction.payee,
- quantity: parent_actualbudget_transaction.amount.try_into().unwrap(),
- date: transform_date(&parent_actualbudget_transaction.date)?,
- account_id: transform_id(&parent_actualbudget_transaction.account_id),
- });
-
- for child_actualbudget_transaction in child_actualbudget_transactions {
- transaction_categorisations.push(TransactionCategorisation {
- id: transform_id(&child_actualbudget_transaction.id),
- description: child_actualbudget_transaction.notes,
- quantity: child_actualbudget_transaction.amount.try_into().unwrap(),
- transaction_id,
- category_id: transform_id(&child_actualbudget_transaction.category_id),
- });
- }
- }
-
- Ok((transactions, transaction_categorisations))
-}
-
-pub fn transform_category_transfers(
- actualbudget_transactions: &[ActualbudgetTransaction],
- actualbudget_category_transfers_account: &ActualbudgetAccount,
-) -> Vec<CategoryTransfer> {
- let mut category_transfers = Vec::<CategoryTransfer>::new();
-
- let mut actualbudget_category_transfers = actualbudget_transactions.to_vec();
- actualbudget_category_transfers
- .retain(|t| t.category_id.clone() == actualbudget_category_transfers_account.id.clone());
- let mut actualbudget_parent_category_transfers = actualbudget_category_transfers.to_vec();
- actualbudget_parent_category_transfers.retain(|t| t.is_parent);
- let mut actualbudget_child_category_transfers = actualbudget_category_transfers.to_vec();
- actualbudget_child_category_transfers.retain(|t| t.is_child);
-
- for actualbudget_parent_category_transfer in actualbudget_parent_category_transfers {
- let mut actualbudget_child_category_transfers =
- actualbudget_child_category_transfers.to_vec();
- actualbudget_child_category_transfers.retain(|t| {
- t.parent_id
- .clone()
- .is_some_and(|parent_id| parent_id == actualbudget_parent_category_transfer.id)
- });
-
- if actualbudget_child_category_transfers.len() != 2 {
- panic!("Category transfers should always have exactly two children.");
- }
-
- let category_1 = actualbudget_child_category_transfers[0].clone();
- let category_2 = actualbudget_child_category_transfers[1].clone();
-
- // To avoid duplicates
- if category_1.amount >= 0 {
- continue;
- }
-
- if actualbudget_child_category_transfers[0].amount
- != -actualbudget_child_category_transfers[1].amount
- {
- panic!("Category transfer children should sum to zero.");
- }
-
- category_transfers.push(CategoryTransfer {
- id: transform_id(&actualbudget_parent_category_transfer.id),
- description: actualbudget_parent_category_transfer.notes,
- quantity: actualbudget_child_category_transfers[0]
- .amount
- .try_into()
- .unwrap(),
- from_category_id: transform_id(&category_1.id),
- to_category_id: transform_id(&category_2.id),
- });
- }
-
- category_transfers
-}