From ffef2d16dccd9b06ee403368f212f51836f8ba36 Mon Sep 17 00:00:00 2001 From: RunasSudo Date: Wed, 28 May 2025 00:16:09 +1000 Subject: [PATCH] Balance assertions view using libdrcr --- src-tauri/src/lib.rs | 1 + src-tauri/src/libdrcr_bridge.rs | 90 ++++++++++++++++++++++++++++- src/pages/BalanceAssertionsView.vue | 51 +++------------- 3 files changed, 99 insertions(+), 43 deletions(-) diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 4033df5..08187c0 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -94,6 +94,7 @@ pub fn run() { libdrcr_bridge::get_balance_sheet, libdrcr_bridge::get_income_statement, libdrcr_bridge::get_trial_balance, + libdrcr_bridge::get_validated_balance_assertions, sql::sql_transaction_begin, sql::sql_transaction_execute, sql::sql_transaction_select, diff --git a/src-tauri/src/libdrcr_bridge.rs b/src-tauri/src/libdrcr_bridge.rs index 4087ed2..71d4553 100644 --- a/src-tauri/src/libdrcr_bridge.rs +++ b/src-tauri/src/libdrcr_bridge.rs @@ -16,19 +16,22 @@ along with this program. If not, see . */ +use std::collections::HashSet; use std::sync::Arc; use chrono::NaiveDate; use libdrcr::db::DbConnection; +use libdrcr::model::assertions::BalanceAssertion; use libdrcr::reporting::builders::register_dynamic_builders; use libdrcr::reporting::dynamic_report::DynamicReport; use libdrcr::reporting::generate_report; use libdrcr::reporting::steps::register_lookup_fns; use libdrcr::reporting::types::{ - DateArgs, DateStartDateEndArgs, MultipleDateArgs, MultipleDateStartDateEndArgs, + BalancesAt, DateArgs, DateStartDateEndArgs, MultipleDateArgs, MultipleDateStartDateEndArgs, ReportingContext, ReportingProduct, ReportingProductId, ReportingProductKind, Transactions, VoidArgs, }; +use serde::{Deserialize, Serialize}; use tauri::State; use tokio::sync::Mutex; @@ -163,3 +166,88 @@ pub(crate) async fn get_trial_balance( .unwrap() .to_json()) } + +#[derive(Deserialize, Serialize)] +struct ValidatedBalanceAssertion { + #[serde(flatten)] + assertion: BalanceAssertion, + is_valid: bool, +} + +#[tauri::command] +pub(crate) async fn get_validated_balance_assertions( + state: State<'_, Mutex>, +) -> Result { + let state = state.lock().await; + let db_filename = state.db_filename.clone().unwrap(); + + // Connect to database + let db_connection = + DbConnection::new(format!("sqlite:{}", db_filename.as_str()).as_str()).await; + + let reporting_commodity = db_connection.metadata().reporting_commodity.clone(); // Needed later + + // First get balance assertions from database + let balance_assertions = db_connection.get_balance_assertions().await; + + // Get dates of balance assertions + let dates = balance_assertions + .iter() + .map(|b| b.dt) + .collect::>(); + + // Initialise ReportingContext + let eofy_date = db_connection.metadata().eofy_date; + let mut context = ReportingContext::new(db_connection, eofy_date, "$".to_string()); + register_lookup_fns(&mut context); + register_dynamic_builders(&mut context); + + // Get report targets + let mut targets = vec![ReportingProductId { + name: "CalculateIncomeTax", + kind: ReportingProductKind::Transactions, + args: Box::new(VoidArgs {}), + }]; + for dt in dates { + // Request ordinary transaction balances at each balance assertion date + targets.push(ReportingProductId { + name: "CombineOrdinaryTransactions", + kind: ReportingProductKind::BalancesAt, + args: Box::new(DateArgs { date: dt.date() }), + }); + } + + // Run report + let products = generate_report(targets, Arc::new(context)).await.unwrap(); + + // Validate each balance assertion + let mut validated_assertions = Vec::new(); + for balance_assertion in balance_assertions { + let balances_at_date = products + .get_or_err(&ReportingProductId { + name: "CombineOrdinaryTransactions", + kind: ReportingProductKind::BalancesAt, + args: Box::new(DateArgs { + date: balance_assertion.dt.date(), + }), + }) + .unwrap() + .downcast_ref::() + .unwrap(); + + let account_balance = *balances_at_date + .balances + .get(&balance_assertion.account) + .unwrap_or(&0); + + let is_valid = balance_assertion.quantity == account_balance + && balance_assertion.commodity == reporting_commodity; + + validated_assertions.push(ValidatedBalanceAssertion { + assertion: balance_assertion, + is_valid, + }); + } + + Ok(serde_json::to_string(&validated_assertions).unwrap()) +} diff --git a/src/pages/BalanceAssertionsView.vue b/src/pages/BalanceAssertionsView.vue index 793f5aa..8127b4c 100644 --- a/src/pages/BalanceAssertionsView.vue +++ b/src/pages/BalanceAssertionsView.vue @@ -1,6 +1,6 @@