diff options
| author | ivar <i@oiee.no> | 2026-03-09 23:05:38 +0100 |
|---|---|---|
| committer | ivar <i@oiee.no> | 2026-03-09 23:05:38 +0100 |
| commit | 69448e29a85cad3a94b3be3ad33efbc52764528f (patch) | |
| tree | c32b8c817322fdf26edbbb3fa75b9505a7020ae8 /app/src/lib | |
| parent | b35302fa020ec82a9d67a6cb34379d42983d3cfc (diff) | |
| download | sparebank1-actualbudget-69448e29a85cad3a94b3be3ad33efbc52764528f.tar.xz sparebank1-actualbudget-69448e29a85cad3a94b3be3ad33efbc52764528f.zip | |
Diffstat (limited to 'app/src/lib')
| -rw-r--r-- | app/src/lib/server/actual.ts | 87 |
1 files changed, 50 insertions, 37 deletions
diff --git a/app/src/lib/server/actual.ts b/app/src/lib/server/actual.ts index fb1a4fb..ca4d9c4 100644 --- a/app/src/lib/server/actual.ts +++ b/app/src/lib/server/actual.ts @@ -1,5 +1,5 @@ import { ACTUAL_FILE_ID, ACTUAL_HOST, ACTUAL_PASS } from "$env/static/private"; -import * as actual from "@actual-app/api" +import * as actualApi from "@actual-app/api" import { existsSync, mkdirSync } from "node:fs"; import path from "node:path" import process from "node:process"; @@ -7,53 +7,66 @@ import type { ImportTransactionEntity } from "@actual-app/api/@types/loot-core/s import { Temporal } from "temporal-polyfill"; import type { Sb1Transaction } from "$lib/shared"; -export async function init_actual() { +let inited = false + +async function init() { + if (inited) return const dataDir = path.resolve(process.cwd(), "data/actualDataDir") if (!existsSync(dataDir)) mkdirSync(dataDir, { recursive: true }); - return actual.init({ + await actualApi.init({ password: ACTUAL_PASS, serverURL: ACTUAL_HOST, - dataDir: dataDir - }).then(async () => { - await actual.downloadBudget(ACTUAL_FILE_ID) - await actual.sync() + dataDir }) + await actualApi.downloadBudget(ACTUAL_FILE_ID) + await actualApi.sync() + inited = true } -export async function import_transactions(account: string, transactions: Sb1Transaction[], dryRun: boolean) { - await init_actual() - function parsedDate(date: number) { - const instant = Temporal.Instant.fromEpochMilliseconds(date) - return instant.toString({ timeZone: "Europe/Oslo" }).split("T")[0] - } +const budget = { + async get_budgets() { + await init() + return actualApi.getBudgets() + }, - function notes(transaction: Sb1Transaction) { - const { description, cleanedDescription } = transaction - if (description.toLowerCase().trim() === cleanedDescription.toLowerCase().trim()) return undefined - return description - } + async get_accounts() { + await init() + return actualApi.getAccounts() + }, - function amount(amount: number) { - return Math.round(amount * 100) - } + async import_transactions(account: string, transactions: Sb1Transaction[], dryRun: boolean) { + await init() - const actualMappedTransactions: ImportTransactionEntity[] = transactions.filter(c => c.bookingStatus === "BOOKED").map(c => ({ - account, - date: parsedDate(c.date), - amount: amount(c.amount), - notes: notes(c), - payee_name: c.cleanedDescription - })) + function parsedDate(date: number) { + return Temporal.Instant.fromEpochMilliseconds(date) + .toString({ timeZone: "Europe/Oslo" }) + .split("T")[0] + } - await actual.importTransactions(account, actualMappedTransactions, { dryRun }) -} + function notes(transaction: Sb1Transaction) { + const { description, cleanedDescription } = transaction + if (description?.toLowerCase().trim() === cleanedDescription?.toLowerCase().trim()) return undefined + return description + } -export async function get_budgets() { - await init_actual() - return actual.getBudgets() -} + function amount(amount: number) { + const res = Math.round(amount * 10000) + console.log(`${amount}->${res}`) + return res + } + + const mapped: ImportTransactionEntity[] = transactions + .filter(c => c.bookingStatus === "BOOKED") + .map(c => ({ + account, + date: parsedDate(c.date), + amount: amount(c.amount), + notes: notes(c), + payee_name: c.cleanedDescription + })) -export async function get_accounts() { - await init_actual() - return actual.getAccounts() + return actualApi.importTransactions(account, mapped, { dryRun }) + } } + +export default { init, budget } |
