diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 9056210024bc..111ee8e32b28 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -4,7 +4,7 @@ import CONST from '../../CONST'; import ONYXKEYS from '../../ONYXKEYS'; import ROUTES from '../../ROUTES'; import * as API from '../API'; -import {getSimplifiedIOUReport, fetchChatReportsByIDs, fetchIOUReportByIDAndUpdateChatReport} from './Report'; +import {getSimplifiedIOUReport, syncChatAndIOUReports} from './Report'; import Navigation from '../Navigation/Navigation'; import asyncOpenURL from '../asyncOpenURL'; @@ -135,14 +135,10 @@ function rejectTransaction({ if (response.jsonCode !== 200) { throw new Error(`${response.code} ${response.message}`); } - fetchChatReportsByIDs([chatReportID]); - - // If an iouReport is open (has an IOU, but is not yet paid) then we sync the chatReport's 'iouReportID' - // field in Onyx, simplifying IOU data retrieval and reducing necessary API calls when displaying IOU - // components. If we didn't sync the reportIDs, the transaction would still be shown to users as rejectable - // The iouReport being fetched here must be open, because only an open iouReoport can be paid. Therefore, - // we should also sync the chatReport after fetching the iouReport. - fetchIOUReportByIDAndUpdateChatReport(reportID, chatReportID); + + const chatReport = response.reports[chatReportID]; + const iouReport = response.reports[reportID]; + syncChatAndIOUReports(chatReport, iouReport); }) .catch(error => console.error(`Error rejecting transaction: ${error}`)) .finally(() => { @@ -212,14 +208,10 @@ function payIOUReport({ if (response.jsonCode !== 200) { throw new Error(response.message); } - fetchChatReportsByIDs([chatReportID]); - - // If an iouReport is open (has an IOU, but is not yet paid) then we sync the chatReport's 'iouReportID' - // field in Onyx, simplifying IOU data retrieval and reducing necessary API calls when displaying IOU - // components. If we didn't sync the reportIDs, the paid IOU would still be shown to users as unpaid. The - // iouReport being fetched here must be open, because only an open iouReoport can be paid. - // Therefore, we should also sync the chatReport after fetching the iouReport. - fetchIOUReportByIDAndUpdateChatReport(reportID, chatReportID); + + const chatReportStuff = response.reports[chatReportID]; + const iouReportStuff = response.reports[reportID]; + syncChatAndIOUReports(chatReportStuff, iouReportStuff); }) .catch((error) => { console.error(`Error Paying iouReport: ${error}`); diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 9ebc42db9629..2ee0440e117a 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -1080,7 +1080,7 @@ function deleteReportComment(reportID, reportAction) { const sequenceNumber = reportAction.sequenceNumber; const reportActionsToMerge = {}; const oldMessage = {...reportAction.message}; - reportActionsToMerge[reportAction.sequenceNumber] = { + reportActionsToMerge[sequenceNumber] = { ...reportAction, message: [ { @@ -1269,6 +1269,40 @@ function saveReportActionDraft(reportID, reportActionID, draftMessage) { Onyx.set(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}${reportID}_${reportActionID}`, draftMessage); } +/** + * Syncs up a chat report and an IOU report in Onyx after an IOU transaction has been made + * by setting the iouReportID and hasOutstandingIOU for the chat report. + * Even though both reports are updated in the back-end, the API doesn't handle syncing their reportIDs. + * If we didn't sync these reportIDs, the paid IOU would still be shown to users as unpaid. + * The iouReport being fetched here must be open, because only an open iouReport can be paid. + * + * @param {Object} chatReport + * @param {Object} iouReport + */ +function syncChatAndIOUReports(chatReport, iouReport) { + // Return early in case there's a back-end issue preventing the IOU command from returning the report objects. + if (!chatReport || !iouReport) { + return; + } + + const simplifiedIouReport = {}; + const simplifiedReport = {}; + const chatReportKey = `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`; + const iouReportKey = `${ONYXKEYS.COLLECTION.REPORT_IOUS}${iouReport.reportID}`; + + // We don't want to sync an iou report that's already been reimbursed with its chat report. + if (!iouReport.stateNum === CONST.REPORT.STATE_NUM.SUBMITTED) { + simplifiedReport[chatReportKey].iouReportID = iouReport.reportID; + } + simplifiedReport[chatReportKey] = getSimplifiedReportObject(chatReport); + simplifiedReport[chatReportKey].hasOutstandingIOU = iouReport.stateNum + === (CONST.REPORT.STATE_NUM.PROCESSING && iouReport.total !== 0); + simplifiedIouReport[iouReportKey] = getSimplifiedIOUReport(iouReport, chatReport.reportID); + + Onyx.mergeCollection(ONYXKEYS.COLLECTION.REPORT_IOUS, simplifiedIouReport); + Onyx.mergeCollection(ONYXKEYS.COLLECTION.REPORT, simplifiedReport); +} + /** * Updates a user's notification preferences for a chat room * @@ -1302,4 +1336,5 @@ export { saveReportActionDraft, deleteReportComment, getSimplifiedIOUReport, + syncChatAndIOUReports, };