- Env key to be more generic
- Cache directory to .cache
- Multiply bank amount by 100 to get correct conversion rate

Removed:
- Unused functions in Actual.ts

Added:
- Test for main functionality
- BankStub for testing
- Added imported_id to Actual Transaction to avoid duplicates
This commit is contained in:
2024-12-01 20:48:42 +01:00
parent cc325b9f08
commit 9ed0a19393
9 changed files with 88 additions and 50 deletions

View File

@ -3,7 +3,6 @@ import {
ACTUAL_DATA_DIR,
ACTUAL_PASSWORD,
ACTUAL_SERVER_URL,
ACTUAL_SYNC_ID,
} from "../config.ts"
import type { TransactionEntity } from "@actual-app/api/@types/loot-core/types/models"
import { type UUID } from "node:crypto"
@ -53,28 +52,3 @@ export class ActualImpl implements Actual {
return await actual.shutdown()
}
}
export async function init() {
return await actual.init({
// Budget data will be cached locally here, in subdirectories for each file.
dataDir: ACTUAL_DATA_DIR,
// This is the URL of your running server
serverURL: ACTUAL_SERVER_URL,
// This is the password you use to log into the server
password: ACTUAL_PASSWORD,
})
}
export async function downloadBudget() {
const something = await actual.downloadBudget(ACTUAL_SYNC_ID)
console.log("downloadBudget", something)
return something
}
export async function getAccounts() {
return await actual.getAccounts()
}
export async function shutdown() {
await actual.shutdown()
}

View File

@ -1,14 +1,15 @@
import { type Actual, ActualImpl } from "@/actual.ts"
import { cronJobDaily } from "@/cron.ts"
import { type Bank, Sparebank1Impl, type Transaction } from "@/sparebank1.ts"
import { transactionIntoActualTransaction } from "@/mappings.ts"
import { bankTransactionIntoActualTransaction } from "@/mappings.ts"
import { ACTUAL_ACCOUNT_IDS, BANK_ACCOUNT_IDS } from "../config.ts"
import logger from "pino"
import type { UUID } from "node:crypto"
// TODO Transports api for pino https://github.com/pinojs/pino/blob/HEAD/docs/transports.md
// TODO create .cache if missing
async function daily(actual: Actual, bank: Bank): Promise<void> {
export async function daily(actual: Actual, bank: Bank): Promise<void> {
// Fetch transactions from the bank
const transactions = await fetchTransactionsFromPastDay(bank)
logger().info(`Fetched ${transactions.length} transactions`)
@ -16,12 +17,14 @@ async function daily(actual: Actual, bank: Bank): Promise<void> {
// TODO multiple accounts
const accountId = ACTUAL_ACCOUNT_IDS[0] as UUID
const actualTransactions = transactions.map((transaction) =>
transactionIntoActualTransaction(transaction, accountId),
bankTransactionIntoActualTransaction(transaction, accountId),
)
// TODO Import transactions into Actual
// If multiple accounts, loop over them
// Get account ID from mapper
// TODO TypeError: Cannot read properties of undefined (reading 'timestamp')
await actual.importTransactions(accountId, actualTransactions)
}
@ -36,12 +39,15 @@ async function fetchTransactionsFromPastDay(
async function main(): Promise<void> {
logger().info("Starting application")
const actual = await ActualImpl.init()
logger().info("Initialized Actual Budget API")
cronJobDaily(async () => {
logger().info("Running daily job")
await daily(actual, new Sparebank1Impl())
logger().info("Finished daily job")
})
logger().info("Shutting down")
// logger().info("Shutting down")
// await actual.shutdown()
}

View File

@ -3,14 +3,17 @@ import type { TransactionEntity } from "@actual-app/api/@types/loot-core/types/m
import type { UUID } from "node:crypto"
// TODO more fields / correct fields?
export function transactionIntoActualTransaction(
export function bankTransactionIntoActualTransaction(
transaction: Transaction,
accountId: UUID,
): TransactionEntity {
return {
id: transaction.id,
// Transactions with the same id will be ignored
imported_id: transaction.id,
account: accountId,
amount: transaction.amount,
// The value without decimals
amount: transaction.amount * 100,
date: transaction.date,
payee: transaction.description,
}