diff --git a/src/CONST.ts b/src/CONST.ts index 709e9d3bafe2..47eb44db6983 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -575,6 +575,7 @@ const CONST = { CREATED: 'CREATED', IOU: 'IOU', MODIFIEDEXPENSE: 'MODIFIEDEXPENSE', + MOVED: 'MOVED', REIMBURSEMENTQUEUED: 'REIMBURSEMENTQUEUED', RENAMED: 'RENAMED', REPORTPREVIEW: 'REPORTPREVIEW', @@ -1189,7 +1190,8 @@ const CONST = { PAYMENT_METHODS: { DEBIT_CARD: 'debitCard', - BANK_ACCOUNT: 'bankAccount', + PERSONAL_BANK_ACCOUNT: 'bankAccount', + BUSINESS_BANK_ACCOUNT: 'businessBankAccount', }, PAYMENT_METHOD_ID_KEYS: { @@ -1278,7 +1280,11 @@ const CONST = { TYPE: { FREE: 'free', PERSONAL: 'personal', + + // Often referred to as "control" workspaces CORPORATE: 'corporate', + + // Often referred to as "collect" workspaces TEAM: 'team', }, ROLE: { diff --git a/src/components/AddPaymentMethodMenu.js b/src/components/AddPaymentMethodMenu.js index 252c8380b062..4f1500132106 100644 --- a/src/components/AddPaymentMethodMenu.js +++ b/src/components/AddPaymentMethodMenu.js @@ -1,15 +1,19 @@ +import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; import React from 'react'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; +import useLocalize from '@hooks/useLocalize'; import compose from '@libs/compose'; import Permissions from '@libs/Permissions'; +import * as ReportActionsUtils from '@libs/ReportActionsUtils'; +import * as ReportUtils from '@libs/ReportUtils'; +import iouReportPropTypes from '@pages/iouReportPropTypes'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import * as Expensicons from './Icon/Expensicons'; import PopoverMenu from './PopoverMenu'; import refPropTypes from './refPropTypes'; -import withLocalize, {withLocalizePropTypes} from './withLocalize'; import withWindowDimensions from './withWindowDimensions'; const propTypes = { @@ -19,6 +23,12 @@ const propTypes = { /** Callback to execute when the component closes. */ onClose: PropTypes.func.isRequired, + /** Callback to execute when the payment method is selected. */ + onItemSelected: PropTypes.func.isRequired, + + /** The IOU/Expense report we are paying */ + iouReport: iouReportPropTypes, + /** Anchor position for the AddPaymentMenu. */ anchorPosition: PropTypes.shape({ horizontal: PropTypes.number, @@ -37,10 +47,15 @@ const propTypes = { /** Popover anchor ref */ anchorRef: refPropTypes, - ...withLocalizePropTypes, + /** Session info for the currently logged in user. */ + session: PropTypes.shape({ + /** Currently logged in user accountID */ + accountID: PropTypes.number, + }), }; const defaultProps = { + iouReport: {}, anchorPosition: {}, anchorAlignment: { horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.LEFT, @@ -48,31 +63,47 @@ const defaultProps = { }, betas: [], anchorRef: () => {}, + session: {}, }; -function AddPaymentMethodMenu(props) { +function AddPaymentMethodMenu({isVisible, onClose, anchorPosition, anchorAlignment, anchorRef, iouReport, onItemSelected, session, betas}) { + const {translate} = useLocalize(); + return ( { - props.onItemSelected(CONST.PAYMENT_METHODS.BANK_ACCOUNT); - }, - }, - ...(Permissions.canUseWallet(props.betas) + ...(ReportUtils.isIOUReport(iouReport) ? [ { - text: props.translate('common.debitCard'), + text: translate('common.personalBankAccount'), + icon: Expensicons.Bank, + onSelected: () => { + onItemSelected(CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT); + }, + }, + ] + : []), + ...(!ReportActionsUtils.hasRequestFromCurrentAccount(lodashGet(iouReport, 'reportID', 0), lodashGet(session, 'accountID', 0)) + ? [ + { + text: translate('common.businessBankAccount'), + icon: Expensicons.Building, + onSelected: () => onItemSelected(CONST.PAYMENT_METHODS.BUSINESS_BANK_ACCOUNT), + }, + ] + : []), + ...(Permissions.canUseWallet(betas) + ? [ + { + text: translate('common.debitCard'), icon: Expensicons.CreditCard, - onSelected: () => props.onItemSelected(CONST.PAYMENT_METHODS.DEBIT_CARD), + onSelected: () => onItemSelected(CONST.PAYMENT_METHODS.DEBIT_CARD), }, ] : []), @@ -88,10 +119,12 @@ AddPaymentMethodMenu.displayName = 'AddPaymentMethodMenu'; export default compose( withWindowDimensions, - withLocalize, withOnyx({ betas: { key: ONYXKEYS.BETAS, }, + session: { + key: ONYXKEYS.SESSION, + }, }), )(AddPaymentMethodMenu); diff --git a/src/components/KYCWall/BaseKYCWall.js b/src/components/KYCWall/BaseKYCWall.js index d55417a6190a..9ba342ddda90 100644 --- a/src/components/KYCWall/BaseKYCWall.js +++ b/src/components/KYCWall/BaseKYCWall.js @@ -10,9 +10,11 @@ import Navigation from '@libs/Navigation/Navigation'; import * as PaymentUtils from '@libs/PaymentUtils'; import * as ReportUtils from '@libs/ReportUtils'; import * as PaymentMethods from '@userActions/PaymentMethods'; +import * as Policy from '@userActions/Policy'; import * as Wallet from '@userActions/Wallet'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; import {defaultProps, propTypes} from './kycWallPropTypes'; // This component allows us to block various actions by forcing the user to first add a default payment method and successfully make it through our Know Your Customer flow @@ -93,10 +95,19 @@ class KYCWall extends React.Component { */ selectPaymentMethod(paymentMethod) { this.props.onSelectPaymentMethod(paymentMethod); - if (paymentMethod === CONST.PAYMENT_METHODS.BANK_ACCOUNT) { + if (paymentMethod === CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT) { Navigation.navigate(this.props.addBankAccountRoute); } else if (paymentMethod === CONST.PAYMENT_METHODS.DEBIT_CARD) { Navigation.navigate(this.props.addDebitCardRoute); + } else if (paymentMethod === CONST.PAYMENT_METHODS.BUSINESS_BANK_ACCOUNT) { + if (ReportUtils.isIOUReport(this.props.iouReport)) { + const policyID = Policy.createWorkspaceFromIOUPayment(this.props.iouReport); + + // Navigate to the bank account set up flow for this specific policy + Navigation.navigate(ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute('', policyID)); + return; + } + Navigation.navigate(this.props.addBankAccountRoute); } } @@ -135,7 +146,7 @@ class KYCWall extends React.Component { ) { Log.info('[KYC Wallet] User does not have valid payment method'); if (!this.props.shouldIncludeDebitCard) { - this.selectPaymentMethod(CONST.PAYMENT_METHODS.BANK_ACCOUNT); + this.selectPaymentMethod(CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT); return; } const clickedElementLocation = getClickedTargetLocation(targetElement); @@ -164,6 +175,7 @@ class KYCWall extends React.Component { <> this.setState({shouldShowAddPaymentMenu: false})} anchorRef={this.anchorRef} anchorPosition={{ diff --git a/src/components/MoneyReportHeader.js b/src/components/MoneyReportHeader.js index df41abea30a3..bf8bc7719316 100644 --- a/src/components/MoneyReportHeader.js +++ b/src/components/MoneyReportHeader.js @@ -119,7 +119,6 @@ function MoneyReportHeader({session, personalDetails, policy, chatReport, nextSt onPress={(paymentType) => IOU.payMoneyRequest(paymentType, chatReport, moneyRequestReport)} enablePaymentsRoute={ROUTES.ENABLE_PAYMENTS} addBankAccountRoute={bankAccountRoute} - shouldShowPaymentOptions style={[styles.pv2]} formattedAmount={formattedAmount} /> @@ -164,7 +163,6 @@ function MoneyReportHeader({session, personalDetails, policy, chatReport, nextSt onPress={(paymentType) => IOU.payMoneyRequest(paymentType, chatReport, moneyRequestReport)} enablePaymentsRoute={ROUTES.ENABLE_PAYMENTS} addBankAccountRoute={bankAccountRoute} - shouldShowPaymentOptions formattedAmount={formattedAmount} /> diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index 605d6909ebbc..732e40195b15 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -508,7 +508,6 @@ function MoneyRequestConfirmationList(props) { addDebitCardRoute={ROUTES.IOU_SEND_ADD_DEBIT_CARD} currency={props.iouCurrencyCode} policyID={props.policyID} - shouldShowPaymentOptions buttonSize={CONST.DROPDOWN_BUTTON_SIZE.LARGE} kycWallAnchorAlignment={{ horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.LEFT, diff --git a/src/components/ReportActionItem/ReportPreview.js b/src/components/ReportActionItem/ReportPreview.js index 9f291e1318f5..f04029182d45 100644 --- a/src/components/ReportActionItem/ReportPreview.js +++ b/src/components/ReportActionItem/ReportPreview.js @@ -254,7 +254,6 @@ function ReportPreview(props) { onPress={(paymentType) => IOU.payMoneyRequest(paymentType, props.chatReport, props.iouReport)} enablePaymentsRoute={ROUTES.ENABLE_PAYMENTS} addBankAccountRoute={bankAccountRoute} - shouldShowPaymentOptions style={[styles.mt3]} kycWallAnchorAlignment={{ horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.LEFT, diff --git a/src/components/SettlementButton.js b/src/components/SettlementButton.js index d2030eac8d7d..27ba3d08a16f 100644 --- a/src/components/SettlementButton.js +++ b/src/components/SettlementButton.js @@ -40,9 +40,6 @@ const propTypes = { /** The route to redirect if user does not have a payment method setup */ enablePaymentsRoute: PropTypes.string.isRequired, - /** Should we show the payment options? */ - shouldShowPaymentOptions: PropTypes.bool, - /** The last payment method used per policy */ nvp_lastPaymentMethod: PropTypes.objectOf(PropTypes.string), @@ -97,7 +94,6 @@ const defaultProps = { betas: CONST.EMPTY_ARRAY, iouReport: CONST.EMPTY_OBJECT, nvp_lastPaymentMethod: CONST.EMPTY_OBJECT, - shouldShowPaymentOptions: false, style: [], policyID: '', formattedAmount: '', @@ -130,7 +126,6 @@ function SettlementButton({ onPress, pressOnEnter, policyID, - shouldShowPaymentOptions, style, }) { const {translate} = useLocalize(); @@ -164,34 +159,11 @@ function SettlementButton({ // To achieve the one tap pay experience we need to choose the correct payment type as default, // if user already paid for some request or expense, let's use the last payment method or use default. - let paymentMethod = nvp_lastPaymentMethod[policyID] || ''; - if (!shouldShowPaymentOptions) { - if (!paymentMethod) { - // In case the user hasn't paid a request yet, let's default to VBBA payment type in case of expense reports - if (isExpenseReport) { - paymentMethod = CONST.IOU.PAYMENT_TYPE.VBBA; - } else if (canUseWallet) { - // If they have Wallet set up, use that payment method as default - paymentMethod = CONST.IOU.PAYMENT_TYPE.EXPENSIFY; - } else { - paymentMethod = CONST.IOU.PAYMENT_TYPE.ELSEWHERE; - } - } - - // In case of the settlement button in the report preview component, we do not show payment options and the label for Wallet and ACH type is simply "Pay". - return [ - { - ...paymentMethods[paymentMethod], - text: paymentMethod === CONST.IOU.PAYMENT_TYPE.ELSEWHERE ? translate('iou.payElsewhere') : translate('iou.pay'), - }, - ]; - } + const paymentMethod = nvp_lastPaymentMethod[policyID] || ''; if (canUseWallet) { buttonOptions.push(paymentMethods[CONST.IOU.PAYMENT_TYPE.EXPENSIFY]); } - if (isExpenseReport) { - buttonOptions.push(paymentMethods[CONST.IOU.PAYMENT_TYPE.VBBA]); - } + buttonOptions.push(paymentMethods[CONST.IOU.PAYMENT_TYPE.VBBA]); buttonOptions.push(paymentMethods[CONST.IOU.PAYMENT_TYPE.ELSEWHERE]); // Put the preferred payment method to the front of the array so its shown as default @@ -199,7 +171,7 @@ function SettlementButton({ return _.sortBy(buttonOptions, (method) => (method.value === paymentMethod ? 0 : 1)); } return buttonOptions; - }, [betas, currency, formattedAmount, iouReport, nvp_lastPaymentMethod, policyID, shouldShowPaymentOptions, translate]); + }, [betas, currency, formattedAmount, iouReport, nvp_lastPaymentMethod, policyID, translate]); const selectPaymentType = (event, iouPaymentType, triggerKYCFlow) => { if (iouPaymentType === CONST.IOU.PAYMENT_TYPE.EXPENSIFY || iouPaymentType === CONST.IOU.PAYMENT_TYPE.VBBA) { diff --git a/src/languages/en.ts b/src/languages/en.ts index 183f0638fbad..d23f33f39090 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -215,6 +215,8 @@ export default { more: 'More', debitCard: 'Debit card', bankAccount: 'Bank account', + personalBankAccount: 'Personal bank account', + businessBankAccount: 'Business bank account', join: 'Join', leave: 'Leave', decline: 'Decline', diff --git a/src/languages/es.ts b/src/languages/es.ts index 12b0c95579e5..65af5112c720 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -205,6 +205,8 @@ export default { more: 'Más', debitCard: 'Tarjeta de débito', bankAccount: 'Cuenta bancaria', + personalBankAccount: 'Cuenta bancaria personal', + businessBankAccount: 'Cuenta bancaria comercial', join: 'Unirse', leave: 'Salir', decline: 'Rechazar', diff --git a/src/libs/PaymentUtils.ts b/src/libs/PaymentUtils.ts index b37db2584394..5bd70fee4d83 100644 --- a/src/libs/PaymentUtils.ts +++ b/src/libs/PaymentUtils.ts @@ -26,7 +26,7 @@ function hasExpensifyPaymentMethod(fundList: Record, bankAccountLi function getPaymentMethodDescription(accountType: AccountType, account: BankAccount['accountData'] | Fund['accountData']): string { if (account) { - if (accountType === CONST.PAYMENT_METHODS.BANK_ACCOUNT && 'accountNumber' in account) { + if (accountType === CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT && 'accountNumber' in account) { return `${Localize.translateLocal('paymentMethodList.accountLastFour')} ${account.accountNumber?.slice(-4)}`; } if (accountType === CONST.PAYMENT_METHODS.DEBIT_CARD && 'cardNumber' in account) { diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index 4615cac245ea..29d426e494a0 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -69,7 +69,7 @@ function isDeletedParentAction(reportAction: OnyxEntry): boolean { } function isReversedTransaction(reportAction: OnyxEntry) { - return (reportAction?.message?.[0].isReversedTransaction ?? false) && (reportAction?.childVisibleActionCount ?? 0) > 0; + return (reportAction?.message?.[0]?.isReversedTransaction ?? false) && (reportAction?.childVisibleActionCount ?? 0) > 0; } function isPendingRemove(reportAction: OnyxEntry): boolean { @@ -628,6 +628,26 @@ function isNotifiableReportAction(reportAction: OnyxEntry): boolea return actions.includes(reportAction.actionName); } +/** + * Helper method to determine if the provided accountID has made a request on the specified report. + * + * @param reportID + * @param currentAccountID + * @returns + */ +function hasRequestFromCurrentAccount(reportID: string, currentAccountID: number): boolean { + if (!reportID) { + return false; + } + + const reportActions = Object.values(getAllReportActions(reportID)); + if (reportActions.length === 0) { + return false; + } + + return reportActions.some((action) => action.actionName === CONST.REPORT.ACTIONS.TYPE.IOU && action.actorAccountID === currentAccountID); +} + export { extractLinksFromMessageHtml, getAllReportActions, @@ -668,6 +688,7 @@ export { isReimbursementQueuedAction, shouldReportActionBeVisible, shouldReportActionBeVisibleAsLastAction, + hasRequestFromCurrentAccount, getFirstVisibleReportActionID, isChannelLogMemberAction, }; diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 673cb09232de..3291a33d8d44 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -1820,9 +1820,10 @@ function getTransactionReportName(reportAction) { * @param {Object} [reportAction={}] This can be either a report preview action or the IOU action * @param {Boolean} [shouldConsiderReceiptBeingScanned=false] * @param {Boolean} isPreviewMessageForParentChatReport + * @param {Object} [policy] * @returns {String} */ -function getReportPreviewMessage(report, reportAction = {}, shouldConsiderReceiptBeingScanned = false, isPreviewMessageForParentChatReport = false) { +function getReportPreviewMessage(report, reportAction = {}, shouldConsiderReceiptBeingScanned = false, isPreviewMessageForParentChatReport = false, policy = undefined) { const reportActionMessage = lodashGet(reportAction, 'message[0].html', ''); if (_.isEmpty(report) || !report.reportID) { @@ -1846,7 +1847,7 @@ function getReportPreviewMessage(report, reportAction = {}, shouldConsiderReceip } const totalAmount = getMoneyRequestReimbursableTotal(report); - const payerName = isExpenseReport(report) ? getPolicyName(report) : getDisplayNameForParticipant(report.managerID, true); + const payerName = isExpenseReport(report) ? getPolicyName(report, false, policy) : getDisplayNameForParticipant(report.managerID, true); const formattedAmount = CurrencyUtils.convertToDisplayString(totalAmount, report.currency); if (isReportApproved(report) && getPolicyType(report, allPolicies) === CONST.POLICY.TYPE.CORPORATE) { @@ -2669,6 +2670,7 @@ function buildOptimisticIOUReportAction( whisperedToAccountIDs: _.contains([CONST.IOU.RECEIPT_STATE.SCANREADY, CONST.IOU.RECEIPT_STATE.SCANNING], receipt.state) ? [currentUserAccountID] : [], }; } + /** * Builds an optimistic APPROVED report action with a randomly generated reportActionID. * @@ -2707,6 +2709,56 @@ function buildOptimisticApprovedReportAction(amount, currency, expenseReportID) }; } +/** + * Builds an optimistic MOVED report action with a randomly generated reportActionID. + * This action is used when we move reports across workspaces. + * + * @param {String} fromPolicyID + * @param {String} toPolicyID + * @param {Number} newParentReportID + * @param {Number} movedReportID + * + * @returns {Object} + */ +function buildOptimisticMovedReportAction(fromPolicyID, toPolicyID, newParentReportID, movedReportID) { + const originalMessage = { + fromPolicyID, + toPolicyID, + newParentReportID, + movedReportID, + }; + + const policyName = getPolicyName(allReports[`${ONYXKEYS.COLLECTION.REPORT}${newParentReportID}`]); + const movedActionMessage = [ + { + html: `moved the report to the ${policyName} workspace`, + text: `moved the report to the ${policyName} workspace`, + type: CONST.REPORT.MESSAGE.TYPE.COMMENT, + }, + ]; + + return { + actionName: CONST.REPORT.ACTIONS.TYPE.MOVED, + actorAccountID: currentUserAccountID, + automatic: false, + avatar: lodashGet(currentUserPersonalDetails, 'avatar', UserUtils.getDefaultAvatarURL(currentUserAccountID)), + isAttachment: false, + originalMessage, + message: movedActionMessage, + person: [ + { + style: 'strong', + text: lodashGet(currentUserPersonalDetails, 'displayName', currentUserEmail), + type: 'TEXT', + }, + ], + reportActionID: NumberUtils.rand64(), + shouldShow: true, + created: DateUtils.getDBTime(), + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + }; +} + /** * Builds an optimistic SUBMITTED report action with a randomly generated reportActionID. * @@ -4341,6 +4393,7 @@ export { buildOptimisticEditedTaskReportAction, buildOptimisticIOUReport, buildOptimisticApprovedReportAction, + buildOptimisticMovedReportAction, buildOptimisticSubmittedReportAction, buildOptimisticExpenseReport, buildOptimisticIOUReportAction, diff --git a/src/libs/actions/PaymentMethods.ts b/src/libs/actions/PaymentMethods.ts index bcc5d8142470..02f0b49fe3d2 100644 --- a/src/libs/actions/PaymentMethods.ts +++ b/src/libs/actions/PaymentMethods.ts @@ -81,7 +81,7 @@ function getMakeDefaultPaymentOnyxData( key: ONYXKEYS.USER_WALLET, value: { walletLinkedAccountID: bankAccountID || fundID, - walletLinkedAccountType: bankAccountID ? CONST.PAYMENT_METHODS.BANK_ACCOUNT : CONST.PAYMENT_METHODS.DEBIT_CARD, + walletLinkedAccountType: bankAccountID ? CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT : CONST.PAYMENT_METHODS.DEBIT_CARD, // Only clear the error if this is optimistic data. If this is failure data, we do not want to clear the error that came from the server. errors: null, }, @@ -91,7 +91,7 @@ function getMakeDefaultPaymentOnyxData( key: ONYXKEYS.USER_WALLET, value: { walletLinkedAccountID: bankAccountID || fundID, - walletLinkedAccountType: bankAccountID ? CONST.PAYMENT_METHODS.BANK_ACCOUNT : CONST.PAYMENT_METHODS.DEBIT_CARD, + walletLinkedAccountType: bankAccountID ? CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT : CONST.PAYMENT_METHODS.DEBIT_CARD, }, }, ]; @@ -99,7 +99,7 @@ function getMakeDefaultPaymentOnyxData( if (previousPaymentMethod?.methodID) { onyxData.push({ onyxMethod: Onyx.METHOD.MERGE, - key: previousPaymentMethod.accountType === CONST.PAYMENT_METHODS.BANK_ACCOUNT ? ONYXKEYS.BANK_ACCOUNT_LIST : ONYXKEYS.FUND_LIST, + key: previousPaymentMethod.accountType === CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT ? ONYXKEYS.BANK_ACCOUNT_LIST : ONYXKEYS.FUND_LIST, value: { [previousPaymentMethod.methodID]: { isDefault: !isOptimisticData, @@ -111,7 +111,7 @@ function getMakeDefaultPaymentOnyxData( if (currentPaymentMethod?.methodID) { onyxData.push({ onyxMethod: Onyx.METHOD.MERGE, - key: currentPaymentMethod.accountType === CONST.PAYMENT_METHODS.BANK_ACCOUNT ? ONYXKEYS.BANK_ACCOUNT_LIST : ONYXKEYS.FUND_LIST, + key: currentPaymentMethod.accountType === CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT ? ONYXKEYS.BANK_ACCOUNT_LIST : ONYXKEYS.FUND_LIST, value: { [currentPaymentMethod.methodID]: { isDefault: isOptimisticData, @@ -223,7 +223,8 @@ function clearDebitCardFormErrorAndSubmit() { * */ function transferWalletBalance(paymentMethod: PaymentMethod) { - const paymentMethodIDKey = paymentMethod.accountType === CONST.PAYMENT_METHODS.BANK_ACCOUNT ? CONST.PAYMENT_METHOD_ID_KEYS.BANK_ACCOUNT : CONST.PAYMENT_METHOD_ID_KEYS.DEBIT_CARD; + const paymentMethodIDKey = + paymentMethod.accountType === CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT ? CONST.PAYMENT_METHOD_ID_KEYS.BANK_ACCOUNT : CONST.PAYMENT_METHOD_ID_KEYS.DEBIT_CARD; type TransferWalletBalanceParameters = Partial, number | undefined>>; diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 4df510d44db7..ebc1cdf9a2e1 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -7,12 +7,15 @@ import lodashUnion from 'lodash/union'; import Onyx from 'react-native-onyx'; import _ from 'underscore'; import * as API from '@libs/API'; +import DateUtils from '@libs/DateUtils'; import * as ErrorUtils from '@libs/ErrorUtils'; import Log from '@libs/Log'; import * as NumberUtils from '@libs/NumberUtils'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; +import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import * as ReportUtils from '@libs/ReportUtils'; +import * as TransactionUtils from '@libs/TransactionUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -415,9 +418,10 @@ function removeMembers(accountIDs, policyID) { * * @param {String} policyID * @param {Object} invitedEmailsToAccountIDs + * @param {Boolean} hasOutstandingChildRequest * @returns {Object} - object with onyxSuccessData, onyxOptimisticData, and optimisticReportIDs (map login to reportID) */ -function createPolicyExpenseChats(policyID, invitedEmailsToAccountIDs) { +function createPolicyExpenseChats(policyID, invitedEmailsToAccountIDs, hasOutstandingChildRequest = false) { const workspaceMembersChats = { onyxSuccessData: [], onyxOptimisticData: [], @@ -463,6 +467,7 @@ function createPolicyExpenseChats(policyID, invitedEmailsToAccountIDs) { createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, }, isOptimisticReport: true, + hasOutstandingChildRequest, }, }); workspaceMembersChats.onyxOptimisticData.push({ @@ -1458,6 +1463,403 @@ function buildOptimisticPolicyRecentlyUsedCategories(policyID, category) { return lodashUnion([category], policyRecentlyUsedCategories); } +/** + * This flow is used for bottom up flow converting IOU report to an expense report. When user takes this action, + * we create a Collect type workspace when the person taking the action becomes an owner and an admin, while we + * add a new member to the workspace as an employee and convert the IOU report passed as a param into an expense report. + * + * @param {Object} iouReport + * @returns {String} policyID of the workspace we have created + */ +function createWorkspaceFromIOUPayment(iouReport) { + // This flow only works for IOU reports + if (!ReportUtils.isIOUReport(iouReport)) { + return; + } + + // Generate new variables for the policy + const policyID = generatePolicyID(); + const workspaceName = generateDefaultWorkspaceName(sessionEmail); + const employeeAccountID = iouReport.ownerAccountID; + const employeeEmail = iouReport.ownerEmail; + const {customUnits, customUnitID, customUnitRateID} = buildOptimisticCustomUnits(); + const oldPersonalPolicyID = iouReport.policyID; + const iouReportID = iouReport.reportID; + + const { + announceChatReportID, + announceChatData, + announceReportActionData, + announceCreatedReportActionID, + adminsChatReportID, + adminsChatData, + adminsReportActionData, + adminsCreatedReportActionID, + expenseChatReportID: workspaceChatReportID, + expenseChatData: workspaceChatData, + expenseReportActionData: workspaceChatReportActionData, + expenseCreatedReportActionID: workspaceChatCreatedReportActionID, + } = ReportUtils.buildOptimisticWorkspaceChats(policyID, workspaceName); + + // Create the workspace chat for the employee whose IOU is being paid + const employeeWorkspaceChat = createPolicyExpenseChats(policyID, {[employeeEmail]: employeeAccountID}, true); + const newWorkspace = { + id: policyID, + + // We are creating a collect policy in this case + type: CONST.POLICY.TYPE.TEAM, + name: workspaceName, + role: CONST.POLICY.ROLE.ADMIN, + owner: sessionEmail, + isPolicyExpenseChatEnabled: true, + + // Setting the currency to USD as we can only add the VBBA for this policy currency right now + outputCurrency: CONST.CURRENCY.USD, + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + customUnits, + }; + + const optimisticData = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: newWorkspace, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY_MEMBERS}${policyID}`, + value: { + [sessionAccountID]: { + role: CONST.POLICY.ROLE.ADMIN, + errors: {}, + }, + [employeeAccountID]: { + role: CONST.POLICY.ROLE.USER, + errors: {}, + }, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${announceChatReportID}`, + value: { + pendingFields: { + addWorkspaceRoom: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + }, + ...announceChatData, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${announceChatReportID}`, + value: announceReportActionData, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`, + value: { + pendingFields: { + addWorkspaceRoom: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + }, + ...adminsChatData, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${adminsChatReportID}`, + value: adminsReportActionData, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${workspaceChatReportID}`, + value: { + pendingFields: { + addWorkspaceRoom: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + }, + ...workspaceChatData, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${workspaceChatReportID}`, + value: workspaceChatReportActionData, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY_DRAFTS}${policyID}`, + value: null, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY_MEMBERS_DRAFTS}${policyID}`, + value: null, + }, + ...employeeWorkspaceChat.onyxOptimisticData, + ]; + + const successData = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: {pendingAction: null}, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${announceChatReportID}`, + value: { + pendingFields: { + addWorkspaceRoom: null, + }, + pendingAction: null, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${announceChatReportID}`, + value: { + [_.keys(announceChatData)[0]]: { + pendingAction: null, + }, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`, + value: { + pendingFields: { + addWorkspaceRoom: null, + }, + pendingAction: null, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${adminsChatReportID}`, + value: { + [_.keys(adminsChatData)[0]]: { + pendingAction: null, + }, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${workspaceChatReportID}`, + value: { + pendingFields: { + addWorkspaceRoom: null, + }, + pendingAction: null, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${workspaceChatReportID}`, + value: { + [_.keys(workspaceChatData)[0]]: { + pendingAction: null, + }, + }, + }, + ...employeeWorkspaceChat.onyxSuccessData, + ]; + + const failureData = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY_MEMBERS}${policyID}`, + value: null, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${announceChatReportID}`, + value: null, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${announceChatReportID}`, + value: null, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${adminsChatReportID}`, + value: null, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${adminsChatReportID}`, + value: null, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${workspaceChatReportID}`, + value: null, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${workspaceChatReportID}`, + value: null, + }, + ]; + + // Compose the memberData object which is used to add the employee to the workspace and + // optimistically create the workspace chat for them. + const memberData = { + accountID: Number(employeeAccountID), + email: employeeEmail, + workspaceChatReportID: employeeWorkspaceChat.reportCreationData[employeeEmail].reportID, + workspaceChatCreatedReportActionID: employeeWorkspaceChat.reportCreationData[employeeEmail].reportActionID, + }; + + const oldChatReportID = iouReport.chatReportID; + + // Next we need to convert the IOU report to Expense report. + // We need to change: + // - report type + // - change the sign of the report total + // - update its policyID and policyName + // - update the chatReportID to point to the new workspace chat + const expenseReport = { + ...iouReport, + chatReportID: memberData.workspaceChatReportID, + policyID, + policyName: workspaceName, + type: CONST.REPORT.TYPE.EXPENSE, + total: -iouReport.total, + }; + optimisticData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${iouReportID}`, + value: expenseReport, + }); + failureData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${iouReportID}`, + value: iouReport, + }); + + // The expense report transactions need to have the amount reversed to negative values + const reportTransactions = TransactionUtils.getAllReportTransactions(iouReportID); + + // For performance reasons, we are going to compose a merge collection data for transactions + const transactionsOptimisticData = {}; + const transactionFailureData = {}; + _.each(reportTransactions, (transaction) => { + transactionsOptimisticData[`${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`] = { + ...transaction, + amount: -transaction.amount, + modifiedAmount: transaction.modifiedAmount ? -transaction.modifiedAmount : 0, + }; + + transactionFailureData[`${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`] = transaction; + }); + + optimisticData.push({ + onyxMethod: Onyx.METHOD.MERGE_COLLECTION, + key: `${ONYXKEYS.COLLECTION.TRANSACTION}`, + value: transactionsOptimisticData, + }); + failureData.push({ + onyxMethod: Onyx.METHOD.MERGE_COLLECTION, + key: `${ONYXKEYS.COLLECTION.TRANSACTION}`, + value: transactionFailureData, + }); + + // We need to move the report preview action from the DM to the workspace chat. + const reportPreview = ReportActionsUtils.getParentReportAction(iouReport); + optimisticData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oldChatReportID}`, + value: {[reportPreview.reportActionID]: null}, + }); + failureData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oldChatReportID}`, + value: {[reportPreview.reportActionID]: reportPreview}, + }); + + // To optimistically remove the GBR from the DM we need to update the hasOutstandingChildRequest param to false + optimisticData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${oldChatReportID}`, + value: { + hasOutstandingChildRequest: false, + }, + }); + failureData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${oldChatReportID}`, + value: { + hasOutstandingChildRequest: true, + }, + }); + + // Update the created timestamp of the report preview action to be after the workspace chat created timestamp. + optimisticData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${memberData.workspaceChatReportID}`, + value: { + [reportPreview.reportActionID]: { + ...reportPreview, + message: ReportUtils.getReportPreviewMessage(expenseReport, {}, false, false, newWorkspace), + created: DateUtils.getDBTime(), + }, + }, + }); + failureData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${memberData.workspaceChatReportID}`, + value: {[reportPreview.reportActionID]: null}, + }); + + // Create the MOVED report action and add it to the DM chat which indicates to the user where the report has been moved + const movedReportAction = ReportUtils.buildOptimisticMovedReportAction(oldPersonalPolicyID, policyID, memberData.workspaceChatReportID, iouReportID); + optimisticData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oldChatReportID}`, + value: {[movedReportAction.reportActionID]: movedReportAction}, + }); + successData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oldChatReportID}`, + value: { + [movedReportAction.reportActionID]: { + ...movedReportAction, + pendingAction: null, + }, + }, + }); + failureData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oldChatReportID}`, + value: {[movedReportAction.reportActionID]: null}, + }); + + API.write( + 'CreateWorkspaceFromIOUPayment', + { + policyID, + announceChatReportID, + adminsChatReportID, + expenseChatReportID: workspaceChatReportID, + ownerEmail: '', + makeMeAdmin: false, + policyName: workspaceName, + type: CONST.POLICY.TYPE.TEAM, + announceCreatedReportActionID, + adminsCreatedReportActionID, + expenseCreatedReportActionID: workspaceChatCreatedReportActionID, + customUnitID, + customUnitRateID, + iouReportID, + memberData: JSON.stringify(memberData), + reportActionID: movedReportAction.reportActionID, + }, + {optimisticData, successData, failureData}, + ); + + return policyID; +} + export { removeMembers, addMembersToWorkspace, @@ -1484,6 +1886,7 @@ export { openWorkspaceMembersPage, openWorkspaceInvitePage, removeWorkspace, + createWorkspaceFromIOUPayment, setWorkspaceInviteMembersDraft, clearErrors, dismissAddedWithPrimaryLoginMessages, diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 9f803f72cbbb..17d49bd0f486 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -428,7 +428,12 @@ function ReportActionItem(props) { isHidden={isHidden} style={[ _.contains( - [..._.values(CONST.REPORT.ACTIONS.TYPE.POLICYCHANGELOG), CONST.REPORT.ACTIONS.TYPE.IOU, CONST.REPORT.ACTIONS.TYPE.APPROVED], + [ + ..._.values(CONST.REPORT.ACTIONS.TYPE.POLICYCHANGELOG), + CONST.REPORT.ACTIONS.TYPE.IOU, + CONST.REPORT.ACTIONS.TYPE.APPROVED, + CONST.REPORT.ACTIONS.TYPE.MOVED, + ], props.action.actionName, ) ? styles.colorMuted diff --git a/src/pages/settings/Wallet/ChooseTransferAccountPage.js b/src/pages/settings/Wallet/ChooseTransferAccountPage.js index 15c172d33626..2ffbf12f52c2 100644 --- a/src/pages/settings/Wallet/ChooseTransferAccountPage.js +++ b/src/pages/settings/Wallet/ChooseTransferAccountPage.js @@ -37,7 +37,7 @@ function ChooseTransferAccountPage(props) { * @param {Object} account of the selected account data */ const selectAccountAndNavigateBack = (event, accountType, account) => { - PaymentMethods.saveWalletTransferAccountTypeAndID(accountType, accountType === CONST.PAYMENT_METHODS.BANK_ACCOUNT ? account.bankAccountID : account.fundID); + PaymentMethods.saveWalletTransferAccountTypeAndID(accountType, accountType === CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT ? account.bankAccountID : account.fundID); Navigation.goBack(ROUTES.SETTINGS_WALLET_TRANSFER_BALANCE); }; @@ -70,7 +70,7 @@ function ChooseTransferAccountPage(props) { method.accountType === CONST.PAYMENT_METHODS.BANK_ACCOUNT || method.accountType === CONST.PAYMENT_METHODS.DEBIT_CARD, + (method) => method.accountType === CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT || method.accountType === CONST.PAYMENT_METHODS.DEBIT_CARD, ).length; return defaultablePaymentMethodCount > 1; } diff --git a/src/pages/settings/Wallet/TransferBalancePage.js b/src/pages/settings/Wallet/TransferBalancePage.js index 41120a158acd..59704e323eb6 100644 --- a/src/pages/settings/Wallet/TransferBalancePage.js +++ b/src/pages/settings/Wallet/TransferBalancePage.js @@ -85,7 +85,7 @@ function TransferBalancePage(props) { title: props.translate('transferAmountPage.ach'), description: props.translate('transferAmountPage.achSummary'), icon: Expensicons.Bank, - type: CONST.PAYMENT_METHODS.BANK_ACCOUNT, + type: CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT, }, ]; @@ -146,7 +146,7 @@ function TransferBalancePage(props) { { - if (paymentMethod.selectedPaymentMethodType === CONST.PAYMENT_METHODS.BANK_ACCOUNT) { + if (paymentMethod.selectedPaymentMethodType === CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT) { return paymentMethod.selectedPaymentMethod.bankAccountID; } if (paymentMethod.selectedPaymentMethodType === CONST.PAYMENT_METHODS.DEBIT_CARD) { @@ -152,12 +152,12 @@ function WalletPage({bankAccountList, betas, cardList, fundList, isLoadingPaymen // The delete/default menu if (accountType) { let formattedSelectedPaymentMethod; - if (accountType === CONST.PAYMENT_METHODS.BANK_ACCOUNT) { + if (accountType === CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT) { formattedSelectedPaymentMethod = { title: account.addressName, icon: account.icon, description: PaymentUtils.getPaymentMethodDescription(accountType, account), - type: CONST.PAYMENT_METHODS.BANK_ACCOUNT, + type: CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT, }; } else if (accountType === CONST.PAYMENT_METHODS.DEBIT_CARD) { formattedSelectedPaymentMethod = { @@ -202,7 +202,7 @@ function WalletPage({bankAccountList, betas, cardList, fundList, isLoadingPaymen return; } - if (paymentType === CONST.PAYMENT_METHODS.BANK_ACCOUNT) { + if (paymentType === CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT) { BankAccounts.openPersonalBankAccountSetupView(); return; } @@ -228,7 +228,7 @@ function WalletPage({bankAccountList, betas, cardList, fundList, isLoadingPaymen const previousPaymentMethod = _.find(paymentMethods, (method) => method.isDefault); const currentPaymentMethod = _.find(paymentMethods, (method) => method.methodID === paymentMethod.methodID); - if (paymentMethod.selectedPaymentMethodType === CONST.PAYMENT_METHODS.BANK_ACCOUNT) { + if (paymentMethod.selectedPaymentMethodType === CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT) { PaymentMethods.makeDefaultPaymentMethod(paymentMethod.selectedPaymentMethod.bankAccountID, null, previousPaymentMethod, currentPaymentMethod); } else if (paymentMethod.selectedPaymentMethodType === CONST.PAYMENT_METHODS.DEBIT_CARD) { PaymentMethods.makeDefaultPaymentMethod(null, paymentMethod.selectedPaymentMethod.fundID, previousPaymentMethod, currentPaymentMethod); @@ -243,7 +243,7 @@ function WalletPage({bankAccountList, betas, cardList, fundList, isLoadingPaymen ]); const deletePaymentMethod = useCallback(() => { - if (paymentMethod.selectedPaymentMethodType === CONST.PAYMENT_METHODS.BANK_ACCOUNT) { + if (paymentMethod.selectedPaymentMethodType === CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT) { BankAccounts.deletePaymentBankAccount(paymentMethod.selectedPaymentMethod.bankAccountID); } else if (paymentMethod.selectedPaymentMethodType === CONST.PAYMENT_METHODS.DEBIT_CARD) { PaymentMethods.deletePaymentCard(paymentMethod.selectedPaymentMethod.fundID); @@ -294,7 +294,7 @@ function WalletPage({bankAccountList, betas, cardList, fundList, isLoadingPaymen // We should reset selected payment method state values and close corresponding modals if the selected payment method is deleted let shouldResetPaymentMethodData = false; - if (paymentMethod.selectedPaymentMethodType === CONST.PAYMENT_METHODS.BANK_ACCOUNT && _.isEmpty(bankAccountList[paymentMethod.methodID])) { + if (paymentMethod.selectedPaymentMethodType === CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT && _.isEmpty(bankAccountList[paymentMethod.methodID])) { shouldResetPaymentMethodData = true; } else if (paymentMethod.selectedPaymentMethodType === CONST.PAYMENT_METHODS.DEBIT_CARD && _.isEmpty(fundList[paymentMethod.methodID])) { shouldResetPaymentMethodData = true; @@ -310,7 +310,7 @@ function WalletPage({bankAccountList, betas, cardList, fundList, isLoadingPaymen const shouldShowMakeDefaultButton = !paymentMethod.isSelectedPaymentMethodDefault && Permissions.canUseWallet(betas) && - !(paymentMethod.formattedSelectedPaymentMethod.type === CONST.PAYMENT_METHODS.BANK_ACCOUNT && paymentMethod.selectedPaymentMethod.type === CONST.BANK_ACCOUNT.TYPE.BUSINESS); + !(paymentMethod.formattedSelectedPaymentMethod.type === CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT && paymentMethod.selectedPaymentMethod.type === CONST.BANK_ACCOUNT.TYPE.BUSINESS); // Determines whether or not the modal popup is mounted from the bottom of the screen instead of the side mount on Web or Desktop screens const isPopoverBottomMount = anchorPosition.anchorPositionTop === 0 || isSmallScreenWidth; @@ -364,7 +364,7 @@ function WalletPage({bankAccountList, betas, cardList, fundList, isLoadingPaymen navigateToWalletOrTransferBalancePage(source)} onSelectPaymentMethod={(selectedPaymentMethod) => { - if (hasActivatedWallet || selectedPaymentMethod !== CONST.PAYMENT_METHODS.BANK_ACCOUNT) { + if (hasActivatedWallet || selectedPaymentMethod !== CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT) { return; } // To allow upgrading to a gold wallet, continue with the KYC flow after adding a bank account diff --git a/src/pages/settings/Wallet/walletTransferPropTypes.js b/src/pages/settings/Wallet/walletTransferPropTypes.js index 38c65fcfd703..9e25213382e9 100644 --- a/src/pages/settings/Wallet/walletTransferPropTypes.js +++ b/src/pages/settings/Wallet/walletTransferPropTypes.js @@ -7,7 +7,7 @@ const walletTransferPropTypes = PropTypes.shape({ selectedAccountID: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), /** Type to filter the payment Method list */ - filterPaymentMethodType: PropTypes.oneOf([CONST.PAYMENT_METHODS.DEBIT_CARD, CONST.PAYMENT_METHODS.BANK_ACCOUNT, '']), + filterPaymentMethodType: PropTypes.oneOf([CONST.PAYMENT_METHODS.DEBIT_CARD, CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT, '']), /** Whether the success screen is shown to user. */ shouldShowSuccess: PropTypes.bool, diff --git a/src/types/onyx/BankAccount.ts b/src/types/onyx/BankAccount.ts index 4a7b6dac7387..2b2bee7df6b0 100644 --- a/src/types/onyx/BankAccount.ts +++ b/src/types/onyx/BankAccount.ts @@ -4,7 +4,7 @@ import * as OnyxCommon from './OnyxCommon'; type BankAccount = { /** The bank account type */ - accountType?: typeof CONST.PAYMENT_METHODS.BANK_ACCOUNT; + accountType?: typeof CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT; /** string like 'Account ending in XXXX' */ description?: string; diff --git a/src/types/onyx/WalletTransfer.ts b/src/types/onyx/WalletTransfer.ts index e1b1468d6536..cebea543884b 100644 --- a/src/types/onyx/WalletTransfer.ts +++ b/src/types/onyx/WalletTransfer.ts @@ -25,7 +25,7 @@ type WalletTransfer = { paymentMethodType?: ValueOf>; }; -type FilterMethodPaymentType = typeof CONST.PAYMENT_METHODS.DEBIT_CARD | typeof CONST.PAYMENT_METHODS.BANK_ACCOUNT | null; +type FilterMethodPaymentType = typeof CONST.PAYMENT_METHODS.DEBIT_CARD | typeof CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT | null; export default WalletTransfer;