Skip to content

Commit

Permalink
Implement parsing of the Amount from the Transaction ID for EUR trans…
Browse files Browse the repository at this point in the history
…actions
  • Loading branch information
Yosif Yosifov committed Aug 15, 2023
1 parent d7d3ed3 commit 7dde257
Show file tree
Hide file tree
Showing 2 changed files with 158 additions and 3 deletions.
131 changes: 131 additions & 0 deletions apps/api/src/tasks/bank-import/import-transactions.task.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,137 @@ describe('ImportTransactionsTask', () => {

expect(prepareBankTrxSpy).not.toHaveBeenCalled()
})

it('should handle EUR currency and parse the BGN equivalent from the transactionId', () => {
const eurTransaction: IrisTransactionInfo = {
transactionId: 'Booked_6516347588_70001524349032963FTRO23184809601C202307034024.69_20230703',
bookingDate: '2023-07-03',
creditorAccount: {
iban: 'BG66UNCR70001524349032',
},
creditorName: 'СДРУЖЕНИЕ ПОДКРЕПИ БГ',
debtorAccount: {
iban: 'BG21UNCR111111111111',
},
debtorName: 'Name not relevant for the example',
remittanceInformationUnstructured: '98XF-SZ50-RC8H',
transactionAmount: {
amount: 2069.25,
currency: 'EUR',
},
exchangeRate: null,
valueDate: '2023-07-03',
creditDebitIndicator: 'CREDIT',
}

// eslint-disable-next-line
// @ts-ignore
const preparedTransactions = irisTasks.prepareBankTransactionRecords(
[eurTransaction],
irisIBANAccountMock,
)

expect(preparedTransactions.length).toEqual(1)
const actual = preparedTransactions[0]

// We expect to have converted the Amount from EUR to BGN by parsing the transaction ID
const expected = {
id: 'Booked_6516347588_70001524349032963FTRO23184809601C202307034024.69_20230703',
ibanNumber: 'BG66UNCR70009994349032',
bankName: 'UniCredit',
transactionDate: new Date('2023-07-03T00:00:00.000Z'),
senderName: 'Name not relevant for the example',
recipientName: 'СДРУЖЕНИЕ ПОДКРЕПИ БГ',
senderIban: 'BG21UNCR111111111111',
recipientIban: 'BG66UNCR70001524349032',
type: 'credit',
amount: 402469,
currency: 'BGN',
description: '98XF-SZ50-RC8H',
matchedRef: '98XF-SZ50-RC8H',
}

expect(actual).toEqual(expected)
})

describe('extractAmountFromTransactionId', () => {
it('can parse a whole number', () => {
// eslint-disable-next-line
// @ts-ignore
const amount = irisTasks.extractAmountFromTransactionId(
'Booked_6516347588_70001524349032963FTRO23184809601C202307032018_20230703',
'2023-07-03',
)

expect(amount).toBe(2018)
})

it('can parse a floating number', () => {
// eslint-disable-next-line
// @ts-ignore
const amount = irisTasks.extractAmountFromTransactionId(
'Booked_6516347588_70001524349032963FTRO23184809601C202307031300.500_20230703',
'2023-07-03',
)

expect(amount).toBe(1300.5)
})

it('can parse a zero', () => {
// eslint-disable-next-line
// @ts-ignore
const amount = irisTasks.extractAmountFromTransactionId(
'Booked_6516347588_70001524349032963FTRO23184809601C202307030_20230703',
'2023-07-03',
)

expect(amount).toBe(0)
})

it('will not parse a negative number', () => {
// eslint-disable-next-line
// @ts-ignore
const amount = irisTasks.extractAmountFromTransactionId(
'Booked_6516347588_70001524349032963FTRO23184809601C20230703-2018_20230703',
'2023-07-03',
)

expect(amount).toBe(NaN)
})

it('will not parse empty number', () => {
// eslint-disable-next-line
// @ts-ignore
const amount = irisTasks.extractAmountFromTransactionId(
'Booked_6516347588_70001524349032963FTRO23184809601C20230703_20230703',
'2023-07-03',
)

expect(amount).toBe(NaN)
})

it('will not parse invalid floating number', () => {
// eslint-disable-next-line
// @ts-ignore
const amount = irisTasks.extractAmountFromTransactionId(
'Booked_6516347588_70001524349032963FTRO23184809601C20230703130.10.500_20230703',
'2023-07-03',
)

expect(amount).toBe(NaN)
})

it('will not parse string', () => {
// eslint-disable-next-line
// @ts-ignore
const amount = irisTasks.extractAmountFromTransactionId(
'Booked_6516347588_70001524349032963FTRO23184809601C20230703test_20230703',
'2023-07-03',
)

expect(amount).toBe(NaN)
})
})
})

describe('notifyForExpiringIrisConsentTASK', () => {
Expand Down
30 changes: 27 additions & 3 deletions apps/api/src/tasks/bank-import/import-transactions.task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,15 @@ export class IrisTasks {
return transactions.length === count
}

private extractAmountFromTransactionId(transactionId, transactionValueDate): number {
const formattedDate = DateTime.fromISO(transactionValueDate).toFormat('yyyyMMdd')
const matchAmountRegex = new RegExp(`${formattedDate}(?<amount>[0-9.]+)_${formattedDate}`)

const amount = Number(transactionId.match(matchAmountRegex)?.groups?.amount)

return amount
}

// Only prepares the data, without inserting it in the DB
private prepareBankTransactionRecords(
transactions: IrisTransactionInfo[],
Expand All @@ -298,8 +307,23 @@ export class IrisTasks {
.replace(/[ _]+/g, '-')
.match(this.regexPaymentRef)

const transactionAmount = {
amount: trx.transactionAmount?.amount,
currency: trx.transactionAmount?.currency,
}
const id = trx.transactionId?.trim() || ''

// If we receive EUR in the BGN account - try parsing from the transaction id the amount in BGN
if (trx.transactionAmount?.currency === Currency.EUR && trx.transactionAmount?.amount > 0) {
const amount = this.extractAmountFromTransactionId(id, trx.valueDate)
if (amount) {
transactionAmount.amount = amount
transactionAmount.currency = Currency.BGN
}
}

filteredTransactions.push({
id: trx.transactionId?.trim() || ``,
id: id,
ibanNumber: ibanAccount.iban,
bankName: ibanAccount.bankName,
bankIdCode: this.bankBIC,
Expand All @@ -309,8 +333,8 @@ export class IrisTasks {
senderIban: trx.debtorAccount?.iban?.trim(),
recipientIban: trx.creditorAccount?.iban?.trim(),
type: trx.creditDebitIndicator === 'CREDIT' ? 'credit' : 'debit',
amount: toMoney(trx.transactionAmount?.amount),
currency: trx.transactionAmount?.currency,
amount: toMoney(transactionAmount.amount),
currency: transactionAmount.currency,
description: trx.remittanceInformationUnstructured?.trim(),
// Not saved in the DB, it's added only for convinience and efficiency
matchedRef: matchedRef ? matchedRef[0] : null,
Expand Down

0 comments on commit 7dde257

Please sign in to comment.