diff --git a/src/subdomains/supporting/bank/virtual-iban/__tests__/virtual-iban.service.spec.ts b/src/subdomains/supporting/bank/virtual-iban/__tests__/virtual-iban.service.spec.ts index 33aed14c9c..a5727856d1 100644 --- a/src/subdomains/supporting/bank/virtual-iban/__tests__/virtual-iban.service.spec.ts +++ b/src/subdomains/supporting/bank/virtual-iban/__tests__/virtual-iban.service.spec.ts @@ -1377,7 +1377,11 @@ describe('VirtualIbanService', () => { expect(yapealVibanProvider.reserveViban).not.toHaveBeenCalled(); }); - it('getActiveForUserAndCurrency keeps the merge-base selection semantics without excluding Frick', async () => { + it('getActiveForUserAndCurrency only considers rows whose bank still receives', async () => { + // A customer can hold several active rows per currency - a retired Yapeal EUR IBAN next to a + // working Frick one. findOne has no ORDER BY, so without this filter the retired row can win, + // the caller sees "found, but the bank does not receive", and with no collection-account + // fallback left the request fails outright. That hit every holder of a retired Yapeal EUR IBAN. jest.spyOn(virtualIbanRepo, 'findOne').mockResolvedValue(null); await service.getActiveForUserAndCurrency(userData, 'CHF'); @@ -1386,6 +1390,7 @@ describe('VirtualIbanService', () => { where: { userData: { id: 7 }, currency: { name: 'CHF' }, + bank: { receive: true }, active: true, status: VirtualIbanStatus.ACTIVE, }, diff --git a/src/subdomains/supporting/bank/virtual-iban/virtual-iban.service.ts b/src/subdomains/supporting/bank/virtual-iban/virtual-iban.service.ts index 8a9f6902ba..a74b64f7e1 100644 --- a/src/subdomains/supporting/bank/virtual-iban/virtual-iban.service.ts +++ b/src/subdomains/supporting/bank/virtual-iban/virtual-iban.service.ts @@ -126,6 +126,13 @@ export class VirtualIbanService { where: { userData: { id: userData.id }, currency: { name: currencyName }, + // A customer can hold several active rows for one currency - e.g. an old Yapeal EUR IBAN + // alongside a newer Frick one. Rows whose bank no longer receives must not be returned: this + // is a findOne without an ORDER BY, so a retired row can win over a working one, and the + // caller then sees "IBAN found, bank does not receive" and gives up. Since the collection + // account is no longer a fallback, that surfaced as PersonalIbanIssuanceFailed for every + // customer holding a retired Yapeal EUR IBAN. + bank: { receive: true }, active: true, status: VirtualIbanStatus.ACTIVE, },