Skip to content

Commit

Permalink
Merge pull request #34135 from paultsimura/fix/33362-is-loading-tbd
Browse files Browse the repository at this point in the history
fix: unify TBD-related logic for Distance requests
  • Loading branch information
neil-marcellini authored Feb 7, 2024
2 parents e2b6704 + 2e4c40f commit 60c7d92
Show file tree
Hide file tree
Showing 16 changed files with 184 additions and 114 deletions.
8 changes: 3 additions & 5 deletions src/components/DistanceEReceipt.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {ScrollView, View} from 'react-native';
import _ from 'underscore';
import EReceiptBackground from '@assets/images/eReceipt_background.svg';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import * as CurrencyUtils from '@libs/CurrencyUtils';
Expand Down Expand Up @@ -33,10 +32,9 @@ function DistanceEReceipt({transaction}) {
const theme = useTheme();
const styles = useThemeStyles();
const {translate} = useLocalize();
const {isOffline} = useNetwork();
const {thumbnail} = TransactionUtils.hasReceipt(transaction) ? ReceiptUtils.getThumbnailAndImageURIs(transaction) : {};
const {amount: transactionAmount, currency: transactionCurrency, merchant: transactionMerchant, created: transactionDate} = ReportUtils.getTransactionDetails(transaction);
const formattedTransactionAmount = transactionAmount ? CurrencyUtils.convertToDisplayString(transactionAmount, transactionCurrency) : translate('common.tbd');
const formattedTransactionAmount = CurrencyUtils.convertToDisplayString(transactionAmount, transactionCurrency);
const thumbnailSource = tryResolveUrlFromApiRoot(thumbnail || '');
const waypoints = lodashGet(transaction, 'comment.waypoints', {});
const sortedWaypoints = useMemo(
Expand Down Expand Up @@ -64,7 +62,7 @@ function DistanceEReceipt({transaction}) {
/>

<View style={[styles.moneyRequestViewImage, styles.mh0, styles.mt0, styles.mb5, styles.borderNone]}>
{isOffline || !thumbnailSource ? (
{TransactionUtils.isFetchingWaypointsFromServer(transaction) || !thumbnailSource ? (
<PendingMapView />
) : (
<ThumbnailImage
Expand All @@ -76,7 +74,7 @@ function DistanceEReceipt({transaction}) {
)}
</View>
<View style={[styles.mb10, styles.gap5, styles.ph2, styles.flexColumn, styles.alignItemsCenter]}>
<Text style={styles.eReceiptAmount}>{formattedTransactionAmount}</Text>
{!!transactionAmount && <Text style={styles.eReceiptAmount}>{formattedTransactionAmount}</Text>}
<Text style={styles.eReceiptMerchant}>{transactionMerchant}</Text>
</View>
<View style={[styles.mb10, styles.gap5, styles.ph2]}>
Expand Down
24 changes: 16 additions & 8 deletions src/components/MoneyRequestConfirmationList.js
Original file line number Diff line number Diff line change
Expand Up @@ -255,9 +255,9 @@ function MoneyRequestConfirmationList(props) {
const shouldShowBillable = !lodashGet(props.policy, 'disabledFields.defaultBillable', true);

const hasRoute = TransactionUtils.hasRoute(transaction);
const isDistanceRequestWithoutRoute = props.isDistanceRequest && !hasRoute;
const formattedAmount = isDistanceRequestWithoutRoute
? translate('common.tbd')
const isDistanceRequestWithPendingRoute = props.isDistanceRequest && (!hasRoute || !rate);
const formattedAmount = isDistanceRequestWithPendingRoute
? ''
: CurrencyUtils.convertToDisplayString(
shouldCalculateDistanceAmount ? DistanceRequestUtils.getDistanceRequestAmount(distance, unit, rate) : props.iouAmount,
props.isDistanceRequest ? currency : props.iouCurrencyCode,
Expand Down Expand Up @@ -332,7 +332,7 @@ function MoneyRequestConfirmationList(props) {
let text;
if (isSplitBill && props.iouAmount === 0) {
text = translate('iou.split');
} else if ((props.receiptPath && isTypeRequest) || isDistanceRequestWithoutRoute) {
} else if ((props.receiptPath && isTypeRequest) || isDistanceRequestWithPendingRoute) {
text = translate('iou.request');
if (props.iouAmount !== 0) {
text = translate('iou.requestAmount', {amount: formattedAmount});
Expand All @@ -347,7 +347,7 @@ function MoneyRequestConfirmationList(props) {
value: props.iouType,
},
];
}, [isSplitBill, isTypeRequest, props.iouType, props.iouAmount, props.receiptPath, formattedAmount, isDistanceRequestWithoutRoute, translate]);
}, [isSplitBill, isTypeRequest, props.iouType, props.iouAmount, props.receiptPath, formattedAmount, isDistanceRequestWithPendingRoute, translate]);

const selectedParticipants = useMemo(() => _.filter(props.selectedParticipants, (participant) => participant.selected), [props.selectedParticipants]);
const payeePersonalDetails = useMemo(() => props.payeePersonalDetails || props.currentUserPersonalDetails, [props.payeePersonalDetails, props.currentUserPersonalDetails]);
Expand Down Expand Up @@ -426,9 +426,17 @@ function MoneyRequestConfirmationList(props) {
if (!props.isDistanceRequest) {
return;
}

/*
Set pending waypoints based on the route status. We should handle this dynamically to cover cases such as:
When the user completes the initial steps of the IOU flow offline and then goes online on the confirmation page.
In this scenario, the route will be fetched from the server, and the waypoints will no longer be pending.
*/
IOU.setMoneyRequestPendingFields(props.transactionID, {waypoints: isDistanceRequestWithPendingRoute ? CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD : null});

const distanceMerchant = DistanceRequestUtils.getDistanceMerchant(hasRoute, distance, unit, rate, currency, translate, toLocaleDigit);
IOU.setMoneyRequestMerchant_temporaryForRefactor(props.transactionID, distanceMerchant);
}, [hasRoute, distance, unit, rate, currency, translate, toLocaleDigit, props.isDistanceRequest, props.transactionID]);
}, [isDistanceRequestWithPendingRoute, hasRoute, distance, unit, rate, currency, translate, toLocaleDigit, props.isDistanceRequest, props.transactionID]);

/**
* @param {Object} option
Expand Down Expand Up @@ -482,7 +490,7 @@ function MoneyRequestConfirmationList(props) {
} else {
// validate the amount for distance requests
const decimals = CurrencyUtils.getCurrencyDecimals(props.iouCurrencyCode);
if (props.isDistanceRequest && !isDistanceRequestWithoutRoute && !MoneyRequestUtils.validateAmount(String(props.iouAmount), decimals)) {
if (props.isDistanceRequest && !isDistanceRequestWithPendingRoute && !MoneyRequestUtils.validateAmount(String(props.iouAmount), decimals)) {
setFormError('common.error.invalidAmount');
return;
}
Expand All @@ -505,7 +513,7 @@ function MoneyRequestConfirmationList(props) {
props.iouType,
props.isDistanceRequest,
props.iouCategory,
isDistanceRequestWithoutRoute,
isDistanceRequestWithPendingRoute,
props.iouCurrencyCode,
props.iouAmount,
transaction,
Expand Down
24 changes: 16 additions & 8 deletions src/components/MoneyTemporaryForRefactorRequestConfirmationList.js
Original file line number Diff line number Diff line change
Expand Up @@ -284,9 +284,9 @@ function MoneyTemporaryForRefactorRequestConfirmationList({
const shouldShowBillable = !lodashGet(policy, 'disabledFields.defaultBillable', true);

const hasRoute = TransactionUtils.hasRoute(transaction);
const isDistanceRequestWithoutRoute = isDistanceRequest && !hasRoute;
const formattedAmount = isDistanceRequestWithoutRoute
? translate('common.tbd')
const isDistanceRequestWithPendingRoute = isDistanceRequest && (!hasRoute || !rate);
const formattedAmount = isDistanceRequestWithPendingRoute
? ''
: CurrencyUtils.convertToDisplayString(
shouldCalculateDistanceAmount ? DistanceRequestUtils.getDistanceRequestAmount(distance, unit, rate) : iouAmount,
isDistanceRequest ? currency : iouCurrencyCode,
Expand Down Expand Up @@ -376,7 +376,7 @@ function MoneyTemporaryForRefactorRequestConfirmationList({
let text;
if (isTypeSplit && iouAmount === 0) {
text = translate('iou.split');
} else if ((receiptPath && isTypeRequest) || isDistanceRequestWithoutRoute) {
} else if ((receiptPath && isTypeRequest) || isDistanceRequestWithPendingRoute) {
text = translate('iou.request');
if (iouAmount !== 0) {
text = translate('iou.requestAmount', {amount: formattedAmount});
Expand All @@ -391,7 +391,7 @@ function MoneyTemporaryForRefactorRequestConfirmationList({
value: iouType,
},
];
}, [isTypeSplit, isTypeRequest, iouType, iouAmount, receiptPath, formattedAmount, isDistanceRequestWithoutRoute, translate]);
}, [isTypeSplit, isTypeRequest, iouType, iouAmount, receiptPath, formattedAmount, isDistanceRequestWithPendingRoute, translate]);

const selectedParticipants = useMemo(() => _.filter(pickedParticipants, (participant) => participant.selected), [pickedParticipants]);
const personalDetailsOfPayee = useMemo(() => payeePersonalDetails || currentUserPersonalDetails, [payeePersonalDetails, currentUserPersonalDetails]);
Expand Down Expand Up @@ -473,9 +473,17 @@ function MoneyTemporaryForRefactorRequestConfirmationList({
if (!isDistanceRequest) {
return;
}

/*
Set pending waypoints based on the route status. We should handle this dynamically to cover cases such as:
When the user completes the initial steps of the IOU flow offline and then goes online on the confirmation page.
In this scenario, the route will be fetched from the server, and the waypoints will no longer be pending.
*/
IOU.setMoneyRequestPendingFields(transaction.transactionID, {waypoints: isDistanceRequestWithPendingRoute ? CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD : null});

const distanceMerchant = DistanceRequestUtils.getDistanceMerchant(hasRoute, distance, unit, rate, currency, translate, toLocaleDigit);
IOU.setMoneyRequestMerchant_temporaryForRefactor(transaction.transactionID, distanceMerchant);
}, [hasRoute, distance, unit, rate, currency, translate, toLocaleDigit, isDistanceRequest, transaction]);
}, [isDistanceRequestWithPendingRoute, hasRoute, distance, unit, rate, currency, translate, toLocaleDigit, isDistanceRequest, transaction]);

/**
* @param {Object} option
Expand Down Expand Up @@ -530,7 +538,7 @@ function MoneyTemporaryForRefactorRequestConfirmationList({
} else {
// validate the amount for distance requests
const decimals = CurrencyUtils.getCurrencyDecimals(iouCurrencyCode);
if (isDistanceRequest && !isDistanceRequestWithoutRoute && !MoneyRequestUtils.validateAmount(String(iouAmount), decimals)) {
if (isDistanceRequest && !isDistanceRequestWithPendingRoute && !MoneyRequestUtils.validateAmount(String(iouAmount), decimals)) {
setFormError('common.error.invalidAmount');
return;
}
Expand All @@ -555,7 +563,7 @@ function MoneyTemporaryForRefactorRequestConfirmationList({
onSendMoney,
iouCurrencyCode,
isDistanceRequest,
isDistanceRequestWithoutRoute,
isDistanceRequestWithPendingRoute,
iouAmount,
isEditingSplitBill,
onConfirm,
Expand Down
2 changes: 1 addition & 1 deletion src/components/ReportActionItem/MoneyReportView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function MoneyReportView({report, policy, policyReportFields, shouldShowHorizont
const {totalDisplaySpend, nonReimbursableSpend, reimbursableSpend} = ReportUtils.getMoneyRequestSpendBreakdown(report);

const shouldShowBreakdown = nonReimbursableSpend && reimbursableSpend;
const formattedTotalAmount = CurrencyUtils.convertToDisplayString(totalDisplaySpend, report.currency, ReportUtils.hasOnlyDistanceRequestTransactions(report.reportID));
const formattedTotalAmount = CurrencyUtils.convertToDisplayString(totalDisplaySpend, report.currency);
const formattedOutOfPocketAmount = CurrencyUtils.convertToDisplayString(reimbursableSpend, report.currency);
const formattedCompanySpendAmount = CurrencyUtils.convertToDisplayString(nonReimbursableSpend, report.currency);

Expand Down
25 changes: 16 additions & 9 deletions src/components/ReportActionItem/MoneyRequestPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,20 +155,27 @@ function MoneyRequestPreview({
const isScanning = hasReceipt && TransactionUtils.isReceiptBeingScanned(transaction);
const hasFieldErrors = TransactionUtils.hasMissingSmartscanFields(transaction);
const isDistanceRequest = TransactionUtils.isDistanceRequest(transaction);
const isFetchingWaypointsFromServer = TransactionUtils.isFetchingWaypointsFromServer(transaction);
const isCardTransaction = TransactionUtils.isCardTransaction(transaction);
const isSettled = ReportUtils.isSettled(iouReport?.reportID);
const isDeleted = action?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE;

// Show the merchant for IOUs and expenses only if they are custom or not related to scanning smartscan
const shouldShowMerchant = !!requestMerchant && requestMerchant !== CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT && requestMerchant !== CONST.TRANSACTION.DEFAULT_MERCHANT;
/*
Show the merchant for IOUs and expenses only if:
- the merchant is not empty, is custom, or is not related to scanning smartscan;
- the request is not a distance request with a pending route and amount = 0 - in this case,
the merchant says: "Route pending...", which is already shown in the amount field;
*/
const shouldShowMerchant =
!!requestMerchant &&
requestMerchant !== CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT &&
requestMerchant !== CONST.TRANSACTION.DEFAULT_MERCHANT &&
!(isFetchingWaypointsFromServer && !requestAmount);
const shouldShowDescription = !!description && !shouldShowMerchant && !isScanning;
const hasPendingWaypoints = transaction?.pendingFields?.waypoints;

let merchantOrDescription = requestMerchant;
if (!shouldShowMerchant) {
merchantOrDescription = description || '';
} else if (hasPendingWaypoints) {
merchantOrDescription = requestMerchant.replace(CONST.REGEX.FIRST_SPACE, translate('common.tbd'));
}

const receiptImages = hasReceipt ? [ReceiptUtils.getThumbnailAndImageURIs(transaction)] : [];
Expand Down Expand Up @@ -217,14 +224,14 @@ function MoneyRequestPreview({
};

const getDisplayAmountText = (): string => {
if (isDistanceRequest) {
return requestAmount && !hasPendingWaypoints ? CurrencyUtils.convertToDisplayString(requestAmount, requestCurrency) : translate('common.tbd');
}

if (isScanning) {
return translate('iou.receiptScanning');
}

if (isFetchingWaypointsFromServer && !requestAmount) {
return translate('iou.routePending');
}

if (!isSettled && TransactionUtils.hasMissingSmartscanFields(transaction)) {
return Localize.translateLocal('iou.receiptMissingDetails');
}
Expand Down
8 changes: 2 additions & 6 deletions src/components/ReportActionItem/MoneyRequestView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,7 @@ function MoneyRequestView({
} = ReportUtils.getTransactionDetails(transaction) ?? {};
const isEmptyMerchant = transactionMerchant === '' || transactionMerchant === CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT;
const isDistanceRequest = TransactionUtils.isDistanceRequest(transaction);
let formattedTransactionAmount = transactionAmount ? CurrencyUtils.convertToDisplayString(transactionAmount, transactionCurrency) : '';
const hasPendingWaypoints = transaction?.pendingFields?.waypoints;
if (isDistanceRequest && (!formattedTransactionAmount || hasPendingWaypoints)) {
formattedTransactionAmount = translate('common.tbd');
}
const formattedTransactionAmount = transactionAmount ? CurrencyUtils.convertToDisplayString(transactionAmount, transactionCurrency) : '';
const formattedOriginalAmount = transactionOriginalAmount && transactionOriginalCurrency && CurrencyUtils.convertToDisplayString(transactionOriginalAmount, transactionOriginalCurrency);
const isCardTransaction = TransactionUtils.isCardTransaction(transaction);
const cardProgramName = isCardTransaction && transactionCardID !== undefined ? CardUtils.getCardDescription(transactionCardID) : '';
Expand Down Expand Up @@ -289,7 +285,7 @@ function MoneyRequestView({
<OfflineWithFeedback pendingAction={getPendingFieldAction('waypoints')}>
<MenuItemWithTopDescription
description={translate('common.distance')}
title={hasPendingWaypoints ? transactionMerchant?.replace(CONST.REGEX.FIRST_SPACE, translate('common.tbd')) : transactionMerchant}
title={transactionMerchant}
interactive={canEditDistance}
shouldShowRightIcon={canEditDistance}
titleStyle={styles.flex1}
Expand Down
Loading

0 comments on commit 60c7d92

Please sign in to comment.