Skip to content

Commit 3eb6f4a

Browse files
committed
fixed 404 not found and loading bug on IOU track distance fields
1 parent ac9b9ed commit 3eb6f4a

3 files changed

Lines changed: 37 additions & 14 deletions

File tree

src/libs/TransactionUtils/index.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -728,13 +728,17 @@ function getUpdatedTransaction({
728728
}
729729
shouldStopSmartscan = true;
730730

731-
if (!transactionChanges.routes?.route0?.geometry?.coordinates) {
731+
// A manual-distance edit re-sends unchanged waypoints; when they truly didn't change, leave
732+
// `amount`/`modifiedAmount` to the sibling `distance` branch instead of zeroing them here.
733+
const waypointsActuallyChanged = !deepEqual(transactionChanges.waypoints, transaction?.comment?.waypoints);
734+
735+
if (waypointsActuallyChanged && !transactionChanges.routes?.route0?.geometry?.coordinates) {
732736
// The waypoints were changed, but there is no route – it is pending from the BE and we should mark the fields as pending
733737
updatedTransaction.amount = CONST.IOU.DEFAULT_AMOUNT;
734738
updatedTransaction.modifiedAmount = CONST.IOU.DEFAULT_AMOUNT;
735739
// eslint-disable-next-line @typescript-eslint/no-deprecated
736740
updatedTransaction.modifiedMerchant = translateLocal('iou.fieldPending');
737-
} else {
741+
} else if (transactionChanges.routes?.route0?.geometry?.coordinates) {
738742
const mileageRate = DistanceRequestUtils.getRate({transaction: updatedTransaction, policy});
739743
const {unit, rate} = mileageRate;
740744

@@ -881,6 +885,8 @@ function getUpdatedTransaction({
881885

882886
if (Object.hasOwn(transactionChanges, 'distance') && typeof transactionChanges.distance === 'number') {
883887
const distance = roundToTwoDecimalPlaces(transactionChanges.distance ?? 0);
888+
// Capture before mutating quantity below; needed by the fallback amount computation.
889+
const previousDistanceInMeters = getDistanceInMeters(transaction, transaction?.comment?.customUnit?.distanceUnit);
884890

885891
lodashSet(updatedTransaction, 'comment.customUnit.quantity', distance);
886892
lodashSet(updatedTransaction, 'routes.route0.distance', null);
@@ -906,9 +912,20 @@ function getUpdatedTransaction({
906912
isManualDistanceRequest(transaction),
907913
);
908914

909-
updatedTransaction.modifiedAmount = amount;
910-
updatedTransaction.modifiedMerchant = updatedMerchant;
911-
updatedTransaction.modifiedCurrency = updatedCurrency;
915+
// No locally resolvable rate (e.g. track expense without policy loaded) → scale the previous
916+
// amount by the distance ratio so the optimistic value isn't 0. `modifiedAmount` is `""` for
917+
// unedited transactions, so coerce via Number() and fall through to `amount`.
918+
const previousAmount = Number(transaction?.modifiedAmount) || transaction?.amount || 0;
919+
const useFallback = !rate && !!previousDistanceInMeters && !!previousAmount && !!distanceInMeters;
920+
if (useFallback) {
921+
updatedTransaction.modifiedAmount = Math.round(previousAmount * (distanceInMeters / previousDistanceInMeters));
922+
updatedTransaction.modifiedMerchant = updatedMerchant;
923+
// Leave currency alone — without a resolvable rate we don't know the target currency.
924+
} else {
925+
updatedTransaction.modifiedAmount = amount;
926+
updatedTransaction.modifiedMerchant = updatedMerchant;
927+
updatedTransaction.modifiedCurrency = updatedCurrency;
928+
}
912929
}
913930

914931
if (Object.hasOwn(transactionChanges, 'odometerStart') && typeof transactionChanges.odometerStart === 'number') {

src/libs/actions/TransactionEdit.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ function createBackupTransaction(transaction: OnyxEntry<Transaction>, isDraft: b
3939
key: `${ONYXKEYS.COLLECTION.TRANSACTION_BACKUP}${transaction.transactionID}`,
4040
callback: (transactionBackup) => {
4141
Onyx.disconnect(conn);
42-
if (transactionBackup) {
42+
// Treat a backup missing `transactionID` as corrupted (a partial route-fetch shape can
43+
// leak in via Pusher) and overwrite it instead of restoring from it.
44+
if (transactionBackup?.transactionID) {
4345
// If the transactionBackup exists it means we haven't properly restored original value on unmount
4446
// such as on page refresh, so we will just restore the transaction from the transactionBackup here.
4547
Onyx.set(`${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`, transactionBackup);

src/pages/iou/request/step/IOURequestStepDistance.tsx

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -203,22 +203,23 @@ function IOURequestStepDistance({
203203
// from overwriting in-progress manual input.
204204
const isManuallyEditing = useRef(false);
205205

206-
// Sync the manual tab input when the route recalculates (e.g. after waypoint edits on the map tab).
207-
// Skip the sync if the user is actively editing on the manual tab to avoid overwriting their input.
208-
// Skip the very first render so we don't clobber a previously-saved manual quantity with the route
209-
// distance on edit re-open.
206+
// Push the route distance into the manual tab input only on a real waypoint-driven recalculation
207+
// (a non-null → different non-null transition). Skip the initial null → value transition, which
208+
// is the post-save re-fetch, so we don't overwrite a saved manual quantity with the route distance.
210209
const routeDistance = currentTransaction?.routes?.route0?.distance;
211-
const isInitialRouteSync = useRef(true);
210+
const lastSyncedRouteDistance = useRef<number | null | undefined>(routeDistance);
212211
useEffect(() => {
213-
if (isInitialRouteSync.current) {
214-
isInitialRouteSync.current = false;
212+
if (routeDistance == null || !distanceUnit || isManuallyEditing.current) {
213+
lastSyncedRouteDistance.current = routeDistance;
215214
return;
216215
}
217-
if (routeDistance == null || !distanceUnit || isManuallyEditing.current) {
216+
if (lastSyncedRouteDistance.current == null || lastSyncedRouteDistance.current === routeDistance) {
217+
lastSyncedRouteDistance.current = routeDistance;
218218
return;
219219
}
220220
const routeDistanceInUnit = roundToTwoDecimalPlaces(DistanceRequestUtils.convertDistanceUnit(routeDistance, distanceUnit));
221221
manualNumberFormRef.current?.updateNumber(routeDistanceInUnit.toString());
222+
lastSyncedRouteDistance.current = routeDistance;
222223
}, [routeDistance, distanceUnit]);
223224

224225
// Sets `amount` and `split` share data before moving to the next step to avoid briefly showing `0.00` as the split share for participants
@@ -625,6 +626,9 @@ function IOURequestStepDistance({
625626
recentWaypoints,
626627
});
627628
transactionWasSaved.current = true;
629+
// Remove the backup eagerly so the parent report view reads the optimistic transaction
630+
// immediately, instead of the stale backup, while the API request is still in flight.
631+
removeBackupTransaction(transaction?.transactionID);
628632
navigateBackAfterSave();
629633
}, [
630634
translate,

0 commit comments

Comments
 (0)