-
-
Notifications
You must be signed in to change notification settings - Fork 651
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' of https://github.com/Waseh/LaegernesBank
- Loading branch information
Showing
4 changed files
with
364 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { printIban, amountToInteger } from '../utils.js'; | ||
|
||
/** @type {import('./bank.interface.js').IBank} */ | ||
export default { | ||
institutionIds: ['ING_INGDDEFF'], | ||
|
||
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', | ||
}; | ||
}, | ||
|
||
normalizeTransaction(transaction, _booked) { | ||
const remittanceInformationMatch = /remittanceinformation:(.*)$/.exec( | ||
transaction.remittanceInformationUnstructured, | ||
); | ||
const remittanceInformation = remittanceInformationMatch | ||
? remittanceInformationMatch[1] | ||
: transaction.remittanceInformationUnstructured; | ||
|
||
return { | ||
...transaction, | ||
remittanceInformationUnstructured: remittanceInformation, | ||
date: transaction.bookingDate || transaction.valueDate, | ||
}; | ||
}, | ||
|
||
sortTransactions(transactions = []) { | ||
return transactions.sort((a, b) => { | ||
const diff = | ||
+new Date(b.valueDate || b.bookingDate) - | ||
+new Date(a.valueDate || a.bookingDate); | ||
if (diff) return diff; | ||
const idA = parseInt(a.transactionId); | ||
const idB = parseInt(b.transactionId); | ||
if (!isNaN(idA) && !isNaN(idB)) return idB - idA; | ||
return 0; | ||
}); | ||
}, | ||
|
||
calculateStartingBalance(sortedTransactions = [], balances = []) { | ||
const currentBalance = balances.find( | ||
(balance) => 'interimBooked' === balance.balanceType, | ||
); | ||
|
||
return sortedTransactions.reduce((total, trans) => { | ||
return total - amountToInteger(trans.transactionAmount.amount); | ||
}, amountToInteger(currentBalance.balanceAmount.amount)); | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,300 @@ | ||
import IngIngddeff from '../ing-ingddeff.js'; | ||
|
||
describe('IngIngddeff', () => { | ||
describe('#normalizeAccount', () => { | ||
/** @type {import('../../gocardless.types.js').DetailedAccountWithInstitution} */ | ||
const accountRaw = { | ||
resourceId: 'e896eec6-6096-4efc-a941-756bd9d74765', | ||
iban: 'DE02500105170137075030', | ||
currency: 'EUR', | ||
ownerName: 'Jane Doe', | ||
product: 'Girokonto', | ||
id: 'a787ba27-02ee-4fd6-be86-73831adc5498', | ||
created: '2023-12-29T14:17:11.630352Z', | ||
last_accessed: '2023-12-29T14:19:42.709478Z', | ||
institution_id: 'ING_INGDDEFF', | ||
status: 'READY', | ||
owner_name: 'Jane Doe', | ||
institution: { | ||
id: 'ING_INGDDEFF', | ||
name: 'ING', | ||
bic: 'INGDDEFFXXX', | ||
transaction_total_days: '390', | ||
countries: ['DE'], | ||
logo: 'https://storage.googleapis.com/gc-prd-institution_icons-production/DE/PNG/ing.png', | ||
supported_payments: { | ||
'single-payment': ['SCT'], | ||
}, | ||
supported_features: [ | ||
'account_selection', | ||
'business_accounts', | ||
'corporate_accounts', | ||
'payments', | ||
'pending_transactions', | ||
'private_accounts', | ||
], | ||
/*identification_codes: [],*/ | ||
}, | ||
}; | ||
|
||
it('returns normalized account data returned to Frontend', () => { | ||
expect(IngIngddeff.normalizeAccount(accountRaw)).toEqual({ | ||
account_id: 'a787ba27-02ee-4fd6-be86-73831adc5498', | ||
iban: 'DE02500105170137075030', | ||
institution: { | ||
bic: 'INGDDEFFXXX', | ||
countries: ['DE'], | ||
id: 'ING_INGDDEFF', | ||
logo: 'https://storage.googleapis.com/gc-prd-institution_icons-production/DE/PNG/ing.png', | ||
name: 'ING', | ||
supported_features: [ | ||
'account_selection', | ||
'business_accounts', | ||
'corporate_accounts', | ||
'payments', | ||
'pending_transactions', | ||
'private_accounts', | ||
], | ||
supported_payments: { | ||
'single-payment': ['SCT'], | ||
}, | ||
transaction_total_days: '390', | ||
}, | ||
mask: '5030', | ||
name: 'Girokonto (XXX 5030)', | ||
official_name: 'Girokonto', | ||
type: 'checking', | ||
}); | ||
}); | ||
}); | ||
|
||
const transactionsRaw = [ | ||
{ | ||
transactionId: '000010348081381', | ||
endToEndId: 'NOTPROVIDED', | ||
bookingDate: '2023-12-29', | ||
valueDate: '2023-12-29', | ||
transactionAmount: { | ||
amount: '-4.00', | ||
currency: 'EUR', | ||
}, | ||
creditorName: 'VISA XXXXXXXXXXXXXXXXXXXX ', | ||
remittanceInformationUnstructured: | ||
'mandatereference:,creditorid:,remittanceinformation:NR XXXX 63053 51590342815 KAUFUMSATZ 24.90 2311825 ARN044873748454374484719431 Google Pay ', | ||
proprietaryBankTransactionCode: 'Lastschrifteinzug', | ||
internalTransactionId: '085179a2e5fa34b0ff71b3f2c9f4876f', | ||
date: '2023-12-29', | ||
}, | ||
{ | ||
transactionId: '000010348081380', | ||
endToEndId: 'NOTPROVIDED', | ||
bookingDate: '2023-12-29', | ||
valueDate: '2023-12-29', | ||
transactionAmount: { | ||
amount: '-2.00', | ||
currency: 'EUR', | ||
}, | ||
creditorName: 'VISA XXXXXXXXXXXXXXXXXXXX ', | ||
remittanceInformationUnstructured: | ||
'mandatereference:,creditorid:,remittanceinformation:NR XXXX 8987 90671935362 KAUFUMSATZ 94.81 929614 ARN54795476045598005130492 Google Pay ', | ||
proprietaryBankTransactionCode: 'Lastschrifteinzug', | ||
internalTransactionId: '0707bbe2de27e5aabfd5dc614c584951', | ||
date: '2023-12-29', | ||
}, | ||
{ | ||
transactionId: '000010348081379', | ||
endToEndId: 'NOTPROVIDED', | ||
bookingDate: '2023-12-29', | ||
valueDate: '2023-12-29', | ||
transactionAmount: { | ||
amount: '-6.00', | ||
currency: 'EUR', | ||
}, | ||
creditorName: 'VISA XXXXXXXXXXXXXXXXXXXX ', | ||
remittanceInformationUnstructured: | ||
'mandatereference:,creditorid:,remittanceinformation:NR XXXX 2206 17679024325 KAUFUMSATZ 55.25 819456 ARN08595270353806495555431 Google Pay ', | ||
proprietaryBankTransactionCode: 'Lastschrifteinzug', | ||
internalTransactionId: '4b15b590652c9ebdc3f974591b15b250', | ||
date: '2023-12-29', | ||
}, | ||
{ | ||
transactionId: '000010348081378', | ||
endToEndId: 'NOTPROVIDED', | ||
bookingDate: '2023-12-29', | ||
valueDate: '2023-12-29', | ||
transactionAmount: { | ||
amount: '-12.99', | ||
currency: 'EUR', | ||
}, | ||
creditorName: 'VISA XXXXXXXXXXXXXXXXXXXX ', | ||
remittanceInformationUnstructured: | ||
'mandatereference:,creditorid:,remittanceinformation:NR XXXX 9437 535-182-825 LU KAUFUMSATZ 43.79 665448 ARN86236748928277201384604 ', | ||
proprietaryBankTransactionCode: 'Lastschrifteinzug', | ||
internalTransactionId: 'f930f8c153f3e37fb9906e4b3a2b4552', | ||
date: '2023-12-29', | ||
}, | ||
{ | ||
transactionId: '000010348081377', | ||
endToEndId: 'NOTPROVIDED', | ||
bookingDate: '2023-12-29', | ||
valueDate: '2023-12-29', | ||
transactionAmount: { | ||
amount: '-9.00', | ||
currency: 'EUR', | ||
}, | ||
creditorName: 'VISA XXXXXXXXXXXXXXXXXXXX ', | ||
remittanceInformationUnstructured: | ||
'mandatereference:,creditorid:,remittanceinformation:NR XXXX 3582 98236826123 KAUFUMSATZ 88.90 477561 ARN64452564252952225664357 Google Pay ', | ||
proprietaryBankTransactionCode: 'Lastschrifteinzug', | ||
internalTransactionId: '1ce866282deb78cc4ff4cd108e11b8cc', | ||
date: '2023-12-29', | ||
}, | ||
{ | ||
transactionId: '000010347374680', | ||
endToEndId: '9212020-0900000070-2023121711315956', | ||
bookingDate: '2023-12-29', | ||
valueDate: '2023-12-29', | ||
transactionAmount: { | ||
amount: '2892.61', | ||
currency: 'EUR', | ||
}, | ||
debtorName: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', | ||
remittanceInformationUnstructured: | ||
'mandatereference:,creditorid:,remittanceinformation:F22685813 Gehalt 80/6586', | ||
proprietaryBankTransactionCode: 'Gehalt/Rente', | ||
internalTransactionId: 'e731d8eb47f1ae96ccc11e1fb8b76a60', | ||
date: '2023-12-29', | ||
}, | ||
{ | ||
transactionId: '000010336959253', | ||
endToEndId: 'NOTPROVIDED', | ||
bookingDate: '2023-12-28', | ||
valueDate: '2023-12-28', | ||
transactionAmount: { | ||
amount: '-85.80', | ||
currency: 'EUR', | ||
}, | ||
creditorName: 'VISA XXXXXXXXXXXXXXXXXXXX ', | ||
remittanceInformationUnstructured: | ||
'mandatereference:,creditorid:,remittanceinformation:NR XXXX 7082 FAUCOGNEY E FR KAUFUMSATZ 38.20 265113 ARN47998616225906149245029 ', | ||
proprietaryBankTransactionCode: 'Lastschrifteinzug', | ||
internalTransactionId: '2bbc054ae7ba299482a7849fded864f3', | ||
date: '2023-12-28', | ||
}, | ||
{ | ||
transactionId: '000010350537843', | ||
endToEndId: 'NOTPROVIDED', | ||
bookingDate: '2023-12-29', | ||
valueDate: '2023-12-27', | ||
transactionAmount: { | ||
amount: '2.79', | ||
currency: 'EUR', | ||
}, | ||
debtorName: ' ', | ||
remittanceInformationUnstructured: | ||
'mandatereference:,creditorid:,remittanceinformation: Zins/Dividende ISIN IE36B9RBWM04 VANG.FTSE', | ||
proprietaryBankTransactionCode: 'Zins / Dividende WP', | ||
internalTransactionId: '3bb7c58199d3fa5a44e85871d9001798', | ||
date: '2023-12-29', | ||
}, | ||
{ | ||
transactionId: '000010341786083', | ||
endToEndId: 'NOTPROVIDED', | ||
bookingDate: '2023-12-28', | ||
valueDate: '2023-12-27', | ||
transactionAmount: { | ||
amount: '79.80', | ||
currency: 'EUR', | ||
}, | ||
debtorName: 'VISA XXXXXXXXXXXXXXXXXXXX ', | ||
remittanceInformationUnstructured: | ||
'mandatereference:,creditorid:,remittanceinformation:NR XXXX 4619 GUTSCHRIFTSBELEG 03.91 134870 ', | ||
proprietaryBankTransactionCode: 'Gutschrift', | ||
internalTransactionId: '5570eefb7213e39153a6c7fb97d7dc6f', | ||
date: '2023-12-28', | ||
}, | ||
{ | ||
transactionId: '000010328399902', | ||
endToEndId: 'NOTPROVIDED', | ||
bookingDate: '2023-12-27', | ||
valueDate: '2023-12-27', | ||
transactionAmount: { | ||
amount: '-10.90', | ||
currency: 'EUR', | ||
}, | ||
debtorName: 'VISA XXXXXXXXXXXXXXXXXXXX ', | ||
remittanceInformationUnstructured: | ||
'mandatereference:,creditorid:,remittanceinformation:NR XXXX 3465 XXXXXXXXX KAUFUMSATZ 90.40 505416 ARN63639757770303957985044 Google Pay ', | ||
proprietaryBankTransactionCode: 'Lastschrifteinzug', | ||
internalTransactionId: '1b1bf30b23afb56ba4d41b9c65cf0efa', | ||
date: '2023-12-27', | ||
}, | ||
]; | ||
|
||
describe('#sortTransactions', () => { | ||
it('handles empty arrays', () => { | ||
const transactions = []; | ||
const sortedTransactions = IngIngddeff.sortTransactions(transactions); | ||
expect(sortedTransactions).toEqual([]); | ||
}); | ||
|
||
it('returns empty array for undefined input', () => { | ||
const sortedTransactions = IngIngddeff.sortTransactions(undefined); | ||
expect(sortedTransactions).toEqual([]); | ||
}); | ||
|
||
it('returns sorted array for unsorted inputs', () => { | ||
const normalizeTransactions = transactionsRaw.map((tx) => | ||
IngIngddeff.normalizeTransaction(tx, true), | ||
); | ||
const originalOrder = Array.from(normalizeTransactions); | ||
const swap = (a, b) => { | ||
const swap = normalizeTransactions[a]; | ||
normalizeTransactions[a] = normalizeTransactions[b]; | ||
normalizeTransactions[b] = swap; | ||
}; | ||
swap(1, 4); | ||
swap(3, 6); | ||
swap(0, 7); | ||
const sortedTransactions = IngIngddeff.sortTransactions( | ||
normalizeTransactions, | ||
); | ||
expect(sortedTransactions).toEqual(originalOrder); | ||
}); | ||
}); | ||
|
||
describe('#countStartingBalance', () => { | ||
/** @type {import('../../gocardless-node.types.js').Balance[]} */ | ||
const balances = [ | ||
{ | ||
balanceAmount: { amount: '3596.87', currency: 'EUR' }, | ||
balanceType: 'interimBooked', | ||
lastChangeDateTime: '2023-12-29T16:44:06.479Z', | ||
}, | ||
]; | ||
|
||
it('should calculate the starting balance correctly', () => { | ||
const normalizeTransactions = transactionsRaw.map((tx) => | ||
IngIngddeff.normalizeTransaction(tx, true), | ||
); | ||
const sortedTransactions = IngIngddeff.sortTransactions( | ||
normalizeTransactions, | ||
); | ||
|
||
const startingBalance = IngIngddeff.calculateStartingBalance( | ||
sortedTransactions, | ||
balances, | ||
); | ||
|
||
expect(startingBalance).toEqual(75236); | ||
}); | ||
|
||
it('returns the same balance amount when no transactions', () => { | ||
const transactions = []; | ||
|
||
expect( | ||
IngIngddeff.calculateStartingBalance(transactions, balances), | ||
).toEqual(359687); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
category: Enhancements | ||
authors: [t4cmyk] | ||
--- | ||
|
||
Add GoCardless integration for ING (Germany). |