From 0ddffd142089c5a13e78fd6ad5257a18f7a7ca1d Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 7 Feb 2024 00:31:50 +0700 Subject: [PATCH 1/4] =?UTF-8?q?fix:=20Approving=20a=20report=20causes=20th?= =?UTF-8?q?e=20workspace=20chat=20to=20=E2=80=9Cflash=E2=80=9D=20in=20the?= =?UTF-8?q?=20LHN=20before=20disappearing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/actions/IOU.ts | 60 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index a7a82e642e62..f46451d810bf 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -3253,8 +3253,49 @@ function sendMoneyWithWallet(report: OnyxTypes.Report, amount: number, currency: Report.notifyNewAction(params.chatReportID, managerID); } +function shouldShowSettlementButton(iouReportID: string, isPaidGroupPolicy: boolean, isPolicyExpenseChat: boolean, iouCanceled: boolean) { + const iouReport = ReportUtils.getReport(iouReportID) as OnyxTypes.Report; + const isApproved = ReportUtils.isReportApproved(iouReport); + const policy = ReportUtils.getPolicy(iouReport.policyID); + const policyType = policy?.type; + const isPolicyAdmin = policyType !== CONST.POLICY.TYPE.PERSONAL && policy?.role === CONST.POLICY.ROLE.ADMIN; + const managerID = iouReport?.managerID ?? 0; + const isCurrentUserManager = managerID === userAccountID; + const isMoneyRequestReport = ReportUtils.isMoneyRequestReport(iouReport); + + const isPayer = isPaidGroupPolicy + ? // In a paid group policy, the admin approver can pay the report directly by skipping the approval step + isPolicyAdmin && (isApproved || isCurrentUserManager) + : isPolicyAdmin || (isMoneyRequestReport && isCurrentUserManager); + + const isDraftExpenseReport = isPolicyExpenseChat && ReportUtils.isDraftExpenseReport(iouReport); + const iouSettled = ReportUtils.isSettled(iouReport.reportID); + const {reimbursableSpend} = ReportUtils.getMoneyRequestSpendBreakdown(iouReport); + const isAutoReimbursable = ReportUtils.canBeAutoReimbursed(iouReport, policy as OnyxEntry); + + const shouldShowPayButton = isPayer && !isDraftExpenseReport && !iouSettled && !iouReport?.isWaitingOnBankAccount && reimbursableSpend !== 0 && !iouCanceled && !isAutoReimbursable; + + const shouldShowApproveButton = isPaidGroupPolicy && isCurrentUserManager && !isDraftExpenseReport && !isApproved && !iouSettled; + + return shouldShowPayButton || shouldShowApproveButton; +} + +function hasIOUToApproveOrPay(chatReport: OnyxEntry, excludedIOUReportID: string): boolean { + const isPaidGroupPolicy = ReportUtils.isPaidGroupPolicyExpenseChat(chatReport); + const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(chatReport); + const iouCanceled = ReportUtils.isArchivedRoom(chatReport); + const chatReportActions = ReportActionsUtils.getAllReportActions(chatReport?.reportID ?? ''); + return !!Object.values(chatReportActions).find( + (action) => + action.childReportID?.toString() !== excludedIOUReportID && + action.actionName === CONST.REPORT.ACTIONS.TYPE.REPORTPREVIEW && + shouldShowSettlementButton(action.childReportID ?? '', isPaidGroupPolicy, isPolicyExpenseChat, iouCanceled), + ); +} + function approveMoneyRequest(expenseReport: OnyxTypes.Report | EmptyObject) { const currentNextStep = allNextSteps[`${ONYXKEYS.COLLECTION.NEXT_STEP}${expenseReport.reportID}`] ?? null; + const chatReport = ReportUtils.getReport(expenseReport.chatReportID) as OnyxEntry; const optimisticApprovedReportAction = ReportUtils.buildOptimisticApprovedReportAction(expenseReport.total ?? 0, expenseReport.currency ?? '', expenseReport.reportID); @@ -3279,7 +3320,16 @@ function approveMoneyRequest(expenseReport: OnyxTypes.Report | EmptyObject) { statusNum: CONST.REPORT.STATUS_NUM.APPROVED, }, }; - const optimisticData: OnyxUpdate[] = [optimisticIOUReportData, optimisticReportActionsData]; + + const optimisticChatReportData: OnyxUpdate = { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport.chatReportID}`, + value: { + hasOutstandingChildRequest: hasIOUToApproveOrPay(chatReport, expenseReport.reportID), + }, + }; + + const optimisticData: OnyxUpdate[] = [optimisticIOUReportData, optimisticReportActionsData, optimisticChatReportData]; const successData: OnyxUpdate[] = [ { @@ -3303,6 +3353,13 @@ function approveMoneyRequest(expenseReport: OnyxTypes.Report | EmptyObject) { }, }, }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport.chatReportID}`, + value: { + hasOutstandingChildRequest: chatReport?.hasOutstandingChildRequest, + }, + }, ]; if (currentNextStep) { @@ -3727,4 +3784,5 @@ export { editMoneyRequest, navigateToStartStepIfScanFileCannotBeRead, savePreferredPaymentMethod, + shouldShowSettlementButton, }; From 11800a4aa05605b191b461e6f07fc7a8475a1dde Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 14 Feb 2024 10:13:45 +0700 Subject: [PATCH 2/4] lint fix --- src/libs/actions/IOU.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index ff1de08e3ca0..24e423b3956c 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -3569,8 +3569,8 @@ function approveMoneyRequest(expenseReport: OnyxTypes.Report | EmptyObject) { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.NEXT_STEP}${expenseReport.reportID}`, value: currentNextStep, - }) - }; + }); + } const parameters: ApproveMoneyRequestParams = { reportID: expenseReport.reportID, From 293223fbd9a058c31e539629468ce8d0a230cec2 Mon Sep 17 00:00:00 2001 From: tienifr Date: Tue, 27 Feb 2024 17:11:47 +0700 Subject: [PATCH 3/4] refactor --- src/components/MoneyReportHeader.tsx | 22 ++----- .../ReportActionItem/ReportPreview.tsx | 40 ++----------- src/libs/actions/IOU.ts | 58 ++++++++++++------- 3 files changed, 48 insertions(+), 72 deletions(-) diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index 3f551da788f5..9be06ed4f08d 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -8,7 +8,6 @@ import useWindowDimensions from '@hooks/useWindowDimensions'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import * as HeaderUtils from '@libs/HeaderUtils'; import Navigation from '@libs/Navigation/Navigation'; -import * as PolicyUtils from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import * as IOU from '@userActions/IOU'; import CONST from '@src/CONST'; @@ -56,7 +55,6 @@ function MoneyReportHeader({session, policy, chatReport, nextStep, report: money const canAllowSettlement = ReportUtils.hasUpdatedTotal(moneyRequestReport); const policyType = policy?.type; const isPolicyAdmin = policyType !== CONST.POLICY.TYPE.PERSONAL && policy?.role === CONST.POLICY.ROLE.ADMIN; - const isAutoReimbursable = ReportUtils.canBeAutoReimbursed(moneyRequestReport, policy); const isPaidGroupPolicy = ReportUtils.isPaidGroupPolicy(moneyRequestReport); const isManager = ReportUtils.isMoneyRequestReport(moneyRequestReport) && session?.accountID === moneyRequestReport.managerID; const isPayer = isPaidGroupPolicy @@ -74,22 +72,12 @@ function MoneyReportHeader({session, policy, chatReport, nextStep, report: money setIsConfirmModalVisible(false); }, [moneyRequestReport, chatReport]); - const isOnInstantSubmitPolicy = PolicyUtils.isInstantSubmitEnabled(policy); - const isOnSubmitAndClosePolicy = PolicyUtils.isSubmitAndClose(policy); - const shouldShowPayButton = useMemo( - () => isPayer && !isDraft && !isSettled && !moneyRequestReport.isWaitingOnBankAccount && reimbursableSpend !== 0 && !ReportUtils.isArchivedRoom(chatReport) && !isAutoReimbursable, - [isPayer, isDraft, isSettled, moneyRequestReport, reimbursableSpend, chatReport, isAutoReimbursable], - ); - const shouldShowApproveButton = useMemo(() => { - if (!isPaidGroupPolicy) { - return false; - } - if (isOnInstantSubmitPolicy && isOnSubmitAndClosePolicy) { - return false; - } - return isManager && !isDraft && !isApproved && !isSettled; - }, [isPaidGroupPolicy, isManager, isDraft, isApproved, isSettled, isOnInstantSubmitPolicy, isOnSubmitAndClosePolicy]); + const shouldShowPayButton = useMemo(() => IOU.shouldShowPayButton(moneyRequestReport, chatReport, policy), [moneyRequestReport, chatReport, policy]); + + const shouldShowApproveButton = useMemo(() => IOU.shouldShowApproveButton(moneyRequestReport, chatReport, policy), [moneyRequestReport, chatReport, policy]); + const shouldShowSettlementButton = shouldShowPayButton || shouldShowApproveButton; + const shouldShowSubmitButton = isDraft && reimbursableSpend !== 0; const isFromPaidPolicy = policyType === CONST.POLICY.TYPE.TEAM || policyType === CONST.POLICY.TYPE.CORPORATE; const shouldShowNextStep = isFromPaidPolicy && !!nextStep?.message?.length; diff --git a/src/components/ReportActionItem/ReportPreview.tsx b/src/components/ReportActionItem/ReportPreview.tsx index 591767234b8b..b02df61de13e 100644 --- a/src/components/ReportActionItem/ReportPreview.tsx +++ b/src/components/ReportActionItem/ReportPreview.tsx @@ -19,7 +19,6 @@ import ControlSelection from '@libs/ControlSelection'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import Navigation from '@libs/Navigation/Navigation'; -import * as PolicyUtils from '@libs/PolicyUtils'; import * as ReceiptUtils from '@libs/ReceiptUtils'; import * as ReportActionUtils from '@libs/ReportActionsUtils'; import * as ReportUtils from '@libs/ReportUtils'; @@ -30,7 +29,7 @@ import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import type {Policy, Report, ReportAction, Session, Transaction, TransactionViolations} from '@src/types/onyx'; +import type {Policy, Report, ReportAction, Transaction, TransactionViolations} from '@src/types/onyx'; import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; import ReportActionItemImages from './ReportActionItemImages'; @@ -44,9 +43,6 @@ type ReportPreviewOnyxProps = { /** Active IOU Report for current report */ iouReport: OnyxEntry; - /** Session info for the currently logged in user. */ - session: OnyxEntry; - /** All the transactions, used to update ReportPreview label and status */ transactions: OnyxCollection; @@ -85,7 +81,6 @@ type ReportPreviewProps = ReportPreviewOnyxProps & { function ReportPreview({ iouReport, - session, policy, iouReportID, policyID, @@ -118,13 +113,9 @@ function ReportPreview({ ); const managerID = iouReport?.managerID ?? 0; - const isCurrentUserManager = managerID === session?.accountID; const {totalDisplaySpend, reimbursableSpend} = ReportUtils.getMoneyRequestSpendBreakdown(iouReport); - const policyType = policy?.type; - const isAutoReimbursable = ReportUtils.canBeAutoReimbursed(iouReport, policy); const iouSettled = ReportUtils.isSettled(iouReportID); - const iouCanceled = ReportUtils.isArchivedRoom(chatReport); const numberOfRequests = ReportActionUtils.getNumberOfMoneyRequests(action); const moneyRequestComment = action?.childLastMoneyRequestComment ?? ''; const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(chatReport); @@ -132,7 +123,6 @@ function ReportPreview({ const isApproved = ReportUtils.isReportApproved(iouReport); const canAllowSettlement = ReportUtils.hasUpdatedTotal(iouReport); - const isMoneyRequestReport = ReportUtils.isMoneyRequestReport(iouReport); const transactionsWithReceipts = ReportUtils.getTransactionsWithReceipts(iouReportID); const numberOfScanningReceipts = transactionsWithReceipts.filter((transaction) => TransactionUtils.isReceiptBeingScanned(transaction)).length; @@ -208,27 +198,10 @@ function ReportPreview({ const bankAccountRoute = ReportUtils.getBankAccountRoute(chatReport); - const isPaidGroupPolicy = ReportUtils.isPaidGroupPolicyExpenseChat(chatReport); - const isPolicyAdmin = policyType !== CONST.POLICY.TYPE.PERSONAL && policy?.role === CONST.POLICY.ROLE.ADMIN; - const isPayer = isPaidGroupPolicy - ? // In a paid group policy, the admin approver can pay the report directly by skipping the approval step - isPolicyAdmin && (isApproved || isCurrentUserManager) - : isPolicyAdmin || (isMoneyRequestReport && isCurrentUserManager); - const isOnInstantSubmitPolicy = PolicyUtils.isInstantSubmitEnabled(policy); - const isOnSubmitAndClosePolicy = PolicyUtils.isSubmitAndClose(policy); - const shouldShowPayButton = useMemo( - () => isPayer && !isDraftExpenseReport && !iouSettled && !iouReport?.isWaitingOnBankAccount && reimbursableSpend !== 0 && !iouCanceled && !isAutoReimbursable, - [isPayer, isDraftExpenseReport, iouSettled, reimbursableSpend, iouCanceled, isAutoReimbursable, iouReport], - ); - const shouldShowApproveButton = useMemo(() => { - if (!isPaidGroupPolicy) { - return false; - } - if (isOnInstantSubmitPolicy && isOnSubmitAndClosePolicy) { - return false; - } - return isCurrentUserManager && !isDraftExpenseReport && !isApproved && !iouSettled; - }, [isPaidGroupPolicy, isCurrentUserManager, isDraftExpenseReport, isApproved, isOnInstantSubmitPolicy, isOnSubmitAndClosePolicy, iouSettled]); + const shouldShowPayButton = useMemo(() => IOU.shouldShowPayButton(iouReport, chatReport, policy), [iouReport, chatReport, policy]); + + const shouldShowApproveButton = useMemo(() => IOU.shouldShowApproveButton(iouReport, chatReport, policy), [iouReport, chatReport, policy]); + const shouldShowSettlementButton = shouldShowPayButton || shouldShowApproveButton; /* @@ -353,9 +326,6 @@ export default withOnyx({ iouReport: { key: ({iouReportID}) => `${ONYXKEYS.COLLECTION.REPORT}${iouReportID}`, }, - session: { - key: ONYXKEYS.SESSION, - }, transactions: { key: ONYXKEYS.COLLECTION.TRANSACTION, }, diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 122b461e0c34..cb7a6e317809 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -3621,15 +3621,16 @@ function sendMoneyWithWallet(report: OnyxTypes.Report, amount: number, currency: Report.notifyNewAction(params.chatReportID, managerID); } -function shouldShowSettlementButton(iouReportID: string, isPaidGroupPolicy: boolean, isPolicyExpenseChat: boolean, iouCanceled: boolean) { - const iouReport = ReportUtils.getReport(iouReportID) as OnyxTypes.Report; - const isApproved = ReportUtils.isReportApproved(iouReport); - const policy = ReportUtils.getPolicy(iouReport.policyID); +function shouldShowPayButton(iouReport: OnyxEntry, chatReport: OnyxEntry, policy: OnyxEntry) { const policyType = policy?.type; const isPolicyAdmin = policyType !== CONST.POLICY.TYPE.PERSONAL && policy?.role === CONST.POLICY.ROLE.ADMIN; + const isMoneyRequestReport = ReportUtils.isMoneyRequestReport(iouReport); + const isApproved = ReportUtils.isReportApproved(iouReport); const managerID = iouReport?.managerID ?? 0; const isCurrentUserManager = managerID === userAccountID; - const isMoneyRequestReport = ReportUtils.isMoneyRequestReport(iouReport); + const isPaidGroupPolicy = ReportUtils.isPaidGroupPolicyExpenseChat(chatReport); + const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(chatReport); + const iouCanceled = ReportUtils.isArchivedRoom(chatReport); const isPayer = isPaidGroupPolicy ? // In a paid group policy, the admin approver can pay the report directly by skipping the approval step @@ -3637,28 +3638,44 @@ function shouldShowSettlementButton(iouReportID: string, isPaidGroupPolicy: bool : isPolicyAdmin || (isMoneyRequestReport && isCurrentUserManager); const isDraftExpenseReport = isPolicyExpenseChat && ReportUtils.isDraftExpenseReport(iouReport); - const iouSettled = ReportUtils.isSettled(iouReport.reportID); + const iouSettled = ReportUtils.isSettled(iouReport?.reportID); + const {reimbursableSpend} = ReportUtils.getMoneyRequestSpendBreakdown(iouReport); - const isAutoReimbursable = ReportUtils.canBeAutoReimbursed(iouReport, policy as OnyxEntry); + const isAutoReimbursable = ReportUtils.canBeAutoReimbursed(iouReport, policy); + return isPayer && !isDraftExpenseReport && !iouSettled && !iouReport?.isWaitingOnBankAccount && reimbursableSpend !== 0 && !iouCanceled && !isAutoReimbursable; +} - const shouldShowPayButton = isPayer && !isDraftExpenseReport && !iouSettled && !iouReport?.isWaitingOnBankAccount && reimbursableSpend !== 0 && !iouCanceled && !isAutoReimbursable; +function shouldShowApproveButton(iouReport: OnyxEntry, chatReport: OnyxEntry, policy: OnyxEntry) { + const managerID = iouReport?.managerID ?? 0; + const isCurrentUserManager = managerID === userAccountID; + const isPaidGroupPolicy = ReportUtils.isPaidGroupPolicyExpenseChat(chatReport); + const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(chatReport); - const shouldShowApproveButton = isPaidGroupPolicy && isCurrentUserManager && !isDraftExpenseReport && !isApproved && !iouSettled; + const isDraftExpenseReport = isPolicyExpenseChat && ReportUtils.isDraftExpenseReport(iouReport); + const isApproved = ReportUtils.isReportApproved(iouReport); + const iouSettled = ReportUtils.isSettled(iouReport?.reportID); + const isOnInstantSubmitPolicy = PolicyUtils.isInstantSubmitEnabled(policy); + const isOnSubmitAndClosePolicy = PolicyUtils.isSubmitAndClose(policy); + if (!isPaidGroupPolicy) { + return false; + } + if (isOnInstantSubmitPolicy && isOnSubmitAndClosePolicy) { + return false; + } - return shouldShowPayButton || shouldShowApproveButton; + return isCurrentUserManager && !isDraftExpenseReport && !isApproved && !iouSettled; } function hasIOUToApproveOrPay(chatReport: OnyxEntry, excludedIOUReportID: string): boolean { - const isPaidGroupPolicy = ReportUtils.isPaidGroupPolicyExpenseChat(chatReport); - const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(chatReport); - const iouCanceled = ReportUtils.isArchivedRoom(chatReport); const chatReportActions = ReportActionsUtils.getAllReportActions(chatReport?.reportID ?? ''); - return !!Object.values(chatReportActions).find( - (action) => - action.childReportID?.toString() !== excludedIOUReportID && - action.actionName === CONST.REPORT.ACTIONS.TYPE.REPORTPREVIEW && - shouldShowSettlementButton(action.childReportID ?? '', isPaidGroupPolicy, isPolicyExpenseChat, iouCanceled), - ); + + return !!Object.values(chatReportActions).find((action) => { + const iouReport = ReportUtils.getReport(action.childReportID ?? '') as OnyxEntry; + const policy = ReportUtils.getPolicy(iouReport?.policyID) as OnyxEntry; + + const shouldShowSettlementButton = shouldShowPayButton(iouReport, chatReport, policy) || shouldShowApproveButton(iouReport, chatReport, policy); + return action.childReportID?.toString() !== excludedIOUReportID && action.actionName === CONST.REPORT.ACTIONS.TYPE.REPORTPREVIEW && shouldShowSettlementButton; + }); } function approveMoneyRequest(expenseReport: OnyxTypes.Report | EmptyObject) { @@ -4338,5 +4355,6 @@ export { cancelPayment, navigateToStartStepIfScanFileCannotBeRead, savePreferredPaymentMethod, - shouldShowSettlementButton, + shouldShowPayButton, + shouldShowApproveButton, }; From d46b13a455ce8e876316545d8eb8597a03e86d4f Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 7 Mar 2024 12:05:25 +0700 Subject: [PATCH 4/4] refactor --- src/libs/PolicyUtils.ts | 4 ++-- src/libs/ReportUtils.ts | 4 ++-- src/libs/actions/IOU.ts | 38 ++++++++++++++++++-------------------- 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index b510edd7dcf4..1b3043eef377 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -227,14 +227,14 @@ function isPaidGroupPolicy(policy: OnyxEntry | EmptyObject): boolean { * Checks if policy's scheduled submit / auto reporting frequency is "instant". * Note: Free policies have "instant" submit always enabled. */ -function isInstantSubmitEnabled(policy: OnyxEntry): boolean { +function isInstantSubmitEnabled(policy: OnyxEntry | EmptyObject): boolean { return policy?.autoReportingFrequency === CONST.POLICY.AUTO_REPORTING_FREQUENCIES.INSTANT || policy?.type === CONST.POLICY.TYPE.FREE; } /** * Checks if policy's approval mode is "optional", a.k.a. "Submit & Close" */ -function isSubmitAndClose(policy: OnyxEntry): boolean { +function isSubmitAndClose(policy: OnyxEntry | EmptyObject): boolean { return policy?.approvalMode === CONST.POLICY.APPROVAL_MODE.OPTIONAL; } diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 2bfcb6712109..d37edcadbe32 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -5072,8 +5072,8 @@ function getAllAncestorReportActionIDs(report: Report | null | undefined): Ances return allAncestorIDs; } -function canBeAutoReimbursed(report: OnyxEntry, policy: OnyxEntry = null): boolean { - if (!policy) { +function canBeAutoReimbursed(report: OnyxEntry, policy: OnyxEntry | EmptyObject): boolean { + if (isEmptyObject(policy)) { return false; } type CurrencyType = (typeof CONST.DIRECT_REIMBURSEMENT_CURRENCIES)[number]; diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 5887313c41e5..c7fa553cecbb 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -3691,10 +3691,14 @@ function sendMoneyWithWallet(report: OnyxTypes.Report, amount: number, currency: Report.notifyNewAction(params.chatReportID, managerID); } -function shouldShowPayButton(iouReport: OnyxEntry, chatReport: OnyxEntry, policy: OnyxEntry) { +function shouldShowPayButton(iouReport: OnyxEntry | EmptyObject, chatReport: OnyxEntry | EmptyObject, policy: OnyxEntry | EmptyObject) { const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(chatReport); const iouCanceled = ReportUtils.isArchivedRoom(chatReport); + if (isEmptyObject(iouReport)) { + return false; + } + const isPayer = ReportUtils.isPayer( { email: currentUserEmail, @@ -3711,7 +3715,14 @@ function shouldShowPayButton(iouReport: OnyxEntry, chatReport: return isPayer && !isDraftExpenseReport && !iouSettled && !iouReport?.isWaitingOnBankAccount && reimbursableSpend !== 0 && !iouCanceled && !isAutoReimbursable; } -function shouldShowApproveButton(iouReport: OnyxEntry, chatReport: OnyxEntry, policy: OnyxEntry) { +function shouldShowApproveButton( + iouReport: OnyxEntry | EmptyObject, + chatReport: OnyxEntry | EmptyObject, + policy: OnyxEntry | EmptyObject, +) { + if (isEmptyObject(chatReport)) { + return false; + } const managerID = iouReport?.managerID ?? 0; const isCurrentUserManager = managerID === userAccountID; const isPaidGroupPolicy = ReportUtils.isPaidGroupPolicyExpenseChat(chatReport); @@ -3732,12 +3743,12 @@ function shouldShowApproveButton(iouReport: OnyxEntry, chatRep return isCurrentUserManager && !isDraftExpenseReport && !isApproved && !iouSettled; } -function hasIOUToApproveOrPay(chatReport: OnyxEntry, excludedIOUReportID: string): boolean { +function hasIOUToApproveOrPay(chatReport: OnyxEntry | EmptyObject, excludedIOUReportID: string): boolean { const chatReportActions = ReportActionsUtils.getAllReportActions(chatReport?.reportID ?? ''); - return !!Object.values(chatReportActions).find((action) => { - const iouReport = ReportUtils.getReport(action.childReportID ?? '') as OnyxEntry; - const policy = ReportUtils.getPolicy(iouReport?.policyID) as OnyxEntry; + return Object.values(chatReportActions).some((action) => { + const iouReport = ReportUtils.getReport(action.childReportID ?? ''); + const policy = ReportUtils.getPolicy(iouReport?.policyID); const shouldShowSettlementButton = shouldShowPayButton(iouReport, chatReport, policy) || shouldShowApproveButton(iouReport, chatReport, policy); return action.childReportID?.toString() !== excludedIOUReportID && action.actionName === CONST.REPORT.ACTIONS.TYPE.REPORTPREVIEW && shouldShowSettlementButton; @@ -3748,7 +3759,7 @@ function approveMoneyRequest(expenseReport: OnyxTypes.Report | EmptyObject) { const currentNextStep = allNextSteps[`${ONYXKEYS.COLLECTION.NEXT_STEP}${expenseReport.reportID}`] ?? null; const optimisticApprovedReportAction = ReportUtils.buildOptimisticApprovedReportAction(expenseReport.total ?? 0, expenseReport.currency ?? '', expenseReport.reportID); const optimisticNextStep = NextStepUtils.buildNextStep(expenseReport, CONST.REPORT.STATUS_NUM.APPROVED); - const chatReport = ReportUtils.getReport(expenseReport.chatReportID) as OnyxEntry; + const chatReport = ReportUtils.getReport(expenseReport.chatReportID); const optimisticReportActionsData: OnyxUpdate = { onyxMethod: Onyx.METHOD.MERGE, @@ -3823,19 +3834,6 @@ function approveMoneyRequest(expenseReport: OnyxTypes.Report | EmptyObject) { }, ]; - if (currentNextStep) { - optimisticData.push({ - onyxMethod: Onyx.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.NEXT_STEP}${expenseReport.reportID}`, - value: null, - }); - failureData.push({ - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.NEXT_STEP}${expenseReport.reportID}`, - value: currentNextStep, - }); - } - const parameters: ApproveMoneyRequestParams = { reportID: expenseReport.reportID, approvedReportActionID: optimisticApprovedReportAction.reportActionID,