Skip to content

Commit

Permalink
Merge pull request #27667 from fvlvte/24871-migrate-models-to-ts
Browse files Browse the repository at this point in the history
[No QA][TS migration] Migrate 'models' lib to TypeScript
  • Loading branch information
neil-marcellini authored Nov 29, 2023
2 parents a0b2197 + 91b3bb0 commit d2a9f81
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 88 deletions.
140 changes: 53 additions & 87 deletions src/libs/models/BankAccount.js → src/libs/models/BankAccount.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
import Str from 'expensify-common/lib/str';
import lodashGet from 'lodash/get';
import lodashHas from 'lodash/has';
import _ from 'underscore';
import {ValueOf} from 'type-fest';
import CONST from '@src/CONST';
import BankAccountJSON, {AdditionalData} from '@src/types/onyx/BankAccount';

type State = ValueOf<typeof BankAccount.STATE>;

type ACHData = {
routingNumber: string;
accountNumber: string;
addressName: string;
isSavings: boolean;
bankAccountID: number;
state: State;
validateCodeExpectedDate: string;
needsToUpgrade: boolean;
};

class BankAccount {
json: BankAccountJSON;

static STATE = {
PENDING: 'PENDING',
OPEN: 'OPEN',
Expand All @@ -14,14 +28,12 @@ class BankAccount {
VERIFYING: 'VERIFYING',
};

constructor(accountJSON) {
constructor(accountJSON: BankAccountJSON) {
this.json = accountJSON;
}

/**
* Return the ID of the reimbursement account
*
* @returns {Number}
*/
getID() {
return this.json.methodID;
Expand All @@ -30,236 +42,190 @@ class BankAccount {
/**
* Return the account number, which has been obfuscated by the back end
* example "XXXXXX3956"
*
* @returns {String}
*/
getMaskedAccountNumber() {
return this.json.accountData.accountNumber;
return this.json.accountData?.accountNumber;
}

/**
* Used as the display name for the account...
* @returns {String}
*/
getAddressName() {
return this.json.accountData.addressName;
return this.json.accountData?.addressName;
}

/**
* @returns {String}
*/
getProcessor() {
return this.json.accountData.processor;
return this.json.accountData?.processor;
}

/**
* @returns {String}
*/
getRoutingNumber() {
return this.json.accountData.routingNumber;
return this.json.accountData?.routingNumber;
}

/**
* Get all user emails that have access to this bank account
* @return {String[]}
*/
getSharees() {
return this.json.accountData.sharees;
return this.json.accountData?.sharees;
}

/**
* @returns {String}
* @private
*/
getState() {
return this.json.accountData.state;
return this.json.accountData?.state;
}

/**
* @returns {Boolean}
*/
isOpen() {
return this.getState() === BankAccount.STATE.OPEN;
}

/**
* @deprecated Use !isPending instead.
* @returns {Boolean}
*/
isVerified() {
return !this.isPending();
}

/**
* If the user still needs to enter the 3 micro deposit amounts.
* @returns {Boolean}
*/
isPending() {
return this.getState() === BankAccount.STATE.PENDING;
}

/**
* If success team is currently verifying the bank account data provided by the user.
* @returns {Boolean}
*/
isVerifying() {
return this.getState() === BankAccount.STATE.VERIFYING;
}

/**
* If the user didn't finish entering all their info.
* @returns {Boolean}
*/
isInSetup() {
return this.getState() === BankAccount.STATE.SETUP;
}

/**
* @returns {Boolean}
*/
isLocked() {
return this.getState() === BankAccount.STATE.LOCKED;
}

/**
* Is it the account to use by default to receive money?
*
* @returns {Boolean}
*/
isDefaultCredit() {
return this.json.accountData.defaultCredit === true;
return this.json.accountData?.defaultCredit === true;
}

/**
* Can we use this account to pay other people?
*
* @returns {Boolean}
*/
isWithdrawal() {
return this.json.accountData.allowDebit === true;
return this.json.accountData?.allowDebit === true;
}

getType() {
return this.json.accountData.type;
return this.json.accountData?.type;
}

/**
* Return the client ID of this bank account
*
* @NOTE WARNING KEEP IN SYNC WITH THE PHP
* @returns {String}
*/
getClientID() {
// eslint-disable-next-line max-len
return `${Str.makeID(this.getMaskedAccountNumber())}${Str.makeID(this.getAddressName())}${Str.makeID(this.getRoutingNumber())}${this.getTransactionType()}`;
return `${Str.makeID(this.getMaskedAccountNumber() ?? '')}${Str.makeID(this.getAddressName() ?? '')}${Str.makeID(this.getRoutingNumber() ?? '')}${this.getTransactionType()}`;
}

/**
* @returns {String}
* @private
*/
getTransactionType() {
private getTransactionType() {
return this.isWithdrawal() ? 'withdrawal' : 'direct-deposit';
}

/**
* Return the internal json data structure used by auth
* @returns {Object}
*/
getJSON() {
return this.json;
}

/**
* Return whether or not this bank account has been risk checked
* @returns {Boolean}
* Return whether this bank account has been risk checked
*/
isRiskChecked() {
return Boolean(this.json.accountData.riskChecked);
return Boolean(this.json.accountData?.riskChecked);
}

/**
* Return when the 3 micro amounts for validation were supposed to reach the bank account.
* @returns {String}
*/
getValidateCodeExpectedDate() {
return this.json.validateCodeExpectedDate || '';
return this.json.validateCodeExpectedDate ?? '';
}

/**
* In which country is the bank account?
* @returns {string}
*/
getCountry() {
return lodashGet(this.json, ['accountData', 'additionalData', 'country'], CONST.COUNTRY.US);
return this.json.accountData?.additionalData?.country ?? CONST.COUNTRY.US;
}

/**
* In which currency is the bank account?
* @returns {String}
*/
getCurrency() {
return lodashGet(this.json, ['accountData', 'additionalData', 'currency'], 'USD');
return this.json.accountData?.additionalData?.currency ?? 'USD';
}

/**
* In which bank is the bank account?
* @returns {String}
*/
getBankName() {
return lodashGet(this.json, ['accountData', 'additionalData', 'bankName'], '');
return this.json.accountData?.additionalData?.bankName ?? '';
}

/**
* Did we get bank account details for local transfer or international wire?
* @returns {Boolean}
*/
hasInternationalWireDetails() {
return lodashGet(this.json, ['accountData', 'additionalData', 'fieldsType'], 'local') === 'international';
return (this.json.accountData?.additionalData?.fieldsType ?? 'local') === 'international';
}

/**
* Get the additional data of a bankAccount
* @returns {Object}
*/
getAdditionalData() {
return this.json.accountData.additionalData || {};
getAdditionalData(): Partial<AdditionalData> {
return this.json.accountData?.additionalData ?? {};
}

/**
* Get the pending action of the bank account
* @returns {String}
*/
getPendingAction() {
return lodashGet(this.json, 'pendingAction', '');
return this.json.pendingAction ?? '';
}

/**
* Return a map needed to setup a withdrawal account
* @returns {Object}
* Return a map needed to set up a withdrawal account
*/
toACHData() {
return _.extend(
{
routingNumber: this.getRoutingNumber(),
accountNumber: this.getMaskedAccountNumber(),
addressName: this.getAddressName(),
isSavings: this.json.isSavings,
bankAccountID: this.getID(),
state: this.getState(),
validateCodeExpectedDate: this.getValidateCodeExpectedDate(),
needsToUpgrade: this.needsToUpgrade(),
},
this.getAdditionalData(),
);
toACHData(): Partial<ACHData> {
return {
routingNumber: this.getRoutingNumber(),
accountNumber: this.getMaskedAccountNumber(),
addressName: this.getAddressName(),
isSavings: this.json.isSavings,
bankAccountID: this.getID(),
state: this.getState(),
validateCodeExpectedDate: this.getValidateCodeExpectedDate(),
needsToUpgrade: this.needsToUpgrade(),
...this.getAdditionalData(),
} as ACHData;
}

/**
* Check if user hasn't upgraded their bank account yet.
* @return {Boolean}
*/
needsToUpgrade() {
return !this.isInSetup() && !lodashHas(this.json, ['accountData', 'additionalData', 'beneficialOwners']);
return !this.isInSetup() && this.json.accountData?.additionalData?.beneficialOwners === undefined;
}
}

Expand Down
17 changes: 16 additions & 1 deletion src/types/onyx/BankAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@ import CONST from '@src/CONST';
import AccountData from './AccountData';
import * as OnyxCommon from './OnyxCommon';

type AdditionalData = {
isP2PDebitCard?: boolean;
beneficialOwners?: string[];
currency?: string;
bankName?: string;
fieldsType?: string;
country?: string;
};

type BankAccount = {
/** The bank account type */
accountType?: typeof CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT;
Expand All @@ -11,6 +20,12 @@ type BankAccount = {

isDefault?: boolean;

/* Determines if the bank account is a savings account */
isSavings?: boolean;

/** Date when the 3 micro amounts for validation were supposed to reach the bank account. */
validateCodeExpectedDate?: string;

/** string like 'bankAccount-{<bankAccountID>}' where <bankAccountID> is the bankAccountID */
key?: string;

Expand All @@ -31,4 +46,4 @@ type BankAccount = {
};

export default BankAccount;
export type {AccountData};
export type {AccountData, AdditionalData};

0 comments on commit d2a9f81

Please sign in to comment.