Include austax account kinds in chart of accounts
This commit is contained in:
parent
6ae2106a8a
commit
815b4843e2
@ -15,6 +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/>.
|
||||
|
||||
-- NB: Content of this file is also parsed by frontend src/plugins/austax/account_kinds.ts
|
||||
-- Check the syntax is compatible with that parser!
|
||||
local income_types = {
|
||||
{'income1', 'Salary or wages', '1'},
|
||||
{'income2', 'Allowances, earnings, tips, director\'s fees etc.', '2'},
|
||||
@ -42,6 +44,8 @@ local income_types = {
|
||||
{'income24', 'Other income', '24'},
|
||||
}
|
||||
|
||||
-- NB: Content of this file is also parsed by frontend src/plugins/austax/account_kinds.ts
|
||||
-- Check the syntax is compatible with that parser!
|
||||
local deduction_types = {
|
||||
{'d1', 'Work-related car expenses', 'D1'},
|
||||
{'d2', 'Work-related travel expenses', 'D2'},
|
||||
|
@ -13,6 +13,7 @@
|
||||
"@heroicons/vue": "^2.2.0",
|
||||
"@tauri-apps/api": "^2.5.0",
|
||||
"@tauri-apps/plugin-dialog": "~2.2.2",
|
||||
"@tauri-apps/plugin-fs": "~2.3.0",
|
||||
"@tauri-apps/plugin-shell": "^2.2.1",
|
||||
"@tauri-apps/plugin-sql": "~2.2.0",
|
||||
"@tauri-apps/plugin-store": "~2.2.0",
|
||||
|
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
@ -17,6 +17,9 @@ importers:
|
||||
'@tauri-apps/plugin-dialog':
|
||||
specifier: ~2.2.2
|
||||
version: 2.2.2
|
||||
'@tauri-apps/plugin-fs':
|
||||
specifier: ~2.3.0
|
||||
version: 2.3.0
|
||||
'@tauri-apps/plugin-shell':
|
||||
specifier: ^2.2.1
|
||||
version: 2.2.1
|
||||
@ -459,6 +462,9 @@ packages:
|
||||
'@tauri-apps/plugin-dialog@2.2.2':
|
||||
resolution: {integrity: sha512-Pm9qnXQq8ZVhAMFSEPwxvh+nWb2mk7LASVlNEHYaksHvcz8P6+ElR5U5dNL9Ofrm+uwhh1/gYKWswK8JJJAh6A==}
|
||||
|
||||
'@tauri-apps/plugin-fs@2.3.0':
|
||||
resolution: {integrity: sha512-G9gEyYVUaaxhdRJBgQTTLmzAe0vtHYxYyN1oTQzU3zwvb8T+tVLcAqCdFMWHq0qGeGbmynI5whvYpcXo5LvZ1w==}
|
||||
|
||||
'@tauri-apps/plugin-shell@2.2.1':
|
||||
resolution: {integrity: sha512-G1GFYyWe/KlCsymuLiNImUgC8zGY0tI0Y3p8JgBCWduR5IEXlIJS+JuG1qtveitwYXlfJrsExt3enhv5l2/yhA==}
|
||||
|
||||
@ -1305,6 +1311,10 @@ snapshots:
|
||||
dependencies:
|
||||
'@tauri-apps/api': 2.5.0
|
||||
|
||||
'@tauri-apps/plugin-fs@2.3.0':
|
||||
dependencies:
|
||||
'@tauri-apps/api': 2.5.0
|
||||
|
||||
'@tauri-apps/plugin-shell@2.2.1':
|
||||
dependencies:
|
||||
'@tauri-apps/api': 2.5.0
|
||||
|
1
src-tauri/Cargo.lock
generated
1
src-tauri/Cargo.lock
generated
@ -804,6 +804,7 @@ dependencies = [
|
||||
"tauri",
|
||||
"tauri-build",
|
||||
"tauri-plugin-dialog",
|
||||
"tauri-plugin-fs",
|
||||
"tauri-plugin-shell",
|
||||
"tauri-plugin-sql",
|
||||
"tauri-plugin-store",
|
||||
|
@ -26,6 +26,7 @@ serde_json = "1"
|
||||
sqlx = { version = "0.8", features = ["json", "time"] }
|
||||
tauri = { version = "2", features = [] }
|
||||
tauri-plugin-dialog = "2"
|
||||
tauri-plugin-fs = "2"
|
||||
tauri-plugin-shell = "2"
|
||||
tauri-plugin-sql = { version = "2", features = ["sqlite"] }
|
||||
tauri-plugin-store = "2"
|
||||
|
@ -12,6 +12,9 @@
|
||||
"core:window:allow-set-title",
|
||||
"core:window:allow-show",
|
||||
"dialog:default",
|
||||
"fs:default",
|
||||
"fs:allow-read-text-file",
|
||||
"fs:allow-resource-read-recursive",
|
||||
"shell:allow-open",
|
||||
"sql:default",
|
||||
"sql:allow-execute",
|
||||
|
@ -85,6 +85,7 @@ pub fn run() {
|
||||
Ok(())
|
||||
})
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.plugin(tauri_plugin_fs::init())
|
||||
.plugin(tauri_plugin_shell::init())
|
||||
.plugin(tauri_plugin_sql::Builder::new().build())
|
||||
.plugin(tauri_plugin_store::Builder::new().build())
|
||||
|
@ -44,7 +44,7 @@ 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') },
|
||||
{ path: '/austax/tax-summary', name: 'tax-summary', component: () => import('./austax/TaxSummaryReport.vue') },
|
||||
{ path: '/austax/tax-summary', name: 'tax-summary', component: () => import('./plugins/austax/TaxSummaryReport.vue') },
|
||||
];
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
|
@ -1,6 +1,6 @@
|
||||
<!--
|
||||
DrCr: Web-based double-entry bookkeeping framework
|
||||
Copyright (C) 2022–2024 Lee Yingtong Li (RunasSudo)
|
||||
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
|
||||
@ -57,20 +57,21 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
import { accountKinds } from '../registry.ts';
|
||||
import { drcrAccountKinds, getAccountKinds } from '../registry.ts';
|
||||
import { db } from '../db.ts';
|
||||
import DropdownBox from '../components/DropdownBox.vue';
|
||||
|
||||
const accountKindsMap = new Map(accountKinds);
|
||||
const accountKindsByModule = [...Map.groupBy(accountKinds, (k) => k[0].split('.')[0]).entries()];
|
||||
const accountKinds = ref([...drcrAccountKinds]);
|
||||
const accountKindsMap = computed(() => new Map(accountKinds.value));
|
||||
const accountKindsByModule = computed(() => [...Map.groupBy(accountKinds.value, (k) => k[0].split('.')[0]).entries()]);
|
||||
|
||||
const accounts = ref(new Map<string, string[]>());
|
||||
const selectedAccounts = ref([]);
|
||||
const selectedAccountKind = ref(accountKinds[0]);
|
||||
const selectedAccountKind = ref(drcrAccountKinds[0]);
|
||||
|
||||
async function load() {
|
||||
async function loadAccountConfigurations() {
|
||||
const session = await db.load();
|
||||
|
||||
const accountKindsRaw: {account: string, kind: string | null}[] = await session.select(
|
||||
@ -88,7 +89,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
load();
|
||||
async function loadAccountKinds() {
|
||||
accountKinds.value = await getAccountKinds();
|
||||
}
|
||||
|
||||
loadAccountConfigurations();
|
||||
loadAccountKinds();
|
||||
|
||||
async function addAccountType() {
|
||||
// Associate selected accounts with the selected account kind
|
||||
@ -109,7 +115,7 @@
|
||||
|
||||
// Reload data
|
||||
accounts.value.clear();
|
||||
await load();
|
||||
await loadAccountConfigurations();
|
||||
}
|
||||
|
||||
async function removeAccountType() {
|
||||
@ -131,6 +137,6 @@
|
||||
|
||||
// Reload data
|
||||
accounts.value.clear();
|
||||
await load();
|
||||
await loadAccountConfigurations();
|
||||
}
|
||||
</script>
|
||||
|
@ -24,8 +24,8 @@
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { ref } from 'vue';
|
||||
|
||||
import DynamicReportComponent from '../components/DynamicReportComponent.vue';
|
||||
import { DynamicReport } from '../reports/base.ts';
|
||||
import DynamicReportComponent from '../../components/DynamicReportComponent.vue';
|
||||
import { DynamicReport } from '../../reports/base.ts';
|
||||
|
||||
const report = ref(null as DynamicReport | null);
|
||||
|
75
src/plugins/austax/account_kinds.ts
Normal file
75
src/plugins/austax/account_kinds.ts
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { resolveResource } from '@tauri-apps/api/path';
|
||||
import { readTextFile } from '@tauri-apps/plugin-fs';
|
||||
|
||||
// Dodgy implementation to parse Lua table as JSON
|
||||
function parseLua(luaArray: string): any[] {
|
||||
luaArray = luaArray.trim();
|
||||
|
||||
// Remove surrounding { and }
|
||||
if (!luaArray.startsWith('{') || !luaArray.endsWith('}')) {
|
||||
throw new Error('Unparseable Lua array');
|
||||
}
|
||||
luaArray = luaArray.substring(1, luaArray.length - 1).trim();
|
||||
|
||||
if (luaArray.endsWith(',')) {
|
||||
// Remove trailing comma as this is invalid JSON
|
||||
luaArray = luaArray.substring(0, luaArray.length - 1);
|
||||
}
|
||||
|
||||
// Replace Lua {...} with JSON [...]
|
||||
luaArray = luaArray.replaceAll('{', '[').replaceAll('}', ']');
|
||||
|
||||
// Replace single quotes with double quotes
|
||||
luaArray = luaArray.replaceAll(/(?<!\\)'/g, '"');
|
||||
luaArray = luaArray.replaceAll("\\'", "'");
|
||||
|
||||
return JSON.parse('[' + luaArray + ']');
|
||||
}
|
||||
|
||||
export async function getAccountKinds(): Promise<[string, string][]> {
|
||||
// Read contents of account_kinds.luau
|
||||
const luaFilePath = await resolveResource('plugins/austax/account_kinds.luau');
|
||||
const luaFileContent = await readTextFile(luaFilePath);
|
||||
|
||||
const accountKinds: [string, string][] = [];
|
||||
|
||||
// Parse income_types
|
||||
const incomeTypesLua = luaFileContent.match(/local income_types = ({.*?\n})\n/s)![1];
|
||||
const incomeTypes = parseLua(incomeTypesLua);
|
||||
for (const [code, name, number] of incomeTypes) {
|
||||
accountKinds.push(['austax.' + code, name + ' (' + number + ')']);
|
||||
}
|
||||
|
||||
// Parse deduction_types
|
||||
const deductionTypesLua = luaFileContent.match(/local deduction_types = ({.*?\n})\n/s)![1];
|
||||
const deductionTypes = parseLua(deductionTypesLua);
|
||||
for (const [code, name, number] of deductionTypes) {
|
||||
accountKinds.push(['austax.' + code, name + ' (' + number + ')']);
|
||||
}
|
||||
|
||||
// Hard-coded types
|
||||
accountKinds.push(['austax.offset', 'Tax offset']);
|
||||
accountKinds.push(['austax.paygw', 'PAYG withheld amounts']);
|
||||
accountKinds.push(['austax.cgtasset', 'CGT asset']);
|
||||
accountKinds.push(['austax.rfb', 'Reportable fringe benefit']);
|
||||
|
||||
return accountKinds;
|
||||
}
|
@ -16,10 +16,21 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
export const accountKinds: [string, string][] = [
|
||||
import * as austax from './plugins/austax/account_kinds.ts';
|
||||
|
||||
export const drcrAccountKinds: [string, string][] = [
|
||||
['drcr.asset', 'Asset'],
|
||||
['drcr.liability', 'Liability'],
|
||||
['drcr.income', 'Income'],
|
||||
['drcr.expense', 'Expense'],
|
||||
['drcr.equity', 'Equity']
|
||||
];
|
||||
|
||||
export async function getAccountKinds() {
|
||||
const accountKinds = [...drcrAccountKinds];
|
||||
|
||||
// FIXME: Make this customisable
|
||||
accountKinds.push(...await austax.getAccountKinds());
|
||||
|
||||
return accountKinds;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user