Skip to content

Commit 1008065

Browse files
committed
Fix: Unable to add unreported expense to IOU report
1 parent d9daefe commit 1008065

2 files changed

Lines changed: 167 additions & 2 deletions

File tree

src/libs/actions/IOU.ts

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ import {
129129
buildOptimisticUnHoldReportAction,
130130
canBeAutoReimbursed,
131131
canUserPerformWriteAction as canUserPerformWriteActionReportUtils,
132+
findSelfDMReportID,
132133
getAllHeldTransactions as getAllHeldTransactionsReportUtils,
133134
getAllPolicyReports,
134135
getApprovalChain,
@@ -143,6 +144,7 @@ import {
143144
getPersonalDetailsForAccountID,
144145
getReportNotificationPreference,
145146
getReportOrDraftReport,
147+
getReportRecipientAccountIDs,
146148
getReportTransactions,
147149
getTransactionDetails,
148150
hasHeldExpenses as hasHeldExpensesReportUtils,
@@ -5059,6 +5061,161 @@ function convertTrackedExpenseToRequest(convertTrackedExpenseParams: ConvertTrac
50595061
API.write(WRITE_COMMANDS.CONVERT_TRACKED_EXPENSE_TO_REQUEST, parameters, {optimisticData, successData, failureData});
50605062
}
50615063

5064+
/**
5065+
* Move multiple tracked expenses from self-DM to an IOU report
5066+
*/
5067+
function convertBulkTrackedExpensesToIOU(transactionIDs: string[], targetReportID: string) {
5068+
const iouReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${targetReportID}`];
5069+
5070+
if (!iouReport || !isMoneyRequestReportReportUtils(iouReport)) {
5071+
Log.warn('[convertBulkTrackedExpensesToIOU] Invalid IOU report', {targetReportID});
5072+
return;
5073+
}
5074+
5075+
const chatReportID = iouReport.chatReportID;
5076+
if (!chatReportID) {
5077+
Log.warn('[convertBulkTrackedExpensesToIOU] No chat report found for IOU', {targetReportID});
5078+
return;
5079+
}
5080+
5081+
const chatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`];
5082+
if (!chatReport) {
5083+
Log.warn('[convertBulkTrackedExpensesToIOU] Chat report not found', {chatReportID});
5084+
return;
5085+
}
5086+
5087+
const participantAccountIDs = getReportRecipientAccountIDs(iouReport, userAccountID);
5088+
const payerAccountID = participantAccountIDs.at(0);
5089+
5090+
if (!payerAccountID) {
5091+
Log.warn('[convertBulkTrackedExpensesToIOU] No payer found', {targetReportID, participantAccountIDs});
5092+
return;
5093+
}
5094+
5095+
const payerEmail = personalDetailsList?.[payerAccountID]?.login ?? '';
5096+
const selfDMReportID = findSelfDMReportID();
5097+
5098+
if (!selfDMReportID) {
5099+
Log.warn('[convertBulkTrackedExpensesToIOU] Self DM not found');
5100+
return;
5101+
}
5102+
5103+
const selfDMReportActions = getAllReportActions(selfDMReportID);
5104+
5105+
transactionIDs.forEach((transactionID) => {
5106+
const transaction = allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`];
5107+
if (!transaction) {
5108+
Log.warn('[convertBulkTrackedExpensesToIOU] Transaction not found', {transactionID});
5109+
return;
5110+
}
5111+
5112+
const linkedTrackedExpenseReportAction = Object.values(selfDMReportActions).find((action) => {
5113+
if (!isMoneyRequestAction(action)) {
5114+
return false;
5115+
}
5116+
const originalMessage = getOriginalMessage(action);
5117+
return originalMessage?.IOUTransactionID === transactionID;
5118+
});
5119+
5120+
if (!linkedTrackedExpenseReportAction) {
5121+
Log.warn('[convertBulkTrackedExpensesToIOU] Tracked expense IOU action not found', {transactionID});
5122+
return;
5123+
}
5124+
5125+
const actionableWhisperReportActionID = getTrackExpenseActionableWhisper(transactionID, selfDMReportID)?.reportActionID;
5126+
5127+
const commentText = typeof transaction.comment === 'string' ? transaction.comment : (transaction.comment?.comment ?? '');
5128+
const parsedComment = getParsedComment(commentText);
5129+
5130+
const attendees = transaction.comment?.attendees;
5131+
5132+
const transactionThreadReportID = (linkedTrackedExpenseReportAction as OnyxTypes.ReportAction).childReportID;
5133+
5134+
if (!transactionThreadReportID) {
5135+
Log.warn('[convertBulkTrackedExpensesToIOU] No transaction thread found for tracked expense, skipping', {
5136+
transactionID,
5137+
actionReportActionID: (linkedTrackedExpenseReportAction as OnyxTypes.ReportAction).reportActionID,
5138+
});
5139+
return;
5140+
}
5141+
5142+
const participantParams = {
5143+
payeeAccountID: userAccountID,
5144+
payeeEmail: currentUserEmail,
5145+
participant: {
5146+
accountID: payerAccountID,
5147+
login: payerEmail,
5148+
},
5149+
};
5150+
5151+
const transactionParams = {
5152+
amount: getAmount(transaction),
5153+
currency: getCurrency(transaction),
5154+
comment: parsedComment,
5155+
merchant: getMerchant(transaction),
5156+
created: transaction.created,
5157+
attendees,
5158+
actionableWhisperReportActionID,
5159+
linkedTrackedExpenseReportAction,
5160+
linkedTrackedExpenseReportID: selfDMReportID,
5161+
};
5162+
5163+
const {
5164+
payerAccountID: moneyRequestPayerAccountID,
5165+
payerEmail: moneyRequestPayerEmail,
5166+
iouReport: moneyRequestIOUReport,
5167+
chatReport: moneyRequestChatReport,
5168+
transaction: moneyRequestTransaction,
5169+
iouAction,
5170+
createdChatReportActionID,
5171+
createdIOUReportActionID,
5172+
reportPreviewAction,
5173+
transactionThreadReportID: moneyRequestTransactionThreadReportID,
5174+
onyxData,
5175+
} = getMoneyRequestInformation({
5176+
parentChatReport: chatReport,
5177+
participantParams,
5178+
transactionParams,
5179+
moneyRequestReportID: targetReportID,
5180+
existingTransactionID: transactionID,
5181+
existingTransaction: transaction,
5182+
});
5183+
5184+
const convertParams: ConvertTrackedExpenseToRequestParams = {
5185+
payerParams: {
5186+
accountID: moneyRequestPayerAccountID,
5187+
email: moneyRequestPayerEmail,
5188+
},
5189+
transactionParams: {
5190+
amount: getAmount(transaction),
5191+
currency: getCurrency(transaction),
5192+
comment: parsedComment,
5193+
merchant: getMerchant(transaction),
5194+
created: transaction.created,
5195+
attendees,
5196+
transactionID: moneyRequestTransaction.transactionID,
5197+
actionableWhisperReportActionID,
5198+
linkedTrackedExpenseReportAction,
5199+
linkedTrackedExpenseReportID: selfDMReportID,
5200+
transactionThreadReportID: moneyRequestTransactionThreadReportID,
5201+
},
5202+
chatParams: {
5203+
reportID: moneyRequestChatReport.reportID,
5204+
createdReportActionID: createdChatReportActionID,
5205+
reportPreviewReportActionID: reportPreviewAction.reportActionID,
5206+
},
5207+
iouParams: {
5208+
reportID: moneyRequestIOUReport.reportID,
5209+
createdReportActionID: createdIOUReportActionID,
5210+
reportActionID: iouAction.reportActionID,
5211+
},
5212+
onyxData,
5213+
};
5214+
5215+
convertTrackedExpenseToRequest(convertParams);
5216+
});
5217+
}
5218+
50625219
function categorizeTrackedExpense(trackedExpenseParams: TrackedExpenseParams) {
50635220
const {onyxData, reportInformation, transactionParams, policyParams, createdWorkspaceParams} = trackedExpenseParams;
50645221
const {optimisticData, successData, failureData} = onyxData ?? {};
@@ -11846,6 +12003,7 @@ export {
1184612003
dismissModalAndOpenReportInInboxTab,
1184712004
navigateToStartStepIfScanFileCannotBeRead,
1184812005
completePaymentOnboarding,
12006+
convertBulkTrackedExpensesToIOU,
1184912007
payInvoice,
1185012008
payMoneyRequest,
1185112009
putOnHold,

src/pages/AddUnreportedExpense.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ import useThemeStyles from '@hooks/useThemeStyles';
1616
import {fetchUnreportedExpenses} from '@libs/actions/UnreportedExpenses';
1717
import interceptAnonymousUser from '@libs/interceptAnonymousUser';
1818
import type {AddUnreportedExpensesParamList} from '@libs/Navigation/types';
19+
import {isMoneyRequestReport} from '@libs/ReportUtils';
1920
import {shouldRestrictUserBillableActions} from '@libs/SubscriptionUtils';
2021
import {createUnreportedExpenseSections} from '@libs/TransactionUtils';
2122
import Navigation from '@navigation/Navigation';
2223
import type {PlatformStackScreenProps} from '@navigation/PlatformStackNavigation/types';
23-
import {startMoneyRequest} from '@userActions/IOU';
24+
import {convertBulkTrackedExpensesToIOU, startMoneyRequest} from '@userActions/IOU';
2425
import {changeTransactionsReport} from '@userActions/Transaction';
2526
import CONST from '@src/CONST';
2627
import ONYXKEYS from '@src/ONYXKEYS';
@@ -182,7 +183,13 @@ function AddUnreportedExpense({route}: AddUnreportedExpensePageType) {
182183
return;
183184
}
184185
Navigation.dismissModal();
185-
changeTransactionsReport([...selectedIds], report?.reportID ?? CONST.REPORT.UNREPORTED_REPORT_ID, policy);
186+
187+
if (report && isMoneyRequestReport(report)) {
188+
convertBulkTrackedExpensesToIOU([...selectedIds], report.reportID);
189+
} else {
190+
changeTransactionsReport([...selectedIds], report?.reportID ?? CONST.REPORT.UNREPORTED_REPORT_ID, policy);
191+
}
192+
186193
setErrorMessage('');
187194
}}
188195
onEndReached={fetchMoreUnreportedTransactions}

0 commit comments

Comments
 (0)