From 50ef94dfeeee81960900dd81da01fc5074299487 Mon Sep 17 00:00:00 2001 From: RunasSudo Date: Fri, 13 Jun 2025 23:12:32 +1000 Subject: [PATCH] Refactor DynamicReport to TypeScript class --- src/pages/ChartOfAccountsView.vue | 6 +++--- src/plugins/austax/TaxSummaryReport.vue | 2 +- src/reports/BalanceSheetReport.vue | 10 +++++----- src/reports/IncomeStatementReport.vue | 2 +- src/reports/TrialBalanceReport.vue | 2 +- src/reports/base.ts | 17 ++++++++++++----- 6 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/pages/ChartOfAccountsView.vue b/src/pages/ChartOfAccountsView.vue index d4ec22f..f8f4293 100644 --- a/src/pages/ChartOfAccountsView.vue +++ b/src/pages/ChartOfAccountsView.vue @@ -63,7 +63,7 @@ import { drcrAccountKinds, getAccountKinds } from '../registry.ts'; import { db } from '../db.ts'; import DropdownBox from '../components/DropdownBox.vue'; - import { DynamicReport, reportEntryById, Row, Section } from '../reports/base.ts'; + import { DynamicReport, Row, Section } from '../reports/base.ts'; const accountKinds = ref([...drcrAccountKinds]); const accountKindsMap = computed(() => new Map(accountKinds.value)); @@ -77,8 +77,8 @@ const session = await db.load(); // Get all accounts on the trial balance - const trialBalance = JSON.parse(await invoke('get_trial_balance', { date: '9999-12-31' })) as DynamicReport; - const trialBalanceAccounts = (reportEntryById(trialBalance, 'accounts') as { Section: Section }).Section.entries.map((e) => (e as { Row: Row }).Row.text); + const trialBalance = DynamicReport.fromJSON(await invoke('get_trial_balance', { date: '9999-12-31' })) as DynamicReport; + const trialBalanceAccounts = (trialBalance.byId('accounts') as { Section: Section }).Section.entries.map((e) => (e as { Row: Row }).Row.text); // Get all configured account kinds const accountKindsRaw: {account: string, kind: string}[] = await session.select( diff --git a/src/plugins/austax/TaxSummaryReport.vue b/src/plugins/austax/TaxSummaryReport.vue index c99c9e8..f33e1d2 100644 --- a/src/plugins/austax/TaxSummaryReport.vue +++ b/src/plugins/austax/TaxSummaryReport.vue @@ -37,7 +37,7 @@ const report = ref(null as DynamicReport | null); async function load() { - report.value = JSON.parse(await invoke('get_tax_summary')); + report.value = DynamicReport.fromJSON(await invoke('get_tax_summary')); } load(); diff --git a/src/reports/BalanceSheetReport.vue b/src/reports/BalanceSheetReport.vue index 8706353..62f20e5 100644 --- a/src/reports/BalanceSheetReport.vue +++ b/src/reports/BalanceSheetReport.vue @@ -55,7 +55,7 @@ import { ExclamationCircleIcon } from '@heroicons/vue/20/solid'; - import { DynamicReport, Row, reportEntryById } from './base.ts'; + import { DynamicReport, Row } from './base.ts'; import { db } from '../db.ts'; import DynamicReportComponent from '../components/DynamicReportComponent.vue'; import DynamicReportMenu from '../components/DynamicReportMenu.vue'; @@ -111,7 +111,7 @@ newReportColumns = ['$']; } - report.value = JSON.parse(await invoke('get_balance_sheet', { dates: reportDates })); + report.value = DynamicReport.fromJSON(await invoke('get_balance_sheet', { dates: reportDates })); reportColumns.value = newReportColumns; // Wait until report available to update this } @@ -120,9 +120,9 @@ return true; } - const totalAssets = (reportEntryById(report.value, 'total_assets') as { Row: Row }).Row.quantity; - const totalLiabilities = (reportEntryById(report.value, 'total_liabilities') as { Row: Row }).Row.quantity; - const totalEquity = (reportEntryById(report.value, 'total_equity') as { Row: Row }).Row.quantity; + const totalAssets = (report.value.byId('total_assets') as { Row: Row }).Row.quantity; + const totalLiabilities = (report.value.byId('total_liabilities') as { Row: Row }).Row.quantity; + const totalEquity = (report.value.byId('total_equity') as { Row: Row }).Row.quantity; let doesBalance = true; for (let column = 0; column < report.value.columns.length; column++) { diff --git a/src/reports/IncomeStatementReport.vue b/src/reports/IncomeStatementReport.vue index b7053b9..97c64a0 100644 --- a/src/reports/IncomeStatementReport.vue +++ b/src/reports/IncomeStatementReport.vue @@ -106,7 +106,7 @@ newReportColumns = ['$']; } - report.value = JSON.parse(await invoke('get_income_statement', { dates: reportDates })); + report.value = DynamicReport.fromJSON(await invoke('get_income_statement', { dates: reportDates })); reportColumns.value = newReportColumns; // Wait until report available to update this } diff --git a/src/reports/TrialBalanceReport.vue b/src/reports/TrialBalanceReport.vue index 3615bcf..5d3e5d1 100644 --- a/src/reports/TrialBalanceReport.vue +++ b/src/reports/TrialBalanceReport.vue @@ -55,6 +55,6 @@ async function updateReport() { const reportDate = dayjs(dt.value!).format('YYYY-MM-DD'); - report.value = JSON.parse(await invoke('get_trial_balance', { date: reportDate })); + report.value = DynamicReport.fromJSON(await invoke('get_trial_balance', { date: reportDate })); } diff --git a/src/reports/base.ts b/src/reports/base.ts index dc44dad..d7139e4 100644 --- a/src/reports/base.ts +++ b/src/reports/base.ts @@ -16,11 +16,18 @@ along with this program. If not, see . */ -// Cannot be a class as these are directly deserialised from JSON -export interface DynamicReport { - title: string; - columns: string[]; - entries: DynamicReportEntry[]; +export class DynamicReport { + title!: string; + columns!: string[]; + entries!: DynamicReportEntry[]; + + static fromJSON(json: string): DynamicReport { + return Object.assign(new DynamicReport(), JSON.parse(json)); + } + + byId(id: string): DynamicReportEntry | null { + return reportEntryById(this, id); + } } // serde_json serialises an enum like this