diff --git a/.eslintrc.changed.js b/.eslintrc.changed.js index d0a7f9a27d21..ae82e38070e7 100644 --- a/.eslintrc.changed.js +++ b/.eslintrc.changed.js @@ -21,7 +21,7 @@ module.exports = { }, overrides: [ { - files: ['src/libs/actions/IOU.ts', 'src/pages/workspace/WorkspaceInitialPage.tsx', 'src/pages/home/report/PureReportActionItem.tsx', 'src/libs/SidebarUtils.ts'], + files: ['src/pages/workspace/WorkspaceInitialPage.tsx', 'src/pages/home/report/PureReportActionItem.tsx', 'src/libs/SidebarUtils.ts'], rules: { 'rulesdir/no-default-id-values': 'off', }, diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 5c0d0b4b376f..9025ebcec844 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -436,7 +436,10 @@ const ROUTES = { }, ROOM_INVITE: { route: 'r/:reportID/invite/:role?', - getRoute: (reportID: string, role?: string, backTo?: string) => { + getRoute: (reportID: string | undefined, role?: string, backTo?: string) => { + if (!reportID) { + Log.warn('Invalid reportID is used to build the ROOM_INVITE route'); + } const route = role ? (`r/${reportID}/invite/${role}` as const) : (`r/${reportID}/invite` as const); return getUrlWithBackToParam(route, backTo); }, @@ -770,7 +773,12 @@ const ROUTES = { }, WORKSPACE_PROFILE_ADDRESS: { route: 'settings/workspaces/:policyID/profile/address', - getRoute: (policyID: string, backTo?: string) => getUrlWithBackToParam(`settings/workspaces/${policyID}/profile/address` as const, backTo), + getRoute: (policyID: string | undefined, backTo?: string) => { + if (!policyID) { + Log.warn('Invalid policyID is used to build the WORKSPACE_PROFILE_ADDRESS route'); + } + return getUrlWithBackToParam(`settings/workspaces/${policyID}/profile/address` as const, backTo); + }, }, WORKSPACE_PROFILE_PLAN: { route: 'settings/workspaces/:policyID/profile/plan', diff --git a/src/libs/API/parameters/CategorizeTrackedExpenseParams.ts b/src/libs/API/parameters/CategorizeTrackedExpenseParams.ts index 78eb0adecc5e..7186ae131b83 100644 --- a/src/libs/API/parameters/CategorizeTrackedExpenseParams.ts +++ b/src/libs/API/parameters/CategorizeTrackedExpenseParams.ts @@ -6,14 +6,14 @@ type CategorizeTrackedExpenseParams = { comment: string; created: string; merchant: string; - policyID: string; - transactionID: string; - moneyRequestPreviewReportActionID: string; - moneyRequestReportID: string; - moneyRequestCreatedReportActionID: string; + policyID: string | undefined; + transactionID: string | undefined; + moneyRequestPreviewReportActionID: string | undefined; + moneyRequestReportID: string | undefined; + moneyRequestCreatedReportActionID: string | undefined; actionableWhisperReportActionID: string; modifiedExpenseReportActionID: string; - reportPreviewReportActionID: string; + reportPreviewReportActionID: string | undefined; category?: string; tag?: string; receipt?: Receipt; diff --git a/src/libs/API/parameters/CompleteSplitBillParams.ts b/src/libs/API/parameters/CompleteSplitBillParams.ts index 67ca011b70d9..123ee7b05257 100644 --- a/src/libs/API/parameters/CompleteSplitBillParams.ts +++ b/src/libs/API/parameters/CompleteSplitBillParams.ts @@ -1,5 +1,5 @@ type CompleteSplitBillParams = { - transactionID: string; + transactionID: string | undefined; amount?: number; currency?: string; created?: string; diff --git a/src/libs/API/parameters/ConvertTrackedExpenseToRequestParams.ts b/src/libs/API/parameters/ConvertTrackedExpenseToRequestParams.ts index 2942923f6b37..21a59f7e614f 100644 --- a/src/libs/API/parameters/ConvertTrackedExpenseToRequestParams.ts +++ b/src/libs/API/parameters/ConvertTrackedExpenseToRequestParams.ts @@ -8,9 +8,9 @@ type ConvertTrackedExpenseToRequestParams = { chatReportID: string; transactionID: string; actionableWhisperReportActionID: string; - createdChatReportActionID: string; + createdChatReportActionID?: string; moneyRequestReportID: string; - moneyRequestCreatedReportActionID: string; + moneyRequestCreatedReportActionID: string | undefined; moneyRequestPreviewReportActionID: string; reportPreviewReportActionID: string; }; diff --git a/src/libs/API/parameters/CreateDistanceRequestParams.ts b/src/libs/API/parameters/CreateDistanceRequestParams.ts index 07dd594d7356..81385d092530 100644 --- a/src/libs/API/parameters/CreateDistanceRequestParams.ts +++ b/src/libs/API/parameters/CreateDistanceRequestParams.ts @@ -1,7 +1,7 @@ type CreateDistanceRequestParams = { transactionID: string; chatReportID: string; - createdChatReportActionID: string; + createdChatReportActionID?: string; reportActionID: string; waypoints: string; customUnitRateID: string; diff --git a/src/libs/API/parameters/CreatePerDiemRequestParams.ts b/src/libs/API/parameters/CreatePerDiemRequestParams.ts index 2a64748807d5..61740fbd0a37 100644 --- a/src/libs/API/parameters/CreatePerDiemRequestParams.ts +++ b/src/libs/API/parameters/CreatePerDiemRequestParams.ts @@ -14,11 +14,11 @@ type CreatePerDiemRequestParams = { chatReportID: string; transactionID: string; reportActionID: string; - createdChatReportActionID: string; - createdIOUReportActionID: string; + createdChatReportActionID?: string; + createdIOUReportActionID?: string; reportPreviewReportActionID: string; transactionThreadReportID: string; - createdReportActionIDForThread: string; + createdReportActionIDForThread: string | undefined; }; export default CreatePerDiemRequestParams; diff --git a/src/libs/API/parameters/DeleteMoneyRequestParams.ts b/src/libs/API/parameters/DeleteMoneyRequestParams.ts index 6e7fe30811c4..b44223905e8c 100644 --- a/src/libs/API/parameters/DeleteMoneyRequestParams.ts +++ b/src/libs/API/parameters/DeleteMoneyRequestParams.ts @@ -1,5 +1,5 @@ type DeleteMoneyRequestParams = { - transactionID: string; + transactionID: string | undefined; reportActionID: string; }; diff --git a/src/libs/API/parameters/PayInvoiceParams.ts b/src/libs/API/parameters/PayInvoiceParams.ts index 7f80e5d20c4c..aaf1d906d143 100644 --- a/src/libs/API/parameters/PayInvoiceParams.ts +++ b/src/libs/API/parameters/PayInvoiceParams.ts @@ -2,7 +2,7 @@ import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; import type CreateWorkspaceParams from './CreateWorkspaceParams'; type PayInvoiceParams = Partial & { - reportID: string; + reportID: string | undefined; reportActionID: string; paymentMethodType: PaymentMethodType; payAsBusiness: boolean; diff --git a/src/libs/API/parameters/PayMoneyRequestParams.ts b/src/libs/API/parameters/PayMoneyRequestParams.ts index 3ad98429b75c..337c38d7164e 100644 --- a/src/libs/API/parameters/PayMoneyRequestParams.ts +++ b/src/libs/API/parameters/PayMoneyRequestParams.ts @@ -1,7 +1,7 @@ import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; type PayMoneyRequestParams = { - iouReportID: string; + iouReportID: string | undefined; chatReportID: string; reportActionID: string; paymentMethodType: PaymentMethodType; diff --git a/src/libs/API/parameters/RequestMoneyParams.ts b/src/libs/API/parameters/RequestMoneyParams.ts index e3e600a4e367..4fe0a0a29e9f 100644 --- a/src/libs/API/parameters/RequestMoneyParams.ts +++ b/src/libs/API/parameters/RequestMoneyParams.ts @@ -14,8 +14,8 @@ type RequestMoneyParams = { chatReportID: string; transactionID: string; reportActionID: string; - createdChatReportActionID: string; - createdIOUReportActionID: string; + createdChatReportActionID?: string; + createdIOUReportActionID?: string; reportPreviewReportActionID: string; receipt?: Receipt; receiptState?: ValueOf; @@ -26,7 +26,7 @@ type RequestMoneyParams = { billable?: boolean; receiptGpsPoints?: string; transactionThreadReportID: string; - createdReportActionIDForThread: string; + createdReportActionIDForThread: string | undefined; reimbursible?: boolean; }; diff --git a/src/libs/API/parameters/SendInvoiceParams.ts b/src/libs/API/parameters/SendInvoiceParams.ts index e2cac84e0d12..2b172ee6ce6d 100644 --- a/src/libs/API/parameters/SendInvoiceParams.ts +++ b/src/libs/API/parameters/SendInvoiceParams.ts @@ -2,7 +2,7 @@ import type {RequireAtLeastOne} from 'type-fest'; type SendInvoiceParams = RequireAtLeastOne< { - senderWorkspaceID: string; + senderWorkspaceID: string | undefined; accountID: number; receiverEmail?: string; receiverInvoiceRoomID?: string; @@ -21,7 +21,7 @@ type SendInvoiceParams = RequireAtLeastOne< companyName?: string; companyWebsite?: string; createdIOUReportActionID: string; - createdReportActionIDForThread: string; + createdReportActionIDForThread: string | undefined; reportActionID: string; }, 'receiverEmail' | 'receiverInvoiceRoomID' diff --git a/src/libs/API/parameters/SendMoneyParams.ts b/src/libs/API/parameters/SendMoneyParams.ts index 449a87fb5313..1e9a58ab74a5 100644 --- a/src/libs/API/parameters/SendMoneyParams.ts +++ b/src/libs/API/parameters/SendMoneyParams.ts @@ -7,11 +7,11 @@ type SendMoneyParams = { paymentMethodType: PaymentMethodType; transactionID: string; newIOUReportDetails: string; - createdReportActionID: string; + createdReportActionID: string | undefined; reportPreviewReportActionID: string; createdIOUReportActionID: string; transactionThreadReportID: string; - createdReportActionIDForThread: string; + createdReportActionIDForThread: string | undefined; }; export default SendMoneyParams; diff --git a/src/libs/API/parameters/ShareTrackedExpenseParams.ts b/src/libs/API/parameters/ShareTrackedExpenseParams.ts index dac75ae5c5d5..115135d21e2e 100644 --- a/src/libs/API/parameters/ShareTrackedExpenseParams.ts +++ b/src/libs/API/parameters/ShareTrackedExpenseParams.ts @@ -6,14 +6,14 @@ type ShareTrackedExpenseParams = { comment: string; created: string; merchant: string; - policyID: string; - transactionID: string; - moneyRequestPreviewReportActionID: string; - moneyRequestReportID: string; - moneyRequestCreatedReportActionID: string; + policyID: string | undefined; + transactionID: string | undefined; + moneyRequestPreviewReportActionID: string | undefined; + moneyRequestReportID: string | undefined; + moneyRequestCreatedReportActionID: string | undefined; actionableWhisperReportActionID: string; modifiedExpenseReportActionID: string; - reportPreviewReportActionID: string; + reportPreviewReportActionID: string | undefined; category?: string; tag?: string; receipt?: Receipt; diff --git a/src/libs/API/parameters/TrackExpenseParams.ts b/src/libs/API/parameters/TrackExpenseParams.ts index 3a7d0df6736c..89b8d79e3b9a 100644 --- a/src/libs/API/parameters/TrackExpenseParams.ts +++ b/src/libs/API/parameters/TrackExpenseParams.ts @@ -9,10 +9,10 @@ type TrackExpenseParams = { created: string; merchant: string; iouReportID?: string; - chatReportID: string; - transactionID: string; - reportActionID: string; - createdChatReportActionID: string; + chatReportID: string | undefined; + transactionID: string | undefined; + reportActionID: string | undefined; + createdChatReportActionID?: string; createdIOUReportActionID?: string; reportPreviewReportActionID?: string; receipt?: Receipt; @@ -23,8 +23,8 @@ type TrackExpenseParams = { taxAmount: number; billable?: boolean; receiptGpsPoints?: string; - transactionThreadReportID: string; - createdReportActionIDForThread: string; + transactionThreadReportID: string | undefined; + createdReportActionIDForThread: string | undefined; waypoints?: string; actionableWhisperReportActionID?: string; customUnitRateID?: string; diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index de89fd2cb783..05026bbfd52d 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -1601,7 +1601,10 @@ function wasActionTakenByCurrentUser(reportAction: OnyxInputOrEntry { +function getIOUActionForReportID(reportID: string | undefined, transactionID: string): OnyxEntry { + if (!reportID) { + return; + } const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; const reportActions = getAllReportActions(report?.reportID); const action = Object.values(reportActions ?? {})?.find((reportAction) => { diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 4db7d5ff9358..4353aeb1797d 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -789,7 +789,7 @@ Onyx.connect({ reportsTransactions = Object.values(value).reduce>((all, transaction) => { const reportsMap = all; - if (!transaction) { + if (!transaction?.reportID) { return reportsMap; } @@ -3191,6 +3191,10 @@ function getReportFieldKey(reportFieldId: string | undefined) { * Get the report fields attached to the policy given policyID */ function getReportFieldsByPolicyID(policyID: string | undefined): Record { + if (!policyID) { + return {}; + } + const policyReportFields = Object.entries(allPolicies ?? {}).find(([key]) => key.replace(ONYXKEYS.COLLECTION.POLICY, '') === policyID); const fieldList = policyReportFields?.[1]?.fieldList; @@ -4801,7 +4805,7 @@ function buildOptimisticIOUReport( payeeAccountID: number, payerAccountID: number, total: number, - chatReportID: string, + chatReportID: string | undefined, currency: string, isSendingMoney = false, parentReportActionID?: string, @@ -4873,7 +4877,14 @@ function populateOptimisticReportFormula(formula: string, report: OptimisticExpe } /** Builds an optimistic invoice report with a randomly generated reportID */ -function buildOptimisticInvoiceReport(chatReportID: string, policyID: string, receiverAccountID: number, receiverName: string, total: number, currency: string): OptimisticExpenseReport { +function buildOptimisticInvoiceReport( + chatReportID: string, + policyID: string | undefined, + receiverAccountID: number, + receiverName: string, + total: number, + currency: string, +): OptimisticExpenseReport { const formattedTotal = convertToDisplayString(total, currency); const invoiceReport = { reportID: generateReportID(), @@ -4945,8 +4956,8 @@ function getExpenseReportStateAndStatus(policy: OnyxEntry) { * @param parentReportActionID – The parent ReportActionID of the PolicyExpenseChat */ function buildOptimisticExpenseReport( - chatReportID: string, - policyID: string, + chatReportID: string | undefined, + policyID: string | undefined, payeeAccountID: number, total: number, currency: string, @@ -5547,7 +5558,7 @@ function buildOptimisticModifiedExpenseReportAction( * @param transactionThreadID - The reportID of the transaction thread * @param movedToReportID - The reportID of the report the transaction is moved to */ -function buildOptimisticMovedTrackedExpenseModifiedReportAction(transactionThreadID: string, movedToReportID: string): OptimisticModifiedExpenseReportAction { +function buildOptimisticMovedTrackedExpenseModifiedReportAction(transactionThreadID: string | undefined, movedToReportID: string | undefined): OptimisticModifiedExpenseReportAction { const delegateAccountDetails = getPersonalDetailByEmail(delegateEmail); return { @@ -8581,10 +8592,6 @@ function canReportBeMentionedWithinPolicy(report: OnyxEntry, policyID: s return isChatRoom(report) && !isInvoiceRoom(report) && !isThread(report); } -function shouldShowMerchantColumn(transactions: Transaction[]) { - return transactions.some((transaction) => isExpenseReport(allReports?.[transaction.reportID] ?? null)); -} - /** * Whether a given report is used for onboarding tasks. In the past, it could be either the Concierge chat or the system * DM, and we saved the report ID in the user's `onboarding` NVP. As a fallback for users who don't have the NVP, we now @@ -9123,7 +9130,6 @@ export { getTripIDFromTransactionParentReportID, buildOptimisticInvoiceReport, getInvoiceChatByParticipants, - shouldShowMerchantColumn, isCurrentUserInvoiceReceiver, isDraftReport, changeMoneyRequestHoldStatus, diff --git a/src/libs/TransactionUtils/index.ts b/src/libs/TransactionUtils/index.ts index 749236638045..b52a024879a9 100644 --- a/src/libs/TransactionUtils/index.ts +++ b/src/libs/TransactionUtils/index.ts @@ -42,7 +42,7 @@ import getDistanceInMeters from './getDistanceInMeters'; type TransactionParams = { amount: number; currency: string; - reportID: string; + reportID: string | undefined; comment?: string; attendees?: Attendee[]; created?: string; diff --git a/src/libs/TripReservationUtils.ts b/src/libs/TripReservationUtils.ts index 2c774637b4a0..6d376620deef 100644 --- a/src/libs/TripReservationUtils.ts +++ b/src/libs/TripReservationUtils.ts @@ -13,10 +13,10 @@ import type {Reservation, ReservationType} from '@src/types/onyx/Transaction'; import type Transaction from '@src/types/onyx/Transaction'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type IconAsset from '@src/types/utils/IconAsset'; -import * as Link from './actions/Link'; +import {openTravelDotLink} from './actions/Link'; import Log from './Log'; import Navigation from './Navigation/Navigation'; -import * as PolicyUtils from './PolicyUtils'; +import {getPolicy} from './PolicyUtils'; let travelSettings: OnyxEntry; Onyx.connect({ @@ -65,7 +65,7 @@ function getTripReservationIcon(reservationType?: ReservationType): IconAsset { } } -type ReservationData = {reservation: Reservation; transactionID: string; reportID: string; reservationIndex: number}; +type ReservationData = {reservation: Reservation; transactionID: string; reportID: string | undefined; reservationIndex: number}; function getReservationsFromTripTransactions(transactions: Transaction[]): ReservationData[] { return transactions @@ -100,9 +100,9 @@ function bookATrip(translate: LocaleContextProps['translate'], setCtaErrorMessag setCtaErrorMessage(translate('travel.phoneError')); return; } - const policy = PolicyUtils.getPolicy(activePolicyID); + const policy = getPolicy(activePolicyID); if (isEmptyObject(policy?.address)) { - Navigation.navigate(ROUTES.WORKSPACE_PROFILE_ADDRESS.getRoute(activePolicyID ?? '-1', Navigation.getActiveRoute())); + Navigation.navigate(ROUTES.WORKSPACE_PROFILE_ADDRESS.getRoute(activePolicyID, Navigation.getActiveRoute())); return; } if (!travelSettings?.hasAcceptedTerms) { @@ -112,7 +112,7 @@ function bookATrip(translate: LocaleContextProps['translate'], setCtaErrorMessag if (ctaErrorMessage) { setCtaErrorMessage(''); } - Link.openTravelDotLink(activePolicyID) + openTravelDotLink(activePolicyID) ?.then(() => { if (!NativeModules.HybridAppModule || !isSingleNewDotEntry) { return; diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 143590b7169d..b2ec4478284c 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -187,11 +187,11 @@ type MoneyRequestInformation = { chatReport: OnyxTypes.Report; transaction: OnyxTypes.Transaction; iouAction: OptimisticIOUReportAction; - createdChatReportActionID: string; - createdIOUReportActionID: string; + createdChatReportActionID?: string; + createdIOUReportActionID?: string; reportPreviewAction: OnyxTypes.ReportAction; transactionThreadReportID: string; - createdReportActionIDForThread: string; + createdReportActionIDForThread: string | undefined; onyxData: OnyxData; }; @@ -201,16 +201,16 @@ type TrackExpenseInformation = { chatReport: OnyxTypes.Report; transaction: OnyxTypes.Transaction; iouAction: OptimisticIOUReportAction; - createdChatReportActionID: string; + createdChatReportActionID?: string; createdIOUReportActionID?: string; reportPreviewAction?: OnyxTypes.ReportAction; transactionThreadReportID: string; - createdReportActionIDForThread: string; + createdReportActionIDForThread: string | undefined; actionableWhisperReportActionIDParam?: string; onyxData: OnyxData; }; type TrackedExpenseTransactionParams = { - transactionID: string; + transactionID: string | undefined; amount: number; currency: string; comment: string; @@ -224,18 +224,18 @@ type TrackedExpenseTransactionParams = { receipt?: Receipt; }; type TrackedExpensePolicyParams = { - policyID: string; + policyID: string | undefined; isDraftPolicy?: boolean; }; type TrackedExpenseReportInformation = { - moneyRequestPreviewReportActionID: string; - moneyRequestReportID: string; - moneyRequestCreatedReportActionID: string; + moneyRequestPreviewReportActionID: string | undefined; + moneyRequestReportID: string | undefined; + moneyRequestCreatedReportActionID: string | undefined; actionableWhisperReportActionID: string; linkedTrackedExpenseReportAction: OnyxTypes.ReportAction; linkedTrackedExpenseReportID: string; - transactionThreadReportID: string; - reportPreviewReportActionID: string; + transactionThreadReportID: string | undefined; + reportPreviewReportActionID: string | undefined; }; type TrackedExpenseParams = { onyxData?: OnyxData; @@ -246,7 +246,7 @@ type TrackedExpenseParams = { }; type SendInvoiceInformation = { - senderWorkspaceID: string; + senderWorkspaceID: string | undefined; receiver: Partial; invoiceRoom: OnyxTypes.Report; createdChatReportActionID: string; @@ -255,7 +255,7 @@ type SendInvoiceInformation = { transactionID: string; transactionThreadReportID: string; createdIOUReportActionID: string; - createdReportActionIDForThread: string; + createdReportActionIDForThread: string | undefined; reportActionID: string; onyxData: OnyxData; }; @@ -512,7 +512,7 @@ Onyx.connect({ key: ONYXKEYS.SESSION, callback: (value) => { currentUserEmail = value?.email ?? ''; - userAccountID = value?.accountID ?? -1; + userAccountID = value?.accountID ?? CONST.DEFAULT_NUMBER_ID; }, }); @@ -573,7 +573,7 @@ Onyx.connect({ /** * Find the report preview action from given chat report and iou report */ -function getReportPreviewAction(chatReportID: string, iouReportID: string): OnyxInputValue> { +function getReportPreviewAction(chatReportID: string | undefined, iouReportID: string | undefined): OnyxInputValue> { const reportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReportID}`] ?? {}; // Find the report preview action from the chat report @@ -1423,14 +1423,18 @@ function buildOnyxDataForInvoice( key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport.reportID}`, value: transactionThreadReport, }, - { + ]; + + if (transactionThreadCreatedReportAction?.reportActionID) { + optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport.reportID}`, value: { - [transactionThreadCreatedReportAction?.reportActionID ?? '-1']: transactionThreadCreatedReportAction, + [transactionThreadCreatedReportAction.reportActionID]: transactionThreadCreatedReportAction, }, - }, - ]; + }); + } + const successData: OnyxUpdate[] = []; if (chatReport) { @@ -1566,17 +1570,20 @@ function buildOnyxDataForInvoice( }, }, }, - { + ); + + if (transactionThreadCreatedReportAction?.reportActionID) { + successData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport.reportID}`, value: { - [transactionThreadCreatedReportAction?.reportActionID ?? '-1']: { + [transactionThreadCreatedReportAction.reportActionID]: { pendingAction: null, errors: null, }, }, - }, - ); + }); + } if (isNewChatReport) { successData.push( @@ -1660,16 +1667,19 @@ function buildOnyxDataForInvoice( }, }, }, - { + ]; + + if (transactionThreadCreatedReportAction?.reportActionID) { + failureData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport.reportID}`, value: { - [transactionThreadCreatedReportAction?.reportActionID ?? '-1']: { + [transactionThreadCreatedReportAction.reportActionID]: { errors: getMicroSecondOnyxErrorWithTranslationKey('iou.error.genericCreateInvoiceFailureMessage', errorKey), }, }, - }, - ]; + }); + } if (companyName && companyWebsite) { optimisticData.push({ @@ -2073,16 +2083,19 @@ function buildOnyxDataForTrackExpense( pendingFields: clearedPendingFields, }, }, - { + ); + + if (transactionThreadCreatedReportAction?.reportActionID) { + failureData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport?.reportID}`, value: { - [transactionThreadCreatedReportAction?.reportActionID ?? '-1']: { + [transactionThreadCreatedReportAction?.reportActionID]: { errors: getMicroSecondOnyxErrorWithTranslationKey('iou.error.genericCreateFailureMessage'), }, }, - }, - ); + }); + } // We don't need to compute violations unless we're on a paid policy if (!policy || !isPaidGroupPolicy(policy)) { @@ -2112,7 +2125,7 @@ function buildOnyxDataForTrackExpense( function getDeleteTrackExpenseInformation( chatReportID: string, - transactionID: string, + transactionID: string | undefined, reportAction: OnyxTypes.ReportAction, shouldDeleteTransactionFromOnyx = true, isMovingTransactionFromTrackExpense = false, @@ -2161,8 +2174,8 @@ function getDeleteTrackExpenseInformation( if (chatReport) { canUserPerformWriteAction = !!canUserPerformWriteActionReportUtils(chatReport); } - const lastVisibleAction = getLastVisibleAction(chatReport?.reportID ?? '-1', canUserPerformWriteAction, updatedReportAction); - const {lastMessageText = '', lastMessageHtml = ''} = getLastVisibleMessage(chatReport?.reportID ?? '-1', canUserPerformWriteAction, updatedReportAction); + const lastVisibleAction = getLastVisibleAction(chatReportID, canUserPerformWriteAction, updatedReportAction); + const {lastMessageText = '', lastMessageHtml = ''} = getLastVisibleMessage(chatReportID, canUserPerformWriteAction, updatedReportAction); // STEP 4: Build Onyx data const optimisticData: OnyxUpdate[] = []; @@ -2345,9 +2358,9 @@ function getSendInvoiceInformation( ): SendInvoiceInformation { const {amount = 0, currency = '', created = '', merchant = '', category = '', tag = '', taxCode = '', taxAmount = 0, billable, comment, participants} = transaction ?? {}; const trimmedComment = (comment?.comment ?? '').trim(); - const senderWorkspaceID = participants?.find((participant) => participant?.isSender)?.policyID ?? '-1'; + const senderWorkspaceID = participants?.find((participant) => participant?.isSender)?.policyID; const receiverParticipant: Participant | InvoiceReceiver | undefined = participants?.find((participant) => participant?.accountID) ?? invoiceChatReport?.invoiceReceiver; - const receiverAccountID = receiverParticipant && 'accountID' in receiverParticipant && receiverParticipant.accountID ? receiverParticipant.accountID : -1; + const receiverAccountID = receiverParticipant && 'accountID' in receiverParticipant && receiverParticipant.accountID ? receiverParticipant.accountID : CONST.DEFAULT_NUMBER_ID; let receiver = getPersonalDetailsForAccountID(receiverAccountID); let optimisticPersonalDetailListAction = {}; const receiverType = getReceiverType(receiverParticipant); @@ -2464,7 +2477,7 @@ function getSendInvoiceInformation( return { createdIOUReportActionID: optimisticCreatedActionForIOUReport.reportActionID, - createdReportActionIDForThread: optimisticCreatedActionForTransactionThread?.reportActionID ?? '-1', + createdReportActionIDForThread: optimisticCreatedActionForTransactionThread?.reportActionID, reportActionID: iouAction.reportActionID, senderWorkspaceID, receiver, @@ -2529,7 +2542,7 @@ function getMoneyRequestInformation(moneyRequestInformation: MoneyRequestInforma if (!iouReport || shouldCreateNewMoneyRequestReport) { iouReport = isPolicyExpenseChat - ? buildOptimisticExpenseReport(chatReport.reportID, chatReport.policyID ?? '-1', payeeAccountID, amount, currency) + ? buildOptimisticExpenseReport(chatReport.reportID, chatReport.policyID, payeeAccountID, amount, currency) : buildOptimisticIOUReport(payeeAccountID, payerAccountID, amount, chatReport.reportID, currency); } else if (isPolicyExpenseChat) { iouReport = {...iouReport}; @@ -2683,11 +2696,11 @@ function getMoneyRequestInformation(moneyRequestInformation: MoneyRequestInforma chatReport, transaction: optimisticTransaction, iouAction, - createdChatReportActionID: isNewChatReport ? optimisticCreatedActionForChat.reportActionID : '-1', - createdIOUReportActionID: shouldCreateNewMoneyRequestReport ? optimisticCreatedActionForIOUReport.reportActionID : '-1', + createdChatReportActionID: isNewChatReport ? optimisticCreatedActionForChat.reportActionID : undefined, + createdIOUReportActionID: shouldCreateNewMoneyRequestReport ? optimisticCreatedActionForIOUReport.reportActionID : undefined, reportPreviewAction, - transactionThreadReportID: optimisticTransactionThread?.reportID ?? '-1', - createdReportActionIDForThread: optimisticCreatedActionForTransactionThread?.reportActionID ?? '-1', + transactionThreadReportID: optimisticTransactionThread?.reportID, + createdReportActionIDForThread: optimisticCreatedActionForTransactionThread?.reportActionID, onyxData: { optimisticData, successData, @@ -2780,7 +2793,7 @@ function getPerDiemExpenseInformation(perDiemExpenseInformation: PerDiemExpenseI if (!iouReport || shouldCreateNewMoneyRequestReport) { iouReport = isPolicyExpenseChat - ? buildOptimisticExpenseReport(chatReport.reportID, chatReport.policyID ?? '-1', payeeAccountID, amount, currency) + ? buildOptimisticExpenseReport(chatReport.reportID, chatReport.policyID, payeeAccountID, amount, currency) : buildOptimisticIOUReport(payeeAccountID, payerAccountID, amount, chatReport.reportID, currency); } else if (isPolicyExpenseChat) { iouReport = {...iouReport}; @@ -2920,11 +2933,11 @@ function getPerDiemExpenseInformation(perDiemExpenseInformation: PerDiemExpenseI chatReport, transaction: optimisticTransaction, iouAction, - createdChatReportActionID: isNewChatReport ? optimisticCreatedActionForChat.reportActionID : '-1', - createdIOUReportActionID: shouldCreateNewMoneyRequestReport ? optimisticCreatedActionForIOUReport.reportActionID : '-1', + createdChatReportActionID: isNewChatReport ? optimisticCreatedActionForChat.reportActionID : undefined, + createdIOUReportActionID: shouldCreateNewMoneyRequestReport ? optimisticCreatedActionForIOUReport.reportActionID : undefined, reportPreviewAction, - transactionThreadReportID: optimisticTransactionThread?.reportID ?? '-1', - createdReportActionIDForThread: optimisticCreatedActionForTransactionThread?.reportActionID ?? '-1', + transactionThreadReportID: optimisticTransactionThread?.reportID, + createdReportActionIDForThread: optimisticCreatedActionForTransactionThread?.reportActionID, onyxData: { optimisticData, successData, @@ -3008,7 +3021,7 @@ function getTrackExpenseInformation( shouldCreateNewMoneyRequestReport = shouldCreateNewMoneyRequestReportReportUtils(iouReport, chatReport); if (!iouReport || shouldCreateNewMoneyRequestReport) { - iouReport = buildOptimisticExpenseReport(chatReport.reportID, chatReport.policyID ?? '-1', payeeAccountID, amount, currency, amount); + iouReport = buildOptimisticExpenseReport(chatReport.reportID, chatReport.policyID, payeeAccountID, amount, currency, amount); } else { iouReport = {...iouReport}; // Because of the Expense reports are stored as negative values, we subtract the total from the amount @@ -3049,7 +3062,7 @@ function getTrackExpenseInformation( transactionParams: { amount: isExpenseReport(iouReport) ? -amount : amount, currency, - reportID: shouldUseMoneyReport && iouReport ? iouReport.reportID : '-1', + reportID: shouldUseMoneyReport && iouReport ? iouReport.reportID : undefined, comment, created, merchant, @@ -3140,12 +3153,11 @@ function getTrackExpenseInformation( iouReport: iouReport ?? undefined, transaction: optimisticTransaction, iouAction, - createdChatReportActionID: '-1', - createdIOUReportActionID: shouldCreateNewMoneyRequestReport ? optimisticCreatedActionForIOUReport.reportActionID : '-1', + createdIOUReportActionID: shouldCreateNewMoneyRequestReport ? optimisticCreatedActionForIOUReport.reportActionID : undefined, reportPreviewAction: reportPreviewAction ?? undefined, transactionThreadReportID: optimisticTransactionThread.reportID, - createdReportActionIDForThread: optimisticCreatedActionForTransactionThread?.reportActionID ?? '-1', - actionableWhisperReportActionIDParam: actionableTrackExpenseWhisper?.reportActionID ?? '', + createdReportActionIDForThread: optimisticCreatedActionForTransactionThread?.reportActionID, + actionableWhisperReportActionIDParam: actionableTrackExpenseWhisper?.reportActionID, onyxData: { optimisticData: optimisticData.concat(trackExpenseOnyxData[0]), successData: successData.concat(trackExpenseOnyxData[1]), @@ -3342,7 +3354,15 @@ function getUpdateMoneyRequestParams( } } } else { - updatedMoneyRequestReport = updateIOUOwnerAndTotal(iouReport, updatedReportAction.actorAccountID ?? -1, diff, getCurrency(transaction), false, true, isTransactionOnHold); + updatedMoneyRequestReport = updateIOUOwnerAndTotal( + iouReport, + updatedReportAction.actorAccountID ?? CONST.DEFAULT_NUMBER_ID, + diff, + getCurrency(transaction), + false, + true, + isTransactionOnHold, + ); } optimisticData.push( @@ -3383,30 +3403,33 @@ function getUpdateMoneyRequestParams( }); if (isScanning && ('amount' in transactionChanges || 'currency' in transactionChanges)) { - optimisticData.push( - { + if (transactionThread?.parentReportActionID) { + optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport?.reportID}`, value: { - [transactionThread?.parentReportActionID ?? '-1']: { + [transactionThread?.parentReportActionID]: { originalMessage: { whisperedTo: [], }, }, }, - }, - { + }); + } + + if (iouReport?.parentReportActionID) { + optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport?.parentReportID}`, value: { - [iouReport?.parentReportActionID ?? '-1']: { + [iouReport.parentReportActionID]: { originalMessage: { whisperedTo: [], }, }, }, - }, - ); + }); + } } // Update recently used categories if the category is changed @@ -3653,17 +3676,11 @@ function getUpdateTrackExpenseParams( }, }); - if (isScanning && ('amount' in transactionChanges || 'currency' in transactionChanges)) { + if (isScanning && transactionThread?.parentReportActionID && ('amount' in transactionChanges || 'currency' in transactionChanges)) { optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.reportID}`, - value: { - [transactionThread?.parentReportActionID ?? '-1']: { - originalMessage: { - whisperedTo: [], - }, - }, - }, + value: {[transactionThread.parentReportActionID]: {originalMessage: {whisperedTo: []}}}, }); } @@ -4000,12 +4017,12 @@ function updateMoneyRequestDistanceRate( } const getConvertTrackedExpenseInformation = ( - transactionID: string, + transactionID: string | undefined, actionableWhisperReportActionID: string, - moneyRequestReportID: string, + moneyRequestReportID: string | undefined, linkedTrackedExpenseReportAction: OnyxTypes.ReportAction, linkedTrackedExpenseReportID: string, - transactionThreadReportID: string, + transactionThreadReportID: string | undefined, resolution: IOUAction, ) => { const optimisticData: OnyxUpdate[] = []; @@ -4060,9 +4077,9 @@ function convertTrackedExpenseToRequest( chatReportID: string, transactionID: string, actionableWhisperReportActionID: string, - createdChatReportActionID: string, + createdChatReportActionID: string | undefined, moneyRequestReportID: string, - moneyRequestCreatedReportActionID: string, + moneyRequestCreatedReportActionID: string | undefined, moneyRequestPreviewReportActionID: string, linkedTrackedExpenseReportAction: OnyxTypes.ReportAction, linkedTrackedExpenseReportID: string, @@ -4575,7 +4592,7 @@ function trackExpense( return; } const transactionParams: TrackedExpenseTransactionParams = { - transactionID: transaction?.transactionID ?? '-1', + transactionID: transaction?.transactionID, amount, currency, comment, @@ -4589,18 +4606,18 @@ function trackExpense( receipt: trackedReceipt instanceof Blob ? trackedReceipt : undefined, }; const policyParams: TrackedExpensePolicyParams = { - policyID: chatReport?.policyID ?? '-1', + policyID: chatReport?.policyID, isDraftPolicy, }; const reportInformation: TrackedExpenseReportInformation = { - moneyRequestPreviewReportActionID: iouAction?.reportActionID ?? '-1', - moneyRequestReportID: iouReport?.reportID ?? '-1', - moneyRequestCreatedReportActionID: createdIOUReportActionID ?? '-1', + moneyRequestPreviewReportActionID: iouAction?.reportActionID, + moneyRequestReportID: iouReport?.reportID, + moneyRequestCreatedReportActionID: createdIOUReportActionID, actionableWhisperReportActionID, linkedTrackedExpenseReportAction, linkedTrackedExpenseReportID, - transactionThreadReportID: transactionThreadReportID ?? '-1', - reportPreviewReportActionID: reportPreviewAction?.reportActionID ?? '-1', + transactionThreadReportID, + reportPreviewReportActionID: reportPreviewAction?.reportActionID, }; const trackedExpenseParams: TrackedExpenseParams = { onyxData, @@ -4618,7 +4635,7 @@ function trackExpense( return; } const transactionParams = { - transactionID: transaction?.transactionID ?? '-1', + transactionID: transaction?.transactionID, amount, currency, comment, @@ -4632,17 +4649,17 @@ function trackExpense( receipt: trackedReceipt instanceof Blob ? trackedReceipt : undefined, }; const policyParams = { - policyID: chatReport?.policyID ?? '-1', + policyID: chatReport?.policyID, }; const reportInformation = { - moneyRequestPreviewReportActionID: iouAction?.reportActionID ?? '-1', - moneyRequestReportID: iouReport?.reportID ?? '-1', - moneyRequestCreatedReportActionID: createdIOUReportActionID ?? '-1', + moneyRequestPreviewReportActionID: iouAction?.reportActionID, + moneyRequestReportID: iouReport?.reportID, + moneyRequestCreatedReportActionID: createdIOUReportActionID, actionableWhisperReportActionID, linkedTrackedExpenseReportAction, linkedTrackedExpenseReportID, - transactionThreadReportID: transactionThreadReportID ?? '-1', - reportPreviewReportActionID: reportPreviewAction?.reportActionID ?? '-1', + transactionThreadReportID, + reportPreviewReportActionID: reportPreviewAction?.reportActionID, }; const trackedExpenseParams = { onyxData, @@ -4662,10 +4679,10 @@ function trackExpense( created, merchant, iouReportID: iouReport?.reportID, - chatReportID: chatReport?.reportID ?? '-1', - transactionID: transaction?.transactionID ?? '-1', - reportActionID: iouAction?.reportActionID ?? '-1', - createdChatReportActionID: createdChatReportActionID ?? '-1', + chatReportID: chatReport?.reportID, + transactionID: transaction?.transactionID, + reportActionID: iouAction?.reportActionID, + createdChatReportActionID, createdIOUReportActionID, reportPreviewReportActionID: reportPreviewAction?.reportActionID, receipt: trackedReceipt instanceof Blob ? trackedReceipt : undefined, @@ -4677,8 +4694,8 @@ function trackExpense( billable, // This needs to be a string of JSON because of limitations with the fetch() API and nested objects receiptGpsPoints: gpsPoints ? JSON.stringify(gpsPoints) : undefined, - transactionThreadReportID: transactionThreadReportID ?? '-1', - createdReportActionIDForThread: createdReportActionIDForThread ?? '-1', + transactionThreadReportID, + createdReportActionIDForThread, waypoints: validWaypoints ? JSON.stringify(sanitizeRecentWaypoints(validWaypoints)) : undefined, customUnitRateID, }; @@ -4696,15 +4713,15 @@ function trackExpense( Navigation.goBack(); Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(activeReportID)); } - Navigation.setNavigationActionToMicrotaskQueue(() => Navigation.navigate(ROUTES.ROOM_INVITE.getRoute(activeReportID ?? '-1', CONST.IOU.SHARE.ROLE.ACCOUNTANT))); + Navigation.setNavigationActionToMicrotaskQueue(() => Navigation.navigate(ROUTES.ROOM_INVITE.getRoute(activeReportID, CONST.IOU.SHARE.ROLE.ACCOUNTANT))); } - notifyNewAction(activeReportID ?? '', payeeAccountID); + notifyNewAction(activeReportID, payeeAccountID); } function getOrCreateOptimisticSplitChatReport(existingSplitChatReportID: string, participants: Participant[], participantAccountIDs: number[], currentUserAccountID: number) { // The existing chat report could be passed as reportID or exist on the sole "participant" (in this case a report option) - const existingChatReportID = existingSplitChatReportID || (participants.at(0)?.reportID ?? '-1'); + const existingChatReportID = existingSplitChatReportID || participants.at(0)?.reportID; // Check if the report is available locally if we do have one let existingSplitChatReport = existingChatReportID ? allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${existingChatReportID}`] : null; @@ -4962,7 +4979,7 @@ function createSplitsAndOnyxData( participants.forEach((participant) => { // In a case when a participant is a workspace, even when a current user is not an owner of the workspace const isPolicyExpenseChat = isPolicyExpenseChatReportUtils(participant); - const splitAmount = splitShares?.[participant.accountID ?? -1]?.amount ?? calculateIOUAmount(participants.length, amount, currency, false); + const splitAmount = splitShares?.[participant.accountID ?? CONST.DEFAULT_NUMBER_ID]?.amount ?? calculateIOUAmount(participants.length, amount, currency, false); const splitTaxAmount = calculateIOUAmount(participants.length, taxAmount, currency, false); // To exclude someone from a split, the amount can be 0. The scenario for this is when creating a split from a group chat, we have remove the option to deselect users to exclude them. @@ -5007,7 +5024,7 @@ function createSplitsAndOnyxData( if (!oneOnOneIOUReport || shouldCreateNewOneOnOneIOUReport) { oneOnOneIOUReport = isOwnPolicyExpenseChat - ? buildOptimisticExpenseReport(oneOnOneChatReport.reportID, oneOnOneChatReport.policyID ?? '-1', currentUserAccountID, splitAmount, currency) + ? buildOptimisticExpenseReport(oneOnOneChatReport.reportID, oneOnOneChatReport.policyID, currentUserAccountID, splitAmount, currency) : buildOptimisticIOUReport(currentUserAccountID, accountID, splitAmount, oneOnOneChatReport.reportID, currency); } else if (isOwnPolicyExpenseChat) { // Because of the Expense reports are stored as negative values, we subtract the total from the amount @@ -5558,7 +5575,7 @@ function startSplitBill({ return; } - const participantPersonalDetails = allPersonalDetails[participant?.accountID ?? -1]; + const participantPersonalDetails = allPersonalDetails[participant?.accountID ?? CONST.DEFAULT_NUMBER_ID]; if (!participantPersonalDetails) { optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, @@ -5653,7 +5670,7 @@ function startSplitBill({ API.write(WRITE_COMMANDS.START_SPLIT_BILL, parameters, {optimisticData, successData, failureData}); Navigation.dismissModalWithReport(splitChatReport); - notifyNewAction(splitChatReport.reportID ?? '-1', currentUserAccountID); + notifyNewAction(splitChatReport.reportID, currentUserAccountID); } /** Used for editing a split expense while it's still scanning or when SmartScan fails, it completes a split expense started by startSplitBill above. @@ -5666,7 +5683,7 @@ function startSplitBill({ */ function completeSplitBill(chatReportID: string, reportAction: OnyxTypes.ReportAction, updatedTransaction: OnyxEntry, sessionAccountID: number, sessionEmail: string) { const currentUserEmailForIOUSplit = addSMSDomainIfPhoneNumber(sessionEmail); - const transactionID = updatedTransaction?.transactionID ?? '-1'; + const transactionID = updatedTransaction?.transactionID; const unmodifiedTransaction = allTransactions[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]; // Save optimistic updated transaction and action @@ -5749,7 +5766,7 @@ function completeSplitBill(chatReportID: string, reportAction: OnyxTypes.ReportA // In case this is still the optimistic accountID saved in the splits array, return early as we cannot know // if there is an existing chat between the split creator and this participant // Instead, we will rely on Auth generating the report IDs and the user won't see any optimistic chats or reports created - const participantPersonalDetails: OnyxTypes.PersonalDetails | null = allPersonalDetails[participant?.accountID ?? -1]; + const participantPersonalDetails: OnyxTypes.PersonalDetails | null = allPersonalDetails[participant?.accountID ?? CONST.DEFAULT_NUMBER_ID]; if (!participantPersonalDetails || participantPersonalDetails.isOptimisticPersonalDetail) { splits.push({ email: participant.email, @@ -5774,8 +5791,8 @@ function completeSplitBill(chatReportID: string, reportAction: OnyxTypes.ReportA if (!oneOnOneIOUReport || shouldCreateNewOneOnOneIOUReport) { oneOnOneIOUReport = isPolicyExpenseChat - ? buildOptimisticExpenseReport(oneOnOneChatReport?.reportID ?? '-1', participant.policyID ?? '-1', sessionAccountID, splitAmount, currency ?? '') - : buildOptimisticIOUReport(sessionAccountID, participant.accountID ?? -1, splitAmount, oneOnOneChatReport?.reportID ?? '-1', currency ?? ''); + ? buildOptimisticExpenseReport(oneOnOneChatReport?.reportID, participant.policyID, sessionAccountID, splitAmount, currency ?? '') + : buildOptimisticIOUReport(sessionAccountID, participant.accountID ?? CONST.DEFAULT_NUMBER_ID, splitAmount, oneOnOneChatReport?.reportID, currency ?? ''); } else if (isPolicyExpenseChat) { if (typeof oneOnOneIOUReport?.total === 'number') { // Because of the Expense reports are stored as negative values, we subtract the total from the amount @@ -5790,7 +5807,7 @@ function completeSplitBill(chatReportID: string, reportAction: OnyxTypes.ReportA transactionParams: { amount: isPolicyExpenseChat ? -splitAmount : splitAmount, currency: currency ?? '', - reportID: oneOnOneIOUReport?.reportID ?? '-1', + reportID: oneOnOneIOUReport?.reportID, comment: updatedTransaction?.comment?.comment, created: updatedTransaction?.modifiedCreated, merchant: updatedTransaction?.modifiedMerchant, @@ -5818,7 +5835,7 @@ function completeSplitBill(chatReportID: string, reportAction: OnyxTypes.ReportA undefined, ); - let oneOnOneReportPreviewAction = getReportPreviewAction(oneOnOneChatReport?.reportID ?? '-1', oneOnOneIOUReport?.reportID ?? '-1'); + let oneOnOneReportPreviewAction = getReportPreviewAction(oneOnOneChatReport?.reportID, oneOnOneIOUReport?.reportID); if (oneOnOneReportPreviewAction) { oneOnOneReportPreviewAction = updateReportPreview(oneOnOneIOUReport, oneOnOneReportPreviewAction); } else { @@ -5968,7 +5985,7 @@ function createDistanceRequest(distanceRequestInformation: CreateDistanceRequest category ?? '', tag ?? '', splitShares, - report?.reportID ?? '', + report?.reportID, billable, CONST.IOU.REQUEST_TYPE.DISTANCE, taxCode, @@ -5981,7 +5998,7 @@ function createDistanceRequest(distanceRequestInformation: CreateDistanceRequest parameters = { transactionID: splitData.transactionID, chatReportID: splitData.chatReportID, - createdChatReportActionID: splitData.createdReportActionID ?? '', + createdChatReportActionID: splitData.createdReportActionID, reportActionID: splitData.reportActionID, waypoints: JSON.stringify(sanitizedWaypoints), customUnitRateID, @@ -6072,7 +6089,7 @@ function createDistanceRequest(distanceRequestInformation: CreateDistanceRequest API.write(WRITE_COMMANDS.CREATE_DISTANCE_REQUEST, parameters, onyxData); InteractionManager.runAfterInteractions(() => removeDraftTransaction(CONST.IOU.OPTIMISTIC_TRANSACTION_ID)); - const activeReportID = isMoneyRequestReport ? report?.reportID ?? '-1' : parameters.chatReportID; + const activeReportID = isMoneyRequestReport && report?.reportID ? report.reportID : parameters.chatReportID; Navigation.dismissModal(isSearchTopmostCentralPane() ? undefined : activeReportID); notifyNewAction(activeReportID, userAccountID); } @@ -6127,11 +6144,10 @@ function updateMoneyRequestAmountAndCurrency({ */ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxTypes.ReportAction) { // STEP 1: Get all collections we're updating - const iouReportID = isMoneyRequestAction(reportAction) ? getOriginalMessage(reportAction)?.IOUReportID : '-1'; + const iouReportID = isMoneyRequestAction(reportAction) ? getOriginalMessage(reportAction)?.IOUReportID : undefined; const iouReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${iouReportID}`] ?? null; const chatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${iouReport?.chatReportID}`]; - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const reportPreviewAction = getReportPreviewAction(iouReport?.chatReportID ?? '-1', iouReport?.reportID ?? '-1')!; + const reportPreviewAction = getReportPreviewAction(iouReport?.chatReportID, iouReport?.reportID); const transaction = allTransactions[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]; const isTransactionOnHold = isOnHold(transaction); const transactionViolations = allTransactionViolations[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`]; @@ -6172,14 +6188,14 @@ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxT if (chatReport) { canUserPerformWriteAction = !!canUserPerformWriteActionReportUtils(chatReport); } - const lastVisibleAction = getLastVisibleAction(iouReport?.reportID ?? '-1', canUserPerformWriteAction, updatedReportAction); - const iouReportLastMessageText = getLastVisibleMessage(iouReport?.reportID ?? '-1', canUserPerformWriteAction, updatedReportAction).lastMessageText; + const lastVisibleAction = getLastVisibleAction(iouReport?.reportID, canUserPerformWriteAction, updatedReportAction); + const iouReportLastMessageText = getLastVisibleMessage(iouReport?.reportID, canUserPerformWriteAction, updatedReportAction).lastMessageText; const shouldDeleteIOUReport = iouReportLastMessageText.length === 0 && !isDeletedParentAction(lastVisibleAction) && (!transactionThreadID || shouldDeleteTransactionThread); // STEP 4: Update the iouReport and reportPreview with new totals and messages if it wasn't deleted let updatedIOUReport: OnyxInputValue; const currency = getCurrency(transaction); - const updatedReportPreviewAction: OnyxTypes.ReportAction = {...reportPreviewAction}; + const updatedReportPreviewAction: Partial> = {...reportPreviewAction}; updatedReportPreviewAction.pendingAction = shouldDeleteIOUReport ? CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE : CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE; if (iouReport && isExpenseReport(iouReport)) { updatedIOUReport = {...iouReport}; @@ -6204,7 +6220,15 @@ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxT } } } else { - updatedIOUReport = updateIOUOwnerAndTotal(iouReport, reportAction.actorAccountID ?? -1, getAmount(transaction, false), currency, true, false, isTransactionOnHold); + updatedIOUReport = updateIOUOwnerAndTotal( + iouReport, + reportAction.actorAccountID ?? CONST.DEFAULT_NUMBER_ID, + getAmount(transaction, false), + currency, + true, + false, + isTransactionOnHold, + ); } if (updatedIOUReport) { @@ -6214,7 +6238,7 @@ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxT const hasNonReimbursableTransactions = hasNonReimbursableTransactionsReportUtils(iouReport?.reportID); const messageText = Localize.translateLocal(hasNonReimbursableTransactions ? 'iou.payerSpentAmount' : 'iou.payerOwesAmount', { - payer: getPersonalDetailsForAccountID(updatedIOUReport?.managerID ?? -1).login ?? '', + payer: getPersonalDetailsForAccountID(updatedIOUReport?.managerID ?? CONST.DEFAULT_NUMBER_ID).login ?? '', amount: convertToDisplayString(updatedIOUReport?.total, updatedIOUReport?.currency), }); @@ -6429,6 +6453,18 @@ function cleanUpMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repo if (chatReport) { canUserPerformWriteAction = !!canUserPerformWriteActionReportUtils(chatReport); } + + const lastMessageText = getLastVisibleMessage( + iouReport?.chatReportID, + canUserPerformWriteAction, + reportPreviewAction?.reportActionID ? {[reportPreviewAction.reportActionID]: null} : {}, + )?.lastMessageText; + const lastVisibleActionCreated = getLastVisibleAction( + iouReport?.chatReportID, + canUserPerformWriteAction, + reportPreviewAction?.reportActionID ? {[reportPreviewAction.reportActionID]: null} : {}, + )?.created; + onyxUpdates.push( { onyxMethod: Onyx.METHOD.MERGE, @@ -6436,12 +6472,8 @@ function cleanUpMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repo value: { hasOutstandingChildRequest: false, iouReportID: null, - lastMessageText: getLastVisibleMessage(iouReport?.chatReportID ?? '-1', canUserPerformWriteAction, { - [reportPreviewAction?.reportActionID ?? '-1']: null, - })?.lastMessageText, - lastVisibleActionCreated: getLastVisibleAction(iouReport?.chatReportID ?? '-1', canUserPerformWriteAction, { - [reportPreviewAction?.reportActionID ?? '-1']: null, - })?.created, + lastMessageText, + lastVisibleActionCreated, }, }, { @@ -6545,13 +6577,6 @@ function deleteMoneyRequest(transactionID: string | undefined, reportAction: Ony key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport?.reportID}`, value: updatedIOUReport, }, - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.reportID}`, - value: { - [reportPreviewAction?.reportActionID ?? '-1']: updatedReportPreviewAction, - }, - }, { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport?.reportID}`, @@ -6559,6 +6584,14 @@ function deleteMoneyRequest(transactionID: string | undefined, reportAction: Ony }, ); + if (reportPreviewAction?.reportActionID) { + optimisticData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.reportID}`, + value: {[reportPreviewAction.reportActionID]: updatedReportPreviewAction}, + }); + } + if (!shouldDeleteIOUReport && updatedReportPreviewAction?.childMoneyRequestCount === 0) { optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, @@ -6574,16 +6607,26 @@ function deleteMoneyRequest(transactionID: string | undefined, reportAction: Ony if (chatReport) { canUserPerformWriteAction = !!canUserPerformWriteActionReportUtils(chatReport); } + + const lastMessageText = getLastVisibleMessage( + iouReport?.chatReportID, + canUserPerformWriteAction, + reportPreviewAction?.reportActionID ? {[reportPreviewAction.reportActionID]: null} : {}, + )?.lastMessageText; + const lastVisibleActionCreated = getLastVisibleAction( + iouReport?.chatReportID, + canUserPerformWriteAction, + reportPreviewAction?.reportActionID ? {[reportPreviewAction.reportActionID]: null} : {}, + )?.created; + optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport?.reportID}`, value: { hasOutstandingChildRequest: false, iouReportID: null, - lastMessageText: getLastVisibleMessage(iouReport?.chatReportID ?? '-1', canUserPerformWriteAction, {[reportPreviewAction?.reportActionID ?? '-1']: null})?.lastMessageText, - lastVisibleActionCreated: getLastVisibleAction(iouReport?.chatReportID ?? '-1', canUserPerformWriteAction, { - [reportPreviewAction?.reportActionID ?? '-1']: null, - })?.created, + lastMessageText, + lastVisibleActionCreated, }, }); optimisticData.push({ @@ -6609,17 +6652,20 @@ function deleteMoneyRequest(transactionID: string | undefined, reportAction: Ony }, }, }, - { + ]; + + if (reportPreviewAction?.reportActionID) { + successData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.reportID}`, value: { - [reportPreviewAction?.reportActionID ?? '-1']: { + [reportPreviewAction.reportActionID]: { pendingAction: null, errors: null, }, }, - }, - ]; + }); + } // Ensure that any remaining data is removed upon successful completion, even if the server sends a report removal response. // This is done to prevent the removal update from lingering in the applyHTTPSOnyxUpdates function. @@ -6688,11 +6734,14 @@ function deleteMoneyRequest(transactionID: string | undefined, reportAction: Ony key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport?.reportID}`, value: iouReport, }, - { + ); + + if (reportPreviewAction?.reportActionID) { + failureData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.reportID}`, value: { - [reportPreviewAction?.reportActionID ?? '-1']: { + [reportPreviewAction.reportActionID]: { ...reportPreviewAction, pendingAction: null, errors: { @@ -6700,8 +6749,8 @@ function deleteMoneyRequest(transactionID: string | undefined, reportAction: Ony }, }, }, - }, - ); + }); + } if (chatReport && shouldDeleteIOUReport) { failureData.push({ @@ -6894,13 +6943,13 @@ function getSendMoneyParams( [reportPreviewAction.reportActionID]: reportPreviewAction, }, }; - const optimisticTransactionThreadReportActionsData: OnyxUpdate = { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${optimisticTransactionThread.reportID}`, - value: { - [optimisticCreatedActionForTransactionThread?.reportActionID ?? '-1']: optimisticCreatedActionForTransactionThread, - }, - }; + const optimisticTransactionThreadReportActionsData: OnyxUpdate | undefined = optimisticCreatedActionForTransactionThread + ? { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${optimisticTransactionThread.reportID}`, + value: {[optimisticCreatedActionForTransactionThread?.reportActionID]: optimisticCreatedActionForTransactionThread}, + } + : undefined; const successData: OnyxUpdate[] = []; @@ -6993,15 +7042,6 @@ function getSendMoneyParams( }, }, }, - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${optimisticTransactionThread.reportID}`, - value: { - [optimisticCreatedActionForTransactionThread?.reportActionID ?? '-1']: { - pendingAction: null, - }, - }, - }, ); const failureData: OnyxUpdate[] = [ @@ -7021,15 +7061,6 @@ function getSendMoneyParams( }, }, }, - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${optimisticTransactionThread.reportID}`, - value: { - [optimisticCreatedActionForTransactionThread?.reportActionID ?? '-1']: { - errors: getMicroSecondOnyxErrorWithTranslationKey('iou.error.genericCreateFailureMessage'), - }, - }, - }, { onyxMethod: Onyx.METHOD.SET, key: ONYXKEYS.NVP_QUICK_ACTION_GLOBAL_CREATE, @@ -7037,6 +7068,19 @@ function getSendMoneyParams( }, ]; + if (optimisticCreatedActionForTransactionThread?.reportActionID) { + successData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${optimisticTransactionThread.reportID}`, + value: {[optimisticCreatedActionForTransactionThread?.reportActionID]: {pendingAction: null}}, + }); + failureData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${optimisticTransactionThread.reportID}`, + value: {[optimisticCreatedActionForTransactionThread?.reportActionID]: {errors: getMicroSecondOnyxErrorWithTranslationKey('iou.error.genericCreateFailureMessage')}}, + }); + } + // Now, let's add the data we need just when we are creating a new chat report if (isNewChat) { successData.push({ @@ -7091,9 +7135,11 @@ function getSendMoneyParams( optimisticIOUReportActionsData, optimisticTransactionData, optimisticTransactionThreadData, - optimisticTransactionThreadReportActionsData, ]; + if (optimisticTransactionThreadReportActionsData) { + optimisticData.push(optimisticTransactionThreadReportActionsData); + } if (!isEmptyObject(optimisticPersonalDetailListData)) { optimisticData.push(optimisticPersonalDetailListData); } @@ -7106,11 +7152,11 @@ function getSendMoneyParams( paymentMethodType, transactionID: optimisticTransaction.transactionID, newIOUReportDetails, - createdReportActionID: isNewChat ? optimisticCreatedActionForChat.reportActionID : '-1', + createdReportActionID: isNewChat ? optimisticCreatedActionForChat.reportActionID : undefined, reportPreviewReportActionID: reportPreviewAction.reportActionID, createdIOUReportActionID: optimisticCreatedActionForIOUReport.reportActionID, transactionThreadReportID: optimisticTransactionThread.reportID, - createdReportActionIDForThread: optimisticCreatedActionForTransactionThread?.reportActionID ?? '-1', + createdReportActionIDForThread: optimisticCreatedActionForTransactionThread?.reportActionID, }, optimisticData, successData, @@ -7123,14 +7169,14 @@ type OptimisticHoldReportExpenseActionID = { oldReportActionID: string; }; -function getHoldReportActionsAndTransactions(reportID: string) { +function getHoldReportActionsAndTransactions(reportID: string | undefined) { const iouReportActions = getAllReportActions(reportID); const holdReportActions: Array> = []; const holdTransactions: OnyxTypes.Transaction[] = []; Object.values(iouReportActions).forEach((action) => { - const transactionID = isMoneyRequestAction(action) ? getOriginalMessage(action)?.IOUTransactionID ?? null : null; - const transaction = getTransaction(transactionID ?? '-1'); + const transactionID = isMoneyRequestAction(action) ? getOriginalMessage(action)?.IOUTransactionID : undefined; + const transaction = getTransaction(transactionID); if (transaction?.comment?.hold) { holdReportActions.push(action as OnyxTypes.ReportAction); @@ -7153,7 +7199,7 @@ function getReportFromHoldRequestsOnyxData( successData: OnyxUpdate[]; failureData: OnyxUpdate[]; } { - const {holdReportActions, holdTransactions} = getHoldReportActionsAndTransactions(iouReport?.reportID ?? ''); + const {holdReportActions, holdTransactions} = getHoldReportActionsAndTransactions(iouReport?.reportID); const firstHoldTransaction = holdTransactions.at(0); const newParentReportActionID = rand64(); @@ -7164,14 +7210,22 @@ function getReportFromHoldRequestsOnyxData( const optimisticExpenseReport = isPolicyExpenseChat ? buildOptimisticExpenseReport( chatReport.reportID, - chatReport.policyID ?? iouReport?.policyID ?? '', + chatReport.policyID ?? iouReport?.policyID, recipient.accountID ?? 1, holdAmount, iouReport?.currency ?? '', holdNonReimbursableAmount, newParentReportActionID, ) - : buildOptimisticIOUReport(iouReport?.ownerAccountID ?? -1, iouReport?.managerID ?? -1, holdAmount, chatReport.reportID, iouReport?.currency ?? '', false, newParentReportActionID); + : buildOptimisticIOUReport( + iouReport?.ownerAccountID ?? CONST.DEFAULT_NUMBER_ID, + iouReport?.managerID ?? CONST.DEFAULT_NUMBER_ID, + holdAmount, + chatReport.reportID, + iouReport?.currency ?? '', + false, + newParentReportActionID, + ); const optimisticExpenseReportPreview = buildOptimisticReportPreview( chatReport, @@ -7264,7 +7318,7 @@ function getReportFromHoldRequestsOnyxData( // remove hold report actions from old iou report { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport?.reportID ?? ''}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport?.reportID}`, value: deleteHoldReportActions, }, // add hold report actions to new iou report @@ -7340,7 +7394,7 @@ function getReportFromHoldRequestsOnyxData( // add hold report actions back to old iou report { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport?.reportID ?? ''}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport?.reportID}`, value: bringReportActionsBack, }, // remove hold report actions from the new iou report @@ -7420,7 +7474,7 @@ function getPayMoneyRequestParams( } let total = (iouReport?.total ?? 0) - (iouReport?.nonReimbursableTotal ?? 0); - if (hasHeldExpensesReportUtils(iouReport?.reportID ?? '') && !full && !!iouReport?.unheldTotal) { + if (hasHeldExpensesReportUtils(iouReport?.reportID) && !full && !!iouReport?.unheldTotal) { total = iouReport.unheldTotal - (iouReport?.unheldNonReimbursableTotal ?? 0); } @@ -7439,14 +7493,14 @@ function getPayMoneyRequestParams( // In some instances, the report preview action might not be available to the payer (only whispered to the requestor) // hence we need to make the updates to the action safely. let optimisticReportPreviewAction = null; - const reportPreviewAction = getReportPreviewAction(chatReport.reportID, iouReport?.reportID ?? ''); + const reportPreviewAction = getReportPreviewAction(chatReport.reportID, iouReport?.reportID); if (reportPreviewAction) { optimisticReportPreviewAction = updateReportPreview(iouReport, reportPreviewAction, true); } let currentNextStep = null; let optimisticNextStep = null; if (!isInvoiceReport) { - currentNextStep = allNextSteps[`${ONYXKEYS.COLLECTION.NEXT_STEP}${iouReport?.reportID ?? ''}`] ?? null; + currentNextStep = allNextSteps[`${ONYXKEYS.COLLECTION.NEXT_STEP}${iouReport?.reportID}`] ?? null; optimisticNextStep = buildNextStep(iouReport, CONST.REPORT.STATUS_NUM.REIMBURSED); } @@ -7473,7 +7527,7 @@ function getPayMoneyRequestParams( }, { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport?.reportID ?? ''}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport?.reportID}`, value: { [optimisticIOUReportAction.reportActionID]: { ...(optimisticIOUReportAction as OnyxTypes.ReportAction), @@ -7483,7 +7537,7 @@ function getPayMoneyRequestParams( }, { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport?.reportID ?? ''}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport?.reportID}`, value: { ...iouReport, lastMessageText: getReportActionText(optimisticIOUReportAction), @@ -7501,19 +7555,24 @@ function getPayMoneyRequestParams( }, { onyxMethod: Onyx.METHOD.MERGE, - key: ONYXKEYS.NVP_LAST_PAYMENT_METHOD, - value: {[iouReport?.policyID ?? '-1']: paymentMethodType}, - }, - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.NEXT_STEP}${iouReport?.reportID ?? ''}`, + key: `${ONYXKEYS.COLLECTION.NEXT_STEP}${iouReport?.reportID}`, value: optimisticNextStep, }, ); + if (iouReport?.policyID) { + optimisticData.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.NVP_LAST_PAYMENT_METHOD, + value: { + [iouReport.policyID]: paymentMethodType, + }, + }); + } + successData.push({ onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport?.reportID ?? ''}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport?.reportID}`, value: { pendingFields: { preview: null, @@ -7527,7 +7586,7 @@ function getPayMoneyRequestParams( failureData.push( { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport?.reportID ?? ''}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport?.reportID}`, value: { [optimisticIOUReportAction.reportActionID]: { errors: getMicroSecondOnyxErrorWithTranslationKey('iou.error.other'), @@ -7536,7 +7595,7 @@ function getPayMoneyRequestParams( }, { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport?.reportID ?? ''}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport?.reportID}`, value: { ...iouReport, }, @@ -7548,7 +7607,7 @@ function getPayMoneyRequestParams( }, { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.NEXT_STEP}${iouReport?.reportID ?? ''}`, + key: `${ONYXKEYS.COLLECTION.NEXT_STEP}${iouReport?.reportID}`, value: currentNextStep, }, ); @@ -7633,7 +7692,7 @@ function getPayMoneyRequestParams( return { params: { - iouReportID: iouReport?.reportID ?? '', + iouReportID: iouReport?.reportID, chatReportID: chatReport.reportID, reportActionID: optimisticIOUReportAction.reportActionID, paymentMethodType, @@ -7691,7 +7750,7 @@ function canApproveIOU( return false; } - const managerID = iouReport?.managerID ?? -1; + const managerID = iouReport?.managerID ?? CONST.DEFAULT_NUMBER_ID; const isCurrentUserManager = managerID === userAccountID; const isOpenExpenseReport = isOpenExpenseReportReportUtils(iouReport); const isApproved = isReportApproved(iouReport); @@ -7806,18 +7865,18 @@ function canSubmitReport( ); } -function getIOUReportActionToApproveOrPay(chatReport: OnyxEntry, excludedIOUReportID: string): OnyxEntry { +function getIOUReportActionToApproveOrPay(chatReport: OnyxEntry, excludedIOUReportID: string | undefined): OnyxEntry { const chatReportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.reportID}`] ?? {}; return Object.values(chatReportActions).find((action) => { - const iouReport = getReportOrDraftReport(action.childReportID ?? '-1'); + const iouReport = getReportOrDraftReport(action.childReportID); const policy = getPolicy(iouReport?.policyID); const shouldShowSettlementButton = canIOUBePaid(iouReport, chatReport, policy) || canApproveIOU(iouReport, policy); return action.childReportID?.toString() !== excludedIOUReportID && action.actionName === CONST.REPORT.ACTIONS.TYPE.REPORT_PREVIEW && shouldShowSettlementButton; }); } -function hasIOUToApproveOrPay(chatReport: OnyxEntry, excludedIOUReportID: string): boolean { +function hasIOUToApproveOrPay(chatReport: OnyxEntry, excludedIOUReportID: string | undefined): boolean { return !!getIOUReportActionToApproveOrPay(chatReport, excludedIOUReportID); } @@ -7846,31 +7905,35 @@ function getNextApproverAccountID(report: OnyxEntry) { } function approveMoneyRequest(expenseReport: OnyxEntry, full?: boolean) { - if (expenseReport?.policyID && shouldRestrictUserBillableActions(expenseReport.policyID)) { + if (!expenseReport) { + return; + } + + if (expenseReport.policyID && shouldRestrictUserBillableActions(expenseReport.policyID)) { Navigation.navigate(ROUTES.RESTRICTED_ACTION.getRoute(expenseReport.policyID)); return; } - const currentNextStep = allNextSteps[`${ONYXKEYS.COLLECTION.NEXT_STEP}${expenseReport?.reportID}`] ?? null; - let total = expenseReport?.total ?? 0; - const hasHeldExpenses = hasHeldExpensesReportUtils(expenseReport?.reportID); - if (hasHeldExpenses && !full && !!expenseReport?.unheldTotal) { - total = expenseReport?.unheldTotal; + const currentNextStep = allNextSteps[`${ONYXKEYS.COLLECTION.NEXT_STEP}${expenseReport.reportID}`] ?? null; + let total = expenseReport.total ?? 0; + const hasHeldExpenses = hasHeldExpensesReportUtils(expenseReport.reportID); + if (hasHeldExpenses && !full && !!expenseReport.unheldTotal) { + total = expenseReport.unheldTotal; } - const optimisticApprovedReportAction = buildOptimisticApprovedReportAction(total, expenseReport?.currency ?? '', expenseReport?.reportID ?? '-1'); + const optimisticApprovedReportAction = buildOptimisticApprovedReportAction(total, expenseReport.currency ?? '', expenseReport.reportID); - const approvalChain = getApprovalChain(getPolicy(expenseReport?.policyID), expenseReport); + const approvalChain = getApprovalChain(getPolicy(expenseReport.policyID), expenseReport); const predictedNextStatus = isLastApprover(approvalChain) ? CONST.REPORT.STATUS_NUM.APPROVED : CONST.REPORT.STATUS_NUM.SUBMITTED; const predictedNextState = isLastApprover(approvalChain) ? CONST.REPORT.STATE_NUM.APPROVED : CONST.REPORT.STATE_NUM.SUBMITTED; - const managerID = isLastApprover(approvalChain) ? expenseReport?.managerID : getNextApproverAccountID(expenseReport); + const managerID = isLastApprover(approvalChain) ? expenseReport.managerID : getNextApproverAccountID(expenseReport); const optimisticNextStep = buildNextStep(expenseReport, predictedNextStatus); - const chatReport = getReportOrDraftReport(expenseReport?.chatReportID); + const chatReport = getReportOrDraftReport(expenseReport.chatReportID); const optimisticReportActionsData: OnyxUpdate = { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport?.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport.reportID}`, value: { [optimisticApprovedReportAction.reportActionID]: { ...(optimisticApprovedReportAction as OnyxTypes.ReportAction), @@ -7880,7 +7943,7 @@ function approveMoneyRequest(expenseReport: OnyxEntry, full?: }; const optimisticIOUReportData: OnyxUpdate = { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport?.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport.reportID}`, value: { ...expenseReport, lastMessageText: getReportActionText(optimisticApprovedReportAction), @@ -7896,15 +7959,15 @@ function approveMoneyRequest(expenseReport: OnyxEntry, full?: const optimisticChatReportData: OnyxUpdate = { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport?.chatReportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport.chatReportID}`, value: { - hasOutstandingChildRequest: hasIOUToApproveOrPay(chatReport, expenseReport?.reportID ?? '-1'), + hasOutstandingChildRequest: hasIOUToApproveOrPay(chatReport, expenseReport.reportID), }, }; const optimisticNextStepData: OnyxUpdate = { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.NEXT_STEP}${expenseReport?.reportID}`, + key: `${ONYXKEYS.COLLECTION.NEXT_STEP}${expenseReport.reportID}`, value: optimisticNextStep, }; const optimisticData: OnyxUpdate[] = [optimisticIOUReportData, optimisticReportActionsData, optimisticNextStepData, optimisticChatReportData]; @@ -7912,7 +7975,7 @@ function approveMoneyRequest(expenseReport: OnyxEntry, full?: const successData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport?.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport.reportID}`, value: { [optimisticApprovedReportAction.reportActionID]: { pendingAction: null, @@ -7921,7 +7984,7 @@ function approveMoneyRequest(expenseReport: OnyxEntry, full?: }, { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport?.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport.reportID}`, value: { pendingFields: { partial: null, @@ -7933,7 +7996,7 @@ function approveMoneyRequest(expenseReport: OnyxEntry, full?: const failureData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport?.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport.reportID}`, value: { [optimisticApprovedReportAction.reportActionID]: { errors: getMicroSecondOnyxErrorWithTranslationKey('iou.error.other'), @@ -7942,7 +8005,7 @@ function approveMoneyRequest(expenseReport: OnyxEntry, full?: }, { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport?.chatReportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport.chatReportID}`, value: { hasOutstandingChildRequest: chatReport?.hasOutstandingChildRequest, pendingFields: { @@ -7952,14 +8015,14 @@ function approveMoneyRequest(expenseReport: OnyxEntry, full?: }, { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.NEXT_STEP}${expenseReport?.reportID}`, + key: `${ONYXKEYS.COLLECTION.NEXT_STEP}${expenseReport.reportID}`, value: currentNextStep, }, ]; // Clear hold reason of all transactions if we approve all requests if (full && hasHeldExpenses) { - const heldTransactions = getAllHeldTransactionsReportUtils(expenseReport?.reportID); + const heldTransactions = getAllHeldTransactionsReportUtils(expenseReport.reportID); heldTransactions.forEach((heldTransaction) => { optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, @@ -7997,7 +8060,7 @@ function approveMoneyRequest(expenseReport: OnyxEntry, full?: } const parameters: ApproveMoneyRequestParams = { - reportID: expenseReport?.reportID ?? '-1', + reportID: expenseReport.reportID, approvedReportActionID: optimisticApprovedReportAction.reportActionID, full, optimisticHoldReportID, @@ -8265,8 +8328,8 @@ function cancelPayment(expenseReport: OnyxEntry, chatReport: O const stateNum: ValueOf = approvalMode === CONST.POLICY.APPROVAL_MODE.OPTIONAL ? CONST.REPORT.STATE_NUM.SUBMITTED : CONST.REPORT.STATE_NUM.APPROVED; const statusNum: ValueOf = approvalMode === CONST.POLICY.APPROVAL_MODE.OPTIONAL ? CONST.REPORT.STATUS_NUM.CLOSED : CONST.REPORT.STATUS_NUM.APPROVED; const optimisticNextStep = buildNextStep(expenseReport, statusNum); - const iouReportActions = getAllReportActions(chatReport.iouReportID ?? '-1'); - const expenseReportActions = getAllReportActions(expenseReport.reportID ?? '-1'); + const iouReportActions = getAllReportActions(chatReport.iouReportID); + const expenseReportActions = getAllReportActions(expenseReport.reportID); const iouCreatedAction = Object.values(iouReportActions).find((action) => isCreatedAction(action)); const expenseCreatedAction = Object.values(expenseReportActions).find((action) => isCreatedAction(action)); const optimisticData: OnyxUpdate[] = [ @@ -8325,7 +8388,7 @@ function cancelPayment(expenseReport: OnyxEntry, chatReport: O onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport.reportID}`, value: { - [optimisticReportAction.reportActionID ?? '-1']: { + [optimisticReportAction.reportActionID]: { errors: getMicroSecondOnyxErrorWithTranslationKey('iou.error.other'), }, }, @@ -8392,7 +8455,7 @@ function cancelPayment(expenseReport: OnyxEntry, chatReport: O { iouReportID: expenseReport.reportID, chatReportID: chatReport.reportID, - managerAccountID: expenseReport.managerID ?? -1, + managerAccountID: expenseReport.managerID ?? CONST.DEFAULT_NUMBER_ID, reportActionID: optimisticReportAction.reportActionID, }, {optimisticData, successData, failureData}, @@ -8449,7 +8512,7 @@ function payMoneyRequest(paymentType: PaymentMethodType, chatReport: OnyxTypes.R const paymentSelected = paymentType === CONST.IOU.PAYMENT_TYPE.VBBA ? CONST.IOU.PAYMENT_SELECTED.BBA : CONST.IOU.PAYMENT_SELECTED.PBA; completePaymentOnboarding(paymentSelected); - const recipient = {accountID: iouReport?.ownerAccountID ?? -1}; + const recipient = {accountID: iouReport?.ownerAccountID ?? CONST.DEFAULT_NUMBER_ID}; const {params, optimisticData, successData, failureData} = getPayMoneyRequestParams(chatReport, iouReport, recipient, paymentType, full); // For now, we need to call the PayMoneyRequestWithWallet API since PayMoneyRequest was not updated to work with @@ -8458,11 +8521,11 @@ function payMoneyRequest(paymentType: PaymentMethodType, chatReport: OnyxTypes.R playSound(SOUNDS.SUCCESS); API.write(apiCommand, params, {optimisticData, successData, failureData}); - notifyNewAction(Navigation.getTopmostReportId() ?? iouReport?.reportID ?? '', userAccountID); + notifyNewAction(Navigation.getTopmostReportId() ?? iouReport?.reportID, userAccountID); } function payInvoice(paymentMethodType: PaymentMethodType, chatReport: OnyxTypes.Report, invoiceReport: OnyxEntry, payAsBusiness = false) { - const recipient = {accountID: invoiceReport?.ownerAccountID ?? -1}; + const recipient = {accountID: invoiceReport?.ownerAccountID ?? CONST.DEFAULT_NUMBER_ID}; const { optimisticData, successData, @@ -8485,7 +8548,7 @@ function payInvoice(paymentMethodType: PaymentMethodType, chatReport: OnyxTypes. completePaymentOnboarding(paymentSelected); let params: PayInvoiceParams = { - reportID: invoiceReport?.reportID ?? '', + reportID: invoiceReport?.reportID, reportActionID, paymentMethodType, payAsBusiness, @@ -9103,10 +9166,10 @@ function savePreferredPaymentMethod(policyID: string, paymentMethod: PaymentMeth } /** Get report policy id of IOU request */ -function getIOURequestPolicyID(transaction: OnyxEntry, report: OnyxEntry): string { +function getIOURequestPolicyID(transaction: OnyxEntry, report: OnyxEntry): string | undefined { // Workspace sender will exist for invoices const workspaceSender = transaction?.participants?.find((participant) => participant.isSender); - return workspaceSender?.policyID ?? report?.policyID ?? '-1'; + return workspaceSender?.policyID ?? report?.policyID; } function getIOUActionForTransactions(transactionIDList: Array, iouReportID: string | undefined): Array> { @@ -9327,10 +9390,12 @@ function resolveDuplicates(params: TransactionMergeParams) { }); const iouActionList = params.reportID ? getIOUActionForTransactions(params.transactionIDList, params.reportID) : []; - const orderedTransactionIDList = iouActionList.map((action) => { - const message = getOriginalMessage(action); - return message?.IOUTransactionID ?? ''; - }); + const orderedTransactionIDList = iouActionList + .map((action) => { + const message = getOriginalMessage(action); + return message?.IOUTransactionID; + }) + .filter((id): id is string => !!id); const optimisticHoldActions: OnyxUpdate[] = []; const failureHoldActions: OnyxUpdate[] = []; diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index f0d2d2a08ac9..cf1c44e1d69c 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -525,7 +525,7 @@ function subscribeToNewActionEvent(reportID: string, callback: SubscriberCallbac } /** Notify the ReportActionsView that a new comment has arrived */ -function notifyNewAction(reportID: string, accountID?: number, reportActionID?: string) { +function notifyNewAction(reportID: string | undefined, accountID?: number, reportActionID?: string) { const actionSubscriber = newActionSubscribers.find((subscriber) => subscriber.reportID === reportID); if (!actionSubscriber) { return; diff --git a/src/types/onyx/Transaction.ts b/src/types/onyx/Transaction.ts index fda51d9cc037..968b9a4dea4b 100644 --- a/src/types/onyx/Transaction.ts +++ b/src/types/onyx/Transaction.ts @@ -452,7 +452,7 @@ type Transaction = OnyxCommon.OnyxValueWithOfflineFeedback< receipt?: Receipt; /** The iouReportID associated with the transaction */ - reportID: string; + reportID: string | undefined; /** Existing routes */ routes?: Routes;