From 023d1035c5c785bb84c94281d37ec3a6efedc705 Mon Sep 17 00:00:00 2001 From: RunasSudo Date: Mon, 2 Jun 2025 17:39:10 +1000 Subject: [PATCH] austax: Reorganise code structure --- libdrcr/plugins/austax/calc.luau | 46 ++++++++++++++++ libdrcr/plugins/austax/plugin.luau | 28 ++++++++++ .../austax/{austax.luau => reporting.luau} | 54 +++++-------------- libdrcr/src/main.rs | 2 +- src-tauri/src/libdrcr_bridge.rs | 2 +- 5 files changed, 88 insertions(+), 44 deletions(-) create mode 100644 libdrcr/plugins/austax/calc.luau create mode 100644 libdrcr/plugins/austax/plugin.luau rename libdrcr/plugins/austax/{austax.luau => reporting.luau} (86%) diff --git a/libdrcr/plugins/austax/calc.luau b/libdrcr/plugins/austax/calc.luau new file mode 100644 index 0000000..672d8a6 --- /dev/null +++ b/libdrcr/plugins/austax/calc.luau @@ -0,0 +1,46 @@ +--!strict +-- 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 . + +local libdrcr = require('../libdrcr') +local tax_tables = require('../austax/tax_tables') + +local calc = {} + +function calc.base_income_tax(net_taxable: number, context: libdrcr.ReportingContext): number + local year, _, _ = libdrcr.parse_date(context.eofy_date) + local base_tax_table = tax_tables.base_tax[year] + + for i, row in ipairs(base_tax_table) do + local upper_limit = row[1] * (10 ^ context.dps) + local flat_amount = row[2] * (10 ^ context.dps) + local marginal_rate = row[3] + + -- Lower limit is the upper limit of the preceding bracket + local lower_limit = 0 + if i > 1 then + lower_limit = base_tax_table[i - 1][1] * (10 ^ context.dps) + end + + if net_taxable <= upper_limit then + return flat_amount + marginal_rate * (net_taxable - lower_limit) + end + end + + error('Taxable income not within any tax bracket') +end + +return calc diff --git a/libdrcr/plugins/austax/plugin.luau b/libdrcr/plugins/austax/plugin.luau new file mode 100644 index 0000000..9283d45 --- /dev/null +++ b/libdrcr/plugins/austax/plugin.luau @@ -0,0 +1,28 @@ +--!strict +-- 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 . + +local libdrcr = require('../libdrcr') +local reporting = require('../austax/reporting') + +local plugin: libdrcr.Plugin = { + name = 'austax', + reporting_steps = { + reporting.CalculateIncomeTax + }, +} + +return plugin diff --git a/libdrcr/plugins/austax/austax.luau b/libdrcr/plugins/austax/reporting.luau similarity index 86% rename from libdrcr/plugins/austax/austax.luau rename to libdrcr/plugins/austax/reporting.luau index e7bfc83..baf06ba 100644 --- a/libdrcr/plugins/austax/austax.luau +++ b/libdrcr/plugins/austax/reporting.luau @@ -16,34 +16,17 @@ -- along with this program. If not, see . local libdrcr = require('../libdrcr') - local account_kinds = require('../austax/account_kinds') -local tax_tables = require('../austax/tax_tables') +local calc = require('../austax/calc') -function get_base_income_tax(net_taxable: number, context: libdrcr.ReportingContext): number - local year, _, _ = libdrcr.parse_date(context.eofy_date) - local base_tax_table = tax_tables.base_tax[year] - - for i, row in ipairs(base_tax_table) do - local upper_limit = row[1] * (10 ^ context.dps) - local flat_amount = row[2] * (10 ^ context.dps) - local marginal_rate = row[3] - - -- Lower limit is the upper limit of the preceding bracket - local lower_limit = 0 - if i > 1 then - lower_limit = base_tax_table[i - 1][1] * (10 ^ context.dps) - end - - if net_taxable <= upper_limit then - return flat_amount + marginal_rate * (net_taxable - lower_limit) - end - end - - error('Taxable income not within any tax bracket') -end +local reporting = {} -function requires(args, context) +reporting.CalculateIncomeTax = { + name = 'CalculateIncomeTax', + product_kinds = {'DynamicReport', 'Transactions'}, +} :: libdrcr.ReportingStep + +function reporting.CalculateIncomeTax.requires(args, context) return { { name = 'CombineOrdinaryTransactions', @@ -53,7 +36,7 @@ function requires(args, context) } end -function after_init_graph(args, steps, add_dependency, context) +function reporting.CalculateIncomeTax.after_init_graph(args, steps, add_dependency, context) for _, other in ipairs(steps) do if other.name == 'AllTransactionsExceptEarningsToEquity' then -- AllTransactionsExceptEarningsToEquity depends on CalculateIncomeTax @@ -75,7 +58,7 @@ function after_init_graph(args, steps, add_dependency, context) end end -function execute(args, context, kinds_for_account, get_product) +function reporting.CalculateIncomeTax.execute(args, context, kinds_for_account, get_product) -- Get balances for current year local product = get_product({ name = 'CombineOrdinaryTransactions', @@ -208,7 +191,7 @@ function execute(args, context, kinds_for_account, get_product) table.insert(report.entries, 'Spacer') -- Base income tax row - local tax_base = get_base_income_tax(net_taxable, context) + local tax_base = calc.base_income_tax(net_taxable, context) table.insert(report.entries, { Row = { text = 'Base income tax', quantity = {tax_base}, @@ -338,17 +321,4 @@ function entries_subtotal(entries: {libdrcr.DynamicReportEntry}): number return subtotal end -local plugin: libdrcr.Plugin = { - name = 'austax', - reporting_steps = { - { - name = 'CalculateIncomeTax', - product_kinds = {'DynamicReport', 'Transactions'}, - requires = requires, - after_init_graph = after_init_graph, - execute = execute, - } - }, -} - -return plugin +return reporting diff --git a/libdrcr/src/main.rs b/libdrcr/src/main.rs index 7c3fb64..86a420e 100644 --- a/libdrcr/src/main.rs +++ b/libdrcr/src/main.rs @@ -39,7 +39,7 @@ async fn main() { let mut context = ReportingContext::new( db_connection, "plugins".to_string(), - vec!["austax.austax".to_string()], + vec!["austax.plugin".to_string()], NaiveDate::from_ymd_opt(2025, 6, 30).unwrap(), "$".to_string(), ); diff --git a/src-tauri/src/libdrcr_bridge.rs b/src-tauri/src/libdrcr_bridge.rs index 0165748..c3adfb1 100644 --- a/src-tauri/src/libdrcr_bridge.rs +++ b/src-tauri/src/libdrcr_bridge.rs @@ -44,7 +44,7 @@ fn prepare_reporting_context(context: &mut ReportingContext) { fn get_plugins() -> Vec { // FIXME: Dynamically get this - vec!["austax.austax".to_string()] + vec!["austax.plugin".to_string()] } pub(crate) async fn get_report(