0% found this document useful (0 votes)
2 views5 pages

Cross Currency Issue

The document describes the implementation of a cross-currency intrabank transfer component in an Angular application. It includes the HTML structure for the transfer amount group and TypeScript logic for handling beneficiary selection, exchange rate fetching, and amount conversion. The component utilizes reactive forms and observables to manage state and validate user inputs effectively.

Uploaded by

dev
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views5 pages

Cross Currency Issue

The document describes the implementation of a cross-currency intrabank transfer component in an Angular application. It includes the HTML structure for the transfer amount group and TypeScript logic for handling beneficiary selection, exchange rate fetching, and amount conversion. The component utilizes reactive forms and observables to manage state and validate user inputs effectively.

Uploaded by

dev
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 5

/Users/dthorat/Documents/Projects/BSF/web-retail-us-portalless/src/libs/bsf-p2p-initiate-

payment-journey/src/lib/components/bsf-normal-transfer/bsf-normal-
transfer.component.html

97

<bsf-cross-currency-intratransfer-amount-group

[crossCurrencyAmountControl]="transferForm.controls.crossCurrencyIntrabank?.controls?.a
mount"

[crossCurrencytoCurrencyControl]="transferForm.controls.crossCurrencyIntrabank?.controls
?.currency"

[crossCurrencyAmountTypeControl]="transferForm.controls.crossCurrencyIntrabank?.contro
ls?.amountType"
[fromAccountControl]="transferForm.controls.fromAccount"
[toAccountControl]="transferForm.controls.toAccount"
[transferAmountControl]="transferAmountControl"
[showSwapButtonControl]="false"
></bsf-cross-currency-intratransfer-amount-group>

/Users/dthorat/Documents/Projects/BSF/web-retail-us-portalless/src/libs/bsf-p2p-initiate-
payment-journey/src/lib/components/bsf-normal-transfer/bsf-normal-transfer.component.ts

onBeneficiarySelect() {
this.transferAmountControl.reset();
this.fromAccountControl.reset(undefined, {
emitEvent: false,
});
this.transferForm.controls.purposeOfPayment.reset();
this.transferForm.controls.otherPurpose.reset();
this.transferForm.controls.crossCurrencyInternational.controls.payment.reset();
this.transferForm.controls.crossCurrencyIntrabank?.controls?.amount.reset();
this.transferForm.controls.crossCurrencyIntrabank?.controls?.currency.reset();
this.transferForm.controls.transferAmount.setValidators([
Validators.required,
paymentAmountValidator({ invalidAmount: true }),
]);
this.transferForm.updateValueAndValidity();
this.selectedFromAccount = undefined;
}
/Users/dthorat/Documents/Projects/BSF/web-retail-us-portalless/src/libs/bsf-p2p-initiate-
payment-journey/src/lib/components/bsf-normal-transfer/cross-currency-amount-group/
intrabank/amount-group.component.ts

import { Component, ChangeDetectionStrategy, Input, OnInit, OnDestroy } from


'@angular/core';
import { FormControl, Validators } from '@angular/forms';
import { ExchangeRateResponseBody, ExchangeRateResponseBodyExchangeInformation }
from '@bsf/payment-support-http-ang';
import { Observable, Subject, catchError, filter, map, merge, of, startWith, switchMap, tap }
from 'rxjs';

import {
AmountType,
ArrangementBusinessFunction,
BeneficiaryCategory,
currencyCodeSAR,
} from '../../../../models/bsf-p2p-initiate-payment.model';
import { BsfP2pInitiatePaymentService } from '../../../../services/bsf-p2p-initiate-
payment.service';
import { paymentAmountValidator } from '../../../../validators/amount-validator';

const AMOUNT_VALIDATORS = [Validators.required,


paymentAmountValidator({ invalidAmount: true })];

@Component({
selector: 'bsf-cross-currency-intratransfer-amount-group',
templateUrl: './amount-group.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class BsfIntrabankCrossCurrencyAmountGroupComponent implements OnInit,
OnDestroy {
@Input() crossCurrencyAmountControl: FormControl;
@Input() crossCurrencytoCurrencyControl: FormControl;
@Input() crossCurrencyAmountTypeControl: FormControl;
@Input() fromAccountControl: FormControl;
@Input() toAccountControl: FormControl;
@Input() transferAmountControl: FormControl;
@Input() showSwapButtonControl: boolean;

// to use the enum in template for checks


AmountType = AmountType;
exchangeRate$!: Observable<ExchangeRateResponseBody> | any;
isLoading = true;
private readonly fetchExchangeRate$ = new Subject<void>();

constructor(private readonly bsfP2pInitiatePaymentService: BsfP2pInitiatePaymentService)


{}

ngOnInit() {
this.exchangeRate$ = merge(
this.fetchExchangeRate$.pipe(map((value) => ({ source: 'exchangeRateTrigger', value }))),
this.fromAccountControl.valueChanges.pipe(
startWith(this.fromAccountControl.value),
map((value) => ({ source: 'control', value })),
),
).pipe(
// not to emit anything when from account changes and the account selected is the same
currency as toCurrency
filter((item) => {
if (item.source === 'control' && this.crossCurrencytoCurrencyControl.value) {
return item.value?.currency !== this.crossCurrencytoCurrencyControl.value;
} else {
const currencyCode =
this.toAccountControl.value?.category.toLowerCase() ===
BeneficiaryCategory.brokerage ||
this.toAccountControl.value?.category.toLowerCase() ===
BeneficiaryCategory.company
? this.toAccountControl.value?.currencyCode
: currencyCodeSAR;
this.crossCurrencytoCurrencyControl.patchValue(currencyCode);
}
return true;
}),
tap((item) => {
// reset amountType to SOURCE if from account changes to reset the order of
currencies in display &
// skip below change if it is an Edit operation
if (item.source === 'control' && !this.crossCurrencyAmountTypeControl.value) {
this.crossCurrencyAmountTypeControl.patchValue(AmountType.SOURCE);
}
}),
tap(() => {
this.isLoading = true;
}),
switchMap(() => {
const fromAccount = this.fromAccountControl.value;
const amountType = this.crossCurrencyAmountTypeControl.value;
const transferAmount =
amountType === AmountType.SOURCE ? this.transferAmountControl.value :
this.crossCurrencyAmountControl.value;
// TODO: fix typo below - interbank should be intrabank
const paymentType = ArrangementBusinessFunction.Interbank;

return this.bsfP2pInitiatePaymentService
.getCrossCurrencyExchangeRates({
exchangeRateRequestBody: {
paymentType,
amount: parseFloat(transferAmount) || 1,
amountType,
sourceCurrency: fromAccount.currency,
targetCurrency: this.crossCurrencytoCurrencyControl.value,
},
})
.pipe(
tap((exchangeRateResponse: ExchangeRateResponseBody) => {
this.onCrossCurrencyAmountChange(exchangeRateResponse.exchangeInformation);
this.isLoading = false;
}),
catchError((error) => {
this.isLoading = false;
return of({ error });
}),
);
}),
);
}

ngOnDestroy() {
this.crossCurrencyAmountControl.reset();
this.crossCurrencytoCurrencyControl.reset();
this.crossCurrencyAmountTypeControl.reset();
}

onCrossCurrencyAmountChange(exchangeRate:
ExchangeRateResponseBodyExchangeInformation) {
if (this.crossCurrencyAmountTypeControl.value === AmountType.SOURCE) {
const amount = this.transferAmountControl.value || 0;
const convertedAmount = (parseFloat(amount) *
exchangeRate.actualExchangeRate).toFixed(2);
this.crossCurrencyAmountControl.setValue(convertedAmount);
} else {
const amount = this.crossCurrencyAmountControl.value || 0;
const convertedAmount = (parseFloat(amount) *
exchangeRate.actualExchangeRate).toFixed(2);
this.transferAmountControl.setValue(convertedAmount);
}
this.updateControlsValidity();
}

retryExchangeRate() {
this.fetchExchangeRate$.next();
}

private updateControlsValidity() {
this.transferAmountControl.updateValueAndValidity();
this.crossCurrencyAmountControl.updateValueAndValidity();
}
}

You might also like