diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index ec52a6158ad7..5ea35c2d3c3f 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -27,6 +27,7 @@ import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; import MoneyReportHeaderStatusBar from './MoneyReportHeaderStatusBar'; import MoneyRequestHeaderStatusBar from './MoneyRequestHeaderStatusBar'; +import type {ActionHandledType} from './ProcessMoneyReportHoldMenu'; import ProcessMoneyReportHoldMenu from './ProcessMoneyReportHoldMenu'; import SettlementButton from './SettlementButton'; @@ -79,7 +80,7 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea isActionOwner && (ReportUtils.canAddOrDeleteTransactions(moneyRequestReport) || ReportUtils.isTrackExpenseReport(transactionThreadReport)) && !isDeletedParentAction; const [isHoldMenuVisible, setIsHoldMenuVisible] = useState(false); const [paymentType, setPaymentType] = useState(); - const [requestType, setRequestType] = useState<'pay' | 'approve'>(); + const [requestType, setRequestType] = useState(); const canAllowSettlement = ReportUtils.hasUpdatedTotal(moneyRequestReport, policy); const policyType = policy?.type; const isPayer = ReportUtils.isPayer(session, moneyRequestReport); @@ -124,7 +125,7 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea return; } setPaymentType(type); - setRequestType('pay'); + setRequestType(CONST.IOU.REPORT_ACTION_TYPE.PAY); if (ReportUtils.hasHeldExpenses(moneyRequestReport.reportID)) { setIsHoldMenuVisible(true); } else if (ReportUtils.isInvoiceReport(moneyRequestReport)) { @@ -135,7 +136,7 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea }; const confirmApproval = () => { - setRequestType('approve'); + setRequestType(CONST.IOU.REPORT_ACTION_TYPE.APPROVE); if (ReportUtils.hasHeldExpenses(moneyRequestReport.reportID)) { setIsHoldMenuVisible(true); } else { diff --git a/src/components/ProcessMoneyReportHoldMenu.tsx b/src/components/ProcessMoneyReportHoldMenu.tsx index 6e81c9d57bc8..01896fb0a3cb 100644 --- a/src/components/ProcessMoneyReportHoldMenu.tsx +++ b/src/components/ProcessMoneyReportHoldMenu.tsx @@ -4,11 +4,15 @@ import useLocalize from '@hooks/useLocalize'; import Navigation from '@libs/Navigation/Navigation'; import {isLinkedTransactionHeld} from '@libs/ReportActionsUtils'; import * as IOU from '@userActions/IOU'; +import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import type * as OnyxTypes from '@src/types/onyx'; import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; +import type DeepValueOf from '@src/types/utils/DeepValueOf'; import DecisionModal from './DecisionModal'; +type ActionHandledType = DeepValueOf; + type ProcessMoneyReportHoldMenuProps = { /** The chat report this report is linked to */ chatReport: OnyxEntry; @@ -35,7 +39,7 @@ type ProcessMoneyReportHoldMenuProps = { paymentType?: PaymentMethodType; /** Type of action handled */ - requestType?: 'pay' | 'approve'; + requestType?: ActionHandledType; }; function ProcessMoneyReportHoldMenu({ @@ -50,7 +54,7 @@ function ProcessMoneyReportHoldMenu({ moneyRequestReport, }: ProcessMoneyReportHoldMenuProps) { const {translate} = useLocalize(); - const isApprove = requestType === 'approve'; + const isApprove = requestType === CONST.IOU.REPORT_ACTION_TYPE.APPROVE; const onSubmit = (full: boolean) => { if (isApprove) { @@ -82,3 +86,4 @@ function ProcessMoneyReportHoldMenu({ ProcessMoneyReportHoldMenu.displayName = 'ProcessMoneyReportHoldMenu'; export default ProcessMoneyReportHoldMenu; +export type {ActionHandledType}; diff --git a/src/components/ReportActionItem/ReportPreview.tsx b/src/components/ReportActionItem/ReportPreview.tsx index 0bf5d18ddfa4..00fd3cc8e036 100644 --- a/src/components/ReportActionItem/ReportPreview.tsx +++ b/src/components/ReportActionItem/ReportPreview.tsx @@ -1,5 +1,5 @@ import truncate from 'lodash/truncate'; -import React, {useMemo} from 'react'; +import React, {useMemo, useState} from 'react'; import type {StyleProp, ViewStyle} from 'react-native'; import {View} from 'react-native'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; @@ -9,6 +9,8 @@ import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; +import ProcessMoneyReportHoldMenu from '@components/ProcessMoneyReportHoldMenu'; +import type {ActionHandledType} from '@components/ProcessMoneyReportHoldMenu'; import SettlementButton from '@components/SettlementButton'; import {showContextMenuForReport} from '@components/ShowContextMenuContext'; import Text from '@components/Text'; @@ -16,6 +18,7 @@ import useLocalize from '@hooks/useLocalize'; import usePermissions from '@hooks/usePermissions'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; +import useWindowDimensions from '@hooks/useWindowDimensions'; import ControlSelection from '@libs/ControlSelection'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; @@ -119,6 +122,12 @@ function ReportPreview({ [transactions, iouReportID, action], ); + const [isHoldMenuVisible, setIsHoldMenuVisible] = useState(false); + const [requestType, setRequestType] = useState(); + const [nonHeldAmount, fullAmount] = ReportUtils.getNonHeldAndFullAmount(iouReport, policy); + const {isSmallScreenWidth} = useWindowDimensions(); + const [paymentType, setPaymentType] = useState(); + const managerID = iouReport?.managerID ?? 0; const {totalDisplaySpend, reimbursableSpend} = ReportUtils.getMoneyRequestSpendBreakdown(iouReport); @@ -164,6 +173,32 @@ function ReportPreview({ [chatReport?.isOwnPolicyExpenseChat, policy?.harvesting?.enabled], ); + const confirmPayment = (type: PaymentMethodType | undefined) => { + if (!type) { + return; + } + setPaymentType(type); + setRequestType(CONST.IOU.REPORT_ACTION_TYPE.PAY); + if (ReportUtils.hasHeldExpenses(iouReport?.reportID)) { + setIsHoldMenuVisible(true); + } else if (chatReport && iouReport) { + if (ReportUtils.isInvoiceReport(iouReport)) { + IOU.payInvoice(type, chatReport, iouReport); + } else { + IOU.payMoneyRequest(type, chatReport, iouReport); + } + } + }; + + const confirmApproval = () => { + setRequestType(CONST.IOU.REPORT_ACTION_TYPE.APPROVE); + if (ReportUtils.hasHeldExpenses(iouReport?.reportID)) { + setIsHoldMenuVisible(true); + } else { + IOU.approveMoneyRequest(iouReport ?? {}, true); + } + }; + const getDisplayAmount = (): string => { if (totalDisplaySpend) { return CurrencyUtils.convertToDisplayString(totalDisplaySpend, iouReport?.currency); @@ -282,17 +317,6 @@ function ReportPreview({ }; }, [formattedMerchant, formattedDescription, moneyRequestComment, translate, numberOfRequests, numberOfScanningReceipts, numberOfPendingRequests]); - const confirmPayment = (paymentMethodType?: PaymentMethodType) => { - if (!paymentMethodType || !chatReport || !iouReport) { - return; - } - if (ReportUtils.isInvoiceReport(iouReport)) { - IOU.payInvoice(paymentMethodType, chatReport, iouReport); - } else { - IOU.payMoneyRequest(paymentMethodType, chatReport, iouReport); - } - }; - return ( + {isHoldMenuVisible && iouReport && requestType !== undefined && ( + setIsHoldMenuVisible(false)} + isVisible={isHoldMenuVisible} + paymentType={paymentType} + chatReport={chatReport} + moneyRequestReport={iouReport} + /> + )} ); }