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
5 changes: 3 additions & 2 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6699,9 +6699,10 @@ function buildOptimisticTaskCommentReportAction(
return reportAction;
}

function buildOptimisticSelfDMReport(created: string): Report {
function buildOptimisticSelfDMReport(created: string, reportID?: string): Report {
return {
reportID: generateReportID(),
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
reportID: reportID || generateReportID(),
participants: {
[currentUserAccountID ?? CONST.DEFAULT_NUMBER_ID]: {
notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.MUTE,
Expand Down
28 changes: 27 additions & 1 deletion src/libs/actions/Report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@
let currentUserAccountID = -1;
let currentUserEmail: string | undefined;

Onyx.connect({

Check warning on line 280 in src/libs/actions/Report.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) => {
// When signed out, val is undefined
Expand All @@ -290,7 +290,7 @@
},
});

Onyx.connect({

Check warning on line 293 in src/libs/actions/Report.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.CONCIERGE_REPORT_ID,
callback: (value) => (conciergeReportID = value),
});
Expand All @@ -298,7 +298,7 @@
// map of reportID to all reportActions for that report
const allReportActions: OnyxCollection<ReportActions> = {};

Onyx.connect({

Check warning on line 301 in src/libs/actions/Report.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_ACTIONS,
callback: (actions, key) => {
if (!key || !actions) {
Expand All @@ -310,14 +310,14 @@
});

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

Check warning on line 313 in src/libs/actions/Report.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) => (allTransactionViolations = value),
});

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

Check warning on line 320 in src/libs/actions/Report.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 @@ -326,7 +326,7 @@
});

let allPersonalDetails: OnyxEntry<PersonalDetailsList> = {};
Onyx.connect({

Check warning on line 329 in src/libs/actions/Report.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 All @@ -341,7 +341,7 @@
});

let onboarding: OnyxEntry<Onboarding>;
Onyx.connect({

Check warning on line 344 in src/libs/actions/Report.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.NVP_ONBOARDING,
callback: (val) => {
if (Array.isArray(val)) {
Expand All @@ -352,13 +352,13 @@
});

let introSelected: OnyxEntry<IntroSelected> = {};
Onyx.connect({

Check warning on line 355 in src/libs/actions/Report.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.NVP_INTRO_SELECTED,
callback: (val) => (introSelected = val),
});

let allReportDraftComments: Record<string, string | undefined> = {};
Onyx.connect({

Check warning on line 361 in src/libs/actions/Report.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_DRAFT_COMMENT,
waitForCollectionCallback: true,
callback: (value) => (allReportDraftComments = value),
Expand Down Expand Up @@ -952,6 +952,7 @@
* @param transaction The transaction object for legacy transactions that don't have a transaction thread or money request preview yet
* @param transactionViolations The violations for the transaction, if any
* @param parentReportID The parent report ID for the transaction thread (optional, defaults to transaction.reportID)
* @param optimisticSelfDMReport The optimistic selfDM report when it exists on the server but was filtered out from OpenApp response (e.g., no actions yet)
*/
// eslint-disable-next-line @typescript-eslint/max-params
function openReport(
Expand All @@ -967,6 +968,7 @@
transaction?: Transaction,
transactionViolations?: TransactionViolations,
parentReportID?: string,
optimisticSelfDMReport?: Report,
) {
if (!reportID) {
return;
Expand Down Expand Up @@ -1050,13 +1052,28 @@
transactionID: transaction?.transactionID,
};

if (optimisticSelfDMReport) {
optimisticData.push({
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${optimisticSelfDMReport.reportID}`,
value: optimisticSelfDMReport,
});
failureData.push({
onyxMethod: Onyx.METHOD.SET,
key: `${ONYXKEYS.COLLECTION.REPORT}${optimisticSelfDMReport.reportID}`,
value: null,
});
}

// This is a legacy transactions that doesn't have either a transaction thread or a money request preview
if (transaction && !parentReportActionID) {
const transactionParentReportID = parentReportID ?? transaction?.reportID;
const iouReportActionID = rand64();

// Get the parent report to determine the actual submitter/owner of the expense
const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionParentReportID}`];
// Use optimisticSelfDMReport if provided (when selfDM exists but wasn't in allReports)
const parentReport =
transactionParentReportID === optimisticSelfDMReport?.reportID ? optimisticSelfDMReport : allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transactionParentReportID}`];
const submitterAccountID = parentReport?.ownerAccountID ?? currentUserAccountID;
const submitterEmail = PersonalDetailsUtils.getLoginsByAccountIDs([submitterAccountID]).at(0) ?? currentUserEmail ?? '';
const submitterPersonalDetails = PersonalDetailsUtils.getPersonalDetailByEmail(submitterEmail);
Expand Down Expand Up @@ -1394,9 +1411,17 @@
const isUnreportedTransaction = transaction?.reportID === CONST.REPORT.UNREPORTED_REPORT_ID;
const selfDMReportID = isTrackExpense || isUnreportedTransaction ? findSelfDMReportID() : undefined;

let optimisticSelfDMReport: Report | undefined;
let reportToUse = iouReport;
if (selfDMReportID) {
reportToUse = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${selfDMReportID}`];

// selfDMReportID may be set but the report is filtered out.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The root cause of this is in backend?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, the root cause is in the backend. The backend behavior is intentional; changing it might affect other processes. This fix handles the specific edge case where we need the selfDM to create a transaction thread.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

yes, edge case. The bug is not reproducible anymore after selfDM is created in frontend.
To reproduce again, need to create another account.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

// Create an optimistic report if needed to proceed with the transaction thread.
if (!reportToUse) {
optimisticSelfDMReport = buildOptimisticSelfDMReport(DateUtils.getDBTime(), selfDMReportID);
reportToUse = optimisticSelfDMReport;
}
}

if (!reportToUse) {
Expand Down Expand Up @@ -1426,6 +1451,7 @@
transaction,
transactionViolations,
selfDMReportID,
optimisticSelfDMReport,
);
return optimisticTransactionThread;
}
Expand Down
Loading