Skip to content
Merged
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
15 changes: 9 additions & 6 deletions src/components/MoneyRequestConfirmationListFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import React, {memo, useMemo} from 'react';
import {View} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import type {ValueOf} from 'type-fest';
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useOnyx from '@hooks/useOnyx';
Expand Down Expand Up @@ -46,7 +47,6 @@ import {isEmptyObject} from '@src/types/utils/EmptyObject';
import Badge from './Badge';
import ConfirmedRoute from './ConfirmedRoute';
import MentionReportContext from './HTMLEngineProvider/HTMLRenderers/MentionReportRenderer/MentionReportContext';
import * as Expensicons from './Icon/Expensicons';
import MenuItem from './MenuItem';
import MenuItemWithTopDescription from './MenuItemWithTopDescription';
import PDFThumbnail from './PDFThumbnail';
Expand Down Expand Up @@ -263,6 +263,7 @@ function MoneyRequestConfirmationListFooter({
isReceiptEditable = false,
isDescriptionRequired = false,
}: MoneyRequestConfirmationListFooterProps) {
const icons = useMemoizedLazyExpensifyIcons(['Stopwatch', 'CalendarSolid'] as const);
const styles = useThemeStyles();
const {translate, toLocaleDigit, localeCompare} = useLocalize();
const {isOffline} = useNetwork();
Expand Down Expand Up @@ -290,6 +291,7 @@ function MoneyRequestConfirmationListFooter({
});
}, [outstandingReportsByPolicyID, reportNameValuePairs]);

const isTrackExpense = iouType === CONST.IOU.TYPE.TRACK;
const shouldShowTags = useMemo(
() => (isPolicyExpenseChat || isUnreported || isCreatingTrackExpense) && hasEnabledTags(policyTagLists),
[isCreatingTrackExpense, isPolicyExpenseChat, isUnreported, policyTagLists],
Expand Down Expand Up @@ -358,7 +360,8 @@ function MoneyRequestConfirmationListFooter({
const canModifyTaxFields = !isReadOnly && !isDistanceRequest && !isPerDiemRequest;
// A flag for showing the billable field
const shouldShowBillable = policy?.disabledFields?.defaultBillable === false;
const shouldShowReimbursable = isPolicyExpenseChat && policy?.disabledFields?.reimbursable !== true && !isManagedCardTransaction(transaction) && !isTypeInvoice;
const shouldShowReimbursable =
(isPolicyExpenseChat || isTrackExpense) && !!policy && policy?.disabledFields?.reimbursable !== true && !isManagedCardTransaction(transaction) && !isTypeInvoice;
// Calculate the formatted tax amount based on the transaction's tax amount and the IOU currency code
const taxAmount = getTaxAmount(transaction, false);
const formattedTaxAmount = convertToDisplayString(taxAmount, iouCurrencyCode);
Expand Down Expand Up @@ -826,7 +829,7 @@ function MoneyRequestConfirmationListFooter({
badges.push(
<Badge
key="firstDay"
icon={Expensicons.Stopwatch}
icon={icons.Stopwatch}
text={translate('iou.firstDayText', {count: firstDay})}
/>,
);
Expand All @@ -835,7 +838,7 @@ function MoneyRequestConfirmationListFooter({
badges.push(
<Badge
key="tripDays"
icon={Expensicons.CalendarSolid}
icon={icons.CalendarSolid}
text={translate('iou.tripLengthText', {count: tripDays})}
/>,
);
Expand All @@ -844,13 +847,13 @@ function MoneyRequestConfirmationListFooter({
badges.push(
<Badge
key="lastDay"
icon={Expensicons.Stopwatch}
icon={icons.Stopwatch}
text={translate('iou.lastDayText', {count: lastDay})}
/>,
);
}
return badges;
}, [firstDay, lastDay, translate, tripDays]);
}, [firstDay, lastDay, translate, tripDays, icons]);

const receiptThumbnailContent = useMemo(
() => (
Expand Down
14 changes: 9 additions & 5 deletions src/components/ReportActionItem/MoneyRequestView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import React, {useCallback, useContext, useEffect, useMemo, useState} from 'reac
import {View} from 'react-native';
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
import Icon from '@components/Icon';
import * as Expensicons from '@components/Icon/Expensicons';
import MenuItem from '@components/MenuItem';
import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
Expand All @@ -15,6 +14,7 @@ import ViolationMessages from '@components/ViolationMessages';
import {WideRHPContext} from '@components/WideRHPContextProvider';
import useActiveRoute from '@hooks/useActiveRoute';
import useEnvironment from '@hooks/useEnvironment';
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useOnyx from '@hooks/useOnyx';
Expand Down Expand Up @@ -126,6 +126,7 @@ function MoneyRequestView({
isFromReviewDuplicates = false,
mergeTransactionID,
}: MoneyRequestViewProps) {
const icons = useMemoizedLazyExpensifyIcons(['DotIndicator', 'Checkmark', 'Suitcase'] as const);
const styles = useThemeStyles();
const theme = useTheme();
const StyleUtils = useStyleUtils();
Expand Down Expand Up @@ -287,7 +288,10 @@ function MoneyRequestView({
const isCurrentTransactionReimbursableDifferentFromPolicyDefault =
policy?.defaultReimbursable !== undefined && !!(updatedTransaction?.reimbursable ?? transactionReimbursable) !== policy.defaultReimbursable;
const shouldShowReimbursable =
isPolicyExpenseChat && (policy?.disabledFields?.reimbursable !== true || isCurrentTransactionReimbursableDifferentFromPolicyDefault) && !isCardTransaction && !isInvoice;
(isPolicyExpenseChat || isExpenseUnreported) &&
(policy?.disabledFields?.reimbursable !== true || isCurrentTransactionReimbursableDifferentFromPolicyDefault) &&
!isCardTransaction &&
!isInvoice;
const canEditReimbursable = isEditable && canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.REIMBURSABLE, undefined, isChatReportArchived);
const shouldShowAttendees = useMemo(() => shouldShowAttendeesTransactionUtils(iouType, policy), [iouType, policy]);

Expand Down Expand Up @@ -656,7 +660,7 @@ function MoneyRequestView({
{isCustomUnitOutOfPolicy && isPerDiemRequest && (
<View style={[styles.flexRow, styles.alignItemsCenter, styles.gap1, styles.mh4, styles.mb2]}>
<Icon
src={Expensicons.DotIndicator}
src={icons.DotIndicator}
fill={theme.danger}
height={16}
width={16}
Expand All @@ -673,7 +677,7 @@ function MoneyRequestView({
<MenuItemWithTopDescription
title={amountTitle}
shouldShowTitleIcon={shouldShowPaid}
titleIcon={Expensicons.Checkmark}
titleIcon={icons.Checkmark}
description={amountDescription}
titleStyle={styles.textHeadlineH2}
interactive={canEditAmount}
Expand Down Expand Up @@ -967,7 +971,7 @@ function MoneyRequestView({
{shouldShowViewTripDetails && (
<MenuItem
title={translate('travel.viewTripDetails')}
icon={Expensicons.Suitcase}
icon={icons.Suitcase}
onPress={() => {
const reservations = transaction?.receipt?.reservationList?.length ?? 0;
if (reservations > 1) {
Expand Down
1 change: 1 addition & 0 deletions src/libs/API/parameters/TrackExpenseParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type TrackExpenseParams = {
taxCode: string;
taxAmount: number;
billable?: boolean;
reimbursable?: boolean;
receiptGpsPoints?: string;
transactionThreadReportID: string | undefined;
createdReportActionIDForThread: string | undefined;
Expand Down
1 change: 1 addition & 0 deletions src/libs/actions/IOU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@
};

let allPersonalDetails: OnyxTypes.PersonalDetailsList = {};
Onyx.connect({

Check warning on line 710 in src/libs/actions/IOU.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.PERSONAL_DETAILS_LIST,
callback: (value) => {
allPersonalDetails = value ?? {};
Expand Down Expand Up @@ -784,7 +784,7 @@
};

let allTransactions: NonNullable<OnyxCollection<OnyxTypes.Transaction>> = {};
Onyx.connect({

Check warning on line 787 in src/libs/actions/IOU.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.TRANSACTION,
waitForCollectionCallback: true,
callback: (value) => {
Expand All @@ -798,7 +798,7 @@
});

let allTransactionDrafts: NonNullable<OnyxCollection<OnyxTypes.Transaction>> = {};
Onyx.connect({

Check warning on line 801 in src/libs/actions/IOU.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.TRANSACTION_DRAFT,
waitForCollectionCallback: true,
callback: (value) => {
Expand All @@ -807,7 +807,7 @@
});

let allTransactionViolations: NonNullable<OnyxCollection<OnyxTypes.TransactionViolations>> = {};
Onyx.connect({

Check warning on line 810 in src/libs/actions/IOU.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS,
waitForCollectionCallback: true,
callback: (value) => {
Expand All @@ -821,7 +821,7 @@
});

let allNextSteps: NonNullable<OnyxCollection<OnyxTypes.ReportNextStepDeprecated>> = {};
Onyx.connect({

Check warning on line 824 in src/libs/actions/IOU.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.NEXT_STEP,
waitForCollectionCallback: true,
callback: (value) => {
Expand All @@ -830,7 +830,7 @@
});

const allPolicies: OnyxCollection<OnyxTypes.Policy> = {};
Onyx.connect({

Check warning on line 833 in src/libs/actions/IOU.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.POLICY,
callback: (val, key) => {
if (!key) {
Expand All @@ -849,14 +849,14 @@
// `allRecentlyUsedTags` was moved here temporarily from `src/libs/actions/Policy/Tag.ts` during the `Deprecate Onyx.connect` refactor.
// All uses of this variable should be replaced with `useOnyx`.
let allRecentlyUsedTags: OnyxCollection<RecentlyUsedTags> = {};
Onyx.connect({

Check warning on line 852 in src/libs/actions/IOU.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS,
waitForCollectionCallback: true,
callback: (val) => (allRecentlyUsedTags = val),
});

let allReports: OnyxCollection<OnyxTypes.Report>;
Onyx.connect({

Check warning on line 859 in src/libs/actions/IOU.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.REPORT,
waitForCollectionCallback: true,
callback: (value) => {
Expand All @@ -865,7 +865,7 @@
});

let allReportNameValuePairs: OnyxCollection<OnyxTypes.ReportNameValuePairs>;
Onyx.connect({

Check warning on line 868 in src/libs/actions/IOU.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS,
waitForCollectionCallback: true,
callback: (value) => {
Expand All @@ -875,7 +875,7 @@

let userAccountID = -1;
let currentUserEmail = '';
Onyx.connect({

Check warning on line 878 in src/libs/actions/IOU.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.SESSION,
callback: (value) => {
currentUserEmail = value?.email ?? '';
Expand Down Expand Up @@ -6577,6 +6577,7 @@
optimisticReportActionID,
receipt: isFileUploadable(trackedReceipt) ? trackedReceipt : undefined,
receiptState: trackedReceipt?.state,
reimbursable,
category,
tag,
taxCode,
Expand Down
10 changes: 8 additions & 2 deletions src/pages/iou/request/step/IOURequestStepConfirmation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -317,11 +317,14 @@ function IOURequestStepConfirmation({
}, [transactionIDs, defaultBillable, isMovingTransactionFromTrackExpense]);

useEffect(() => {
const defaultReimbursable = isPolicyExpenseChat && isPaidGroupPolicy(policy) ? (policy?.defaultReimbursable ?? true) : true;
if (isMovingTransactionFromTrackExpense) {
Copy link
Member

@parasharrajat parasharrajat Nov 12, 2025

Choose a reason for hiding this comment

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

I don't think this is a good idea.

We have 4 default values for Reimbursable.

Image

Here last 2 values will not show the checkbox on the unreported expenses.

Now, when we submit such an expense where the checkbox is not visible or the default workspace is set to any of the last 2 values as default to a different workspace, the default value of that workspace should be shown on the confirm page.

@cristipaval What do you think about this?

Copy link
Member

@parasharrajat parasharrajat Nov 12, 2025

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

so how I'm supposed to handle it?

Copy link
Contributor

Choose a reason for hiding this comment

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

are you talking about the Submit it to someone option?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@parasharrajat and what are the expected results in your opinion? I'm not sure if I get what you mean

Copy link
Member

@parasharrajat parasharrajat Nov 12, 2025

Choose a reason for hiding this comment

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

Yes. I am talking about submitting to someone.

Expected behaviour is to keep the default value for the checkbox on the confirm page while submitting to someone if the reimbursable checkbox is hidden on an unreported expense.

In the last 2 options in the screenshots, the checkbox will be hidden on the unreported expense.

Copy link
Member

Choose a reason for hiding this comment

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

or we can leave it as it is as technically, while submitting to someone, we will move the value of the reimbursable checkbox to the confirm page. And in this case, even though it is hidden but it has a value internally

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@parasharrajat so could you please sum up what the next steps here should be?

Copy link
Member

@parasharrajat parasharrajat Nov 13, 2025

Choose a reason for hiding this comment

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

Discussion on slack group.

return;
}
const defaultReimbursable = (isPolicyExpenseChat && isPaidGroupPolicy(policy)) || isCreatingTrackExpense ? (policy?.defaultReimbursable ?? true) : true;
for (const transactionID of transactionIDs) {
setMoneyRequestReimbursable(transactionID, defaultReimbursable);
}
}, [transactionIDs, policy, isPolicyExpenseChat]);
}, [transactionIDs, policy, isPolicyExpenseChat, isMovingTransactionFromTrackExpense, isCreatingTrackExpense]);

useEffect(() => {
// Exit early if the transaction is still loading
Expand Down Expand Up @@ -624,6 +627,7 @@ function IOURequestStepConfirmation({
viewTourTaskParentReport,
isASAPSubmitBetaEnabled,
isViewTourTaskParentReportArchived,
getMoneyRequestContextForParticipant,
],
);

Expand Down Expand Up @@ -752,6 +756,7 @@ function IOURequestStepConfirmation({
isManualDistanceRequest,
archivedReportsIdSet,
isASAPSubmitBetaEnabled,
getMoneyRequestContextForParticipant,
],
);

Expand Down Expand Up @@ -816,6 +821,7 @@ function IOURequestStepConfirmation({
receiptFiles,
backToReport,
isASAPSubmitBetaEnabled,
getMoneyRequestContextForParticipant,
],
);

Expand Down
Loading