Skip to content

Commit

Permalink
Merge remote-tracking branch 'org/master' into feature/pluggy.ai
Browse files Browse the repository at this point in the history
  • Loading branch information
lelemm committed Feb 11, 2025
2 parents bf0a0bc + 7bd499c commit 8e894b6
Show file tree
Hide file tree
Showing 23 changed files with 169 additions and 175 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
> [!IMPORTANT]
> This repository will be merged into [actualbudget/actual](https://github.com/actualbudget/actual/tree/master/packages/sync-server) in February 2025 and placed in a readonly state. For more information please see our [Docs](https://actualbudget.org/docs/actual-server-repo-move) or our [Discord](https://discord.com/invite/pRYNYr4W5A).

This is the main project to run [Actual](https://github.com/actualbudget/actual), a local-first personal finance tool. It comes with the latest version of Actual, and a server to persist changes and make data available across all devices.

### Getting Started
Expand All @@ -7,7 +11,7 @@ If you are interested in contributing, or want to know how development works, se

Want to say thanks? Click the ⭐ at the top of the page.

### Documentation
### Documentation

We have a wide range of documentation on how to use Actual. This is all available in our [Community Documentation](https://actualbudget.org/docs/), including topics on [installing](https://actualbudget.org/docs/install/), [Budgeting](https://actualbudget.org/docs/budgeting/), [Account Management](https://actualbudget.org/docs/accounts/), [Tips & Tricks](https://actualbudget.org/docs/getting-started/tips-tricks) and some documentation for developers.

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "actual-sync",
"version": "25.1.0",
"version": "25.2.1",
"license": "MIT",
"description": "actual syncing server",
"type": "module",
Expand All @@ -23,7 +23,7 @@
},
"dependencies": {
"@actual-app/crdt": "2.1.0",
"@actual-app/web": "25.1.0",
"@actual-app/web": "25.2.1",
"bcrypt": "^5.1.1",
"better-sqlite3": "^11.7.0",
"body-parser": "^1.20.3",
Expand Down
103 changes: 25 additions & 78 deletions src/app-gocardless/bank-factory.js
Original file line number Diff line number Diff line change
@@ -1,83 +1,30 @@
import AbancaCaglesmm from './banks/abanca_caglesmm.js';
import AbnamroAbnanl2a from './banks/abnamro_abnanl2a.js';
import AmericanExpressAesudef1 from './banks/american_express_aesudef1.js';
import BancsabadellBsabesbb from './banks/bancsabadell_bsabesbbb.js';
import BankinterBkbkesmm from './banks/bankinter_bkbkesmm.js';
import BankOfIrelandB365Bofiie2d from './banks/bank_of_ireland_b365_bofiie2d.js';
import BelfiusGkccbebb from './banks/belfius_gkccbebb.js';
import BerlinerSparkasseBeladebexxx from './banks/berliner_sparkasse_beladebexxx.js';
import BnpBeGebabebb from './banks/bnp_be_gebabebb.js';
import CbcCregbebb from './banks/cbc_cregbebb.js';
import CommerzbankCobadeff from './banks/commerzbank_cobadeff.js';
import DanskebankDabno22 from './banks/danskebank_dabno22.js';
import DirektHeladef1822 from './banks/direkt_heladef1822.js';
import EasybankBawaatww from './banks/easybank_bawaatww.js';
import EntercardSwednokk from './banks/entercard_swednokk.js';
import FortuneoFtnofrp1xxx from './banks/fortuneo_ftnofrp1xxx.js';
import HypeHyeeit22 from './banks/hype_hyeeit22.js';
import IngIngbrobu from './banks/ing_ingbrobu.js';
import IngIngddeff from './banks/ing_ingddeff.js';
import IngPlIngbplpw from './banks/ing_pl_ingbplpw.js';
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url';

import IntegrationBank from './banks/integration-bank.js';
import IsyBankItbbitmm from './banks/isybank_itbbitmm.js';
import KbcKredbebb from './banks/kbc_kredbebb.js';
import LhvLhvbee22 from './banks/lhv-lhvbee22.js';
import MbankRetailBrexplpw from './banks/mbank_retail_brexplpw.js';
import NationwideNaiagb21 from './banks/nationwide_naiagb21.js';
import NbgEthngraaxxx from './banks/nbg_ethngraaxxx.js';
import NorwegianXxNorwnok1 from './banks/norwegian_xx_norwnok1.js';
import RevolutRevolt21 from './banks/revolut_revolt21.js';
import SebKortBankAb from './banks/seb_kort_bank_ab.js';
import SebPrivat from './banks/seb_privat.js';
import SandboxfinanceSfin0000 from './banks/sandboxfinance_sfin0000.js';
import SparnordSpnodk22 from './banks/sparnord_spnodk22.js';
import SpkKarlsruheKarsde66 from './banks/spk_karlsruhe_karsde66.js';
import SpkMarburgBiedenkopfHeladef1mar from './banks/spk_marburg_biedenkopf_heladef1mar.js';
import SpkWormsAlzeyRiedMalade51wor from './banks/spk_worms_alzey_ried_malade51wor.js';
import SskDusseldorfDussdeddxxx from './banks/ssk_dusseldorf_dussdeddxxx.js';
import SwedbankHabalv22 from './banks/swedbank_habalv22.js';
import VirginNrnbgb22 from './banks/virgin_nrnbgb22.js';

export const banks = [
AbancaCaglesmm,
AbnamroAbnanl2a,
AmericanExpressAesudef1,
BancsabadellBsabesbb,
BankinterBkbkesmm,
BankOfIrelandB365Bofiie2d,
BelfiusGkccbebb,
BerlinerSparkasseBeladebexxx,
BnpBeGebabebb,
CbcCregbebb,
CommerzbankCobadeff,
DanskebankDabno22,
DirektHeladef1822,
EasybankBawaatww,
EntercardSwednokk,
FortuneoFtnofrp1xxx,
HypeHyeeit22,
IngIngbrobu,
IngIngddeff,
IngPlIngbplpw,
IsyBankItbbitmm,
KbcKredbebb,
LhvLhvbee22,
MbankRetailBrexplpw,
NationwideNaiagb21,
NbgEthngraaxxx,
NorwegianXxNorwnok1,
RevolutRevolt21,
SebKortBankAb,
SebPrivat,
SandboxfinanceSfin0000,
SparnordSpnodk22,
SpkKarlsruheKarsde66,
SpkMarburgBiedenkopfHeladef1mar,
SpkWormsAlzeyRiedMalade51wor,
SskDusseldorfDussdeddxxx,
SwedbankHabalv22,
VirginNrnbgb22,
];
const dirname = path.resolve(fileURLToPath(import.meta.url), '..');
const banksDir = path.resolve(dirname, 'banks');

async function loadBanks() {
const bankHandlers = fs
.readdirSync(banksDir)
.filter((filename) => filename.includes('_') && filename.endsWith('.js'));

const imports = await Promise.all(
bankHandlers.map((file) => {
const fileUrlToBank = pathToFileURL(path.resolve(banksDir, file)); // pathToFileURL for ESM compatibility
return import(fileUrlToBank.toString()).then(
(handler) => handler.default,
);
}),
);

return imports;
}

export const banks = await loadBanks();

export default (institutionId) =>
banks.find((b) => b.institutionIds.includes(institutionId)) ||
Expand Down
22 changes: 18 additions & 4 deletions src/app-gocardless/banks/ssk_dusseldorf_dussdeddxxx.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,31 @@ export default {
institutionIds: ['SSK_DUSSELDORF_DUSSDEDDXXX'],

normalizeTransaction(transaction, _booked) {
// If the transaction is not booked yet by the bank, don't import it.
// Reason being that the transaction doesn't have the information yet
// to make the payee and notes field be of any use. It's filled with
// a placeholder text and wouldn't be corrected on the next sync.
if (!_booked) {
console.debug(
'Skipping unbooked transaction:',
transaction.transactionId,
);
return null;
}

// Prioritize unstructured information, falling back to structured formats
let remittanceInformationUnstructured =
transaction.remittanceInformationUnstructured ??
transaction.remittanceInformationStructured ??
transaction.remittanceInformationStructuredArray?.join(' ');

if (transaction.additionalInformation)
remittanceInformationUnstructured =
(remittanceInformationUnstructured ?? '') +
' ' +
transaction.additionalInformation;
remittanceInformationUnstructured = [
remittanceInformationUnstructured,
transaction.additionalInformation,
]
.filter(Boolean)
.join(' ');

const usefulCreditorName =
transaction.ultimateCreditor ||
Expand Down
101 changes: 101 additions & 0 deletions src/app-gocardless/banks/tests/ssk_dusseldorf_dussdeddxxx.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { jest } from '@jest/globals';
import SskDusseldorfDussdeddxxx from '../ssk_dusseldorf_dussdeddxxx.js';

describe('ssk_dusseldorf_dussdeddxxx', () => {
let consoleSpy;

beforeEach(() => {
consoleSpy = jest.spyOn(console, 'debug');
});

afterEach(() => {
consoleSpy.mockRestore();
});

describe('#normalizeTransaction', () => {
const bookedTransactionOne = {
transactionId: '2024102900000000-1',
bookingDate: '2024-10-29',
valueDate: '2024-10-29',
transactionAmount: {
amount: '-99.99',
currency: 'EUR',
},
creditorName: 'a useful creditor name',
remittanceInformationStructured: 'structured information',
remittanceInformationUnstructured: 'unstructured information',
additionalInformation: 'some additional information',
};

const bookedTransactionTwo = {
transactionId: '2024102900000000-2',
bookingDate: '2024-10-29',
valueDate: '2024-10-29',
transactionAmount: {
amount: '-99.99',
currency: 'EUR',
},
creditorName: 'a useful creditor name',
ultimateCreditor: 'ultimate creditor',
remittanceInformationStructured: 'structured information',
additionalInformation: 'some additional information',
};

it('properly combines remittance information', () => {
expect(
SskDusseldorfDussdeddxxx.normalizeTransaction(
bookedTransactionOne,
true,
).remittanceInformationUnstructured,
).toEqual('unstructured information some additional information');

expect(
SskDusseldorfDussdeddxxx.normalizeTransaction(
bookedTransactionTwo,
true,
).remittanceInformationUnstructured,
).toEqual('structured information some additional information');
});

it('prioritizes creditor names correctly', () => {
expect(
SskDusseldorfDussdeddxxx.normalizeTransaction(
bookedTransactionOne,
true,
).payeeName,
).toEqual('A Useful Creditor Name');

expect(
SskDusseldorfDussdeddxxx.normalizeTransaction(
bookedTransactionTwo,
true,
).payeeName,
).toEqual('Ultimate Creditor');
});

const unbookedTransaction = {
transactionId: '2024102900000000-1',
valueDate: '2024-10-29',
transactionAmount: {
amount: '-99.99',
currency: 'EUR',
},
creditorName: 'some nonsensical creditor',
remittanceInformationUnstructured: 'some nonsensical information',
};

it('returns null for unbooked transactions', () => {
expect(
SskDusseldorfDussdeddxxx.normalizeTransaction(
unbookedTransaction,
false,
),
).toBeNull();

expect(consoleSpy).toHaveBeenCalledWith(
'Skipping unbooked transaction:',
unbookedTransaction.transactionId,
);
});
});
});
6 changes: 0 additions & 6 deletions upcoming-release-notes/499.md

This file was deleted.

6 changes: 0 additions & 6 deletions upcoming-release-notes/531.md

This file was deleted.

6 changes: 0 additions & 6 deletions upcoming-release-notes/533.md

This file was deleted.

6 changes: 0 additions & 6 deletions upcoming-release-notes/534.md

This file was deleted.

6 changes: 0 additions & 6 deletions upcoming-release-notes/535.md

This file was deleted.

6 changes: 0 additions & 6 deletions upcoming-release-notes/537.md

This file was deleted.

6 changes: 0 additions & 6 deletions upcoming-release-notes/538.md

This file was deleted.

6 changes: 0 additions & 6 deletions upcoming-release-notes/539.md

This file was deleted.

6 changes: 0 additions & 6 deletions upcoming-release-notes/542.md

This file was deleted.

6 changes: 0 additions & 6 deletions upcoming-release-notes/546.md

This file was deleted.

6 changes: 0 additions & 6 deletions upcoming-release-notes/547.md

This file was deleted.

6 changes: 0 additions & 6 deletions upcoming-release-notes/550.md

This file was deleted.

6 changes: 0 additions & 6 deletions upcoming-release-notes/551.md

This file was deleted.

6 changes: 0 additions & 6 deletions upcoming-release-notes/554.md

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ category: Maintenance
authors: [matt-fidd]
---

Standardize GoCardless bank handlers
Dynamically load GoCardless handlers
6 changes: 6 additions & 0 deletions upcoming-release-notes/560.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
category: Maintenance
authors: [MikesGlitch]
---

Updating readme regarding the consolidation of the Actual-Server and Actual repos
Loading

0 comments on commit 8e894b6

Please sign in to comment.