1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
import { ACTUAL_FILE_ID, ACTUAL_HOST, ACTUAL_PASS } from "$env/static/private";
import * as actual from "@actual-app/api"
import { existsSync, mkdirSync } from "node:fs";
import path from "node:path"
import process from "node:process";
import type { ImportTransactionEntity } from "@actual-app/api/@types/loot-core/src/types/models/import-transaction";
import { Temporal } from "temporal-polyfill";
import type { Sb1Transaction } from "$lib/shared";
export async function init_actual() {
const dataDir = path.resolve(process.cwd(), "data/actualDataDir")
if (!existsSync(dataDir)) mkdirSync(dataDir, { recursive: true });
return actual.init({
password: ACTUAL_PASS,
serverURL: ACTUAL_HOST,
dataDir: dataDir
}).then(async () => {
await actual.downloadBudget(ACTUAL_FILE_ID)
await actual.sync()
})
}
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]
}
function notes(transaction: Sb1Transaction) {
const { description, cleanedDescription } = transaction
if (description.toLowerCase().trim() === cleanedDescription.toLowerCase().trim()) return undefined
return description
}
function amount(amount: number) {
return Math.round(amount * 100)
}
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
}))
await actual.importTransactions(account, actualMappedTransactions, { dryRun })
}
export async function get_budgets() {
await init_actual()
return actual.getBudgets()
}
export async function get_accounts() {
await init_actual()
return actual.getAccounts()
}
|