Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions src/components/MoneyRequestConfirmationList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -321,22 +321,26 @@ function MoneyRequestConfirmationList({
const customUnitRateID = getRateID(transaction);

const subRates = transaction?.comment?.customUnit?.subRates ?? [];
const prevSubRates = usePrevious(subRates);
const defaultRate = defaultMileageRate?.customUnitRateID;
const lastSelectedRate = policy?.id ? (lastSelectedDistanceRates?.[policy.id] ?? defaultRate) : defaultRate;

const mileageRate = DistanceRequestUtils.getRate({
transaction,
policy,
...(isMovingTransactionFromTrackExpense && {policyForMovingExpenses}),
isMovingTransactionFromTrackExpense,
policyDraft,
});
const rate = mileageRate.rate;
const distanceRate = mileageRate.rate;
const distanceUnit = mileageRate.unit;
const calculateFromTransactionData = isMovingTransactionFromTrackExpense && !distanceRate;
const unit = calculateFromTransactionData ? transaction?.comment?.customUnit?.distanceUnit : distanceUnit;
const rate = calculateFromTransactionData ? Math.abs(iouAmount) / (transaction?.comment?.customUnit?.quantity ?? 1) : distanceRate;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Guard zero distance quantity before deriving fallback rate

When isMovingTransactionFromTrackExpense is true and no policy rate is found, the fallback rate is derived as Math.abs(iouAmount) / transaction.comment.customUnit.quantity. If quantity is 0 (which is a reachable state for distance requests, e.g. route exists but zero distance), this produces Infinity/NaN and then distanceRequestAmount can become invalid, causing broken amount/merchant updates in confirmation. Use a non-zero guard (or skip fallback calculation) when quantity is 0.

Useful? React with 👍 / 👎.

const currency = calculateFromTransactionData ? iouCurrencyCode : (mileageRate.currency ?? CONST.CURRENCY.USD);
const prevRate = usePrevious(rate);
const unit = mileageRate.unit;
const prevUnit = usePrevious(unit);
const currency = mileageRate.currency ?? CONST.CURRENCY.USD;
const prevCurrency = usePrevious(currency);
const prevSubRates = usePrevious(subRates);

// A flag for showing the categories field
const shouldShowCategories = isTrackExpense
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,7 @@ function DistanceRequestController({
}, [customUnitRateID, transactionID, lastSelectedRate, isDistanceRequest, isPolicyExpenseChat, isMovingTransactionFromTrackExpense, transaction, policy, selectedParticipants]);

useEffect(() => {
if (!isDistanceRequest || (isMovingTransactionFromTrackExpense && !isPolicyExpenseChat) || !transactionID || isReadOnly) {
// We don't want to recalculate the distance merchant when moving a transaction from Track Expense to a 1:1 chat, because the distance rate will be the same default P2P rate.
// When moving to a policy chat (e.g. sharing with an accountant), we should recalculate the distance merchant with the policy's rate.
if (!isDistanceRequest || !transactionID || isReadOnly) {
return;
}

Expand Down Expand Up @@ -199,11 +197,9 @@ function DistanceRequestController({
translate,
toLocaleDigit,
isDistanceRequest,
isPolicyExpenseChat,
transaction,
transactionID,
isReadOnly,
isMovingTransactionFromTrackExpense,
getCurrencySymbol,
isManualDistanceRequest,
]);
Expand Down
9 changes: 6 additions & 3 deletions src/libs/DistanceRequestUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -357,12 +357,12 @@ function getCustomUnitRateID({
return customUnitRateID;
}

// For TrackDistanceExpense we will return the default rate of the policyForMovingExpenses.
// For TrackDistanceExpense we will return the default or last selected rate of the policyForMovingExpenses.
if (isPolicyExpenseChat || isTrackDistanceExpense) {
const distanceUnit = Object.values(policy.customUnits ?? {}).find((unit) => unit.name === CONST.CUSTOM_UNITS.NAME_DISTANCE);
const lastSelectedDistanceRateID = lastSelectedDistanceRates?.[policy.id];
const lastSelectedDistanceRate = lastSelectedDistanceRateID ? distanceUnit?.rates[lastSelectedDistanceRateID] : undefined;
if (!isTrackDistanceExpense && lastSelectedDistanceRate?.enabled && lastSelectedDistanceRateID) {
if (lastSelectedDistanceRate?.enabled && lastSelectedDistanceRateID) {
customUnitRateID = lastSelectedDistanceRateID;
} else {
const defaultMileageRate = getDefaultMileageRate(policy);
Expand Down Expand Up @@ -409,13 +409,15 @@ function getRate({
useTransactionDistanceUnit = true,
policyForMovingExpenses,
isFakeP2PRate,
isMovingTransactionFromTrackExpense,
}: {
transaction: OnyxEntry<Transaction>;
policy: OnyxEntry<Policy>;
policyDraft?: OnyxEntry<Policy>;
policyForMovingExpenses?: OnyxEntry<Policy>;
useTransactionDistanceUnit?: boolean;
isFakeP2PRate?: boolean;
isMovingTransactionFromTrackExpense?: boolean;
}): MileageRate {
let mileageRates = getMileageRates(policy, true, transaction?.comment?.customUnit?.customUnitRateID);
if (isEmptyObject(mileageRates) && policyDraft) {
Expand All @@ -429,7 +431,8 @@ function getRate({
const defaultMileageRate = getDefaultMileageRate(policy);
const customUnitRateID = getRateID(transaction);
const customMileageRate =
(customUnitRateID && (mileageRates?.[customUnitRateID] ?? mileageRatesForMovingExpenses?.[customUnitRateID])) || (isUnreportedExpense ? undefined : defaultMileageRate);
(customUnitRateID && (mileageRates?.[customUnitRateID] ?? mileageRatesForMovingExpenses?.[customUnitRateID])) ||
(isUnreportedExpense || isMovingTransactionFromTrackExpense ? undefined : defaultMileageRate);
const mileageRate = isCustomUnitRateIDForP2P(transaction) || isFakeP2PRate ? getRateForP2P(policyCurrency, transaction) : customMileageRate;
const unit = getDistanceUnit(useTransactionDistanceUnit ? transaction : undefined, mileageRate);
return {
Expand Down
6 changes: 4 additions & 2 deletions src/pages/iou/request/step/IOURequestStepParticipants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@
isTrackDistanceExpense: isDistanceRequest(transaction),
policy: policyForMovingExpenses,
isPolicyExpenseChat: false,
lastSelectedDistanceRates,
});
setCustomUnitRateID(transaction.transactionID, rateID, transaction, policyForMovingExpenses);
const shouldSetParticipantAutoAssignment = iouType === CONST.IOU.TYPE.CREATE;
Expand Down Expand Up @@ -237,6 +238,7 @@
isActivePolicyRequest,
backTo,
policyForMovingExpenses,
lastSelectedDistanceRates,
]);

const addParticipant = useCallback(
Expand Down Expand Up @@ -268,8 +270,8 @@
}

if (!isMovingTransactionFromTrackExpense || !isPolicyExpenseChat) {
// If not moving the transaction from track expense, select the default rate automatically.
// Otherwise, keep the original p2p rate and let the user manually change it to the one they want from the workspace.
// If not moving the transaction from track expense to a workspace, select the default rate automatically.
// Otherwise, keep the original rate and let the user manually change it to the one they want from the workspace.
const rateID = DistanceRequestUtils.getCustomUnitRateID({reportID: firstParticipantReportID, isPolicyExpenseChat, policy, lastSelectedDistanceRates});

if (draftTransactions.length > 0) {
Expand Down Expand Up @@ -388,7 +390,7 @@
});
},
[
action,

Check warning on line 393 in src/pages/iou/request/step/IOURequestStepParticipants.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

React Hook useCallback has a missing dependency: 'currentUserPersonalDetails.email'. Either include it or remove the dependency array
participants,
iouType,
initialTransaction,
Expand Down
Loading