diff options
| author | ivar <i@oiee.no> | 2025-12-26 22:19:09 +0100 |
|---|---|---|
| committer | ivar <i@oiee.no> | 2025-12-26 22:19:09 +0100 |
| commit | abf37599c877a8cc83e5a24c775c3999a9879abf (patch) | |
| tree | 234fbafdadda08735c4cbf6d3092bebd1d725691 /app/src | |
| parent | fe0fe074ec8e8959bbdeff0ccc7f68d20b30e963 (diff) | |
| download | sparebank1-actualbudget-abf37599c877a8cc83e5a24c775c3999a9879abf.tar.xz sparebank1-actualbudget-abf37599c877a8cc83e5a24c775c3999a9879abf.zip | |
Remove delta from form, wip import method
Diffstat (limited to 'app/src')
| -rw-r--r-- | app/src/lib/server/actual.ts | 21 | ||||
| -rw-r--r-- | app/src/lib/server/importer.ts | 12 | ||||
| -rw-r--r-- | app/src/lib/shared.d.ts | 5 | ||||
| -rw-r--r-- | app/src/routes/+page.svelte | 23 | ||||
| -rw-r--r-- | app/src/routes/methods.remote.ts | 20 | ||||
| -rw-r--r-- | app/src/routes/sb1.remote.ts | 38 |
6 files changed, 64 insertions, 55 deletions
diff --git a/app/src/lib/server/actual.ts b/app/src/lib/server/actual.ts index 0875273..389f390 100644 --- a/app/src/lib/server/actual.ts +++ b/app/src/lib/server/actual.ts @@ -3,6 +3,9 @@ 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 { Sb1Transaction } from "./sb1"; +import type { ImportTransactionEntity } from "@actual-app/api/@types/loot-core/src/types/models/import-transaction"; +import { Temporal } from "temporal-polyfill"; async function init_actual() { const dataDir = path.resolve(process.cwd(), "data/actualDataDir") @@ -17,6 +20,24 @@ async function init_actual() { }) } +export async function import_transactions(account: string, transactions: Sb1Transaction[], dryRun: boolean) { + + function parsedDate(date: number) { + const instant = Temporal.Instant.fromEpochMilliseconds(date) + return instant.toString({ timeZone: "Europe/Oslo" }).split("T")[0] + } + + const actualMappedTransactions: ImportTransactionEntity[] = transactions.filter(c => c.bookingStatus === "BOOKED").map(c => ({ + account, + date: parsedDate(c.date), + amount: c.amount, + notes: c.description, + payee_name: c.cleanedDescription + })) + + actual.importTransactions(account, actualMappedTransactions, { dryRun }) +} + export async function get_budgets() { await init_actual() return actual.getBudgets() diff --git a/app/src/lib/server/importer.ts b/app/src/lib/server/importer.ts index 91adce0..02cb94c 100644 --- a/app/src/lib/server/importer.ts +++ b/app/src/lib/server/importer.ts @@ -1,9 +1,11 @@ -import type { Temporal } from "temporal-polyfill"; import sb1 from "./sb1"; +import * as actual from "./actual"; +import type { ImportForm } from "$lib/shared"; -async function importSince(account: string, date: Temporal.Instant) { - const accounts = await sb1.data.get_accounts() - for (const account of accounts?.accounts ?? []) { - const transactions = await sb1.data.get_transactions(account.key); +async function importSince(form: ImportForm) { + for (const mapping of form.mappings) { + const transactions = await sb1.data.get_transactions(mapping.sb1Id); + if (!transactions?.length) continue + } }
\ No newline at end of file diff --git a/app/src/lib/shared.d.ts b/app/src/lib/shared.d.ts new file mode 100644 index 0000000..e63904b --- /dev/null +++ b/app/src/lib/shared.d.ts @@ -0,0 +1,5 @@ +export type ImportForm = { + budgetId: string, + mappings: Array<{ sb1Id: string, actualId: string }>, + dryRun: boolean +}
\ No newline at end of file diff --git a/app/src/routes/+page.svelte b/app/src/routes/+page.svelte index 7b0a495..6f257f6 100644 --- a/app/src/routes/+page.svelte +++ b/app/src/routes/+page.svelte @@ -1,18 +1,19 @@ <script lang="ts"> import Button from "$lib/ui/button.svelte"; - import { clear_auth_session, init_auth_session } from "./sb1.remote"; + import { clear_auth_session, init_auth_session } from "./methods.remote"; import type { PageProps } from "./$types"; import { Temporal } from "temporal-polyfill"; import { instantAsHtmlInputValueString } from "$lib/helpers"; + import type { ImportForm } from "$lib/shared"; let { data }: PageProps = $props(); let navigating = $state(false); - let form = $state({ + let form = $state<ImportForm>({ budgetId: "", - mappings: [] as Array<{ sb1: string; actual: string }>, - delta: instantAsHtmlInputValueString(Temporal.Now.instant().subtract("PT24H")), - dry: true, + mappings: [], + dryRun: true, }); + async function run() {} async function authorize() { @@ -27,10 +28,10 @@ location.reload(); } - function mappingChanged(sb1: string, actual: string) { + function onMappingChanged(sb1Id: string, actualId: string) { let mappings = form.mappings; - if (mappings.find((c) => c.sb1 === sb1)) mappings = mappings.filter((c) => c.sb1 !== sb1); - mappings.push({ sb1, actual }); + if (mappings.find((c) => c.sb1Id === sb1Id)) mappings = mappings.filter((c) => c.sb1Id !== sb1Id); + mappings.push({ sb1Id, actualId }); form.mappings = mappings; } @@ -55,7 +56,7 @@ <code>{account.name}</code> <span>→</span> <label for={actualId}>Actual</label> - <select name={actualId} id={actualId} onchange={(e) => mappingChanged(account.key, e.currentTarget.value)}> + <select name={actualId} id={actualId} onchange={(e) => onMappingChanged(account.key, e.currentTarget.value)}> <option value="-" selected>-</option> {#each data.actual.accounts as actual} <option value={actual.id}> @@ -66,9 +67,7 @@ </div> {/each} <h4>Ellers</h4> - <label for="delta">Importer transaksjoner siden</label> - <input type="date" id="delta" bind:value={form.delta} /><br /> - <input type="checkbox" id="dry" bind:checked={form.dry} /><label for="dry">Tørrkjøring</label><br /><br /> + <input type="checkbox" id="dry" bind:checked={form.dryRun} /><label for="dry">Tørrkjøring</label><br /><br /> <input type="submit" /> </fieldset> </form> diff --git a/app/src/routes/methods.remote.ts b/app/src/routes/methods.remote.ts new file mode 100644 index 0000000..c669164 --- /dev/null +++ b/app/src/routes/methods.remote.ts @@ -0,0 +1,20 @@ +import { db } from "$lib/server/db"; +import { syncSession } from "$lib/server/db/schema"; +import * as v from "valibot" +import { command, query } from "$app/server"; +import sb1 from "$lib/server/sb1"; + +const init_auth_session = command(async () => { + return await sb1.auth.init_auth_session() +}) + + +const clear_auth_session = query(async () => { + await db.delete(syncSession) +}) + + +export { + init_auth_session, + clear_auth_session +}
\ No newline at end of file diff --git a/app/src/routes/sb1.remote.ts b/app/src/routes/sb1.remote.ts deleted file mode 100644 index 1ee0155..0000000 --- a/app/src/routes/sb1.remote.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { db } from "$lib/server/db"; -import { syncSession } from "$lib/server/db/schema"; -import * as v from "valibot" -import { command, query } from "$app/server"; -import sb1 from "$lib/server/sb1"; - -const init_auth_session = command(async () => { - return await sb1.auth.init_auth_session() -}) - -const get_accounts = query(() => { - return sb1.data.get_accounts() -}) - -const get_transactions = query(v.string(), (accountKey: string) => { - return sb1.data.get_transactions(accountKey) -}) - -const clear_auth_session = query(async () => { - await db.delete(syncSession) -}) - -const get_auth_info = query(() => { - return sb1.auth.get_auth_info() -}) - -const refresh_tokem = command(async () => { - await sb1.auth.refresh_token() -}) - -export { - refresh_tokem, - init_auth_session, - get_accounts, - get_transactions, - clear_auth_session, - get_auth_info, -}
\ No newline at end of file |
