Skip to content

Commit

Permalink
Merge pull request #27923 from software-mansion-labs/@Skalakid/ts/Pay…
Browse files Browse the repository at this point in the history
…mentUtils

[TS migration] Migrate 'PaymentUtils.js' lib to TypeScript
  • Loading branch information
Joel Bettner authored Oct 4, 2023
2 parents f709b8d + 7ca844f commit 180fd60
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 108 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import _ from 'underscore';
import {SvgProps} from 'react-native-svg';
import * as Expensicons from './Expensicons';
import AmericanExpress from '../../../assets/images/bankicons/american-express.svg';
import BankOfAmerica from '../../../assets/images/bankicons/bank-of-america.svg';
Expand All @@ -21,14 +21,16 @@ import USBank from '../../../assets/images/bankicons/us-bank.svg';
import USAA from '../../../assets/images/bankicons/usaa.svg';
import variables from '../../styles/variables';

type BankIcon = {
icon: React.FC<SvgProps>;
iconSize?: number;
};

/**
* Returns matching asset icon for bankName
* @param {String} bankName
* @param {Boolean} isCard
* @returns {Object}
*/

function getAssetIcon(bankName, isCard) {
function getAssetIcon(bankName: string, isCard: boolean): React.FC<SvgProps> {
if (bankName.includes('americanexpress')) {
return AmericanExpress;
}
Expand Down Expand Up @@ -106,13 +108,10 @@ function getAssetIcon(bankName, isCard) {

/**
* Returns Bank Icon Object that matches to existing bank icons or default icons
* @param {String} bankName
* @param {Boolean} [isCard = false]
* @returns {Object} Object includes props icon, iconSize only if applicable
*/

export default function getBankIcon(bankName, isCard) {
const bankIcon = {
export default function getBankIcon(bankName: string, isCard = false): BankIcon {
const bankIcon: BankIcon = {
icon: isCard ? Expensicons.CreditCard : GenericBank,
};

Expand All @@ -121,7 +120,7 @@ export default function getBankIcon(bankName, isCard) {
}

// For default Credit Card icon the icon size should not be set.
if (!_.contains([Expensicons.CreditCard], bankIcon.icon)) {
if (![Expensicons.CreditCard].includes(bankIcon.icon)) {
bankIcon.iconSize = variables.iconSizeExtraLarge;
}

Expand Down
95 changes: 0 additions & 95 deletions src/libs/PaymentUtils.js

This file was deleted.

85 changes: 85 additions & 0 deletions src/libs/PaymentUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import {SvgProps} from 'react-native-svg';
import BankAccountModel from './models/BankAccount';
import getBankIcon from '../components/Icon/BankIcons';
import CONST from '../CONST';
import * as Localize from './Localize';
import Fund from '../types/onyx/Fund';
import BankAccount from '../types/onyx/BankAccount';

type AccountType = BankAccount['accountType'] | Fund['accountType'];

type PaymentMethod = (BankAccount | Fund) & {
description: string;
icon: React.FC<SvgProps>;
iconSize?: number;
};

/**
* Check to see if user has either a debit card or personal bank account added
*/
function hasExpensifyPaymentMethod(fundList: Record<string, Fund>, bankAccountList: Record<string, BankAccount>): boolean {
const validBankAccount = Object.values(bankAccountList).some((bankAccountJSON) => {
const bankAccount = new BankAccountModel(bankAccountJSON);
return bankAccount.isDefaultCredit();
});

// Hide any billing cards that are not P2P debit cards for now because you cannot make them your default method, or delete them
const validDebitCard = Object.values(fundList).some((card) => card?.accountData?.additionalData?.isP2PDebitCard ?? false);

return validBankAccount || validDebitCard;
}

function getPaymentMethodDescription(accountType: AccountType, account: BankAccount['accountData'] | Fund['accountData']): string {
if (account) {
if (accountType === CONST.PAYMENT_METHODS.BANK_ACCOUNT && 'accountNumber' in account) {
return `${Localize.translateLocal('paymentMethodList.accountLastFour')} ${account.accountNumber?.slice(-4)}`;
}
if (accountType === CONST.PAYMENT_METHODS.DEBIT_CARD && 'cardNumber' in account) {
return `${Localize.translateLocal('paymentMethodList.cardLastFour')} ${account.cardNumber?.slice(-4)}`;
}
}
return '';
}

/**
* Get the PaymentMethods list
*/
function formatPaymentMethods(bankAccountList: Record<string, BankAccount>, fundList: Record<string, Fund>): PaymentMethod[] {
const combinedPaymentMethods: PaymentMethod[] = [];

Object.values(bankAccountList).forEach((bankAccount) => {
// Add all bank accounts besides the wallet
if (bankAccount?.accountData?.type === CONST.BANK_ACCOUNT_TYPES.WALLET) {
return;
}

const {icon, iconSize} = getBankIcon(bankAccount?.accountData?.additionalData?.bankName ?? '', false);
combinedPaymentMethods.push({
...bankAccount,
description: getPaymentMethodDescription(bankAccount?.accountType, bankAccount.accountData),
icon,
iconSize,
});
});

Object.values(fundList).forEach((card) => {
const {icon, iconSize} = getBankIcon(card?.accountData?.bank ?? '', true);
combinedPaymentMethods.push({
...card,
description: getPaymentMethodDescription(card?.accountType, card.accountData),
icon,
iconSize,
});
});

return combinedPaymentMethods;
}

function calculateWalletTransferBalanceFee(currentBalance: number, methodType: string): number {
const transferMethodTypeFeeStructure =
methodType === CONST.WALLET.TRANSFER_METHOD_TYPE.INSTANT ? CONST.WALLET.TRANSFER_METHOD_TYPE_FEE.INSTANT : CONST.WALLET.TRANSFER_METHOD_TYPE_FEE.ACH;
const calculateFee = Math.ceil(currentBalance * (transferMethodTypeFeeStructure.RATE / 100));
return Math.max(calculateFee, transferMethodTypeFeeStructure.MINIMUM_FEE);
}

export {hasExpensifyPaymentMethod, getPaymentMethodDescription, formatPaymentMethods, calculateWalletTransferBalanceFee};
4 changes: 3 additions & 1 deletion src/types/onyx/BankAccount.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import CONST from '../../CONST';

type AdditionalData = {
isP2PDebitCard?: boolean;
beneficialOwners?: string[];
Expand Down Expand Up @@ -49,7 +51,7 @@ type AccountData = {

type BankAccount = {
/** The bank account type */
accountType?: string;
accountType?: typeof CONST.PAYMENT_METHODS.BANK_ACCOUNT;

/** string like 'Account ending in XXXX' */
description?: string;
Expand Down
5 changes: 4 additions & 1 deletion src/types/onyx/Fund.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import CONST from '../../CONST';

type AdditionalData = {
isBillingCard?: boolean;
isP2PDebitCard?: boolean;
Expand All @@ -18,11 +20,12 @@ type AccountData = {
created?: string;
currency?: string;
fundID?: number;
bank?: string;
};

type Fund = {
accountData?: AccountData;
accountType?: string;
accountType?: typeof CONST.PAYMENT_METHODS.DEBIT_CARD;
description?: string;
key?: string;
methodID?: number;
Expand Down

0 comments on commit 180fd60

Please sign in to comment.