diff --git a/src/app-gocardless/bank-factory.js b/src/app-gocardless/bank-factory.js index 42bc1384d..dc8a6603c 100644 --- a/src/app-gocardless/bank-factory.js +++ b/src/app-gocardless/bank-factory.js @@ -11,6 +11,7 @@ import SparNordSpNoDK22 from './banks/sparnord-spnodk22.js'; import Belfius from './banks/belfius_gkccbebb.js'; import SpkMarburgBiedenkopfHeladef1mar from './banks/spk-marburg-biedenkopf-heladef1mar.js'; import SEBPrivat from './banks/seb-privat.js'; +import SEBKortBankAB from './banks/seb-kort-bank-ab.js'; const banks = [ AmericanExpressAesudef1, @@ -25,6 +26,7 @@ const banks = [ Belfius, SpkMarburgBiedenkopfHeladef1mar, SEBPrivat, + SEBKortBankAB, ]; export default (institutionId) => diff --git a/src/app-gocardless/banks/seb-kort-bank-ab.js b/src/app-gocardless/banks/seb-kort-bank-ab.js new file mode 100644 index 000000000..cc9efbed9 --- /dev/null +++ b/src/app-gocardless/banks/seb-kort-bank-ab.js @@ -0,0 +1,62 @@ +import { + printIban, + amountToInteger, + sortByBookingDateOrValueDate, +} from '../utils.js'; + +/** @type {import('./bank.interface.js').IBank} */ +export default { + institutionIds: ['SEB_KORT_AB_SE_SKHSFI21'], + + normalizeAccount(account) { + return { + account_id: account.id, + institution: account.institution, + mask: account.iban.slice(-4), + iban: account.iban, + name: [account.name, printIban(account)].join(' '), + official_name: account.product, + type: 'checking', + }; + }, + + /** + * Sign of transaction amount needs to be flipped for SEB credit cards + */ + normalizeTransaction(transaction, _booked) { + return { + ...transaction, + // Creditor name is stored in additionInformation for SEB + creditorName: transaction.additionalInformation, + date: transaction.valueDate, + transactionAmount: { + // Flip transaction amount sign + amount: (-parseFloat(transaction.transactionAmount.amount)).toString(), + currency: transaction.transactionAmount.currency, + }, + }; + }, + + sortTransactions(transactions = []) { + return sortByBookingDateOrValueDate(transactions); + }, + + /** + * For SEB_KORT_AB_SE_SKHSFI21 we don't know what balance was + * after each transaction so we have to calculate it by getting + * current balance from the account and subtract all the transactions + * + * As a current balance we use `expected` balance type because it + * corresponds to the current running balance, whereas `interimAvailable` + * holds the remaining credit limit. + */ + calculateStartingBalance(sortedTransactions = [], balances = []) { + const currentBalance = balances.find( + (balance) => 'expected' === balance.balanceType, + ); + + return sortedTransactions.reduce((total, trans) => { + return total - amountToInteger(trans.transactionAmount.amount); + }, -amountToInteger(currentBalance.balanceAmount.amount)); + }, +}; diff --git a/upcoming-release-notes/325.md b/upcoming-release-notes/325.md new file mode 100644 index 000000000..9fce80f4e --- /dev/null +++ b/upcoming-release-notes/325.md @@ -0,0 +1,6 @@ +--- +category: Features +authors: [walleb] +--- + +Add custom bank adapter for 'SEB Kort Bank AB' to properly sync credit card transactions. \ No newline at end of file