Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix wrong total amount of hold expenses when approve/pay partially #49971

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
09a1942
fix the wrong calculation
bernhardoj Oct 1, 2024
d0037f6
Merge branch 'main' into fix/48760-wrong-expense-total-if-currency-di…
bernhardoj Oct 1, 2024
2b5a152
use the current iou when creating the new report
bernhardoj Oct 1, 2024
6196f9c
remove unused import
bernhardoj Oct 1, 2024
8c86bc1
Merge branch 'main' into fix/48760-wrong-expense-total-if-currency-di…
bernhardoj Oct 16, 2024
b831dd1
fix total calculation
bernhardoj Oct 16, 2024
fbdb8ad
Merge branch 'main' into fix/48760-wrong-expense-total-if-currency-di…
bernhardoj Oct 18, 2024
7c223b9
get the reimbursable amount when the type is pay
bernhardoj Oct 18, 2024
62b6727
Merge branch 'main' into fix/48760-wrong-expense-total-if-currency-di…
bernhardoj Oct 22, 2024
903d17d
rename
bernhardoj Oct 22, 2024
997de55
update unheldTotal and unheldReimburableTotal optimistically
bernhardoj Oct 22, 2024
3817ddd
Merge branch 'main' into fix/48760-wrong-expense-total-if-currency-di…
bernhardoj Oct 23, 2024
6e1f6e4
update comment
bernhardoj Oct 23, 2024
077a7d5
calc the amount once
bernhardoj Oct 23, 2024
d7fddd1
store the correct non reimbursable amount
bernhardoj Oct 23, 2024
6932d60
fix lint
bernhardoj Oct 23, 2024
8cbe949
Merge branch 'main' into fix/48760-wrong-expense-total-if-currency-di…
bernhardoj Oct 24, 2024
8ce39ae
fix wrong non reimbursable amount
bernhardoj Oct 24, 2024
c278a1a
optimistically update unheld total for IOU
bernhardoj Oct 24, 2024
54023a3
Merge branch 'main' into fix/48760-wrong-expense-total-if-currency-di…
bernhardoj Oct 30, 2024
d0277e2
Merge branch 'main' into fix/48760-wrong-expense-total-if-currency-di…
bernhardoj Nov 14, 2024
164a73a
fix syntax error
bernhardoj Nov 14, 2024
a3c25a5
Merge branch 'main' into fix/48760-wrong-expense-total-if-currency-di…
bernhardoj Nov 22, 2024
2c4480d
fix lint
bernhardoj Nov 23, 2024
9ade52c
fix another lint
bernhardoj Nov 23, 2024
fa58c4f
fix type error
bernhardoj Nov 23, 2024
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
2 changes: 1 addition & 1 deletion src/components/MoneyReportHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea
shouldShowExportIntegrationButton;
const bankAccountRoute = ReportUtils.getBankAccountRoute(chatReport);
const formattedAmount = CurrencyUtils.convertToDisplayString(reimbursableSpend, moneyRequestReport?.currency);
const [nonHeldAmount, fullAmount] = ReportUtils.getNonHeldAndFullAmount(moneyRequestReport, policy);
const [nonHeldAmount, fullAmount] = ReportUtils.getNonHeldAndFullAmount(moneyRequestReport, shouldShowPayButton);
const isAnyTransactionOnHold = ReportUtils.hasHeldExpenses(moneyRequestReport?.reportID);
const displayedAmount = isAnyTransactionOnHold && canAllowSettlement ? nonHeldAmount : formattedAmount;
const isMoreContentShown = shouldShowNextStep || shouldShowStatusBar || (shouldShowAnyButton && shouldUseNarrowLayout);
Expand Down
24 changes: 13 additions & 11 deletions src/components/ReportActionItem/ReportPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ function ReportPreview({
const [transactions] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION);
const [transactionViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS);
const [userWallet] = useOnyx(ONYXKEYS.USER_WALLET);
const [invoiceReceiverPolicy] = useOnyx(
`${ONYXKEYS.COLLECTION.POLICY}${chatReport?.invoiceReceiver && 'policyID' in chatReport.invoiceReceiver ? chatReport.invoiceReceiver.policyID : -1}`,
);
const theme = useTheme();
const styles = useThemeStyles();
const {translate} = useLocalize();
Expand All @@ -122,13 +125,19 @@ function ReportPreview({
const [isPaidAnimationRunning, setIsPaidAnimationRunning] = useState(false);
const [isHoldMenuVisible, setIsHoldMenuVisible] = useState(false);
const [requestType, setRequestType] = useState<ActionHandledType>();
const [nonHeldAmount, fullAmount] = ReportUtils.getNonHeldAndFullAmount(iouReport, policy);
const hasOnlyHeldExpenses = ReportUtils.hasOnlyHeldExpenses(iouReport?.reportID ?? '');
const [paymentType, setPaymentType] = useState<PaymentMethodType>();
const [invoiceReceiverPolicy] = useOnyx(
`${ONYXKEYS.COLLECTION.POLICY}${chatReport?.invoiceReceiver && 'policyID' in chatReport.invoiceReceiver ? chatReport.invoiceReceiver.policyID : -1}`,

const getCanIOUBePaid = useCallback(
(onlyShowPayElsewhere = false) => IOU.canIOUBePaid(iouReport, chatReport, policy, allTransactions, onlyShowPayElsewhere),
[iouReport, chatReport, policy, allTransactions],
);

const canIOUBePaid = useMemo(() => getCanIOUBePaid(), [getCanIOUBePaid]);
const onlyShowPayElsewhere = useMemo(() => !canIOUBePaid && getCanIOUBePaid(true), [canIOUBePaid, getCanIOUBePaid]);
const shouldShowPayButton = isPaidAnimationRunning || canIOUBePaid || onlyShowPayElsewhere;
const [nonHeldAmount, fullAmount] = ReportUtils.getNonHeldAndFullAmount(iouReport, shouldShowPayButton);
const hasOnlyHeldExpenses = ReportUtils.hasOnlyHeldExpenses(iouReport?.reportID ?? '');

const managerID = iouReport?.managerID ?? action.childManagerAccountID ?? 0;
const {totalDisplaySpend, reimbursableSpend} = ReportUtils.getMoneyRequestSpendBreakdown(iouReport);

Expand Down Expand Up @@ -326,14 +335,7 @@ function ReportPreview({
]);

const bankAccountRoute = ReportUtils.getBankAccountRoute(chatReport);
const getCanIOUBePaid = useCallback(
(onlyShowPayElsewhere = false) => IOU.canIOUBePaid(iouReport, chatReport, policy, allTransactions, onlyShowPayElsewhere),
[iouReport, chatReport, policy, allTransactions],
);

const canIOUBePaid = useMemo(() => getCanIOUBePaid(), [getCanIOUBePaid]);
const onlyShowPayElsewhere = useMemo(() => !canIOUBePaid && getCanIOUBePaid(true), [canIOUBePaid, getCanIOUBePaid]);
const shouldShowPayButton = isPaidAnimationRunning || canIOUBePaid || onlyShowPayElsewhere;
const shouldShowApproveButton = useMemo(() => IOU.canApproveIOU(iouReport, policy), [iouReport, policy]);

const shouldDisableApproveButton = shouldShowApproveButton && !ReportUtils.isAllowedToApproveExpenseReport(iouReport);
Expand Down
26 changes: 11 additions & 15 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,9 @@ type OptimisticExpenseReport = Pick<
| 'stateNum'
| 'statusNum'
| 'total'
| 'unheldTotal'
| 'nonReimbursableTotal'
| 'unheldNonReimbursableTotal'
| 'parentReportID'
| 'lastVisibleActionCreated'
| 'parentReportActionID'
Expand Down Expand Up @@ -4579,7 +4581,9 @@ function buildOptimisticExpenseReport(
stateNum,
statusNum,
total: storedTotal,
unheldTotal: storedTotal,
nonReimbursableTotal: reimbursable ? 0 : storedTotal,
unheldNonReimbursableTotal: reimbursable ? 0 : storedTotal,
participants: {
[payeeAccountID]: {
notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN,
Expand Down Expand Up @@ -7679,26 +7683,18 @@ function hasUpdatedTotal(report: OnyxInputOrEntry<Report>, policy: OnyxInputOrEn
/**
* Return held and full amount formatted with used currency
*/
function getNonHeldAndFullAmount(iouReport: OnyxEntry<Report>, policy: OnyxEntry<Policy>): string[] {
const reportTransactions = reportsTransactions[iouReport?.reportID ?? ''] ?? [];
const hasPendingTransaction = reportTransactions.some((transaction) => !!transaction.pendingAction);

function getNonHeldAndFullAmount(iouReport: OnyxEntry<Report>, shouldExcludeNonReimbursables: boolean): string[] {
// if the report is an expense report, the total amount should be negated
const coefficient = isExpenseReport(iouReport) ? -1 : 1;

if (hasUpdatedTotal(iouReport, policy) && hasPendingTransaction) {
const unheldTotal = reportTransactions.reduce((currentVal, transaction) => currentVal + (!TransactionUtils.isOnHold(transaction) ? transaction.amount : 0), 0);

return [
CurrencyUtils.convertToDisplayString(unheldTotal * coefficient, iouReport?.currency),
CurrencyUtils.convertToDisplayString((iouReport?.total ?? 0) * coefficient, iouReport?.currency),
];
let total = iouReport?.total ?? 0;
let unheldTotal = iouReport?.unheldTotal ?? 0;
if (shouldExcludeNonReimbursables) {
total -= iouReport?.nonReimbursableTotal ?? 0;
unheldTotal -= iouReport?.unheldNonReimbursableTotal ?? 0;
}

return [
CurrencyUtils.convertToDisplayString((iouReport?.unheldTotal ?? 0) * coefficient, iouReport?.currency),
CurrencyUtils.convertToDisplayString((iouReport?.total ?? 0) * coefficient, iouReport?.currency),
];
return [CurrencyUtils.convertToDisplayString(unheldTotal * coefficient, iouReport?.currency), CurrencyUtils.convertToDisplayString(total * coefficient, iouReport?.currency)];
}

/**
Expand Down
99 changes: 86 additions & 13 deletions src/libs/actions/IOU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ import * as ReportUtils from '@libs/ReportUtils';
import * as SessionUtils from '@libs/SessionUtils';
import * as SubscriptionUtils from '@libs/SubscriptionUtils';
import * as TransactionUtils from '@libs/TransactionUtils';
import {getCurrency, getTransaction} from '@libs/TransactionUtils';
import {getTransaction} from '@libs/TransactionUtils';
import ViolationsUtils from '@libs/Violations/ViolationsUtils';
import type {IOUAction, IOUType} from '@src/CONST';
import CONST from '@src/CONST';
Expand Down Expand Up @@ -2075,9 +2075,15 @@ function getMoneyRequestInformation(
: ReportUtils.buildOptimisticIOUReport(payeeAccountID, payerAccountID, amount, chatReport.reportID, currency);
} else if (isPolicyExpenseChat) {
iouReport = {...iouReport};
if (iouReport?.currency === currency && typeof iouReport.total === 'number') {
// Because of the Expense reports are stored as negative values, we subtract the total from the amount
iouReport.total -= amount;
// Because of the Expense reports are stored as negative values, we subtract the total from the amount
if (iouReport?.currency === currency) {
if (typeof iouReport.total === 'number') {
iouReport.total -= amount;
}

if (typeof iouReport.unheldTotal === 'number') {
iouReport.unheldTotal -= amount;
}
Comment on lines +2078 to +2080
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a case where unheldTotal wouldn't exist? If we have an expense report where all the transactions are reminbursable will we have:

  1. unheldTotal set to total
  2. unheldTotal not set at all (undefined)

cc @robertjchen

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In main, we don't add unheldTotal and unheldNonReimbursableTotal when creating the report optimistically (buildOptimisticExpenseReport only, IOU not yet, waiting for the IOU total bug to be fixed), so it will be undefined. But in this PR, I already added both optimistically, so it will never be undefined anymore optimistically. I don't know about the BE.

Copy link
Contributor

Choose a reason for hiding this comment

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

For BE, we will always return these fields.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the confirmation. That means we could technically update the typing for the total, unheldTotal, nonReimbursableTotal, and unheldNonReimbursableTotal to be non-undefined/null, but if we want to do that, we need to update all report optimistic creation (buildOptimisticChatReport, buildOptimisticTaskReport, etc.) to include them all, which isn't the case for now.

}
} else {
iouReport = IOUUtils.updateIOUOwnerAndTotal(iouReport, payeeAccountID, amount, currency);
Expand Down Expand Up @@ -2301,10 +2307,17 @@ function getTrackExpenseInformation(
iouReport = ReportUtils.buildOptimisticExpenseReport(chatReport.reportID, chatReport.policyID ?? '-1', payeeAccountID, amount, currency, false);
} else {
iouReport = {...iouReport};
if (iouReport?.currency === currency && typeof iouReport.total === 'number' && typeof iouReport.nonReimbursableTotal === 'number') {
// Because of the Expense reports are stored as negative values, we subtract the total from the amount
iouReport.total -= amount;
iouReport.nonReimbursableTotal -= amount;
// Because of the Expense reports are stored as negative values, we subtract the total from the amount
if (iouReport?.currency === currency) {
if (typeof iouReport.total === 'number' && typeof iouReport.nonReimbursableTotal === 'number') {
iouReport.total -= amount;
iouReport.nonReimbursableTotal -= amount;
}

if (typeof iouReport.unheldTotal === 'number' && typeof iouReport.unheldNonReimbursableTotal === 'number') {
iouReport.unheldTotal -= amount;
iouReport.unheldNonReimbursableTotal -= amount;
}
}
}
}
Expand Down Expand Up @@ -2505,6 +2518,7 @@ function getUpdateMoneyRequestParams(
// Step 2: Get all the collections being updated
const transactionThread = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReportID}`] ?? null;
const transaction = allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`];
const isTransactionOnHold = TransactionUtils.isOnHold(transaction);
const iouReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionThread?.parentReportID}`] ?? null;
const isFromExpenseReport = ReportUtils.isExpenseReport(iouReport);
const isScanning = TransactionUtils.hasReceipt(transaction) && TransactionUtils.isReceiptBeingScanned(transaction);
Expand Down Expand Up @@ -2624,6 +2638,14 @@ function getUpdateMoneyRequestParams(
if (!transaction?.reimbursable && typeof updatedMoneyRequestReport.nonReimbursableTotal === 'number') {
updatedMoneyRequestReport.nonReimbursableTotal -= diff;
}
if (!isTransactionOnHold) {
if (typeof updatedMoneyRequestReport.unheldTotal === 'number') {
updatedMoneyRequestReport.unheldTotal -= diff;
}
if (!transaction?.reimbursable && typeof updatedMoneyRequestReport.unheldNonReimbursableTotal === 'number') {
updatedMoneyRequestReport.unheldNonReimbursableTotal -= diff;
}
}
} else {
updatedMoneyRequestReport = IOUUtils.updateIOUOwnerAndTotal(iouReport, updatedReportAction.actorAccountID ?? -1, diff, TransactionUtils.getCurrency(transaction), false, true);
}
Expand Down Expand Up @@ -4224,9 +4246,15 @@ function createSplitsAndOnyxData(
? ReportUtils.buildOptimisticExpenseReport(oneOnOneChatReport.reportID, oneOnOneChatReport.policyID ?? '-1', currentUserAccountID, splitAmount, currency)
: ReportUtils.buildOptimisticIOUReport(currentUserAccountID, accountID, splitAmount, oneOnOneChatReport.reportID, currency);
} else if (isOwnPolicyExpenseChat) {
if (typeof oneOnOneIOUReport?.total === 'number') {
// Because of the Expense reports are stored as negative values, we subtract the total from the amount
oneOnOneIOUReport.total -= splitAmount;
// Because of the Expense reports are stored as negative values, we subtract the total from the amount
if (oneOnOneIOUReport?.currency === currency) {
if (typeof oneOnOneIOUReport.total === 'number') {
oneOnOneIOUReport.total -= splitAmount;
}

if (typeof oneOnOneIOUReport.unheldTotal === 'number') {
oneOnOneIOUReport.unheldTotal -= splitAmount;
}
}
} else {
oneOnOneIOUReport = IOUUtils.updateIOUOwnerAndTotal(oneOnOneIOUReport, currentUserAccountID, splitAmount, currency);
Expand Down Expand Up @@ -5624,6 +5652,7 @@ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxT
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const reportPreviewAction = getReportPreviewAction(iouReport?.chatReportID ?? '-1', iouReport?.reportID ?? '-1')!;
const transaction = allTransactions[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`];
const isTransactionOnHold = TransactionUtils.isOnHold(transaction);
const transactionViolations = allTransactionViolations[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`];
const transactionThreadID = reportAction.childReportID;
let transactionThread = null;
Expand Down Expand Up @@ -5679,6 +5708,16 @@ function prepareToCleanUpMoneyRequest(transactionID: string, reportAction: OnyxT
if (!transaction?.reimbursable && typeof updatedIOUReport.nonReimbursableTotal === 'number') {
updatedIOUReport.nonReimbursableTotal += amountDiff;
}

if (!isTransactionOnHold) {
if (typeof updatedIOUReport.unheldTotal === 'number') {
updatedIOUReport.unheldTotal += amountDiff;
}

if (!transaction?.reimbursable && typeof updatedIOUReport.unheldNonReimbursableTotal === 'number') {
updatedIOUReport.unheldNonReimbursableTotal += amountDiff;
}
}
}
} else {
updatedIOUReport = IOUUtils.updateIOUOwnerAndTotal(iouReport, reportAction.actorAccountID ?? -1, TransactionUtils.getAmount(transaction, false), currency, true);
Expand Down Expand Up @@ -6515,8 +6554,8 @@ function getReportFromHoldRequestsOnyxData(
chatReport.reportID,
chatReport.policyID ?? iouReport?.policyID ?? '',
recipient.accountID ?? 1,
holdTransactions.reduce((acc, transaction) => acc + TransactionUtils.getAmount(transaction), 0),
getCurrency(firstHoldTransaction),
((iouReport?.total ?? 0) - (iouReport?.unheldTotal ?? 0)) * (ReportUtils.isIOUReport(iouReport) ? 1 : -1),
bernhardoj marked this conversation as resolved.
Show resolved Hide resolved
iouReport?.currency ?? '',
false,
newParentReportActionID,
bernhardoj marked this conversation as resolved.
Show resolved Hide resolved
);
Expand Down Expand Up @@ -7954,6 +7993,8 @@ function putOnHold(transactionID: string, comment: string, reportID: string, sea
const transactionViolations = allTransactionViolations[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`] ?? [];
const updatedViolations = [...transactionViolations, newViolation];
const parentReportActionOptimistic = ReportUtils.getOptimisticDataForParentReportAction(reportID, createdReportActionComment.created, CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
const transaction = allTransactions[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`];
const iouReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${transaction?.reportID}`];

const optimisticData: OnyxUpdate[] = [
{
Expand Down Expand Up @@ -7981,6 +8022,21 @@ function putOnHold(transactionID: string, comment: string, reportID: string, sea
},
];

if (iouReport && iouReport.currency === transaction?.currency) {
const isExpenseReport = ReportUtils.isExpenseReport(iouReport);
const coefficient = isExpenseReport ? -1 : 1;
optimisticData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport.reportID}`,
value: {
unheldTotal: (iouReport.unheldTotal ?? 0) - TransactionUtils.getAmount(transaction, isExpenseReport) * coefficient,
unheldNonReimbursableTotal: !transaction?.reimbursable
? (iouReport.unheldNonReimbursableTotal ?? 0) - TransactionUtils.getAmount(transaction, isExpenseReport) * coefficient
: iouReport.unheldNonReimbursableTotal,
bernhardoj marked this conversation as resolved.
Show resolved Hide resolved
},
});
}

parentReportActionOptimistic.forEach((parentActionData) => {
if (!parentActionData) {
return;
Expand Down Expand Up @@ -8058,6 +8114,8 @@ function putOnHold(transactionID: string, comment: string, reportID: string, sea
function unholdRequest(transactionID: string, reportID: string, searchHash?: number) {
const createdReportAction = ReportUtils.buildOptimisticUnHoldReportAction();
const transactionViolations = allTransactionViolations[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`];
const transaction = allTransactions[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`];
const iouReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${transaction?.reportID}`];

const optimisticData: OnyxUpdate[] = [
{
Expand All @@ -8084,6 +8142,21 @@ function unholdRequest(transactionID: string, reportID: string, searchHash?: num
},
];

if (iouReport && iouReport.currency === transaction?.currency) {
const isExpenseReport = ReportUtils.isExpenseReport(iouReport);
const coefficient = isExpenseReport ? -1 : 1;
optimisticData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport.reportID}`,
value: {
unheldTotal: (iouReport.unheldTotal ?? 0) + TransactionUtils.getAmount(transaction, isExpenseReport) * coefficient,
unheldNonReimbursableTotal: !transaction?.reimbursable
? (iouReport.unheldNonReimbursableTotal ?? 0) + TransactionUtils.getAmount(transaction, isExpenseReport) * coefficient
: iouReport.unheldNonReimbursableTotal,
bernhardoj marked this conversation as resolved.
Show resolved Hide resolved
},
});
}

const successData: OnyxUpdate[] = [
{
onyxMethod: Onyx.METHOD.MERGE,
Expand Down
1 change: 1 addition & 0 deletions src/pages/home/ReportScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro
ownerAccountID: reportOnyx.ownerAccountID,
currency: reportOnyx.currency,
unheldTotal: reportOnyx.unheldTotal,
unheldNonReimbursableTotal: reportOnyx.unheldNonReimbursableTotal,
participants: reportOnyx.participants,
isWaitingOnBankAccount: reportOnyx.isWaitingOnBankAccount,
iouReportID: reportOnyx.iouReportID,
Expand Down
3 changes: 3 additions & 0 deletions src/types/onyx/Report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,9 @@ type Report = OnyxCommon.OnyxValueWithOfflineFeedback<
/** For expense reports, this is the total amount requested */
unheldTotal?: number;

/** Total amount of unheld and non-reimbursable transactions in an expense report */
bernhardoj marked this conversation as resolved.
Show resolved Hide resolved
unheldNonReimbursableTotal?: number;

/** For expense reports, this is the currency of the expense */
currency?: string;

Expand Down
Loading