Added a gocardless bank parser for Raiffeisen AT bank (#5244)

* Added a gocardless bank parser for Raiffeisen AT bank

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
0x4d4e
2025-06-28 15:13:45 +02:00
committed by GitHub
parent 3214d5dd53
commit 46eb2a7c38
3 changed files with 157 additions and 0 deletions

View File

@@ -0,0 +1,51 @@
import { formatPayeeName } from '../../util/payee-name.js';
import { title } from '../../util/title/index.js';
import Fallback from './integration-bank.js';
/** @type {import('./bank.interface.js').IBank} */
export default {
...Fallback,
institutionIds: ['RAIFFEISEN_AT_RZBAATWW'],
normalizeTransaction(transaction, booked) {
const editedTrans = { ...transaction };
let payeeName = formatPayeeName(transaction);
if (!payeeName) {
payeeName = extractPayeeName(transaction);
}
editedTrans.payeeName = payeeName;
// avoid empty notes if payee is set but no information in unstructured information
// if no structured or unstructured information is provided, return the endToEndId instead
editedTrans.remittanceInformationUnstructured =
transaction.remittanceInformationUnstructured ??
transaction.remittanceInformationStructured ??
transaction.endToEndId;
return Fallback.normalizeTransaction(transaction, booked, editedTrans);
},
};
/**
* Extracts the payee name from the remittanceInformationStructured
* @param {import('../gocardless-node.types.js').Transaction} transaction
*/
function extractPayeeName(transaction) {
const structured = transaction.remittanceInformationStructured;
// The payee name is at the beginning and has a max length of 12 characters
// (if structured information is actually structured ...).
const regex = /(.{12}) \d{4} .* \d{2}\.\d{2}\. \d{2}:\d{2}/;
const matches = structured.match(regex);
if (matches && matches.length > 1 && matches[1]) {
const name = title(matches[1]);
// These transactions never contained creditor information in my tests, thus no
// attempt to add the IBAN to the name...
return name;
} else {
// As a fallback if still no payee is found, the whole information is used
return structured;
}
}

View File

@@ -0,0 +1,100 @@
import { mockTransactionAmount } from '../../services/tests/fixtures.js';
import RaiffeisenAtRzbaatww from '../raiffeisen_at_rzbaatww.js';
describe('raiffeisen_at', () => {
describe('#normalizeTransaction', () => {
it('returns the full structured information as payeeName from a transaction with no payee name', () => {
const transaction = {
transactionId: '10_2025-01-01_0123456789',
bookingDate: '2025-01-01',
valueDate: '2025-01-01',
transactionAmount: mockTransactionAmount,
remittanceInformationStructured: 'NOTHING STRUCTURED',
internalTransactionId: '01234567890123456789',
};
const normalizedTransaction = RaiffeisenAtRzbaatww.normalizeTransaction(
transaction,
true,
);
expect(normalizedTransaction.payeeName).toEqual('NOTHING STRUCTURED');
});
it('returns the expected payeeName from a transaction with payee name inside structuredInformation', () => {
const transaction = {
transactionId: '10_2025-01-01_0123456789',
bookingDate: '2025-01-01',
valueDate: '2025-01-01',
transactionAmount: mockTransactionAmount,
remittanceInformationStructured: 'COMPANY ABCD 2610 D5 01.01. 13:37',
internalTransactionId: '01234567890123456789',
};
const normalizedTransaction = RaiffeisenAtRzbaatww.normalizeTransaction(
transaction,
true,
);
expect(normalizedTransaction.payeeName).toEqual('Company Abcd');
});
it('returns the creditorName for transactions containing one', () => {
const transaction = {
transactionId: '18_2025-01-01_0123456789',
bookingDate: '2025-01-01',
valueDate: '2025-01-01',
transactionAmount: mockTransactionAmount,
creditorName: 'Reci Pient',
creditorAccount: {
iban: 'AT201100021493538935',
},
remittanceInformationStructured: 'just some text here',
additionalInformation: 'more info',
internalTransactionId: '01234567890123456789',
};
const normalizedTransaction = RaiffeisenAtRzbaatww.normalizeTransaction(
transaction,
true,
);
expect(normalizedTransaction.payeeName).toEqual(
'Reci Pient (AT20 XXX 8935)',
);
});
it('returns the unstructured information for POS transactions without payee name or useful structured information', () => {
const transaction = {
transactionId: '18_2025-01-01_0123456789',
bookingDate: '2025-01-01',
valueDate: '2025-01-01',
transactionAmount: mockTransactionAmount,
remittanceInformationUnstructured: 'COMPANY NAME CITY 1010',
remittanceInformationStructured:
'POS 1,11 AT D4 01.01. 13:37',
internalTransactionId: '01234567890123456789',
};
const normalizedTransaction = RaiffeisenAtRzbaatww.normalizeTransaction(
transaction,
true,
);
expect(normalizedTransaction.payeeName).toEqual('Company Name City 1010');
});
it('returns the endToEndId in notes if no structured or unstructured remittance information is present', () => {
const transaction = {
transactionId: '18_2025-01-01_0123456789',
bookingDate: '2025-01-01',
valueDate: '2025-01-01',
transactionAmount: mockTransactionAmount,
creditorName: 'Creditor',
endToEndId: 'Transaction 1234',
internalTransactionId: '01234567890123456789',
};
const normalizedTransaction = RaiffeisenAtRzbaatww.normalizeTransaction(
transaction,
true,
);
expect(normalizedTransaction.notes).toEqual('Transaction 1234');
});
});
});

View File

@@ -0,0 +1,6 @@
---
category: Enhancements
authors: [0x4d4e]
---
Added a GoCardless bank parser for Raiffeisen Bank Austria.