diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index ca50e93e536f..1c3a9336714f 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -390,7 +390,7 @@ function MoneyRequestView({report, shouldShowAnimatedBackground, readonly = fals const shouldShowReceiptAudit = isReceiptAllowed && (shouldShowReceiptEmptyState || hasReceipt); const errors = { - ...(transaction?.errorFields?.route ?? transaction?.errors), + ...(transaction?.errorFields?.route ?? transaction?.errorFields?.waypoints ?? transaction?.errors), ...parentReportAction?.errors, }; diff --git a/src/components/ReportActionItem/ReportActionItemImage.tsx b/src/components/ReportActionItem/ReportActionItemImage.tsx index f999d12f054b..afb7df1e2218 100644 --- a/src/components/ReportActionItem/ReportActionItemImage.tsx +++ b/src/components/ReportActionItem/ReportActionItemImage.tsx @@ -91,7 +91,7 @@ function ReportActionItemImage({ const {translate} = useLocalize(); const isDistanceRequest = !!transaction && TransactionUtils.isDistanceRequest(transaction); const hasPendingWaypoints = transaction && TransactionUtils.isFetchingWaypointsFromServer(transaction); - const hasErrors = !isEmptyObject(transaction?.errors) || !isEmptyObject(transaction?.errorFields); + const hasErrors = !isEmptyObject(transaction?.errors) || !isEmptyObject(transaction?.errorFields?.route) || !isEmptyObject(transaction?.errorFields?.waypoints); const showMapAsImage = isDistanceRequest && (hasErrors || hasPendingWaypoints); if (showMapAsImage) { diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 943a8883ac1f..40bf57ddadd6 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -3251,6 +3251,7 @@ type UpdateMoneyRequestDistanceParams = { policy?: OnyxEntry; policyTagList?: OnyxEntry; policyCategories?: OnyxEntry; + transactionBackup: OnyxEntry; }; /** Updates the waypoints of a distance expense */ @@ -3262,6 +3263,7 @@ function updateMoneyRequestDistance({ policy = {} as OnyxTypes.Policy, policyTagList = {}, policyCategories = {}, + transactionBackup, }: UpdateMoneyRequestDistanceParams) { const transactionChanges: TransactionChanges = { waypoints: sanitizeRecentWaypoints(waypoints), @@ -3285,6 +3287,39 @@ function updateMoneyRequestDistance({ value: recentServerValidatedWaypoints, }); + if (transactionBackup) { + const transaction = allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]; + + // We need to include all keys of the optimisticData's waypoints in the failureData for onyx merge to properly reset + // waypoint keys that do not exist in the failureData's waypoints. For instance, if the optimisticData waypoints had + // three keys and the failureData waypoint had only 2 keys then the third key that doesn't exist in the failureData + // waypoints should be explicitly reset otherwise onyx merge will leave it intact. + const allWaypointKeys = [...new Set([...Object.keys(transactionBackup.comment?.waypoints ?? {}), ...Object.keys(transaction?.comment?.waypoints ?? {})])]; + const onyxWaypoints = allWaypointKeys.reduce((acc: NullishDeep, key) => { + acc[key] = transactionBackup.comment?.waypoints?.[key] ? {...transactionBackup.comment?.waypoints?.[key]} : null; + return acc; + }, {}); + const allModifiedWaypointsKeys = [...new Set([...Object.keys(waypoints ?? {}), ...Object.keys(transaction?.modifiedWaypoints ?? {})])]; + const onyxModifiedWaypoints = allModifiedWaypointsKeys.reduce((acc: NullishDeep, key) => { + acc[key] = transactionBackup.modifiedWaypoints?.[key] ? {...transactionBackup.modifiedWaypoints?.[key]} : null; + return acc; + }, {}); + onyxData?.failureData?.push({ + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, + value: { + comment: { + waypoints: onyxWaypoints, + customUnit: { + quantity: transactionBackup?.comment?.customUnit?.quantity, + }, + }, + modifiedWaypoints: onyxModifiedWaypoints, + routes: null, + }, + }); + } + API.write(WRITE_COMMANDS.UPDATE_MONEY_REQUEST_DISTANCE, params, onyxData); } diff --git a/src/libs/actions/Transaction.ts b/src/libs/actions/Transaction.ts index 3cb6e3dc44ba..c8a007458242 100644 --- a/src/libs/actions/Transaction.ts +++ b/src/libs/actions/Transaction.ts @@ -458,7 +458,7 @@ function abandonReviewDuplicateTransactions() { } function clearError(transactionID: string) { - Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {errors: null, errorFields: {route: null}}); + Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {errors: null, errorFields: {route: null, waypoints: null, routes: null}}); } function markAsCash(transactionID: string, transactionThreadReportID: string) { diff --git a/src/pages/iou/request/step/IOURequestStepDistance.tsx b/src/pages/iou/request/step/IOURequestStepDistance.tsx index efe5d293036b..dd02df8f4177 100644 --- a/src/pages/iou/request/step/IOURequestStepDistance.tsx +++ b/src/pages/iou/request/step/IOURequestStepDistance.tsx @@ -465,6 +465,7 @@ function IOURequestStepDistance({ waypoints, ...(hasRouteChanged ? {routes: transaction?.routes} : {}), policy, + transactionBackup, }); navigateBack(); return; diff --git a/src/types/onyx/Transaction.ts b/src/types/onyx/Transaction.ts index 547e41463c70..594503af78c3 100644 --- a/src/types/onyx/Transaction.ts +++ b/src/types/onyx/Transaction.ts @@ -338,7 +338,7 @@ type Transaction = OnyxCommon.OnyxValueWithOfflineFeedback< errors?: OnyxCommon.Errors | ReceiptErrors; /** Server side errors keyed by microtime */ - errorFields?: OnyxCommon.ErrorFields<'route'>; + errorFields?: OnyxCommon.ErrorFields; /** The name of the file used for a receipt (formerly receiptFilename) */ filename?: string;