diff --git a/src/GeneralLedgerView.vue b/src/GeneralLedgerView.vue
index 8410968..4a984b4 100644
--- a/src/GeneralLedgerView.vue
+++ b/src/GeneralLedgerView.vue
@@ -57,53 +57,25 @@
import { onUnmounted, ref } from 'vue';
import { asCost } from './commodities.ts';
- import { db } from './db.ts';
+ import { JoinedTransactionPosting, Transaction, db, joinedToTransactions } from './db.ts';
import { pp, ppWithCommodity } from './display.ts';
const commodityDetail = ref(false);
- interface _Transaction {
- id: number,
- dt: string,
- description: string,
- postings: _Posting[]
- }
-
- interface _Posting {
- id: number,
- description: string,
- account: string,
- quantity: number,
- commodity: string
- }
-
- const transactions: _Transaction[] = [];
+ let transactions: Transaction[] = [];
let clusterize: Clusterize | null = null;
async function load() {
const session = await db.load();
- const transactionsRaw: {transaction_id: number, dt: string, transaction_description: string, id: number, description: string, account: string, quantity: number, commodity: string}[] = await session.select('SELECT transaction_id, dt, transactions.description AS transaction_description, postings.id, postings.description, account, quantity, commodity FROM transactions LEFT JOIN postings ON transactions.id = postings.transaction_id ORDER BY dt DESC, transaction_id DESC, postings.id');
+ const joinedTransactionPostings: JoinedTransactionPosting[] = await session.select(
+ `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 DESC, transaction_id DESC, postings.id`
+ );
- // Group postings into transactions
- for (const transactionRaw of transactionsRaw) {
- if (transactions.length === 0 || transactions.at(-1)!.id !== transactionRaw.transaction_id) {
- transactions.push({
- id: transactionRaw.transaction_id,
- dt: transactionRaw.dt,
- description: transactionRaw.transaction_description,
- postings: []
- });
- }
-
- transactions.at(-1)!.postings.push({
- id: transactionRaw.id,
- description: transactionRaw.description,
- account: transactionRaw.account,
- quantity: transactionRaw.quantity,
- commodity: transactionRaw.commodity
- });
- }
+ transactions = joinedToTransactions(joinedTransactionPostings);
renderTable();
}
@@ -125,9 +97,9 @@
rows.push(
`
|
- ${ posting.description || '' } |
+ ${ posting.description ?? '' } |
${ posting.quantity >= 0 ? 'Dr' : 'Cr' } |
- ${ posting.account } |
+ ${ posting.account } |
${ posting.quantity >= 0 ? ppWithCommodity(posting.quantity, posting.commodity) : '' }
|
@@ -140,9 +112,9 @@
rows.push(
`
|
- ${ posting.description || '' } |
+ ${ posting.description ?? '' } |
${ posting.quantity >= 0 ? 'Dr' : 'Cr' } |
- ${ posting.account } |
+ ${ posting.account } |
${ posting.quantity >= 0 ? pp(asCost(posting.quantity, posting.commodity)) : '' }
|
diff --git a/src/HomeView.vue b/src/HomeView.vue
index 1dd33ad..a4dffd9 100644
--- a/src/HomeView.vue
+++ b/src/HomeView.vue
@@ -31,8 +31,8 @@
General reports
- - General ledger
- - Trial balance
+ - General ledger
+ - Trial balance
diff --git a/src/TransactionsView.vue b/src/TransactionsView.vue
new file mode 100644
index 0000000..5365456
--- /dev/null
+++ b/src/TransactionsView.vue
@@ -0,0 +1,160 @@
+
+
+
+
+ Account transactions
+
+
+
+
+
+
+
+
+
+
diff --git a/src/TrialBalanceView.vue b/src/TrialBalanceView.vue
index bc57cca..c68ba38 100644
--- a/src/TrialBalanceView.vue
+++ b/src/TrialBalanceView.vue
@@ -31,7 +31,7 @@
- {{ account.account }} |
+ {{ account.account }} |
{{ pp(account.quantity) }}
|
diff --git a/src/db.ts b/src/db.ts
index 0293998..0c78ce4 100644
--- a/src/db.ts
+++ b/src/db.ts
@@ -68,3 +68,60 @@ export async function totalBalances(session: Database): Promise<{account: string
JOIN postings p4 ON p3.account = p4.account AND p3.max_tid = p4.transaction_id ORDER BY account
`);
}
+
+// Type definitions
+
+export interface Transaction {
+ id: number,
+ dt: string,
+ description: string,
+ postings: Posting[]
+}
+
+export interface Posting {
+ id: number,
+ description: string,
+ account: string,
+ quantity: number,
+ commodity: string,
+ running_balance?: number
+}
+
+export interface JoinedTransactionPosting {
+ transaction_id: number,
+ dt: string,
+ transaction_description: string,
+ id: number,
+ description: string,
+ account: string,
+ quantity: number,
+ commodity: string,
+ running_balance?: number
+}
+
+export function joinedToTransactions(joinedTransactionPostings: JoinedTransactionPosting[]): Transaction[] {
+ // Group postings into transactions
+ const transactions: Transaction[] = [];
+
+ for (const joinedTransactionPosting of joinedTransactionPostings) {
+ if (transactions.length === 0 || transactions.at(-1)!.id !== joinedTransactionPosting.transaction_id) {
+ transactions.push({
+ id: joinedTransactionPosting.transaction_id,
+ dt: joinedTransactionPosting.dt,
+ description: joinedTransactionPosting.transaction_description,
+ postings: []
+ });
+ }
+
+ transactions.at(-1)!.postings.push({
+ id: joinedTransactionPosting.id,
+ description: joinedTransactionPosting.description,
+ account: joinedTransactionPosting.account,
+ quantity: joinedTransactionPosting.quantity,
+ commodity: joinedTransactionPosting.commodity,
+ running_balance: joinedTransactionPosting.running_balance
+ });
+ }
+
+ return transactions;
+}
diff --git a/src/main.ts b/src/main.ts
index c0fdd63..b994737 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -22,18 +22,16 @@ import { createApp } from 'vue';
import { createRouter, createWebHistory } from 'vue-router';
import App from './App.vue';
-import HomeView from './HomeView.vue';
-import GeneralLedgerView from './GeneralLedgerView.vue';
-import TrialBalanceView from './TrialBalanceView.vue';
import { db } from './db.ts';
async function initApp() {
// Init router
const routes = [
- { path: '/', component: HomeView },
- { path: '/general-ledger', component: GeneralLedgerView },
- { path: '/trial-balance', component: TrialBalanceView },
+ { path: '/', name: 'index', component: () => import('./HomeView.vue') },
+ { path: '/general-ledger', name: 'general-ledger', component: () => import('./GeneralLedgerView.vue') },
+ { path: '/transactions/:account', name: 'transactions', component: () => import('./TransactionsView.vue') },
+ { path: '/trial-balance', name: 'trial-balance', component: () => import('./TrialBalanceView.vue') },
];
const router = createRouter({
history: createWebHistory(),