libdrcr: Allow configuring backend plugins

This commit is contained in:
RunasSudo 2025-06-09 19:53:06 +10:00
parent 94255ffb9d
commit 02667695cc
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
5 changed files with 49 additions and 26 deletions

View File

@ -1,5 +1,5 @@
--!strict
-- DrCr: Web-based double-entry bookkeeping framework
-- DrCr: Double-entry bookkeeping framework
-- Copyright (C) 2022-2025 Lee Yingtong Li (RunasSudo)
--
-- This program is free software: you can redistribute it and/or modify
@ -15,8 +15,8 @@
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <https://www.gnu.org/licenses/>.
local libdrcr = require('../libdrcr')
local reporting = require('../austax/reporting')
local libdrcr = require('./libdrcr')
local reporting = require('./austax/reporting')
local plugin: libdrcr.Plugin = {
name = 'austax',

View File

@ -1,5 +1,5 @@
/*
DrCr: Web-based double-entry bookkeeping framework
DrCr: Double-entry bookkeeping framework
Copyright (C) 2022-2025 Lee Yingtong Li (RunasSudo)
This program is free software: you can redistribute it and/or modify
@ -216,6 +216,7 @@ pub struct DbMetadata {
pub eofy_date: NaiveDate,
pub reporting_commodity: String,
pub dps: u32,
pub plugins: Vec<String>,
}
impl DbMetadata {
@ -256,11 +257,27 @@ impl DbMetadata {
.await
.expect("SQL error");
let plugins_joined = sqlx::query("SELECT value FROM metadata WHERE key = 'plugins'")
.map(|r: SqliteRow| r.get::<String, _>(0))
.fetch_one(&mut *connection)
.await
.expect("SQL error");
let plugins = if plugins_joined.len() > 0 {
plugins_joined
.split(';')
.map(String::from)
.collect::<Vec<_>>()
} else {
vec![]
};
DbMetadata {
version,
eofy_date,
reporting_commodity,
dps,
plugins,
}
}
}

View File

@ -39,7 +39,7 @@ async fn main() {
let mut context = ReportingContext::new(
db_connection,
"plugins".to_string(),
vec!["austax.plugin".to_string()],
vec!["austax".to_string()],
NaiveDate::from_ymd_opt(2025, 6, 30).unwrap(),
"$".to_string(),
);

View File

@ -1,5 +1,5 @@
/*
DrCr: Web-based double-entry bookkeeping framework
DrCr: Double-entry bookkeeping framework
Copyright (C) 2022-2025 Lee Yingtong Li (RunasSudo)
This program is free software: you can redistribute it and/or modify
@ -41,7 +41,7 @@ fn load_plugin(plugin_dir: &str, plugin_name: &str) -> (Lua, Plugin) {
// Init Lua environment
let package = lua.globals().get::<Table>("package").unwrap();
package
.set("path", format!("{}/?.luau", plugin_dir))
.set("path", format!("{0}/?.luau;{0}/?/init.luau", plugin_dir))
.unwrap();
// Require and call the plugin

View File

@ -1,5 +1,5 @@
/*
DrCr: Web-based double-entry bookkeeping framework
DrCr: Double-entry bookkeeping framework
Copyright (C) 2022-2025 Lee Yingtong Li (RunasSudo)
This program is free software: you can redistribute it and/or modify
@ -42,11 +42,6 @@ fn prepare_reporting_context(context: &mut ReportingContext) {
libdrcr::plugin::register_lookup_fns(context);
}
fn get_plugins() -> Vec<String> {
// FIXME: Dynamically get this
vec!["austax.plugin".to_string()]
}
pub(crate) async fn get_report(
app: AppHandle,
state: State<'_, Mutex<AppState>>,
@ -61,6 +56,7 @@ pub(crate) async fn get_report(
// Initialise ReportingContext
let eofy_date = db_connection.metadata().eofy_date;
let plugin_names = db_connection.metadata().plugins.clone();
let mut context = ReportingContext::new(
db_connection,
app.path()
@ -69,22 +65,25 @@ pub(crate) async fn get_report(
.to_str()
.unwrap()
.to_string(),
get_plugins(),
plugin_names,
eofy_date,
"$".to_string(),
);
prepare_reporting_context(&mut context);
// Get dynamic report
let targets = vec![
// FIXME: Make this configurable
ReportingProductId {
let mut targets = vec![target.clone()];
// Add plugin targets
// FIXME: Detect this robustly
if context.plugin_names.contains(&"austax".to_string()) {
targets.push(ReportingProductId {
name: "CalculateIncomeTax".to_string(),
kind: ReportingProductKind::Transactions,
args: ReportingStepArgs::VoidArgs,
},
target.clone(),
];
});
}
let products = generate_report(targets, Arc::new(context)).await.unwrap();
let result = products.get_owned_or_err(&target).unwrap();
@ -262,6 +261,7 @@ pub(crate) async fn get_validated_balance_assertions(
// Initialise ReportingContext
let eofy_date = db_connection.metadata().eofy_date;
let plugin_names = db_connection.metadata().plugins.clone();
let mut context = ReportingContext::new(
db_connection,
app.path()
@ -270,18 +270,14 @@ pub(crate) async fn get_validated_balance_assertions(
.to_str()
.unwrap()
.to_string(),
get_plugins(),
plugin_names,
eofy_date,
"$".to_string(),
);
prepare_reporting_context(&mut context);
// Get report targets
let mut targets = vec![ReportingProductId {
name: "CalculateIncomeTax".to_string(),
kind: ReportingProductKind::Transactions,
args: ReportingStepArgs::VoidArgs,
}];
let mut targets = Vec::new();
for dt in dates {
// Request ordinary transaction balances at each balance assertion date
targets.push(ReportingProductId {
@ -291,6 +287,16 @@ pub(crate) async fn get_validated_balance_assertions(
});
}
// Add plugin targets
// FIXME: Detect this robustly
if context.plugin_names.contains(&"austax".to_string()) {
targets.push(ReportingProductId {
name: "CalculateIncomeTax".to_string(),
kind: ReportingProductKind::Transactions,
args: ReportingStepArgs::VoidArgs,
});
}
// Run report
let products = generate_report(targets, Arc::new(context)).await.unwrap();