From 9044315da6eb175aa21d5dc817dd18a3b27709dc Mon Sep 17 00:00:00 2001 From: Hans Date: Thu, 24 Apr 2025 17:54:07 +0700 Subject: [PATCH 1/3] address invoices issue part1 --- src/components/SettlementButton/index.tsx | 67 ++++++++++------------- src/libs/actions/IOU.ts | 2 +- src/types/onyx/LastPaymentMethod.ts | 6 +- 3 files changed, 33 insertions(+), 42 deletions(-) diff --git a/src/components/SettlementButton/index.tsx b/src/components/SettlementButton/index.tsx index f142bc9f43f8..7fafa6fdaaa2 100644 --- a/src/components/SettlementButton/index.tsx +++ b/src/components/SettlementButton/index.tsx @@ -264,40 +264,9 @@ function SettlementButton({ }, })); - if (isIndividualInvoiceRoomUtil(chatReport)) { - buttonOptions.push({ - text: translate('iou.settlePersonal', {formattedAmount}), - icon: Expensicons.User, - value: lastPaymentMethod ?? CONST.IOU.PAYMENT_TYPE.ELSEWHERE, - backButtonText: translate('iou.individual'), - subMenuItems: [ - ...(isCurrencySupported ? getPaymentSubitems(false) : []), - { - text: translate('workspace.invoices.paymentMethods.addBankAccount'), - icon: Expensicons.Bank, - onSelected: () => Navigation.navigate(addBankAccountRoute), - }, - { - text: translate('iou.payElsewhere', {formattedAmount: ''}), - icon: Expensicons.Cash, - value: CONST.IOU.PAYMENT_TYPE.ELSEWHERE, - shouldUpdateSelectedIndex: true, - onSelected: () => { - onPress(CONST.IOU.PAYMENT_TYPE.ELSEWHERE, undefined, undefined); - savePreferredPaymentMethod(policyIDKey, CONST.IOU.PAYMENT_TYPE.ELSEWHERE); - }, - }, - ], - }); - } - - buttonOptions.push({ - text: translate('iou.settleBusiness', {formattedAmount}), - icon: Expensicons.Building, - value: lastPaymentMethod ?? CONST.IOU.PAYMENT_TYPE.ELSEWHERE, - backButtonText: translate('iou.business'), - subMenuItems: [ - ...(isCurrencySupported ? getPaymentSubitems(true) : []), + const getInvoicesOptions = (payAsBusiness: boolean) => { + return [ + ...(isCurrencySupported ? getPaymentSubitems(payAsBusiness) : []), { text: translate('workspace.invoices.paymentMethods.addBankAccount'), icon: Expensicons.Bank, @@ -309,12 +278,32 @@ function SettlementButton({ value: CONST.IOU.PAYMENT_TYPE.ELSEWHERE, shouldUpdateSelectedIndex: true, onSelected: () => { - onPress(CONST.IOU.PAYMENT_TYPE.ELSEWHERE, true); + onPress(CONST.IOU.PAYMENT_TYPE.ELSEWHERE, payAsBusiness, undefined); savePreferredPaymentMethod(policyIDKey, CONST.IOU.PAYMENT_TYPE.ELSEWHERE); }, }, - ], - }); + ]; + }; + + if (isIndividualInvoiceRoomUtil(chatReport)) { + buttonOptions.push({ + text: translate('iou.settlePersonal', {formattedAmount}), + icon: Expensicons.User, + value: lastPaymentMethod ?? CONST.IOU.PAYMENT_TYPE.ELSEWHERE, + backButtonText: translate('iou.individual'), + subMenuItems: getInvoicesOptions(false), + }); + buttonOptions.push({ + text: translate('iou.settleBusiness', {formattedAmount}), + icon: Expensicons.Building, + value: lastPaymentMethod ?? CONST.IOU.PAYMENT_TYPE.ELSEWHERE, + backButtonText: translate('iou.business'), + subMenuItems: getInvoicesOptions(true), + }); + } else { + // If there is pay as business option, we should show the submenu items instead. + buttonOptions.push(...getInvoicesOptions(true)); + } } if (shouldShowApproveButton) { @@ -453,6 +442,8 @@ function SettlementButton({ const customText = getCustomText(); const secondlineText = getSecondLineText(); + const shouldUseSplitButton = hasPreferredPaymentMethod || !!lastPaymentPolicy || (!!bankAccount && isExpenseReportUtil(iouReport)) || (isInvoiceReport && !isEmpty(latestBankItem)); + return ( onPress(paymentType, undefined, undefined)} @@ -475,7 +466,7 @@ function SettlementButton({ shouldAlwaysShowDropdownMenu={isInvoiceReport} customText={customText} menuHeaderText={isInvoiceReport ? translate('workspace.invoices.paymentMethods.chooseInvoiceMethod') : undefined} - isSplitButton={hasPreferredPaymentMethod || !!lastPaymentPolicy || (!!bankAccount && isExpenseReportUtil(iouReport))} + isSplitButton={shouldUseSplitButton} isDisabled={isDisabled} isLoading={isLoading} defaultSelectedIndex={lastPaymentPolicy ? paymentButtonOptions.findIndex((option) => option.value === lastPaymentPolicy.id) : 0} diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index af193f1a8f28..26c426675dae 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -8487,7 +8487,7 @@ function getPayMoneyRequestParams( const optimisticLastPaymentMethod = { [iouReport.policyID]: { lastUsed: paymentMethodType, - ...(isInvoiceReport ? {Invoice: {name: paymentMethodType, bankAccountID}} : {}), + ...(isInvoiceReport ? {invoice: {name: paymentMethodType, bankAccountID}} : {}), }, }; diff --git a/src/types/onyx/LastPaymentMethod.ts b/src/types/onyx/LastPaymentMethod.ts index f25cf9d1abcc..460178a46851 100644 --- a/src/types/onyx/LastPaymentMethod.ts +++ b/src/types/onyx/LastPaymentMethod.ts @@ -18,11 +18,11 @@ type LastPaymentMethodType = { /** The default last payment method */ lastUsed: string; /** The lastPaymentMethod of an IOU */ - Iou: string; + iou: string; /** The lastPaymentMethod of an Expense */ - Expense: string; + expense: string; /** The lastPaymentMethod of an Invoice */ - Invoice: string | PaymentInformation; + invoice: string | PaymentInformation; }; /** Record of last payment methods, indexed by policy id */ From cd7268233b2efeb5eece8a9eb34fac90ec28cb71 Mon Sep 17 00:00:00 2001 From: Hans Date: Mon, 28 Apr 2025 09:56:21 +0700 Subject: [PATCH 2/3] fix comment --- src/components/SettlementButton/index.tsx | 28 ++++++++++++----------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/components/SettlementButton/index.tsx b/src/components/SettlementButton/index.tsx index 7fafa6fdaaa2..3599ff71e41c 100644 --- a/src/components/SettlementButton/index.tsx +++ b/src/components/SettlementButton/index.tsx @@ -128,6 +128,20 @@ function SettlementButton({ const shouldShowPaywithExpensifyOption = !shouldHidePaymentOptions; const shouldShowPayElsewhereOption = !shouldHidePaymentOptions && !isInvoiceReport; + function getPaymentSubitems(payAsBusiness: boolean){ + const formattedPaymentMethods = formatPaymentMethods(bankAccountList, fundList, styles); + return formattedPaymentMethods.map((formattedPaymentMethod) => ({ + text: formattedPaymentMethod?.title ?? '', + description: formattedPaymentMethod?.description ?? '', + icon: formattedPaymentMethod?.icon, + shouldUpdateSelectedIndex: true, + onSelected: () => { + onPress(CONST.IOU.PAYMENT_TYPE.EXPENSIFY, payAsBusiness, formattedPaymentMethod.methodID, formattedPaymentMethod.accountType, undefined); + }, + })) + } + ; + function getLatestBankAccountItem() { if (!hasVBBA(policy?.id)) { return; @@ -251,19 +265,7 @@ function SettlementButton({ } if (isInvoiceReport) { - const formattedPaymentMethods = formatPaymentMethods(bankAccountList, fundList, styles); const isCurrencySupported = isCurrencySupportedForDirectReimbursement(currency as CurrencyType); - const getPaymentSubitems = (payAsBusiness: boolean) => - formattedPaymentMethods.map((formattedPaymentMethod) => ({ - text: formattedPaymentMethod?.title ?? '', - description: formattedPaymentMethod?.description ?? '', - icon: formattedPaymentMethod?.icon, - shouldUpdateSelectedIndex: true, - onSelected: () => { - onPress(CONST.IOU.PAYMENT_TYPE.EXPENSIFY, payAsBusiness, formattedPaymentMethod.methodID, formattedPaymentMethod.accountType, undefined); - }, - })); - const getInvoicesOptions = (payAsBusiness: boolean) => { return [ ...(isCurrencySupported ? getPaymentSubitems(payAsBusiness) : []), @@ -442,7 +444,7 @@ function SettlementButton({ const customText = getCustomText(); const secondlineText = getSecondLineText(); - const shouldUseSplitButton = hasPreferredPaymentMethod || !!lastPaymentPolicy || (!!bankAccount && isExpenseReportUtil(iouReport)) || (isInvoiceReport && !isEmpty(latestBankItem)); + const shouldUseSplitButton = hasPreferredPaymentMethod || !!lastPaymentPolicy || (!!bankAccount && isExpenseReportUtil(iouReport)) || (isInvoiceReport && !isEmpty(getPaymentSubitems(false))); return ( Date: Tue, 29 Apr 2025 00:06:23 +0700 Subject: [PATCH 3/3] add intent to pay --- src/components/SettlementButton/index.tsx | 42 +++++++++++++++-------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/src/components/SettlementButton/index.tsx b/src/components/SettlementButton/index.tsx index 3599ff71e41c..01fe6171149b 100644 --- a/src/components/SettlementButton/index.tsx +++ b/src/components/SettlementButton/index.tsx @@ -33,7 +33,7 @@ import {approveMoneyRequest, savePreferredPaymentMethod as savePreferredPaymentM import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import type {LastPaymentMethodType, Policy} from '@src/types/onyx'; +import type {BankAccount, LastPaymentMethodType, Policy} from '@src/types/onyx'; import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue'; @@ -115,6 +115,8 @@ function SettlementButton({ const hasSinglePolicy = !policy && activeAdminPolicies.length === 1; const hasMultiplePolicies = !policy && activeAdminPolicies.length > 1; const lastPaymentMethodRef = useRef(lastPaymentMethod); + const formattedPaymentMethods = formatPaymentMethods(bankAccountList, fundList, styles); + const hasIntentToPay = formattedPaymentMethods.length === 1 && !lastPaymentMethod; useEffect(() => { if (isLoadingLastPaymentMethod) { @@ -128,8 +130,7 @@ function SettlementButton({ const shouldShowPaywithExpensifyOption = !shouldHidePaymentOptions; const shouldShowPayElsewhereOption = !shouldHidePaymentOptions && !isInvoiceReport; - function getPaymentSubitems(payAsBusiness: boolean){ - const formattedPaymentMethods = formatPaymentMethods(bankAccountList, fundList, styles); + function getPaymentSubitems(payAsBusiness: boolean) { return formattedPaymentMethods.map((formattedPaymentMethod) => ({ text: formattedPaymentMethod?.title ?? '', description: formattedPaymentMethod?.description ?? '', @@ -138,16 +139,13 @@ function SettlementButton({ onSelected: () => { onPress(CONST.IOU.PAYMENT_TYPE.EXPENSIFY, payAsBusiness, formattedPaymentMethod.methodID, formattedPaymentMethod.accountType, undefined); }, - })) + })); } - ; function getLatestBankAccountItem() { if (!hasVBBA(policy?.id)) { return; } - - const formattedPaymentMethods = formatPaymentMethods(bankAccountList, fundList ?? {}, styles); const policyBankAccounts = formattedPaymentMethods.filter((method) => method.methodID === policy?.achAccount?.bankAccountID); return policyBankAccounts.map((formattedPaymentMethod) => ({ @@ -291,14 +289,14 @@ function SettlementButton({ buttonOptions.push({ text: translate('iou.settlePersonal', {formattedAmount}), icon: Expensicons.User, - value: lastPaymentMethod ?? CONST.IOU.PAYMENT_TYPE.ELSEWHERE, + value: hasIntentToPay ? CONST.IOU.PAYMENT_TYPE.EXPENSIFY : lastPaymentMethod ?? CONST.IOU.PAYMENT_TYPE.ELSEWHERE, backButtonText: translate('iou.individual'), subMenuItems: getInvoicesOptions(false), }); buttonOptions.push({ text: translate('iou.settleBusiness', {formattedAmount}), icon: Expensicons.Building, - value: lastPaymentMethod ?? CONST.IOU.PAYMENT_TYPE.ELSEWHERE, + value: hasIntentToPay ? CONST.IOU.PAYMENT_TYPE.EXPENSIFY : lastPaymentMethod ?? CONST.IOU.PAYMENT_TYPE.ELSEWHERE, backButtonText: translate('iou.business'), subMenuItems: getInvoicesOptions(true), }); @@ -352,6 +350,19 @@ function SettlementButton({ return; } if (isInvoiceReport) { + // if user has intent to pay, we should get the only bank account information to pay the invoice. + if (hasIntentToPay) { + const currentBankInformation = formattedPaymentMethods.at(0) as BankAccount; + onPress( + CONST.IOU.PAYMENT_TYPE.EXPENSIFY, + currentBankInformation.accountType !== CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT, + currentBankInformation.methodID, + currentBankInformation.accountType, + undefined, + ); + return; + } + const isBusinessInvoice = isBusinessInvoiceRoom(chatReport); if (iouPaymentType === CONST.IOU.PAYMENT_TYPE.ELSEWHERE) { onPress(iouPaymentType, isBusinessInvoice); @@ -418,13 +429,14 @@ function SettlementButton({ return lastPaymentPolicy.name; } - if (lastPaymentMethod === CONST.IOU.PAYMENT_TYPE.EXPENSIFY) { - if (isBusinessInvoiceRoom(chatReport) && bankAccount) { - return translate('iou.invoiceBussinessBank', {lastFour: bankAccount?.accountData?.accountNumber?.slice(-4) ?? ''}); + if (lastPaymentMethod === CONST.IOU.PAYMENT_TYPE.EXPENSIFY || hasIntentToPay) { + const bankAccountToDisplay = hasIntentToPay ? (formattedPaymentMethods.at(0) as BankAccount) : bankAccount; + if (isBusinessInvoiceRoom(chatReport) && bankAccountToDisplay) { + return translate('iou.invoiceBussinessBank', {lastFour: bankAccountToDisplay?.accountData?.accountNumber?.slice(-4) ?? ''}); } - if (isIndividualInvoiceRoomUtil(chatReport) && bankAccount) { - return translate('iou.invoicePersonalBank', {lastFour: bankAccount?.accountData?.accountNumber?.slice(-4) ?? ''}); + if (isIndividualInvoiceRoomUtil(chatReport) && bankAccountToDisplay) { + return translate('iou.invoicePersonalBank', {lastFour: bankAccountToDisplay?.accountData?.accountNumber?.slice(-4) ?? ''}); } return translate('common.wallet'); @@ -444,7 +456,7 @@ function SettlementButton({ const customText = getCustomText(); const secondlineText = getSecondLineText(); - const shouldUseSplitButton = hasPreferredPaymentMethod || !!lastPaymentPolicy || (!!bankAccount && isExpenseReportUtil(iouReport)) || (isInvoiceReport && !isEmpty(getPaymentSubitems(false))); + const shouldUseSplitButton = hasPreferredPaymentMethod || !!lastPaymentPolicy || (!!bankAccount && isExpenseReportUtil(iouReport)) || (isInvoiceReport && hasIntentToPay); return (