From 8a50157192715163b226471400f9f6c1c50363ad Mon Sep 17 00:00:00 2001 From: OSBotify <76178356+OSBotify@users.noreply.github.com> Date: Tue, 16 May 2023 14:59:14 -0400 Subject: [PATCH 1/2] Merge pull request #19058 from Expensify/version-BUILD-C426FC30-782A-4A59-86FF-62A36D27A595 Update version to 1.3.14-13 on main (cherry picked from commit 8bf16eacc77e80efbd79b5cedccd8f67c4e9f828) --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 7834d8ae90cd..e7db08a30e38 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -106,8 +106,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001031412 - versionName "1.3.14-12" + versionCode 1001031413 + versionName "1.3.14-13" } splits { diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index fe60c96e7fb5..c5d0530551bd 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -30,7 +30,7 @@ CFBundleVersion - 1.3.14.12 + 1.3.14.13 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 84de56479723..3a2e6f77f705 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.3.14.12 + 1.3.14.13 diff --git a/package-lock.json b/package-lock.json index 274a2685cafd..8409252f588e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.3.14-12", + "version": "1.3.14-13", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.3.14-12", + "version": "1.3.14-13", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 8dfb65d0218c..d15f812f1350 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.3.14-12", + "version": "1.3.14-13", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", From aab4d311dba81b1ec24f6f7a34b62ebd95ab4f00 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 16 May 2023 12:45:13 -0600 Subject: [PATCH 2/2] Merge pull request #18604 from Expensify/cmartins-createRequestsInExpenseReports Use IOU/Expense reportID for IOU actions (cherry picked from commit d20142be97e93c10e77f89d235718fcb0a513b61) --- .../ReportActionItem/MoneyRequestAction.js | 2 +- src/libs/actions/IOU.js | 672 +++++++++++------- src/pages/iou/IOUDetailsModal.js | 2 +- tests/actions/IOUTest.js | 113 +-- 4 files changed, 489 insertions(+), 300 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestAction.js b/src/components/ReportActionItem/MoneyRequestAction.js index 443944264858..b6f9cd88d5bb 100644 --- a/src/components/ReportActionItem/MoneyRequestAction.js +++ b/src/components/ReportActionItem/MoneyRequestAction.js @@ -112,7 +112,7 @@ const MoneyRequestAction = (props) => { undefined, CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS, props.action.reportActionID, - props.chatReportID, // Needs to be changed to iouReportID + props.requestReportID, ); Report.openReport(thread.reportID, thread.participants, thread, props.action.reportActionID); diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 3a5265286bf1..46e2573bc6a8 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -43,6 +43,200 @@ Onyx.connect({ }, }); +function buildOnyxDataForMoneyRequest(chatReport, iouReport, transaction, chatCreatedAction, iouCreatedAction, iouAction, isNewChatReport, isNewIOUReport) { + const optimisticData = [ + { + // Use SET for new reports because it doesn't exist yet, is faster and we need the data to be available when we navigate to the chat page + onyxMethod: isNewChatReport ? Onyx.METHOD.SET : Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, + value: { + ...chatReport, + lastReadTime: DateUtils.getDBTime(), + hasOutstandingIOU: iouReport.total !== 0, + iouReportID: iouReport.reportID, + ...(isNewChatReport ? {pendingFields: {createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}} : {}), + }, + }, + { + onyxMethod: isNewIOUReport ? Onyx.METHOD.SET : Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport.reportID}`, + value: { + ...iouReport, + lastMessageText: iouAction.message[0].text, + lastMessageHtml: iouAction.message[0].html, + ...(isNewIOUReport ? {pendingFields: {createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}} : {}), + }, + }, + { + onyxMethod: Onyx.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`, + value: transaction, + }, + ...(isNewChatReport + ? [ + { + onyxMethod: Onyx.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, + value: { + [chatCreatedAction.reportActionID]: chatCreatedAction, + }, + }, + ] + : []), + { + onyxMethod: isNewIOUReport ? Onyx.METHOD.SET : Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`, + value: { + ...(isNewIOUReport ? {[iouCreatedAction.reportActionID]: iouCreatedAction} : {}), + [iouAction.reportActionID]: iouAction, + }, + }, + ]; + + const successData = [ + ...(isNewChatReport + ? [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, + value: { + pendingFields: null, + errorFields: null, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, + value: { + [chatCreatedAction.reportActionID]: { + pendingAction: null, + errors: null, + }, + }, + }, + ] + : []), + ...(isNewIOUReport + ? [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport.reportID}`, + value: { + pendingFields: null, + errorFields: null, + }, + }, + ] + : []), + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`, + value: {pendingAction: null}, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`, + value: { + ...(isNewIOUReport + ? { + [iouCreatedAction.reportActionID]: { + pendingAction: null, + errors: null, + }, + } + : {}), + [iouAction.reportActionID]: { + pendingAction: null, + errors: null, + }, + }, + }, + ]; + + const failureData = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, + value: { + hasOutstandingIOU: chatReport.hasOutstandingIOU, + iouReportID: chatReport.iouReportID, + lastReadTime: chatReport.lastReadTime, + ...(isNewChatReport + ? { + errorFields: { + createChat: { + [DateUtils.getMicroseconds()]: Localize.translateLocal('report.genericCreateReportFailureMessage'), + }, + }, + } + : {}), + }, + }, + ...(isNewIOUReport + ? [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport.reportID}`, + value: { + errorFields: { + createChat: { + [DateUtils.getMicroseconds()]: Localize.translateLocal('report.genericCreateReportFailureMessage'), + }, + }, + }, + }, + ] + : []), + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`, + value: { + errors: { + [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.genericCreateFailureMessage'), + }, + }, + }, + ...(isNewChatReport + ? [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, + value: { + [chatCreatedAction.reportActionID]: { + errors: { + [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.genericCreateFailureMessage'), + }, + }, + }, + }, + ] + : []), + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`, + value: { + ...(isNewIOUReport + ? { + [iouCreatedAction.reportActionID]: { + errors: { + [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.genericCreateFailureMessage'), + }, + }, + } + : { + [iouAction.reportActionID]: { + errors: { + [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.genericCreateFailureMessage'), + }, + }, + }), + }, + }, + ]; + + return [optimisticData, successData, failureData]; +} + /** * Request money from another user * @@ -55,9 +249,11 @@ Onyx.connect({ */ function requestMoney(report, amount, currency, payeeEmail, participant, comment) { const payerEmail = OptionsListUtils.addSMSDomainIfPhoneNumber(participant.login); - let chatReport = lodashGet(report, 'reportID', null) ? report : null; const isPolicyExpenseChat = participant.isPolicyExpenseChat || participant.isOwnPolicyExpenseChat; - let isNewChat = false; + + // STEP 1: Get existing chat report OR build a new optimistic one + let isNewChatReport = false; + let chatReport = lodashGet(report, 'reportID', null) ? report : null; // If this is a policyExpenseChat, the chatReport must exist and we can get it from Onyx. // report is null if the flow is initiated from the global create menu. However, participant always stores the reportID if it exists, which is the case for policyExpenseChats @@ -68,52 +264,40 @@ function requestMoney(report, amount, currency, payeeEmail, participant, comment if (!chatReport) { chatReport = ReportUtils.getChatByParticipants([payerEmail]); } + + // If we still don't have a report, it likely doens't exist and we need to build an optimistic one if (!chatReport) { + isNewChatReport = true; chatReport = ReportUtils.buildOptimisticChatReport([payerEmail]); - isNewChat = true; } - let moneyRequestReport; - if (chatReport.iouReportID) { + + // STEP 2: Get existing IOU report and update its total OR build a new optimistic one + const isNewIOUReport = !chatReport.iouReportID; + let iouReport; + + if (!isNewIOUReport) { if (isPolicyExpenseChat) { - moneyRequestReport = {...iouReports[`${ONYXKEYS.COLLECTION.REPORT}${chatReport.iouReportID}`]}; + iouReport = {...iouReports[`${ONYXKEYS.COLLECTION.REPORT}${chatReport.iouReportID}`]}; // Because of the Expense reports are stored as negative values, we substract the total from the amount - moneyRequestReport.total = ReportUtils.isExpenseReport(moneyRequestReport) ? moneyRequestReport.total - amount : moneyRequestReport.total + amount; + iouReport.total -= amount; } else { - moneyRequestReport = IOUUtils.updateIOUOwnerAndTotal(iouReports[`${ONYXKEYS.COLLECTION.REPORT}${chatReport.iouReportID}`], payeeEmail, amount, currency); + iouReport = IOUUtils.updateIOUOwnerAndTotal(iouReports[`${ONYXKEYS.COLLECTION.REPORT}${chatReport.iouReportID}`], payeeEmail, amount, currency); } } else { - moneyRequestReport = isPolicyExpenseChat + iouReport = isPolicyExpenseChat ? ReportUtils.buildOptimisticExpenseReport(chatReport.reportID, chatReport.policyID, payeeEmail, amount, currency) : ReportUtils.buildOptimisticIOUReport(payeeEmail, payerEmail, amount, chatReport.reportID, currency); } - const optimisticTransaction = TransactionUtils.buildOptimisticTransaction(amount, currency, moneyRequestReport.reportID, comment); - const optimisticTransactionData = { - onyxMethod: Onyx.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.TRANSACTION}${optimisticTransaction.transactionID}`, - value: optimisticTransaction, - }; - const transactionSuccessData = { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.TRANSACTION}${optimisticTransaction.transactionID}`, - value: { - pendingAction: null, - }, - }; - const transactionFailureData = { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.TRANSACTION}${optimisticTransaction.transactionID}`, - value: { - errors: { - [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.genericCreateFailureMessage'), - }, - }, - }; + // STEP 3: Build optimistic transaction + const optimisticTransaction = TransactionUtils.buildOptimisticTransaction(amount, currency, iouReport.reportID, comment); - // Note: The created action must be optimistically generated before the IOU action so there's no chance that the created action appears after the IOU action in the chat - const optimisticCreatedAction = ReportUtils.buildOptimisticCreatedReportAction(payeeEmail); - const optimisticReportAction = ReportUtils.buildOptimisticIOUReportAction( + // STEP 4: Build optimistic reportActions. We need a CREATED action for each report and an IOU action for the IOU report + // Note: The CREATED action for the IOU report must be optimistically generated before the IOU action so there's no chance that it appears after the IOU action in the chat + const optimisticCreatedActionForChat = ReportUtils.buildOptimisticCreatedReportAction(payeeEmail); + const optimisticCreatedActionForIOU = ReportUtils.buildOptimisticCreatedReportAction(payeeEmail); + const optimisticIOUAction = ReportUtils.buildOptimisticIOUReportAction( CONST.IOU.REPORT_ACTION_TYPE.CREATE, amount, currency, @@ -121,112 +305,22 @@ function requestMoney(report, amount, currency, payeeEmail, participant, comment [participant], optimisticTransaction.transactionID, '', - moneyRequestReport.reportID, + iouReport.reportID, ); - // First, add data that will be used in all cases - const optimisticChatReportData = { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, - value: { - ...chatReport, - lastReadTime: DateUtils.getDBTime(), - lastMessageText: optimisticReportAction.message[0].text, - lastMessageHtml: optimisticReportAction.message[0].html, - hasOutstandingIOU: moneyRequestReport.total !== 0, - iouReportID: moneyRequestReport.reportID, - }, - }; - - const optimisticIOUReportData = { - onyxMethod: chatReport.hasOutstandingIOU ? Onyx.METHOD.MERGE : Onyx.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.REPORT}${moneyRequestReport.reportID}`, - value: moneyRequestReport, - }; - - const optimisticReportActionsData = { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, - value: { - [optimisticReportAction.reportActionID]: optimisticReportAction, - }, - }; - - let chatReportSuccessData = {}; - const reportActionsSuccessData = { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, - value: { - [optimisticReportAction.reportActionID]: { - pendingAction: null, - }, - }, - }; - - const chatReportFailureData = { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, - value: { - hasOutstandingIOU: chatReport.hasOutstandingIOU, - }, - }; - - const reportActionsFailureData = { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, - value: { - [optimisticReportAction.reportActionID]: { - errors: { - [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.genericCreateFailureMessage'), - }, - }, - }, - }; - - // Now, let's add the data we need just when we are creating a new chat report - if (isNewChat) { - // Change the method to set for new reports because it doesn't exist yet, is faster, - // and we need the data to be available when we navigate to the chat page - optimisticChatReportData.onyxMethod = Onyx.METHOD.SET; - optimisticIOUReportData.onyxMethod = Onyx.METHOD.SET; - optimisticReportActionsData.onyxMethod = Onyx.METHOD.SET; - - // Then add and clear pending fields from the chat report - optimisticChatReportData.value.pendingFields = {createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}; - chatReportSuccessData = { - onyxMethod: Onyx.METHOD.MERGE, - key: optimisticChatReportData.key, - value: { - pendingFields: null, - errorFields: null, - }, - }; - chatReportFailureData.value.pendingFields = {createChat: null}; - delete chatReportFailureData.value.hasOutstandingIOU; - chatReportFailureData.value.errorFields = { - createChat: { - [DateUtils.getMicroseconds()]: Localize.translateLocal('report.genericCreateReportFailureMessage'), - }, - }; - - // Then add an optimistic created action - optimisticReportActionsData.value[optimisticCreatedAction.reportActionID] = optimisticCreatedAction; - reportActionsSuccessData.value[optimisticCreatedAction.reportActionID] = {pendingAction: null}; - - // Failure data should feature red brick road - reportActionsFailureData.value[optimisticCreatedAction.reportActionID] = {pendingAction: null}; - reportActionsFailureData.value[optimisticReportAction.reportActionID] = {pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}; - } - - const optimisticData = [optimisticChatReportData, optimisticIOUReportData, optimisticReportActionsData, optimisticTransactionData]; - - const successData = [reportActionsSuccessData, transactionSuccessData]; - if (!_.isEmpty(chatReportSuccessData)) { - successData.push(chatReportSuccessData); - } - - const failureData = [chatReportFailureData, reportActionsFailureData, transactionFailureData]; + // STEP 5: Build Onyx Data + const [optimisticData, successData, failureData] = buildOnyxDataForMoneyRequest( + chatReport, + iouReport, + optimisticTransaction, + optimisticCreatedActionForChat, + optimisticCreatedActionForIOU, + optimisticIOUAction, + isNewChatReport, + isNewIOUReport, + ); + // STEP 6: Make the request const parsedComment = ReportUtils.getParsedComment(comment); API.write( 'RequestMoney', @@ -235,11 +329,12 @@ function requestMoney(report, amount, currency, payeeEmail, participant, comment amount, currency, comment: parsedComment, - iouReportID: moneyRequestReport.reportID, + iouReportID: iouReport.reportID, chatReportID: chatReport.reportID, transactionID: optimisticTransaction.transactionID, - reportActionID: optimisticReportAction.reportActionID, - createdReportActionID: isNewChat ? optimisticCreatedAction.reportActionID : 0, + reportActionID: optimisticIOUAction.reportActionID, + createdChatReportActionID: isNewChatReport ? optimisticCreatedActionForChat.reportActionID : 0, + createdIOUReportActionID: isNewIOUReport ? optimisticCreatedActionForIOU.reportActionID : 0, }, {optimisticData, successData, failureData}, ); @@ -400,10 +495,10 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment const existingOneOnOneChatReport = !hasMultipleParticipants && !existingGroupChatReportID ? groupChatReport : ReportUtils.getChatByParticipants([email]); const oneOnOneChatReport = existingOneOnOneChatReport || ReportUtils.buildOptimisticChatReport([email]); let oneOnOneIOUReport; - let existingIOUReport = null; + let existingOneOnOneIOUReport = null; if (oneOnOneChatReport.iouReportID) { - existingIOUReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.iouReportID}`]; - oneOnOneIOUReport = IOUUtils.updateIOUOwnerAndTotal(existingIOUReport, currentUserEmail, splitAmount, currency); + existingOneOnOneIOUReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.iouReportID}`]; + oneOnOneIOUReport = IOUUtils.updateIOUOwnerAndTotal(existingOneOnOneIOUReport, currentUserEmail, splitAmount, currency); oneOnOneChatReport.hasOutstandingIOU = oneOnOneIOUReport.total !== 0; } else { oneOnOneIOUReport = ReportUtils.buildOptimisticIOUReport(currentUserEmail, email, splitAmount, oneOnOneChatReport.reportID, currency); @@ -421,8 +516,9 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment ); // Note: The created action must be optimistically generated before the IOU action so there's no chance that the created action appears after the IOU action in the chat - const oneOnOneCreatedReportAction = ReportUtils.buildOptimisticCreatedReportAction(currentUserEmail); - const oneOnOneIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( + const oneOnOneCreatedActionForChat = ReportUtils.buildOptimisticCreatedReportAction(currentUserEmail); + const oneOnOneCreatedActionForIOU = ReportUtils.buildOptimisticCreatedReportAction(currentUserEmail); + const oneOnOneIOUAction = ReportUtils.buildOptimisticIOUReportAction( CONST.IOU.REPORT_ACTION_TYPE.CREATE, splitAmount, currency, @@ -433,27 +529,26 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment oneOnOneIOUReport.reportID, ); - oneOnOneChatReport.lastMessageText = oneOnOneIOUReportAction.message[0].text; - oneOnOneChatReport.lastMessageHtml = oneOnOneIOUReportAction.message[0].html; - - if (!existingOneOnOneChatReport) { - oneOnOneChatReport.pendingFields = { - createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - }; - } - optimisticData.push( { onyxMethod: existingOneOnOneChatReport ? Onyx.METHOD.MERGE : Onyx.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`, - value: oneOnOneChatReport, + value: { + ...oneOnOneChatReport, + lastReadTime: DateUtils.getDBTime(), + hasOutstandingIOU: oneOnOneIOUReport.total !== 0, + iouReportID: oneOnOneIOUReport.reportID, + ...(existingOneOnOneChatReport ? {} : {pendingFields: {createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}}), + }, }, { - onyxMethod: existingOneOnOneChatReport ? Onyx.METHOD.MERGE : Onyx.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`, + onyxMethod: existingOneOnOneIOUReport ? Onyx.METHOD.MERGE : Onyx.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneIOUReport.reportID}`, value: { - ...(existingOneOnOneChatReport ? {} : {[oneOnOneCreatedReportAction.reportActionID]: oneOnOneCreatedReportAction}), - [oneOnOneIOUReportAction.reportActionID]: oneOnOneIOUReportAction, + ...oneOnOneIOUReport, + lastMessageText: oneOnOneIOUAction.message[0].text, + lastMessageHtml: oneOnOneIOUAction.message[0].html, + ...(existingOneOnOneIOUReport ? {} : {pendingFields: {createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}}), }, }, { @@ -461,44 +556,121 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment key: `${ONYXKEYS.COLLECTION.TRANSACTION}${oneOnOneTransaction.transactionID}`, value: oneOnOneTransaction, }, - ); - - successData.push( + ...(existingOneOnOneChatReport + ? [] + : [ + { + onyxMethod: existingOneOnOneChatReport ? Onyx.METHOD.MERGE : Onyx.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`, + value: { + [oneOnOneCreatedActionForChat.reportActionID]: oneOnOneCreatedActionForChat, + }, + }, + ]), { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`, + onyxMethod: existingOneOnOneIOUReport ? Onyx.METHOD.MERGE : Onyx.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneIOUReport.reportID}`, value: { - ...(existingOneOnOneChatReport ? {} : {[oneOnOneCreatedReportAction.reportActionID]: {pendingAction: null}}), - [oneOnOneIOUReportAction.reportActionID]: {pendingAction: null}, + ...(existingOneOnOneIOUReport ? {} : {[oneOnOneCreatedActionForIOU.reportActionID]: oneOnOneCreatedActionForIOU}), + [oneOnOneIOUAction.reportActionID]: oneOnOneIOUAction, }, }, + ); + + successData.push( + ...(existingOneOnOneChatReport + ? [] + : [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`, + value: { + pendingFields: null, + errorFields: null, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`, + value: { + [oneOnOneCreatedActionForChat.reportActionID]: { + pendingAction: null, + errors: null, + }, + }, + }, + ]), + ...(existingOneOnOneIOUReport + ? [] + : [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneIOUReport.reportID}`, + value: { + pendingFields: null, + errorFields: null, + }, + }, + ]), { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.TRANSACTION}${oneOnOneTransaction.transactionID}`, value: {pendingAction: null}, }, - ); - - if (!existingOneOnOneChatReport) { - successData.push({ + { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`, - value: {pendingFields: {createChat: null}}, - }); - } + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneIOUReport.reportID}`, + value: { + ...(existingOneOnOneIOUReport + ? {} + : { + [oneOnOneCreatedActionForIOU.reportActionID]: { + pendingAction: null, + errors: null, + }, + }), + [oneOnOneIOUAction.reportActionID]: { + pendingAction: null, + errors: null, + }, + }, + }, + ); failureData.push( { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`, value: { - [oneOnOneIOUReportAction.reportActionID]: { - errors: { - [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.genericCreateFailureMessage'), - }, - }, + hasOutstandingIOU: oneOnOneChatReport.hasOutstandingIOU, + lastReadTime: oneOnOneChatReport.lastReadTime, + iouReportID: oneOnOneChatReport.iouReportID, + ...(existingOneOnOneChatReport + ? {} + : { + errorFields: { + createChat: { + [DateUtils.getMicroseconds()]: Localize.translateLocal('report.genericCreateReportFailureMessage'), + }, + }, + }), }, }, + ...(existingOneOnOneIOUReport + ? [] + : [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneIOUReport.reportID}`, + value: { + errorFields: { + createChat: { + [DateUtils.getMicroseconds()]: Localize.translateLocal('report.genericCreateReportFailureMessage'), + }, + }, + }, + }, + ]), { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.TRANSACTION}${oneOnOneTransaction.transactionID}`, @@ -508,23 +680,43 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment }, }, }, - ); - - if (!existingOneOnOneChatReport) { - failureData.push({ + ...(existingOneOnOneChatReport + ? [] + : [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`, + value: { + [oneOnOneCreatedActionForChat.reportActionID]: { + errors: { + [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.genericCreateFailureMessage'), + }, + }, + }, + }, + ]), + { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneIOUReport.reportID}`, value: { - hasOutstandingIOU: existingOneOnOneChatReport ? existingOneOnOneChatReport.hasOutstandingIOU : false, - iouReportID: existingOneOnOneChatReport ? existingOneOnOneChatReport.iouReportID : null, - errorFields: { - createChat: { - [DateUtils.getMicroseconds()]: Localize.translateLocal('report.genericCreateReportFailureMessage'), - }, - }, + ...(existingOneOnOneIOUReport + ? { + [oneOnOneIOUAction.reportActionID]: { + errors: { + [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.genericCreateFailureMessage'), + }, + }, + } + : { + [oneOnOneCreatedActionForIOU.reportActionID]: { + errors: { + [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.genericCreateFailureMessage'), + }, + }, + }), }, - }); - } + }, + ); // Regardless of the number of participants, we always want to push the iouReport update to onyxData optimisticData.push({ @@ -539,7 +731,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment failureData.push({ onyxMethod: Onyx.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneIOUReport.reportID}`, - value: existingIOUReport || oneOnOneIOUReport, + value: existingOneOnOneIOUReport || oneOnOneIOUReport, }); const splitData = { @@ -548,11 +740,13 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment iouReportID: oneOnOneIOUReport.reportID, chatReportID: oneOnOneChatReport.reportID, transactionID: oneOnOneTransaction.transactionID, - reportActionID: oneOnOneIOUReportAction.reportActionID, + createdChatReportActionID: oneOnOneCreatedActionForChat.reportActionID, + createdIOUReportActionID: oneOnOneCreatedActionForIOU.reportActionID, + reportActionID: oneOnOneIOUAction.reportActionID, }; - if (!_.isEmpty(oneOnOneCreatedReportAction)) { - splitData.createdReportActionID = oneOnOneCreatedReportAction.reportActionID; + if (!_.isEmpty(oneOnOneCreatedActionForChat)) { + splitData.createdReportActionID = oneOnOneCreatedActionForChat.reportActionID; } splits.push(splitData); @@ -644,12 +838,9 @@ function deleteMoneyRequest(chatReportID, iouReportID, moneyRequestAction, shoul const iouReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT}${iouReportID}`]; const transactionID = moneyRequestAction.originalMessage.IOUTransactionID; - // Make a copy of the chat report so we don't mutate the original one when updating its values - const chatReport = {...chatReports[`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`]}; - // Get the amount we are deleting const amount = moneyRequestAction.originalMessage.amount; - const optimisticReportAction = ReportUtils.buildOptimisticIOUReportAction( + const optimisticIOUAction = ReportUtils.buildOptimisticIOUReportAction( CONST.IOU.REPORT_ACTION_TYPE.DELETE, amount, moneyRequestAction.originalMessage.currency, @@ -660,28 +851,31 @@ function deleteMoneyRequest(chatReportID, iouReportID, moneyRequestAction, shoul iouReportID, ); - const currentUserEmail = optimisticReportAction.actorEmail; - const updatedIOUReport = IOUUtils.updateIOUOwnerAndTotal(iouReport, currentUserEmail, amount, moneyRequestAction.originalMessage.currency, CONST.IOU.REPORT_ACTION_TYPE.DELETE); - chatReport.lastMessageText = optimisticReportAction.message[0].text; - chatReport.lastMessageHtml = optimisticReportAction.message[0].html; - chatReport.hasOutstandingIOU = updatedIOUReport.total !== 0; + const currentUserEmail = optimisticIOUAction.actorEmail; + let updatedIOUReport = {}; + if (ReportUtils.isExpenseReport(iouReportID)) { + updatedIOUReport = {...iouReport}; + + // Because of the Expense reports are stored as negative values, we add the total from the amount + updatedIOUReport.total += amount; + } else { + updatedIOUReport = IOUUtils.updateIOUOwnerAndTotal(iouReport, currentUserEmail, amount, moneyRequestAction.originalMessage.currency, CONST.IOU.REPORT_ACTION_TYPE.DELETE); + } + updatedIOUReport.lastMessageText = optimisticIOUAction.message[0].text; + updatedIOUReport.lastMessageHtml = optimisticIOUAction.message[0].html; + updatedIOUReport.hasOutstandingIOU = updatedIOUReport.total !== 0; const optimisticData = [ { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`, value: { - [optimisticReportAction.reportActionID]: { - ...optimisticReportAction, + [optimisticIOUAction.reportActionID]: { + ...optimisticIOUAction, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, }, }, }, - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`, - value: chatReport, - }, { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${iouReportID}`, @@ -696,9 +890,9 @@ function deleteMoneyRequest(chatReportID, iouReportID, moneyRequestAction, shoul const successData = [ { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`, value: { - [optimisticReportAction.reportActionID]: { + [optimisticIOUAction.reportActionID]: { pendingAction: null, }, }, @@ -707,24 +901,15 @@ function deleteMoneyRequest(chatReportID, iouReportID, moneyRequestAction, shoul const failureData = [ { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`, value: { - [optimisticReportAction.reportActionID]: { + [optimisticIOUAction.reportActionID]: { errors: { [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.genericDeleteFailureMessage'), }, }, }, }, - { - onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`, - value: { - lastMessageText: chatReports[`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`].lastMessageText, - lastMessageHtml: chatReports[`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`].lastMessageHtml, - hasOutstandingIOU: iouReport.total !== 0, - }, - }, { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${iouReportID}`, @@ -742,14 +927,14 @@ function deleteMoneyRequest(chatReportID, iouReportID, moneyRequestAction, shoul { transactionID, chatReportID, - reportActionID: optimisticReportAction.reportActionID, + reportActionID: optimisticIOUAction.reportActionID, iouReportID: updatedIOUReport.reportID, }, {optimisticData, successData, failureData}, ); if (shouldCloseOnDelete) { - Navigation.navigate(ROUTES.getReportRoute(chatReportID)); + Navigation.navigate(ROUTES.getReportRoute(iouReportID)); } } @@ -841,18 +1026,20 @@ function getSendMoneyParams(report, amount, currency, comment, paymentMethodType ...chatReport, lastReadTime: DateUtils.getDBTime(), lastVisibleActionCreated: optimisticIOUReportAction.created, - lastMessageText: optimisticIOUReportAction.message[0].text, - lastMessageHtml: optimisticIOUReportAction.message[0].html, }, }; const optimisticIOUReportData = { onyxMethod: Onyx.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT}${optimisticIOUReport.reportID}`, - value: optimisticIOUReport, + value: { + ...optimisticIOUReport, + lastMessageText: optimisticIOUReportAction.message[0].text, + lastMessageHtml: optimisticIOUReportAction.message[0].html, + }, }; const optimisticReportActionsData = { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${optimisticIOUReport.reportID}`, value: { [optimisticIOUReportAction.reportActionID]: { ...optimisticIOUReportAction, @@ -864,7 +1051,7 @@ function getSendMoneyParams(report, amount, currency, comment, paymentMethodType const successData = [ { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${optimisticIOUReport.reportID}`, value: { [optimisticIOUReportAction.reportActionID]: { pendingAction: null, @@ -881,7 +1068,7 @@ function getSendMoneyParams(report, amount, currency, comment, paymentMethodType const failureData = [ { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${optimisticIOUReport.reportID}`, value: { [optimisticIOUReportAction.reportActionID]: { errors: { @@ -894,7 +1081,6 @@ function getSendMoneyParams(report, amount, currency, comment, paymentMethodType onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.TRANSACTION}${optimisticTransaction.transactionID}`, value: { - pendingAction: null, errors: { [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.other'), }, @@ -983,15 +1169,13 @@ function getPayMoneyRequestParams(chatReport, iouReport, recipient, paymentMetho ...chatReport, lastReadTime: DateUtils.getDBTime(), lastVisibleActionCreated: optimisticIOUReportAction.created, - lastMessageText: optimisticIOUReportAction.message[0].text, - lastMessageHtml: optimisticIOUReportAction.message[0].html, hasOutstandingIOU: false, iouReportID: null, }, }, { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`, value: { [optimisticIOUReportAction.reportActionID]: { ...optimisticIOUReportAction, @@ -1004,6 +1188,8 @@ function getPayMoneyRequestParams(chatReport, iouReport, recipient, paymentMetho key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport.reportID}`, value: { ...iouReport, + lastMessageText: optimisticIOUReportAction.message[0].text, + lastMessageHtml: optimisticIOUReportAction.message[0].html, hasOutstandingIOU: false, stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, }, @@ -1018,7 +1204,7 @@ function getPayMoneyRequestParams(chatReport, iouReport, recipient, paymentMetho const successData = [ { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`, value: { [optimisticIOUReportAction.reportActionID]: { pendingAction: null, @@ -1037,10 +1223,9 @@ function getPayMoneyRequestParams(chatReport, iouReport, recipient, paymentMetho const failureData = [ { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`, value: { [optimisticIOUReportAction.reportActionID]: { - pendingAction: null, errors: { [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.other'), }, @@ -1051,7 +1236,6 @@ function getPayMoneyRequestParams(chatReport, iouReport, recipient, paymentMetho onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.TRANSACTION}${optimisticTransaction.transactionID}`, value: { - pendingAction: null, errors: { [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.genericCreateFailureMessage'), }, diff --git a/src/pages/iou/IOUDetailsModal.js b/src/pages/iou/IOUDetailsModal.js index 3403bf83fb23..f81fe53fb492 100644 --- a/src/pages/iou/IOUDetailsModal.js +++ b/src/pages/iou/IOUDetailsModal.js @@ -186,7 +186,7 @@ class IOUDetailsModal extends Component { 1} + isBillSplit={lodashGet(this.props.chatReport, 'participants', []).length > 1} isIOUAction={false} pendingAction={pendingAction} /> diff --git a/tests/actions/IOUTest.js b/tests/actions/IOUTest.js index 7d18f5fe77d5..aee969e865a1 100644 --- a/tests/actions/IOUTest.js +++ b/tests/actions/IOUTest.js @@ -32,7 +32,6 @@ describe('actions/IOU', () => { it('creates new chat if needed', () => { const amount = 10000; const comment = 'Giv money plz'; - let chatReportID; let iouReportID; let createdAction; let iouAction; @@ -55,7 +54,6 @@ describe('actions/IOU', () => { expect(_.size(chatReports)).toBe(1); expect(_.size(iouReports)).toBe(1); const chatReport = chatReports[0]; - chatReportID = chatReport.reportID; const iouReport = iouReports[0]; iouReportID = iouReport.reportID; @@ -73,15 +71,15 @@ describe('actions/IOU', () => { () => new Promise((resolve) => { const connectionID = Onyx.connect({ - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`, waitForCollectionCallback: true, - callback: (reportActionsForChatReport) => { + callback: (reportActionsForIOUReport) => { Onyx.disconnect(connectionID); - // The chat report should have a CREATED action and IOU action - expect(_.size(reportActionsForChatReport)).toBe(2); - const createdActions = _.filter(reportActionsForChatReport, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED); - const iouActions = _.filter(reportActionsForChatReport, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); + // The IOU report should have a CREATED action and IOU action + expect(_.size(reportActionsForIOUReport)).toBe(2); + const createdActions = _.filter(reportActionsForIOUReport, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED); + const iouActions = _.filter(reportActionsForIOUReport, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); expect(_.size(createdActions)).toBe(1); expect(_.size(iouActions)).toBe(1); createdAction = createdActions[0]; @@ -152,12 +150,12 @@ describe('actions/IOU', () => { () => new Promise((resolve) => { const connectionID = Onyx.connect({ - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`, waitForCollectionCallback: true, - callback: (reportActionsForChatReport) => { + callback: (reportActionsForIOUReport) => { Onyx.disconnect(connectionID); - expect(_.size(reportActionsForChatReport)).toBe(2); - _.each(reportActionsForChatReport, (reportAction) => expect(reportAction.pendingAction).toBeFalsy()); + expect(_.size(reportActionsForIOUReport)).toBe(2); + _.each(reportActionsForIOUReport, (reportAction) => expect(reportAction.pendingAction).toBeFalsy()); resolve(); }, }); @@ -236,14 +234,14 @@ describe('actions/IOU', () => { () => new Promise((resolve) => { const connectionID = Onyx.connect({ - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`, waitForCollectionCallback: true, - callback: (allReportActions) => { + callback: (allIOUReportActions) => { Onyx.disconnect(connectionID); // The chat report should have a CREATED and an IOU action - expect(_.size(allReportActions)).toBe(2); - iouAction = _.find(allReportActions, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); + expect(_.size(allIOUReportActions)).toBe(2); + iouAction = _.find(allIOUReportActions, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); // The CREATED action should not be created after the IOU action expect(Date.parse(createdAction.created)).toBeLessThanOrEqual(Date.parse(iouAction.created)); @@ -309,12 +307,12 @@ describe('actions/IOU', () => { () => new Promise((resolve) => { const connectionID = Onyx.connect({ - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`, waitForCollectionCallback: true, - callback: (reportActionsForChatReport) => { + callback: (reportActionsForIOUReport) => { Onyx.disconnect(connectionID); - expect(_.size(reportActionsForChatReport)).toBe(2); - _.each(reportActionsForChatReport, (reportAction) => expect(reportAction.pendingAction).toBeFalsy()); + expect(_.size(reportActionsForIOUReport)).toBe(2); + _.each(reportActionsForIOUReport, (reportAction) => expect(reportAction.pendingAction).toBeFalsy()); resolve(); }, }); @@ -388,7 +386,7 @@ describe('actions/IOU', () => { return Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`, chatReport) .then(() => Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${iouReportID}`, iouReport)) .then(() => - Onyx.set(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReportID}`, { + Onyx.set(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`, { [createdAction.reportActionID]: createdAction, [iouAction.reportActionID]: iouAction, }), @@ -427,14 +425,14 @@ describe('actions/IOU', () => { () => new Promise((resolve) => { const connectionID = Onyx.connect({ - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`, waitForCollectionCallback: true, - callback: (reportActionsForChatReport) => { + callback: (reportActionsForIOUReport) => { Onyx.disconnect(connectionID); - expect(_.size(reportActionsForChatReport)).toBe(3); + expect(_.size(reportActionsForIOUReport)).toBe(3); newIOUAction = _.find( - reportActionsForChatReport, + reportActionsForIOUReport, (reportAction) => reportAction.reportActionID !== createdAction.reportActionID && reportAction.reportActionID !== iouAction.reportActionID, ); @@ -491,12 +489,12 @@ describe('actions/IOU', () => { () => new Promise((resolve) => { const connectionID = Onyx.connect({ - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`, waitForCollectionCallback: true, - callback: (reportActionsForChatReport) => { + callback: (reportActionsForIOUReport) => { Onyx.disconnect(connectionID); - expect(_.size(reportActionsForChatReport)).toBe(3); - _.each(reportActionsForChatReport, (reportAction) => expect(reportAction.pendingAction).toBeFalsy()); + expect(_.size(reportActionsForIOUReport)).toBe(3); + _.each(reportActionsForIOUReport, (reportAction) => expect(reportAction.pendingAction).toBeFalsy()); resolve(); }, }); @@ -563,15 +561,15 @@ describe('actions/IOU', () => { () => new Promise((resolve) => { const connectionID = Onyx.connect({ - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`, waitForCollectionCallback: true, - callback: (reportActionsForChatReport) => { + callback: (reportActionsForIOUReport) => { Onyx.disconnect(connectionID); // The chat report should have a CREATED action and IOU action - expect(_.size(reportActionsForChatReport)).toBe(2); - const createdActions = _.filter(reportActionsForChatReport, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED); - const iouActions = _.filter(reportActionsForChatReport, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); + expect(_.size(reportActionsForIOUReport)).toBe(2); + const createdActions = _.filter(reportActionsForIOUReport, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED); + const iouActions = _.filter(reportActionsForIOUReport, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); expect(_.size(createdActions)).toBe(1); expect(_.size(iouActions)).toBe(1); createdAction = createdActions[0]; @@ -637,12 +635,12 @@ describe('actions/IOU', () => { () => new Promise((resolve) => { const connectionID = Onyx.connect({ - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`, waitForCollectionCallback: true, - callback: (reportActionsForChatReport) => { + callback: (reportActionsForIOUReport) => { Onyx.disconnect(connectionID); - expect(_.size(reportActionsForChatReport)).toBe(2); - iouAction = _.find(reportActionsForChatReport, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); + expect(_.size(reportActionsForIOUReport)).toBe(2); + iouAction = _.find(reportActionsForIOUReport, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); expect(iouAction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD); resolve(); }, @@ -670,7 +668,7 @@ describe('actions/IOU', () => { .then( () => new Promise((resolve) => { - ReportActions.clearReportActionErrors(chatReportID, iouAction); + ReportActions.clearReportActionErrors(iouReportID, iouAction); resolve(); }), ) @@ -801,6 +799,11 @@ describe('actions/IOU', () => { iouReportID: julesIOUReportID, participants: [JULES_EMAIL], }; + const julesChatCreatedAction = { + reportActionID: NumberUtils.rand64(), + actionName: CONST.REPORT.ACTIONS.TYPE.CREATED, + created: DateUtils.getDBTime(), + }; const julesCreatedAction = { reportActionID: NumberUtils.rand64(), actionName: CONST.REPORT.ACTIONS.TYPE.CREATED, @@ -866,6 +869,9 @@ describe('actions/IOU', () => { [carlosCreatedAction.reportActionID]: carlosCreatedAction, }, [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${julesChatReport.reportID}`]: { + [julesChatCreatedAction.reportActionID]: julesChatCreatedAction, + }, + [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${julesIOUReport.reportID}`]: { [julesCreatedAction.reportActionID]: julesCreatedAction, [julesExistingIOUAction.reportActionID]: julesExistingIOUAction, }, @@ -962,17 +968,16 @@ describe('actions/IOU', () => { callback: (allReportActions) => { Onyx.disconnect(connectionID); - // There should be reportActions on all 4 chat reports - expect(_.size(allReportActions)).toBe(4); + // There should be reportActions on all 4 chat reports + 3 IOU reports in each 1:1 chat + expect(_.size(allReportActions)).toBe(7); - const carlosReportActions = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${carlosChatReport.reportID}`]; - const julesReportActions = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${julesChatReport.reportID}`]; - const vitReportActions = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${vitChatReport.reportID}`]; + const carlosReportActions = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${carlosChatReport.iouReportID}`]; + const julesReportActions = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${julesChatReport.iouReportID}`]; + const vitReportActions = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${vitChatReport.iouReportID}`]; const groupReportActions = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${groupChat.reportID}`]; - // Carlos DM should have two reportActions – the existing CREATED action and an pending IOU action + // Carlos DM should have two reportActions – the existing CREATED action and a pending IOU action expect(_.size(carlosReportActions)).toBe(2); - expect(carlosReportActions[carlosCreatedAction.reportActionID]).toStrictEqual(carlosCreatedAction); carlosIOUAction = _.find(carlosReportActions, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); expect(carlosIOUAction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD); expect(carlosIOUAction.originalMessage.IOUReportID).toBe(carlosIOUReport.reportID); @@ -1193,9 +1198,9 @@ describe('actions/IOU', () => { callback: (allReportActions) => { Onyx.disconnect(connectionID); - const reportActionsForChatReport = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`]; + const reportActionsForIOUReport = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.iouReportID}`]; - createIOUAction = _.find(reportActionsForChatReport, (ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); + createIOUAction = _.find(reportActionsForIOUReport, (ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); expect(createIOUAction).toBeTruthy(); expect(createIOUAction.originalMessage.IOUReportID).toBe(iouReport.reportID); @@ -1263,11 +1268,11 @@ describe('actions/IOU', () => { callback: (allReportActions) => { Onyx.disconnect(connectionID); - const reportActionsForChatReport = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`]; - expect(_.size(reportActionsForChatReport)).toBe(3); + const reportActionsForIOUReport = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`]; + expect(_.size(reportActionsForIOUReport)).toBe(3); payIOUAction = _.find( - reportActionsForChatReport, + reportActionsForIOUReport, (ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU && ra.originalMessage.type === CONST.IOU.REPORT_ACTION_TYPE.PAY, ); expect(payIOUAction).toBeTruthy(); @@ -1314,11 +1319,11 @@ describe('actions/IOU', () => { callback: (allReportActions) => { Onyx.disconnect(connectionID); - const reportActionsForChatReport = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`]; - expect(_.size(reportActionsForChatReport)).toBe(3); + const reportActionsForIOUReport = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`]; + expect(_.size(reportActionsForIOUReport)).toBe(3); payIOUAction = _.find( - reportActionsForChatReport, + reportActionsForIOUReport, (ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU && ra.originalMessage.type === CONST.IOU.REPORT_ACTION_TYPE.PAY, ); expect(payIOUAction).toBeTruthy();