Compare commits
5 Commits
f97420b055
...
29c5e906dd
Author | SHA1 | Date | |
---|---|---|---|
29c5e906dd | |||
94255ffb9d | |||
81bce8e677 | |||
01cdab9ed3 | |||
1fe1aec828 |
162
docs/demo.sql
Normal file
162
docs/demo.sql
Normal file
@ -0,0 +1,162 @@
|
||||
PRAGMA foreign_keys=OFF;
|
||||
BEGIN TRANSACTION;
|
||||
CREATE TABLE account_configurations (
|
||||
id INTEGER NOT NULL,
|
||||
account VARCHAR,
|
||||
kind VARCHAR,
|
||||
data JSON,
|
||||
PRIMARY KEY(id)
|
||||
);
|
||||
INSERT INTO account_configurations VALUES(1,'Business Loan','drcr.liability',NULL);
|
||||
INSERT INTO account_configurations VALUES(2,'Cash at Bank','drcr.asset',NULL);
|
||||
INSERT INTO account_configurations VALUES(3,'Cash on Hand','drcr.asset',NULL);
|
||||
INSERT INTO account_configurations VALUES(4,'Cost of Goods Sold','drcr.expense',NULL);
|
||||
INSERT INTO account_configurations VALUES(5,'Depreciation','drcr.expense',NULL);
|
||||
INSERT INTO account_configurations VALUES(6,'Forex Gains','drcr.income',NULL);
|
||||
INSERT INTO account_configurations VALUES(7,'Interest','drcr.expense',NULL);
|
||||
INSERT INTO account_configurations VALUES(8,'International Account','drcr.asset',NULL);
|
||||
INSERT INTO account_configurations VALUES(9,'Inventory','drcr.asset',NULL);
|
||||
INSERT INTO account_configurations VALUES(10,'Opening Balances','drcr.equity',NULL);
|
||||
INSERT INTO account_configurations VALUES(11,'Plant','drcr.asset',NULL);
|
||||
INSERT INTO account_configurations VALUES(12,'Plant:Less Accumulated Depreciation','drcr.asset',NULL);
|
||||
INSERT INTO account_configurations VALUES(13,'Sales','drcr.income',NULL);
|
||||
CREATE TABLE balance_assertions (
|
||||
id INTEGER NOT NULL,
|
||||
dt DATETIME,
|
||||
description VARCHAR,
|
||||
account VARCHAR,
|
||||
quantity INTEGER,
|
||||
commodity VARCHAR,
|
||||
PRIMARY KEY(id)
|
||||
);
|
||||
CREATE TABLE metadata (
|
||||
id INTEGER NOT NULL,
|
||||
key VARCHAR,
|
||||
value VARCHAR,
|
||||
PRIMARY KEY(id)
|
||||
);
|
||||
INSERT INTO metadata VALUES(1,'version','3');
|
||||
INSERT INTO metadata VALUES(2,'eofy_date','2025-06-30');
|
||||
INSERT INTO metadata VALUES(3,'reporting_commodity','$');
|
||||
INSERT INTO metadata VALUES(4,'amount_dps','2');
|
||||
INSERT INTO metadata VALUES(5,'plugins','');
|
||||
CREATE TABLE postings (
|
||||
id INTEGER NOT NULL,
|
||||
transaction_id INTEGER,
|
||||
description VARCHAR,
|
||||
account VARCHAR,
|
||||
quantity INTEGER,
|
||||
commodity VARCHAR,
|
||||
PRIMARY KEY(id),
|
||||
FOREIGN KEY(transaction_id) REFERENCES transactions(id)
|
||||
);
|
||||
INSERT INTO postings VALUES(1,1,NULL,'Cash at Bank',100000,'$');
|
||||
INSERT INTO postings VALUES(2,1,NULL,'Opening Balances',-100000,'$');
|
||||
INSERT INTO postings VALUES(3,2,NULL,'Cash on Hand',5000,'$');
|
||||
INSERT INTO postings VALUES(4,2,NULL,'Opening Balances',-5000,'$');
|
||||
INSERT INTO postings VALUES(5,3,NULL,'Inventory',10000,'Widgets {5.00}');
|
||||
INSERT INTO postings VALUES(6,3,NULL,'Opening Balances',-10000,'Widgets {5.00}');
|
||||
INSERT INTO postings VALUES(7,4,NULL,'Plant',500000,'$');
|
||||
INSERT INTO postings VALUES(8,4,NULL,'Opening Balances',-500000,'$');
|
||||
INSERT INTO postings VALUES(9,5,NULL,'Cash at Bank',50000,'$');
|
||||
INSERT INTO postings VALUES(10,5,NULL,'Business Loan',-50000,'$');
|
||||
INSERT INTO postings VALUES(11,6,NULL,'International Account',10000,'EUR {1.75}');
|
||||
INSERT INTO postings VALUES(12,6,NULL,'Cash at Bank',-17500,'$');
|
||||
INSERT INTO postings VALUES(13,7,NULL,'Inventory',5000,'Widgets {7.00}');
|
||||
INSERT INTO postings VALUES(14,7,NULL,'Cash at Bank',-35000,'$');
|
||||
INSERT INTO postings VALUES(15,8,NULL,'Cash at Bank',10000,'$');
|
||||
INSERT INTO postings VALUES(16,8,NULL,'Sales',-10000,'$');
|
||||
INSERT INTO postings VALUES(17,9,NULL,'Cost of Goods Sold',5000,'$');
|
||||
INSERT INTO postings VALUES(18,9,NULL,'Inventory',-1000,'Widgets {5.00}');
|
||||
INSERT INTO postings VALUES(19,10,NULL,'International Account',10000,'EUR {1.70}');
|
||||
INSERT INTO postings VALUES(20,10,NULL,'Cash at Bank',-17000,'$');
|
||||
INSERT INTO postings VALUES(21,11,NULL,'Cash at Bank',9000,'$');
|
||||
INSERT INTO postings VALUES(22,11,NULL,'International Account',-5000,'EUR {1.75}');
|
||||
INSERT INTO postings VALUES(23,11,NULL,'Forex Gains',-250,'$');
|
||||
INSERT INTO postings VALUES(24,12,NULL,'Interest',10000,'$');
|
||||
INSERT INTO postings VALUES(25,12,NULL,'Business Loan',-10000,'$');
|
||||
INSERT INTO postings VALUES(26,13,NULL,'Depreciation',50000,'$');
|
||||
INSERT INTO postings VALUES(27,13,NULL,'Plant:Less Accumulated Depreciation',-50000,'$');
|
||||
CREATE TABLE statement_line_reconciliations (
|
||||
id INTEGER NOT NULL,
|
||||
statement_line_id INTEGER,
|
||||
posting_id INTEGER,
|
||||
PRIMARY KEY(id),
|
||||
FOREIGN KEY(statement_line_id) REFERENCES statement_lines(id),
|
||||
FOREIGN KEY(posting_id) REFERENCES postings(id)
|
||||
);
|
||||
CREATE TABLE statement_lines (
|
||||
id INTEGER NOT NULL,
|
||||
source_account VARCHAR,
|
||||
dt DATETIME,
|
||||
description VARCHAR,
|
||||
quantity INTEGER,
|
||||
balance INTEGER,
|
||||
commodity VARCHAR,
|
||||
PRIMARY KEY(id)
|
||||
);
|
||||
CREATE TABLE transactions (
|
||||
id INTEGER NOT NULL,
|
||||
dt DATETIME,
|
||||
description VARCHAR,
|
||||
PRIMARY KEY(id)
|
||||
);
|
||||
INSERT INTO transactions VALUES(1,'2024-06-30 00:00:00.000000','Conversion balances');
|
||||
INSERT INTO transactions VALUES(2,'2024-06-30 00:00:00.000000','Conversion balances');
|
||||
INSERT INTO transactions VALUES(3,'2024-06-30 00:00:00.000000','Conversion balances');
|
||||
INSERT INTO transactions VALUES(4,'2024-06-30 00:00:00.000000','Opening balances');
|
||||
INSERT INTO transactions VALUES(5,'2024-07-01 00:00:00.000000','Loan');
|
||||
INSERT INTO transactions VALUES(6,'2024-07-02 00:00:00.000000','Application');
|
||||
INSERT INTO transactions VALUES(7,'2024-07-03 00:00:00.000000','Inventory purchases');
|
||||
INSERT INTO transactions VALUES(8,'2024-07-04 00:00:00.000000','Sale');
|
||||
INSERT INTO transactions VALUES(9,'2024-07-04 00:00:00.000000','Sale');
|
||||
INSERT INTO transactions VALUES(10,'2024-08-01 00:00:00.000000','Application');
|
||||
INSERT INTO transactions VALUES(11,'2024-09-01 00:00:00.000000','Redemption');
|
||||
INSERT INTO transactions VALUES(12,'2025-06-30 00:00:00.000000','Interest on business loan');
|
||||
INSERT INTO transactions VALUES(13,'2025-06-30 00:00:00.000000','Depreciation');
|
||||
CREATE TABLE austax_cgt_cost_adjustments (
|
||||
id INTEGER NOT NULL,
|
||||
quantity INTEGER,
|
||||
commodity VARCHAR,
|
||||
account VARCHAR,
|
||||
acquisition_dt DATETIME,
|
||||
dt DATETIME,
|
||||
description VARCHAR,
|
||||
cost_adjustment INTEGER,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
CREATE VIEW joined_transactions AS
|
||||
SELECT transaction_id, dt, transactions.description AS transaction_description, postings.id, postings.description, account, quantity, commodity
|
||||
FROM transactions
|
||||
JOIN postings ON transactions.id = postings.transaction_id
|
||||
ORDER BY dt, transaction_id, postings.id;
|
||||
CREATE VIEW transactions_with_quantity_ascost AS
|
||||
SELECT
|
||||
*,
|
||||
CAST(ROUND(
|
||||
-- If already in reporting commodity
|
||||
IIF(
|
||||
commodity = '$',
|
||||
quantity,
|
||||
-- Else if specified as total cost
|
||||
IIF(
|
||||
commodity LIKE '% {{%}}',
|
||||
substr(commodity, instr(commodity, ' {{') + 3, length(commodity) - instr(commodity, ' {{') - 4) * sign(quantity) * 100,
|
||||
-- Else if specified as unit cost
|
||||
IIF(
|
||||
commodity LIKE '% {%}',
|
||||
substr(commodity, instr(commodity, ' {') + 2, length(commodity) - instr(commodity, ' {') - 2) * quantity,
|
||||
-- Unexpected
|
||||
NULL
|
||||
)
|
||||
)
|
||||
)
|
||||
) AS INTEGER) AS quantity_ascost
|
||||
FROM joined_transactions
|
||||
;
|
||||
CREATE VIEW transactions_with_running_balances AS
|
||||
SELECT
|
||||
*,
|
||||
SUM(quantity_ascost) OVER (PARTITION BY account ROWS UNBOUNDED PRECEDING) AS running_balance
|
||||
FROM transactions_with_quantity_ascost;
|
||||
COMMIT;
|
@ -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',
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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(),
|
||||
);
|
||||
|
@ -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
|
||||
|
@ -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,7 +270,7 @@ pub(crate) async fn get_validated_balance_assertions(
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
get_plugins(),
|
||||
plugin_names,
|
||||
eofy_date,
|
||||
"$".to_string(),
|
||||
);
|
||||
|
@ -339,7 +339,7 @@
|
||||
|
||||
async function onAmountChange(posting: EditingPosting) {
|
||||
// Synchronise the amounts if only two postings
|
||||
if (transaction.postings.length == 2) {
|
||||
if (transaction.postings.length === 2 && posting === transaction.postings[0]) {
|
||||
for (const otherPosting of transaction.postings) {
|
||||
if (otherPosting !== posting) {
|
||||
otherPosting.amount_abs = posting.amount_abs;
|
||||
|
17
src/db.ts
17
src/db.ts
@ -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
|
||||
@ -23,7 +23,7 @@ import { readTextFile } from '@tauri-apps/plugin-fs';
|
||||
import Database from '@tauri-apps/plugin-sql';
|
||||
import { reactive } from 'vue';
|
||||
|
||||
import { Balance } from './amounts.ts';
|
||||
import { asCost } from './amounts.ts';
|
||||
import { ExtendedDatabase } from './dbutil.ts';
|
||||
import { CriticalError } from './error.ts';
|
||||
|
||||
@ -39,6 +39,7 @@ export const db = reactive({
|
||||
eofy_date: null! as string,
|
||||
reporting_commodity: null! as string,
|
||||
dps: null! as number,
|
||||
plugins: null! as string[],
|
||||
},
|
||||
|
||||
init: async function(filename: string | null): Promise<void> {
|
||||
@ -77,6 +78,7 @@ export const db = reactive({
|
||||
this.metadata.eofy_date = metadataObject.eofy_date;
|
||||
this.metadata.reporting_commodity = metadataObject.reporting_commodity;
|
||||
this.metadata.dps = parseInt(metadataObject.amount_dps);
|
||||
this.metadata.plugins = metadataObject.plugins.length > 0 ? metadataObject.plugins.split(';') : [];
|
||||
}
|
||||
},
|
||||
|
||||
@ -114,6 +116,10 @@ export async function createNewDatabase(filename: string, eofy_date: string, rep
|
||||
`INSERT INTO metadata (key, value) VALUES (?, ?)`,
|
||||
['amount_dps', dps.toString()] // Manually call .toString() to format as int, otherwise sqlx formats as float
|
||||
);
|
||||
await transaction.execute(
|
||||
`INSERT INTO metadata (key, value) VALUES (?, ?)`,
|
||||
['plugins', '']
|
||||
);
|
||||
|
||||
await transaction.commit();
|
||||
}
|
||||
@ -274,12 +280,11 @@ export class Transaction {
|
||||
) {}
|
||||
|
||||
doesBalance(): boolean {
|
||||
const balance = new Balance();
|
||||
let total = 0;
|
||||
for (const posting of this.postings) {
|
||||
balance.add(posting.quantity, posting.commodity);
|
||||
total += asCost(posting.quantity, posting.commodity);
|
||||
}
|
||||
balance.clean();
|
||||
return balance.amounts.length === 0;
|
||||
return total === 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
41
src/main.ts
41
src/main.ts
@ -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
|
||||
@ -20,16 +20,26 @@ import { invoke } from '@tauri-apps/api/core';
|
||||
import { WebviewWindow } from '@tauri-apps/api/webviewWindow';
|
||||
|
||||
import { createApp } from 'vue';
|
||||
import { createRouter, createWebHistory } from 'vue-router';
|
||||
import { RouteRecordRaw, createRouter, createWebHistory } from 'vue-router';
|
||||
|
||||
import App from './App.vue';
|
||||
|
||||
import { db } from './db.ts';
|
||||
import { handleCriticalError } from './error.ts';
|
||||
import austax from './plugins/austax/plugin.ts';
|
||||
|
||||
async function initApp() {
|
||||
// Init state
|
||||
const dbFilename: string = await invoke('get_open_filename');
|
||||
if (dbFilename !== null) {
|
||||
try {
|
||||
await db.init(dbFilename); // Ensure all metadata cached before loading Vue
|
||||
} catch (err) {
|
||||
handleCriticalError(err);
|
||||
}
|
||||
}
|
||||
|
||||
// Init router
|
||||
const routes = [
|
||||
let routes: RouteRecordRaw[] = [
|
||||
{ path: '/', name: 'index', component: () => import('./pages/HomeView.vue') },
|
||||
{ path: '/balance-assertions', name: 'balance-assertions', component: () => import('./pages/BalanceAssertionsView.vue') },
|
||||
{ path: '/balance-assertions/edit/:id', name: 'balance-assertions-edit', component: () => import('./pages/EditBalanceAssertionView.vue') },
|
||||
@ -46,29 +56,18 @@ async function initApp() {
|
||||
{ path: '/statement-lines/import', name: 'import-statement', component: () => import('./pages/ImportStatementView.vue') },
|
||||
{ path: '/transactions/:account', name: 'transactions', component: () => import('./pages/TransactionsView.vue') },
|
||||
{ path: '/trial-balance', name: 'trial-balance', component: () => import('./reports/TrialBalanceReport.vue') },
|
||||
// TODO: Generate this list dynamically
|
||||
{ path: '/austax/cgt-adjustments', name: 'cgt-adjustments', component: () => import('./plugins/austax/CGTAdjustmentsView.vue') },
|
||||
{ path: '/austax/cgt-adjustments/edit/:id', name: 'cgt-adjustments-edit', component: () => import('./plugins/austax/EditCGTAdjustmentView.vue') },
|
||||
{ path: '/austax/cgt-adjustments/new', name: 'cgt-adjustments-new', component: () => import('./plugins/austax/NewCGTAdjustmentView.vue') },
|
||||
{ path: '/austax/cgt-adjustments/multinew', name: 'cgt-adjustments-multinew', component: () => import('./plugins/austax/MultiNewCGTAdjustmentView.vue') },
|
||||
{ path: '/austax/cgt-assets', name: 'cgt-assets', component: () => import('./plugins/austax/CGTAssetsView.vue') },
|
||||
{ path: '/austax/tax-summary', name: 'tax-summary', component: () => import('./plugins/austax/TaxSummaryReport.vue') },
|
||||
];
|
||||
|
||||
// Init plugin routes
|
||||
if (db.metadata.plugins.indexOf('austax') >= 0) {
|
||||
routes.push(...austax.getRoutes());
|
||||
}
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
});
|
||||
|
||||
// Init state
|
||||
const dbFilename: string = await invoke('get_open_filename');
|
||||
if (dbFilename !== null) {
|
||||
try {
|
||||
await db.init(dbFilename); // Ensure all metadata cached before loading Vue
|
||||
} catch (err) {
|
||||
handleCriticalError(err);
|
||||
}
|
||||
}
|
||||
|
||||
// Create Vue app
|
||||
createApp(App).use(router).mount('#app');
|
||||
}
|
||||
|
@ -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
|
||||
@ -17,7 +17,7 @@
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="grid grid-cols-3 divide-x divide-gray-200">
|
||||
<div :class="{'grid divide-x divide-gray-200': true, 'grid-cols-2': db.metadata.plugins.indexOf('austax') < 0, 'grid-cols-3': db.metadata.plugins.indexOf('austax') >= 0}">
|
||||
<div class="pr-4">
|
||||
<h2 class="font-medium text-gray-700 mb-2">Data sources</h2>
|
||||
<ul class="list-disc ml-6">
|
||||
@ -26,8 +26,7 @@
|
||||
<li><RouterLink :to="{ name: 'balance-assertions' }" class="text-gray-900 hover:text-blue-700 hover:underline">Balance assertions</RouterLink></li>
|
||||
<li><RouterLink :to="{ name: 'chart-of-accounts' }" class="text-gray-900 hover:text-blue-700 hover:underline">Chart of accounts</RouterLink></li>
|
||||
<!-- Plugin reports -->
|
||||
<!-- TODO: Generate this list dynamically -->
|
||||
<li><RouterLink :to="{ name: 'cgt-adjustments' }" class="text-gray-900 hover:text-blue-700 hover:underline">CGT adjustments</RouterLink></li>
|
||||
<component :is="austax.getDataSourcesLinks()" v-if="db.metadata.plugins.indexOf('austax') >= 0"></component>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="px-4">
|
||||
@ -37,15 +36,21 @@
|
||||
<li><RouterLink :to="{ name: 'trial-balance' }" class="text-gray-900 hover:text-blue-700 hover:underline">Trial balance</RouterLink></li>
|
||||
<li><RouterLink :to="{ name: 'balance-sheet' }" class="text-gray-900 hover:text-blue-700 hover:underline">Balance sheet</RouterLink></li>
|
||||
<li><RouterLink :to="{ name: 'income-statement' }" class="text-gray-900 hover:text-blue-700 hover:underline">Income statement</RouterLink></li>
|
||||
<!-- Plugin reports -->
|
||||
<component :is="austax.getGeneralReportsLinks()" v-if="db.metadata.plugins.indexOf('austax') >= 0"></component>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="pl-4">
|
||||
<div class="pl-4" v-if="db.metadata.plugins.indexOf('austax') >= 0">
|
||||
<h2 class="font-medium text-gray-700 mb-2">Advanced reports</h2>
|
||||
<ul class="list-disc ml-6">
|
||||
<!-- TODO: Generate this list dynamically -->
|
||||
<li><RouterLink :to="{ name: 'cgt-assets' }" class="text-gray-900 hover:text-blue-700 hover:underline">CGT assets</RouterLink></li>
|
||||
<li><RouterLink :to="{ name: 'tax-summary' }" class="text-gray-900 hover:text-blue-700 hover:underline">Tax summary</RouterLink></li>
|
||||
<!-- Plugin reports -->
|
||||
<component :is="austax.getAdvancedReportsLinks()" v-if="db.metadata.plugins.indexOf('austax') >= 0"></component>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { db } from '../db.ts';
|
||||
import austax from '../plugins/austax/plugin.ts';
|
||||
</script>
|
||||
|
28
src/plugin.ts
Normal file
28
src/plugin.ts
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
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
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { Component } from 'vue';
|
||||
import { RouteRecordRaw } from 'vue-router';
|
||||
|
||||
export interface Plugin {
|
||||
getAccountKinds: () => Promise<[string, string][]>,
|
||||
getAdvancedReportsLinks: () => Component,
|
||||
getDataSourcesLinks: () => Component,
|
||||
getGeneralReportsLinks: () => Component,
|
||||
getRoutes: () => RouteRecordRaw[],
|
||||
}
|
22
src/plugins/austax/AdvancedReportsLinks.vue
Normal file
22
src/plugins/austax/AdvancedReportsLinks.vue
Normal file
@ -0,0 +1,22 @@
|
||||
<!--
|
||||
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
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<template>
|
||||
<li><RouterLink :to="{ name: 'cgt-assets' }" class="text-gray-900 hover:text-blue-700 hover:underline">CGT assets</RouterLink></li>
|
||||
<li><RouterLink :to="{ name: 'tax-summary' }" class="text-gray-900 hover:text-blue-700 hover:underline">Tax summary</RouterLink></li>
|
||||
</template>
|
@ -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
|
||||
@ -90,8 +90,6 @@
|
||||
const session = await db.load();
|
||||
cgtAssets.value = await getCGTAssets(session);
|
||||
eofyDate.value = dayjs(db.metadata.eofy_date);
|
||||
|
||||
console.log(cgtAssets.value);
|
||||
}
|
||||
|
||||
load();
|
||||
|
21
src/plugins/austax/DataSourcesLinks.vue
Normal file
21
src/plugins/austax/DataSourcesLinks.vue
Normal file
@ -0,0 +1,21 @@
|
||||
<!--
|
||||
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
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<template>
|
||||
<li><RouterLink :to="{ name: 'cgt-adjustments' }" class="text-gray-900 hover:text-blue-700 hover:underline">CGT adjustments</RouterLink></li>
|
||||
</template>
|
20
src/plugins/austax/GeneralReportsLinks.vue
Normal file
20
src/plugins/austax/GeneralReportsLinks.vue
Normal file
@ -0,0 +1,20 @@
|
||||
<!--
|
||||
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
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<template>
|
||||
</template>
|
40
src/plugins/austax/plugin.ts
Normal file
40
src/plugins/austax/plugin.ts
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
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
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { getAccountKinds } from './account_kinds.ts';
|
||||
import DataSourcesLinks from './DataSourcesLinks.vue';
|
||||
import GeneralReportsLinks from './GeneralReportsLinks.vue';
|
||||
import AdvancedReportsLinks from './AdvancedReportsLinks.vue';
|
||||
import { Plugin } from '../../plugin.ts';
|
||||
|
||||
export default {
|
||||
'getAccountKinds': getAccountKinds,
|
||||
|
||||
getDataSourcesLinks: () => DataSourcesLinks,
|
||||
getGeneralReportsLinks: () => GeneralReportsLinks,
|
||||
getAdvancedReportsLinks: () => AdvancedReportsLinks,
|
||||
|
||||
getRoutes: () => [
|
||||
{ path: '/austax/cgt-adjustments', name: 'cgt-adjustments', component: () => import('./CGTAdjustmentsView.vue') },
|
||||
{ path: '/austax/cgt-adjustments/edit/:id', name: 'cgt-adjustments-edit', component: () => import('./EditCGTAdjustmentView.vue') },
|
||||
{ path: '/austax/cgt-adjustments/new', name: 'cgt-adjustments-new', component: () => import('./NewCGTAdjustmentView.vue') },
|
||||
{ path: '/austax/cgt-adjustments/multinew', name: 'cgt-adjustments-multinew', component: () => import('./MultiNewCGTAdjustmentView.vue') },
|
||||
{ path: '/austax/cgt-assets', name: 'cgt-assets', component: () => import('./CGTAssetsView.vue') },
|
||||
{ path: '/austax/tax-summary', name: 'tax-summary', component: () => import('./TaxSummaryReport.vue') },
|
||||
],
|
||||
} as Plugin;
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
DrCr: Web-based double-entry bookkeeping framework
|
||||
Copyright (C) 2022–2024 Lee Yingtong Li (RunasSudo)
|
||||
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
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
@ -16,7 +16,8 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import * as austax from './plugins/austax/account_kinds.ts';
|
||||
import { db } from './db.ts';
|
||||
import austax from './plugins/austax/plugin.ts';
|
||||
|
||||
export const drcrAccountKinds: [string, string][] = [
|
||||
['drcr.asset', 'Asset'],
|
||||
@ -29,8 +30,10 @@ export const drcrAccountKinds: [string, string][] = [
|
||||
export async function getAccountKinds() {
|
||||
const accountKinds = [...drcrAccountKinds];
|
||||
|
||||
// FIXME: Make this customisable
|
||||
// Add plugin account kinds
|
||||
if (db.metadata.plugins.indexOf('austax') >= 0) {
|
||||
accountKinds.push(...await austax.getAccountKinds());
|
||||
}
|
||||
|
||||
return accountKinds;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user