Skip to content

Commit da0805a

Browse files
authored
Merge pull request Expensify#65802 from rayane-d/fix-Unable-to-add-unreported-expense-to-IOU
Fix: Unable to add unreported expense to IOU report
2 parents 7b004d7 + b9b9d2a commit da0805a

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
@@ -131,6 +131,7 @@ import {
131131
buildOptimisticUnHoldReportAction,
132132
canBeAutoReimbursed,
133133
canUserPerformWriteAction as canUserPerformWriteActionReportUtils,
134+
findSelfDMReportID,
134135
getAllHeldTransactions as getAllHeldTransactionsReportUtils,
135136
getAllPolicyReports,
136137
getApprovalChain,
@@ -145,6 +146,7 @@ import {
145146
getPersonalDetailsForAccountID,
146147
getReportNotificationPreference,
147148
getReportOrDraftReport,
149+
getReportRecipientAccountIDs,
148150
getReportTransactions,
149151
getTransactionDetails,
150152
hasHeldExpenses as hasHeldExpensesReportUtils,
@@ -5074,6 +5076,161 @@ function convertTrackedExpenseToRequest(convertTrackedExpenseParams: ConvertTrac
50745076
API.write(WRITE_COMMANDS.CONVERT_TRACKED_EXPENSE_TO_REQUEST, parameters, {optimisticData, successData, failureData});
50755077
}
50765078

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