Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GoCardless integration for ENTERCARD_SWEDNOKK #506

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/app-gocardless/bank-factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import BnpBeGebabebb from './banks/bnp-be-gebabebb.js';
import CBCcregbebb from './banks/cbc_cregbebb.js';
import DanskeBankDabNO22 from './banks/danskebank-dabno22.js';
import EasybankBawaatww from './banks/easybank-bawaatww.js';
import EntercardSwednokk from './banks/entercard-swednokk.js';
import Fortuneo from './banks/FORTUNEO_FTNOFRP1XXX.js';
import IngIngbrobu from './banks/ing-ingbrobu.js';
import IngIngddeff from './banks/ing-ingddeff.js';
Expand All @@ -19,9 +20,9 @@ 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 SandboxfinanceSfin0000 from './banks/sandboxfinance-sfin0000.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';
Expand All @@ -40,6 +41,7 @@ export const banks = [
CBCcregbebb,
DanskeBankDabNO22,
EasybankBawaatww,
EntercardSwednokk,
Fortuneo,
IngIngbrobu,
IngIngddeff,
Expand All @@ -50,9 +52,9 @@ export const banks = [
NbgEthngraaxxx,
NorwegianXxNorwnok1,
RevolutRevolt21,
SandboxfinanceSfin0000,
SEBKortBankAB,
SEBPrivat,
SandboxfinanceSfin0000,
SparNordSpNoDK22,
SpkKarlsruhekarsde66,
SpkMarburgBiedenkopfHeladef1mar,
Expand Down
59 changes: 59 additions & 0 deletions src/app-gocardless/banks/entercard-swednokk.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import * as d from 'date-fns';
import {
amountToInteger,
printIban,
sortByBookingDateOrValueDate,
} from '../utils.js';
import { formatPayeeName } from '../../util/payee-name.js';

/** @type {import('./bank.interface.js').IBank} */
export default {
institutionIds: ['ENTERCARD_SWEDNOKK'],

accessValidForDays: 180,

normalizeAccount(account) {
return {
account_id: account.id,
institution: account.institution,
mask: (account?.iban || '0000').slice(-4),
iban: account?.iban || null,
name: [account.name, printIban(account), account.currency]
.filter(Boolean)
.join(' '),
official_name: `integration-${account.institution_id}`,
type: 'checking',
};
},

normalizeTransaction(transaction, _booked) {
// GoCardless's Entercard integration returns forex transactions with the
// foreign amount in `transactionAmount`, but at least the amount actually
// billed to the account is now available in
// `remittanceInformationUnstructured`.
const remittanceInformationUnstructured =
transaction.remittanceInformationUnstructured;
if (remittanceInformationUnstructured.startsWith('billingAmount: ')) {
transaction.transactionAmount = {
amount: remittanceInformationUnstructured.substring(15),
currency: 'SEK',
Comment on lines +38 to +39
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Parse and validate 'amount' to ensure it's a valid number

When extracting the amount from remittanceInformationUnstructured, it's important to parse and validate it to ensure it's a valid number. This prevents potential errors or injection attacks due to unexpected input formats.

Apply this diff to parse and validate the amount:

 transaction.transactionAmount = {
-  amount: remittanceInformationUnstructured.substring(15),
+  amount: parseFloat(remittanceInformationUnstructured.substring(15)),
   currency: 'SEK',
 };
+if (isNaN(transaction.transactionAmount.amount)) {
+  // Handle the error appropriately, e.g., throw an error or set a default value
+  throw new Error('Invalid transaction amount extracted from remittance information.');
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
amount: remittanceInformationUnstructured.substring(15),
currency: 'SEK',
amount: parseFloat(remittanceInformationUnstructured.substring(15)),
currency: 'SEK',
if (isNaN(transaction.transactionAmount.amount)) {
// Handle the error appropriately, e.g., throw an error or set a default value
throw new Error('Invalid transaction amount extracted from remittance information.');
}

};
}
Comment on lines +35 to +41
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Handle undefined 'remittanceInformationUnstructured' before calling 'startsWith'

If transaction.remittanceInformationUnstructured is undefined or null, calling startsWith on it will result in a runtime error. Consider adding a check to ensure it is defined before calling startsWith.

Apply this diff to fix the issue:

 const remittanceInformationUnstructured =
   transaction.remittanceInformationUnstructured;
+if (
+  remittanceInformationUnstructured &&
+  remittanceInformationUnstructured.startsWith('billingAmount: ')
+) {
   transaction.transactionAmount = {
     amount: remittanceInformationUnstructured.substring(15),
     currency: 'SEK',
   };
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
transaction.remittanceInformationUnstructured;
if (remittanceInformationUnstructured.startsWith('billingAmount: ')) {
transaction.transactionAmount = {
amount: remittanceInformationUnstructured.substring(15),
currency: 'SEK',
};
}
const remittanceInformationUnstructured =
transaction.remittanceInformationUnstructured;
if (
remittanceInformationUnstructured &&
remittanceInformationUnstructured.startsWith('billingAmount: ')
) {
transaction.transactionAmount = {
amount: remittanceInformationUnstructured.substring(15),
currency: 'SEK',
};
}


return {
...transaction,
payeeName: formatPayeeName(transaction),
date: d.format(d.parseISO(transaction.valueDate), 'yyyy-MM-dd'),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Ensure 'transaction.valueDate' is defined before parsing

If transaction.valueDate is undefined or invalid, d.parseISO may result in an invalid date, and d.format could produce unexpected results or throw an error. Consider checking that transaction.valueDate is a valid ISO string before parsing.

Apply this diff to handle undefined transaction.valueDate:

 return {
   ...transaction,
   payeeName: formatPayeeName(transaction),
-  date: d.format(d.parseISO(transaction.valueDate), 'yyyy-MM-dd'),
+  date: transaction.valueDate
+    ? d.format(d.parseISO(transaction.valueDate), 'yyyy-MM-dd')
+    : null,
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
date: d.format(d.parseISO(transaction.valueDate), 'yyyy-MM-dd'),
date: transaction.valueDate
? d.format(d.parseISO(transaction.valueDate), 'yyyy-MM-dd')
: null,

};
},

sortTransactions(transactions = []) {
return sortByBookingDateOrValueDate(transactions);
},

calculateStartingBalance(sortedTransactions = [], balances = []) {
return sortedTransactions.reduce((total, trans) => {
return total - amountToInteger(trans.transactionAmount.amount);
}, amountToInteger(balances[0]?.balanceAmount?.amount || 0));
},
};
6 changes: 6 additions & 0 deletions upcoming-release-notes/506.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
category: Enhancements
authors: [kyrias]
---

Add GoCardless integration for ENTERCARD_SWEDNOKK