diff --git a/src/app-gocardless/bank-factory.js b/src/app-gocardless/bank-factory.js index a38afa3bc..fa09f76fd 100644 --- a/src/app-gocardless/bank-factory.js +++ b/src/app-gocardless/bank-factory.js @@ -28,6 +28,7 @@ import SpkMarburgBiedenkopfHeladef1mar from './banks/spk-marburg-biedenkopf-hela import SpkWormsAlzeyRiedMalade51wor from './banks/spk-worms-alzey-ried-malade51wor.js'; import SwedbankHabaLV22 from './banks/swedbank-habalv22.js'; import VirginNrnbgb22 from './banks/virgin_nrnbgb22.js'; +import Dkb_byladem1 from './banks/dkb_byladem1.js'; export const banks = [ AbancaCaglesmm, @@ -59,6 +60,7 @@ export const banks = [ SpkWormsAlzeyRiedMalade51wor, SwedbankHabaLV22, VirginNrnbgb22, + Dkb_byladem1, ]; export default (institutionId) => diff --git a/src/app-gocardless/banks/dkb_byladem1.js b/src/app-gocardless/banks/dkb_byladem1.js new file mode 100644 index 000000000..e4bf71c40 --- /dev/null +++ b/src/app-gocardless/banks/dkb_byladem1.js @@ -0,0 +1,33 @@ +import Fallback from './integration-bank.js'; +import { printIban } from '../utils.js'; +import * as d from 'date-fns'; + +/** @type {import('./bank.interface.js').IBank} */ +export default { + ...Fallback, + + accessValidForDays: 180, + + institutionIds: ['DKB_BYLADEM1'], + + normalizeAccount(account) { + return { + account_id: account.id, + institution: account.institution, + mask: account.iban.slice(-4), + iban: account.iban, + name: [account.product, printIban(account)].join(' '), + official_name: account.product, + type: 'checking', + }; + }, + + sortTransactions(transactions = []) { + const dateFormat = "yyyy-MM-dd-HH.mm.ss.SSSSSS'Z'"; + return transactions.sort((a, b) => { + const dateA = d.parse(a.transactionId, dateFormat, new Date()); + const dateB = d.parse(b.transactionId, dateFormat, new Date()); + return d.compareAsc(dateA, dateB); + }); + }, +}; diff --git a/src/app-gocardless/banks/tests/dkb_byladem1.spec.js b/src/app-gocardless/banks/tests/dkb_byladem1.spec.js new file mode 100644 index 000000000..73449a311 --- /dev/null +++ b/src/app-gocardless/banks/tests/dkb_byladem1.spec.js @@ -0,0 +1,121 @@ +import Dkb_byladem1 from '../dkb_byladem1.js'; +import { mockTransactionAmount } from '../../services/tests/fixtures.js'; + +describe('dkb_byladem1', function () { + describe('#normalizeAccount', function () { + it('should normalize the account information', function () { + /** @type {import('../../gocardless.types.js').DetailedAccountWithInstitution} */ + const accountRaw = { + resourceId: 'd1c61254-242e-4a88-aaff-8490846e2491', + iban: 'DE02500105170137075030', + currency: 'EUR', + ownerName: 'Jane Doe', + product: 'Girokonto', + id: 'a787ba27-02ee-4fd6-be86-73831adc5498', + created: '2023-09-04T14:38:58.841381Z', + last_accessed: '2024-11-08T08:48:39.667722Z', + institution_id: 'DKB_BYLADEM1', + status: 'READY', + owner_name: 'Jane Doe', + cashAccountType: 'CACC', + usage: 'PRIV', + institution: { + id: 'DKB_BYLADEM1', + name: 'Deutsche Kreditbank AG (DKB)', + bic: 'BALLADE1001', + transaction_total_days: '365', + countries: ['DE'], + logo: 'https://storage.googleapis.com/gc-prd-institution_icons-production/DE/PNG/deutschekreditbank.png', + supported_payments: { + 'single-payment': ['SCT', 'ISCSI'], + }, + supported_features: [ + 'business_accounts', + 'corporate_accounts', + 'payments', + 'pending_transactions', + 'private_accounts', + ], + }, + }; + + /** @type {import('../../gocardless.types.js').NormalizedAccountDetails} */ + const expected = { + account_id: 'a787ba27-02ee-4fd6-be86-73831adc5498', + iban: 'DE02500105170137075030', + institution: { + id: 'DKB_BYLADEM1', + name: 'Deutsche Kreditbank AG (DKB)', + bic: 'BALLADE1001', + transaction_total_days: '365', + countries: ['DE'], + logo: 'https://storage.googleapis.com/gc-prd-institution_icons-production/DE/PNG/deutschekreditbank.png', + supported_payments: { + 'single-payment': ['SCT', 'ISCSI'], + }, + supported_features: [ + 'business_accounts', + 'corporate_accounts', + 'payments', + 'pending_transactions', + 'private_accounts', + ], + }, + mask: '5030', + name: 'Girokonto (XXX 5030)', + official_name: 'Girokonto', + type: 'checking', + }; + + const actual = Dkb_byladem1.normalizeAccount(accountRaw); + expect(actual).toEqual(expected); + }); + }); + + describe('#sortTransactions', function () { + it('should sort by transaction id', function () { + /** @type {import('../../gocardless-node.types.js').Transaction[]} */ + const transactionsRaw = [ + { + transactionId: '2024-11-05-00.25.38.982769Z', + transactionAmount: mockTransactionAmount, + }, + { + transactionId: '2024-11-05-01.25.38.982769Z', + transactionAmount: mockTransactionAmount, + }, + { + transactionId: '2024-11-04-01.26.38.982769Z', + transactionAmount: mockTransactionAmount, + }, + { + transactionId: '2024-11-05-01.26.38.982769Z', + transactionAmount: mockTransactionAmount, + }, + ]; + + /** @type {import('../../gocardless-node.types.js').Transaction[]} */ + const expected = [ + { + transactionId: '2024-11-04-01.26.38.982769Z', + transactionAmount: mockTransactionAmount, + }, + { + transactionId: '2024-11-05-00.25.38.982769Z', + transactionAmount: mockTransactionAmount, + }, + { + transactionId: '2024-11-05-01.25.38.982769Z', + transactionAmount: mockTransactionAmount, + }, + { + transactionId: '2024-11-05-01.26.38.982769Z', + transactionAmount: mockTransactionAmount, + }, + ]; + + const actual = Dkb_byladem1.sortTransactions(transactionsRaw); + expect(actual).toEqual(expected); + }); + }); +}); diff --git a/upcoming-release-notes/500.md b/upcoming-release-notes/500.md new file mode 100644 index 000000000..72869fac8 --- /dev/null +++ b/upcoming-release-notes/500.md @@ -0,0 +1,6 @@ +--- +category: Features +authors: [mrsteakhouse] +--- + +Implements support for sync with DKB bank accounts.