diff --git a/src/db.rs b/src/db.rs index c51a1dc..908c027 100644 --- a/src/db.rs +++ b/src/db.rs @@ -23,8 +23,9 @@ use sqlx::sqlite::SqliteRow; use sqlx::{Connection, Row, SqliteConnection}; use crate::account_config::AccountConfiguration; -use crate::statements::StatementLine; -use crate::transaction::{Posting, Transaction, TransactionWithPostings}; +use crate::model::assertions::BalanceAssertion; +use crate::model::statements::StatementLine; +use crate::model::transaction::{Posting, Transaction, TransactionWithPostings}; use crate::{util::format_date, QuantityInt}; pub struct DbConnection { @@ -86,6 +87,31 @@ impl DbConnection { account_configurations } + /// Get balance assertions from the database + pub async fn get_balance_assertions(&self) -> Vec { + let mut connection = self.connect().await; + + let balance_assertions = sqlx::query( + "SELECT id, dt, description, account, quantity, commodity + FROM balance_assertions + ORDER BY dt DESC, id DESC", + ) + .map(|r: SqliteRow| BalanceAssertion { + id: r.get("id"), + dt: NaiveDateTime::parse_from_str(r.get("dt"), "%Y-%m-%d %H:%M:%S.%6f") + .expect("Invalid balance_assertions.dt"), + description: r.get("description"), + account: r.get("account"), + quantity: r.get("quantity"), + commodity: r.get("commodity"), + }) + .fetch_all(&mut connection) + .await + .expect("SQL error"); + + balance_assertions + } + /// Get account balances from the database pub async fn get_balances(&self, date: NaiveDate) -> HashMap { let mut connection = self.connect().await; diff --git a/src/lib.rs b/src/lib.rs index 3a658cd..4cdbcc4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,8 @@ pub mod account_config; pub mod db; +pub mod model; pub mod reporting; -pub mod transaction; pub mod serde; -pub mod statements; pub mod util; pub type QuantityInt = i64; diff --git a/src/model/assertions.rs b/src/model/assertions.rs new file mode 100644 index 0000000..59e8eb4 --- /dev/null +++ b/src/model/assertions.rs @@ -0,0 +1,33 @@ +/* + DrCr: Web-based double-entry bookkeeping framework + Copyright (C) 2022-2025 Lee Yingtong Li (RunasSudo) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +use chrono::NaiveDateTime; +use serde::{Deserialize, Serialize}; + +use crate::QuantityInt; + +#[derive(Deserialize, Serialize)] +pub struct BalanceAssertion { + pub id: Option, + #[serde(with = "crate::serde::naivedatetime_to_js")] + pub dt: NaiveDateTime, + pub description: String, + pub account: String, + pub quantity: QuantityInt, + pub commodity: String, +} diff --git a/src/model/mod.rs b/src/model/mod.rs new file mode 100644 index 0000000..fc27c3d --- /dev/null +++ b/src/model/mod.rs @@ -0,0 +1,21 @@ +/* + DrCr: Web-based double-entry bookkeeping framework + Copyright (C) 2022-2025 Lee Yingtong Li (RunasSudo) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +pub mod assertions; +pub mod statements; +pub mod transaction; diff --git a/src/statements.rs b/src/model/statements.rs similarity index 100% rename from src/statements.rs rename to src/model/statements.rs diff --git a/src/transaction.rs b/src/model/transaction.rs similarity index 100% rename from src/transaction.rs rename to src/model/transaction.rs diff --git a/src/reporting/builders.rs b/src/reporting/builders.rs index b5ced36..6620e62 100644 --- a/src/reporting/builders.rs +++ b/src/reporting/builders.rs @@ -26,7 +26,7 @@ use std::fmt::Display; use async_trait::async_trait; use tokio::sync::RwLock; -use crate::transaction::update_balances_from_transactions; +use crate::model::transaction::update_balances_from_transactions; use super::calculator::{has_step_or_can_build, HasStepOrCanBuild, ReportingGraphDependencies}; use super::executor::ReportingExecutionError; diff --git a/src/reporting/steps.rs b/src/reporting/steps.rs index c28a70f..bfd76f0 100644 --- a/src/reporting/steps.rs +++ b/src/reporting/steps.rs @@ -26,10 +26,10 @@ use chrono::Datelike; use tokio::sync::RwLock; use crate::account_config::kinds_for_account; -use crate::reporting::types::{BalancesAt, DateStartDateEndArgs, ReportingProductId, Transactions}; -use crate::transaction::{ +use crate::model::transaction::{ update_balances_from_transactions, Posting, Transaction, TransactionWithPostings, }; +use crate::reporting::types::{BalancesAt, DateStartDateEndArgs, ReportingProductId, Transactions}; use crate::util::{get_eofy, sofy_from_eofy}; use crate::QuantityInt; diff --git a/src/reporting/types.rs b/src/reporting/types.rs index 06d648e..13891c2 100644 --- a/src/reporting/types.rs +++ b/src/reporting/types.rs @@ -31,7 +31,7 @@ use serde::{Deserialize, Serialize}; use tokio::sync::RwLock; use crate::db::DbConnection; -use crate::transaction::TransactionWithPostings; +use crate::model::transaction::TransactionWithPostings; use crate::QuantityInt; use super::calculator::ReportingGraphDependencies; @@ -173,13 +173,6 @@ pub struct Transactions { pub transactions: Vec, } -impl Transactions { - /// Serialise the product (as JSON) using serde - pub fn to_json(&self) -> String { - serde_json::to_string(&self.transactions).unwrap() - } -} - impl ReportingProduct for Transactions {} /// Records cumulative account balances at a particular point in time