From 71a989b8a84405330aabf5bfac73de481848860e Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 4 Oct 2022 17:37:45 -0600 Subject: [PATCH 001/100] create splitBill --- src/libs/actions/IOU.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 29ad11eef5c9..103a3bec7cee 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -320,6 +320,10 @@ function payIOUReport({ return promiseWithHandlers; } +function splitBill() { + +} + export { createIOUTransaction, createIOUSplit, @@ -327,4 +331,5 @@ export { rejectTransaction, payIOUReport, setIOUSelectedCurrency, + splitBill, }; From 96e0e4e7965772d15ed115e075142e6013b20d6c Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 5 Oct 2022 10:08:09 -0600 Subject: [PATCH 002/100] rename API commands --- src/libs/actions/IOU.js | 65 +++------------------------------------ src/libs/deprecatedAPI.js | 18 ----------- src/pages/iou/IOUModal.js | 4 +-- 3 files changed, 6 insertions(+), 81 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 103a3bec7cee..68ce0641ab59 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -130,47 +130,8 @@ function createIOUTransaction(params) { * @param {Number} params.amount * @param {String} params.currency */ -function createIOUSplit(params) { - startLoadingAndResetError(); - - let chatReportID; - DeprecatedAPI.CreateChatReport({ - emailList: _.map(params.splits, participant => participant.email).join(','), - }) - .then((response) => { - if (response.jsonCode !== 200) { - return response; - } +function splitBill(params) { - chatReportID = response.reportID; - return DeprecatedAPI.CreateIOUSplit({ - ...params, - splits: JSON.stringify(params.splits), - reportID: response.reportID, - }); - }) - .then((response) => { - if (response.jsonCode !== 200) { - processIOUErrorResponse(response); - return; - } - - // This data needs to go from this: - // {reportIDList: [1, 2], chatReportIDList: [3, 4]} - // to this: - // [{reportID: 1, chatReportID: 3}, {reportID: 2, chatReportID: 4}] - // in order for getIOUReportsForNewTransaction to know which IOU reports are associated with which - // chat reports - const reportParams = []; - for (let i = 0; i < response.reportIDList.length; i++) { - reportParams.push({ - reportID: response.reportIDList[i], - chatReportID: response.chatReportIDList[i], - }); - } - getIOUReportsForNewTransaction(reportParams); - Navigation.navigate(ROUTES.getReportRoute(chatReportID)); - }); } /** @@ -183,21 +144,8 @@ function createIOUSplit(params) { * @param {String} params.currency * @param {String} params.reportID */ -function createIOUSplitGroup(params) { - startLoadingAndResetError(); +function splitBillAndOpenReport(params) { - DeprecatedAPI.CreateIOUSplit({ - ...params, - splits: JSON.stringify(params.splits), - }) - .then((response) => { - if (response.jsonCode !== 200) { - Onyx.merge(ONYXKEYS.IOU, {error: true}); - return; - } - - Onyx.merge(ONYXKEYS.IOU, {loading: false, creatingIOUTransaction: false}); - }); } /** @@ -320,16 +268,11 @@ function payIOUReport({ return promiseWithHandlers; } -function splitBill() { - -} - export { createIOUTransaction, - createIOUSplit, - createIOUSplitGroup, + splitBill, + splitBillAndOpenReport, rejectTransaction, payIOUReport, setIOUSelectedCurrency, - splitBill, }; diff --git a/src/libs/deprecatedAPI.js b/src/libs/deprecatedAPI.js index 68caeea5443d..7b62e805d4dc 100644 --- a/src/libs/deprecatedAPI.js +++ b/src/libs/deprecatedAPI.js @@ -340,23 +340,6 @@ function CreateIOUTransaction(parameters) { return Network.post(commandName, parameters); } -/** - * Create a new IOU Split - * - * @param {Object} parameters - * @param {String} parameters.splits - * @param {String} parameters.currency - * @param {String} parameters.reportID - * @param {String} parameters.amount - * @param {String} parameters.comment - * @returns {Promise} - */ -function CreateIOUSplit(parameters) { - const commandName = 'CreateIOUSplit'; - requireParameters(['splits', 'currency', 'amount', 'reportID'], parameters, commandName); - return Network.post(commandName, parameters); -} - /** * @param {String} firstName * @param {String} lastName @@ -595,7 +578,6 @@ export { User_SecondaryLogin_Send, User_UploadAvatar, CreateIOUTransaction, - CreateIOUSplit, ValidateEmail, Wallet_Activate, Wallet_GetOnfidoSDKToken, diff --git a/src/pages/iou/IOUModal.js b/src/pages/iou/IOUModal.js index f2d35ae2a0a5..db9006437641 100755 --- a/src/pages/iou/IOUModal.js +++ b/src/pages/iou/IOUModal.js @@ -319,7 +319,7 @@ class IOUModal extends Component { // Only splits from a group DM has a reportID // Check if reportID is a number if (splits && CONST.REGEX.NUMBER.test(reportID)) { - IOU.createIOUSplitGroup({ + IOU.splitBillAndOpenReport({ comment: this.state.comment, // should send in cents to API @@ -332,7 +332,7 @@ class IOUModal extends Component { } if (splits) { - IOU.createIOUSplit({ + IOU.splitBill({ comment: this.state.comment, // Send in cents to API. From e662ea6541d205cf7435829163644d2e0ff38c56 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 5 Oct 2022 10:33:47 -0600 Subject: [PATCH 003/100] steps --- src/libs/actions/IOU.js | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 68ce0641ab59..ef83018afa26 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -1,5 +1,6 @@ import Onyx from 'react-native-onyx'; import _ from 'underscore'; +import lodashGet from 'lodash/get'; import CONST from '../../CONST'; import ONYXKEYS from '../../ONYXKEYS'; import ROUTES from '../../ROUTES'; @@ -10,6 +11,9 @@ import Growl from '../Growl'; import * as Localize from '../Localize'; import asyncOpenURL from '../asyncOpenURL'; import Log from '../Log'; +import * as API from '../API'; +import * as ReportUtils from '../ReportUtils'; +import * as NumberUtils from '../NumberUtils'; /** * Gets the IOU Reports for new transaction @@ -121,17 +125,19 @@ function createIOUTransaction(params) { }); } -/** - * Creates IOUSplit Transaction - * - * @param {Object} params - * @param {Array} params.splits - * @param {String} params.comment - * @param {Number} params.amount - * @param {String} params.currency - */ -function splitBill(params) { +function splitBill(report, participants) { + // Create or get group chat + const groupChatReport = lodashGet(report, 'reportID', null) ? report : ReportUtils.buildOptimisticChatReport(participants); + + // Create or get group iouReport + + // Create or get group reportActionID + + // Create or get individual chats + // Create or get individual iouReports + // Create or get individual reportActionIDs + // Call API } /** From 20ea8d5511034ed20dcdd78269789e920df30b98 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 5 Oct 2022 15:32:53 -0600 Subject: [PATCH 004/100] create group chat and reportaction --- src/libs/actions/IOU.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index ef83018afa26..365c01652f31 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -125,19 +125,17 @@ function createIOUTransaction(params) { }); } -function splitBill(report, participants) { +function splitBill(report, participants, amount, currentUserEmail) { // Create or get group chat const groupChatReport = lodashGet(report, 'reportID', null) ? report : ReportUtils.buildOptimisticChatReport(participants); - // Create or get group iouReport - // Create or get group reportActionID + const groupReportAction = ReportUtils.buildOptimisticIOUReportAction( + lodashGet(groupChatReport, 'maxSequenceNumber', 0) + 1, + 'create', + amount, + ); - // Create or get individual chats - // Create or get individual iouReports - // Create or get individual reportActionIDs - - // Call API } /** From 32c67a56ebcb5eb91463e2afa3bb8ee94c6f8850 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 5 Oct 2022 15:34:25 -0600 Subject: [PATCH 005/100] connect iouReports --- src/libs/actions/IOU.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 365c01652f31..613f29c0fb8b 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -15,6 +15,18 @@ import * as API from '../API'; import * as ReportUtils from '../ReportUtils'; import * as NumberUtils from '../NumberUtils'; +const iouReports = {}; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT_IOUS, + callback: (iouReport, key) => { + if (!iouReport || !key || !iouReport.ownerEmail) { + return; + } + + iouReports[key] = iouReport; + }, +}); + /** * Gets the IOU Reports for new transaction * @@ -136,6 +148,18 @@ function splitBill(report, participants, amount, currentUserEmail) { amount, ); + // Loop through participants creating individual chats, iouReports and reportActionIDs as needed + const splitAmount = amount / participants.length; + _.each(participants, (email) => { + if (email === currentUserEmail) { + return; + } + + const oneOnOneReport = lodashGet(report, 'reportID', null) ? report : ReportUtils.buildOptimisticChatReport([currentUserEmail, email]); + // let oneOnOneIOUReport = lodashGet(oneOnOneReport, 'iouReportID', null) ? iouReport : ReportUtils.buildOptimisticIOUReport(currentUserEmail, email, splitAmount, oneOnOneReport.reportID,) + }); + + // Call API } /** From fbab3edc54ece267833227eadd070de0e001602d Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 5 Oct 2022 15:43:51 -0600 Subject: [PATCH 006/100] add optimistic ioureports and reportactions --- src/libs/actions/IOU.js | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 613f29c0fb8b..0b5a2ce8f9f7 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -137,7 +137,7 @@ function createIOUTransaction(params) { }); } -function splitBill(report, participants, amount, currentUserEmail) { +function splitBill(report, participants, amount, currency, currentUserEmail, locale, comment) { // Create or get group chat const groupChatReport = lodashGet(report, 'reportID', null) ? report : ReportUtils.buildOptimisticChatReport(participants); @@ -146,6 +146,7 @@ function splitBill(report, participants, amount, currentUserEmail) { lodashGet(groupChatReport, 'maxSequenceNumber', 0) + 1, 'create', amount, + comment, ); // Loop through participants creating individual chats, iouReports and reportActionIDs as needed @@ -155,8 +156,33 @@ function splitBill(report, participants, amount, currentUserEmail) { return; } + // Chat report const oneOnOneReport = lodashGet(report, 'reportID', null) ? report : ReportUtils.buildOptimisticChatReport([currentUserEmail, email]); - // let oneOnOneIOUReport = lodashGet(oneOnOneReport, 'iouReportID', null) ? iouReport : ReportUtils.buildOptimisticIOUReport(currentUserEmail, email, splitAmount, oneOnOneReport.reportID,) + + // iouReport + let oneOnOneIOUReport; + if (oneOnOneReport.iouReportID) { + oneOnOneIOUReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneReport.iouReportID}`]; + oneOnOneIOUReport.total += splitAmount; + } else { + oneOnOneIOUReport = ReportUtils.buildOptimisticIOUReport( + currentUserEmail, + email, + splitAmount, + oneOnOneReport.reportID, + currency, + locale, + ); + } + + // reportAction + const oneOnOneIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( + lodashGet(oneOnOneReport, 'maxSequenceNumber', 0) + 1, + 'create', + amount, + currency, + comment, + ); }); // Call API From 4b3e33b39fa90a48484490fb88123c407a94bc4d Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 5 Oct 2022 16:11:56 -0600 Subject: [PATCH 007/100] build optimisticData --- src/libs/actions/IOU.js | 48 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 0b5a2ce8f9f7..30f159644075 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -149,6 +149,23 @@ function splitBill(report, participants, amount, currency, currentUserEmail, loc comment, ); + // Define optimisticData + // @TODO: Add RBR pendingAction + const optimisticData = [ + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${groupChatReport.reportID}`, + value: groupChatReport, + }, + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${groupChatReport.reportID}`, + value: { + [groupReportAction.sequenceNumber]: groupReportAction, + }, + }, + ]; + // Loop through participants creating individual chats, iouReports and reportActionIDs as needed const splitAmount = amount / participants.length; _.each(participants, (email) => { @@ -157,19 +174,19 @@ function splitBill(report, participants, amount, currency, currentUserEmail, loc } // Chat report - const oneOnOneReport = lodashGet(report, 'reportID', null) ? report : ReportUtils.buildOptimisticChatReport([currentUserEmail, email]); + const oneOnOneChatReport = lodashGet(report, 'reportID', null) ? report : ReportUtils.buildOptimisticChatReport([currentUserEmail, email]); // iouReport let oneOnOneIOUReport; - if (oneOnOneReport.iouReportID) { - oneOnOneIOUReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneReport.iouReportID}`]; + if (oneOnOneChatReport.iouReportID) { + oneOnOneIOUReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneChatReport.iouReportID}`]; oneOnOneIOUReport.total += splitAmount; } else { oneOnOneIOUReport = ReportUtils.buildOptimisticIOUReport( currentUserEmail, email, splitAmount, - oneOnOneReport.reportID, + oneOnOneChatReport.reportID, currency, locale, ); @@ -177,12 +194,33 @@ function splitBill(report, participants, amount, currency, currentUserEmail, loc // reportAction const oneOnOneIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( - lodashGet(oneOnOneReport, 'maxSequenceNumber', 0) + 1, + lodashGet(oneOnOneChatReport, 'maxSequenceNumber', 0) + 1, 'create', amount, currency, comment, ); + + // @TODO: Add RBR pendingAction + optimisticData.push( + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`, + value: oneOnOneChatReport, + }, + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneChatReport.reportID}`, + value: oneOnOneIOUReport, + }, + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`, + value: { + [oneOnOneIOUReportAction.sequenceNumber]: oneOnOneIOUReportAction, + }, + }, + ); }); // Call API From f74f96794a650c2ece26656bee382ffe06ad10b2 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 5 Oct 2022 16:15:00 -0600 Subject: [PATCH 008/100] call api --- src/libs/actions/IOU.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 30f159644075..d59e37094f82 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -224,6 +224,7 @@ function splitBill(report, participants, amount, currency, currentUserEmail, loc }); // Call API + API.write('SplitBill', params, {optimisticData}); } /** From 833a17d84b7eb73257b27d4afdfa4376be560146 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 5 Oct 2022 16:20:03 -0600 Subject: [PATCH 009/100] create buildSplitBillOnyxData --- src/libs/actions/IOU.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index d59e37094f82..5b4937a056d2 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -137,7 +137,7 @@ function createIOUTransaction(params) { }); } -function splitBill(report, participants, amount, currency, currentUserEmail, locale, comment) { +function buildSplitBillOnyxData(report, participants, amount, comment, currentUserEmail, currency, locale) { // Create or get group chat const groupChatReport = lodashGet(report, 'reportID', null) ? report : ReportUtils.buildOptimisticChatReport(participants); @@ -222,9 +222,15 @@ function splitBill(report, participants, amount, currency, currentUserEmail, loc }, ); }); +} + +function splitBill(report, participants, amount, currency, currentUserEmail, locale, comment) { + const onyxData = buildSplitBillOnyxData(report, participants, amount, comment, currentUserEmail, currency, locale); // Call API - API.write('SplitBill', params, {optimisticData}); + API.write('SplitBill', params, { + optimisticData: onyxData.optimisticData + }); } /** From db7654cea71523f971118cdb34c094efca608bf8 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 5 Oct 2022 16:25:25 -0600 Subject: [PATCH 010/100] rm comments --- src/libs/actions/IOU.js | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 5b4937a056d2..eaca6a79a739 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -138,10 +138,7 @@ function createIOUTransaction(params) { } function buildSplitBillOnyxData(report, participants, amount, comment, currentUserEmail, currency, locale) { - // Create or get group chat const groupChatReport = lodashGet(report, 'reportID', null) ? report : ReportUtils.buildOptimisticChatReport(participants); - - // Create or get group reportActionID const groupReportAction = ReportUtils.buildOptimisticIOUReportAction( lodashGet(groupChatReport, 'maxSequenceNumber', 0) + 1, 'create', @@ -149,7 +146,6 @@ function buildSplitBillOnyxData(report, participants, amount, comment, currentUs comment, ); - // Define optimisticData // @TODO: Add RBR pendingAction const optimisticData = [ { @@ -173,10 +169,7 @@ function buildSplitBillOnyxData(report, participants, amount, comment, currentUs return; } - // Chat report const oneOnOneChatReport = lodashGet(report, 'reportID', null) ? report : ReportUtils.buildOptimisticChatReport([currentUserEmail, email]); - - // iouReport let oneOnOneIOUReport; if (oneOnOneChatReport.iouReportID) { oneOnOneIOUReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneChatReport.iouReportID}`]; @@ -192,7 +185,6 @@ function buildSplitBillOnyxData(report, participants, amount, comment, currentUs ); } - // reportAction const oneOnOneIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( lodashGet(oneOnOneChatReport, 'maxSequenceNumber', 0) + 1, 'create', @@ -221,6 +213,8 @@ function buildSplitBillOnyxData(report, participants, amount, comment, currentUs }, }, ); + + // @TODO: build success and failure data }); } @@ -229,7 +223,7 @@ function splitBill(report, participants, amount, currency, currentUserEmail, loc // Call API API.write('SplitBill', params, { - optimisticData: onyxData.optimisticData + optimisticData: onyxData.optimisticData, }); } From fb9234d5e1ec761aa9b80584b18ece6a211e51dd Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 5 Oct 2022 16:53:06 -0600 Subject: [PATCH 011/100] create const --- src/CONST.js | 1 + src/libs/actions/IOU.js | 15 +++++++++------ src/pages/iou/IOUModal.js | 17 +++++++++-------- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/CONST.js b/src/CONST.js index f95292f39ce4..2de10a4ae73d 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -649,6 +649,7 @@ const CONST = { }, REPORT_ACTION_TYPE: { PAY: 'pay', + CREATE: 'create', }, AMOUNT_MAX_LENGTH: 10, }, diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index eaca6a79a739..d09bbcd3f5bc 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -137,11 +137,14 @@ function createIOUTransaction(params) { }); } +/** + * @param {Object} params + */ function buildSplitBillOnyxData(report, participants, amount, comment, currentUserEmail, currency, locale) { const groupChatReport = lodashGet(report, 'reportID', null) ? report : ReportUtils.buildOptimisticChatReport(participants); const groupReportAction = ReportUtils.buildOptimisticIOUReportAction( lodashGet(groupChatReport, 'maxSequenceNumber', 0) + 1, - 'create', + CONST.IOU.REPORT_ACTION_TYPE.CREATE, amount, comment, ); @@ -169,7 +172,8 @@ function buildSplitBillOnyxData(report, participants, amount, comment, currentUs return; } - const oneOnOneChatReport = lodashGet(report, 'reportID', null) ? report : ReportUtils.buildOptimisticChatReport([currentUserEmail, email]); + // WE need to get the 1:1 chat + const oneOnOneChatReport = lodashGet(getOneOnOneChat, 'reportID', null) ? report : ReportUtils.buildOptimisticChatReport([currentUserEmail, email]); let oneOnOneIOUReport; if (oneOnOneChatReport.iouReportID) { oneOnOneIOUReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneChatReport.iouReportID}`]; @@ -187,7 +191,7 @@ function buildSplitBillOnyxData(report, participants, amount, comment, currentUs const oneOnOneIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( lodashGet(oneOnOneChatReport, 'maxSequenceNumber', 0) + 1, - 'create', + CONST.IOU.REPORT_ACTION_TYPE.CREATE, amount, currency, comment, @@ -215,6 +219,7 @@ function buildSplitBillOnyxData(report, participants, amount, comment, currentUs ); // @TODO: build success and failure data + return {optimisticData}; }); } @@ -222,9 +227,7 @@ function splitBill(report, participants, amount, currency, currentUserEmail, loc const onyxData = buildSplitBillOnyxData(report, participants, amount, comment, currentUserEmail, currency, locale); // Call API - API.write('SplitBill', params, { - optimisticData: onyxData.optimisticData, - }); + API.write('SplitBill', params, onyxData); } /** diff --git a/src/pages/iou/IOUModal.js b/src/pages/iou/IOUModal.js index db9006437641..6bf772a70421 100755 --- a/src/pages/iou/IOUModal.js +++ b/src/pages/iou/IOUModal.js @@ -332,14 +332,15 @@ class IOUModal extends Component { } if (splits) { - IOU.splitBill({ - comment: this.state.comment, - - // Send in cents to API. - amount: Math.round(this.state.amount * 100), - currency: this.props.iou.selectedCurrencyCode, - splits, - }); + IOU.splitBill( + this.props.report, + this.participants, + Math.round(this.state.amount * 100), + this.props.iou.selectedCurrencyCode, + this.props.currentUserPersonalDetails.login, + this.props.preferredLocale, + this.state.comment, + ); return; } From 45190e46159bb6b67176db1b6a1de5ebd1a13c5f Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 5 Oct 2022 17:04:43 -0600 Subject: [PATCH 012/100] use getChatByParticipants --- src/libs/actions/IOU.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index d09bbcd3f5bc..319a2ee00d3c 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -140,8 +140,9 @@ function createIOUTransaction(params) { /** * @param {Object} params */ -function buildSplitBillOnyxData(report, participants, amount, comment, currentUserEmail, currency, locale) { - const groupChatReport = lodashGet(report, 'reportID', null) ? report : ReportUtils.buildOptimisticChatReport(participants); +function buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, currency, locale) { + // getChatByParticipants should be created in this PR https://github.com/Expensify/App/pull/11439/files + const groupChatReport = ReportUtils.getChatByParticipants(participants) || ReportUtils.buildOptimisticChatReport(participants); const groupReportAction = ReportUtils.buildOptimisticIOUReportAction( lodashGet(groupChatReport, 'maxSequenceNumber', 0) + 1, CONST.IOU.REPORT_ACTION_TYPE.CREATE, @@ -172,8 +173,8 @@ function buildSplitBillOnyxData(report, participants, amount, comment, currentUs return; } - // WE need to get the 1:1 chat - const oneOnOneChatReport = lodashGet(getOneOnOneChat, 'reportID', null) ? report : ReportUtils.buildOptimisticChatReport([currentUserEmail, email]); + // getChatByParticipants should be created in this PR https://github.com/Expensify/App/pull/11439/files + const oneOnOneChatReport = ReportUtils.getChatByParticipants([currentUserEmail, email]) || ReportUtils.buildOptimisticChatReport([currentUserEmail, email]); let oneOnOneIOUReport; if (oneOnOneChatReport.iouReportID) { oneOnOneIOUReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneChatReport.iouReportID}`]; From d30900f530c57037cdde1034ccf20cff95b6223f Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 5 Oct 2022 17:13:39 -0600 Subject: [PATCH 013/100] add pendingActions --- src/libs/actions/IOU.js | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 319a2ee00d3c..312992374ed3 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -142,7 +142,8 @@ function createIOUTransaction(params) { */ function buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, currency, locale) { // getChatByParticipants should be created in this PR https://github.com/Expensify/App/pull/11439/files - const groupChatReport = ReportUtils.getChatByParticipants(participants) || ReportUtils.buildOptimisticChatReport(participants); + const existingGroupChatReport = ReportUtils.getChatByParticipants(participants); + const groupChatReport = existingGroupChatReport || ReportUtils.buildOptimisticChatReport(participants); const groupReportAction = ReportUtils.buildOptimisticIOUReportAction( lodashGet(groupChatReport, 'maxSequenceNumber', 0) + 1, CONST.IOU.REPORT_ACTION_TYPE.CREATE, @@ -155,13 +156,21 @@ function buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${groupChatReport.reportID}`, - value: groupChatReport, + value: { + ...groupChatReport, + pendingFields: { + createChat: existingGroupChatReport ? null : CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + }, + }, }, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${groupChatReport.reportID}`, value: { - [groupReportAction.sequenceNumber]: groupReportAction, + [groupReportAction.sequenceNumber]: { + ...groupReportAction, + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + }, }, }, ]; @@ -174,7 +183,8 @@ function buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, } // getChatByParticipants should be created in this PR https://github.com/Expensify/App/pull/11439/files - const oneOnOneChatReport = ReportUtils.getChatByParticipants([currentUserEmail, email]) || ReportUtils.buildOptimisticChatReport([currentUserEmail, email]); + const existingOneOnOneChatReport = ReportUtils.getChatByParticipants([currentUserEmail, email]); + const oneOnOneChatReport = existingOneOnOneChatReport || ReportUtils.buildOptimisticChatReport([currentUserEmail, email]); let oneOnOneIOUReport; if (oneOnOneChatReport.iouReportID) { oneOnOneIOUReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneChatReport.iouReportID}`]; @@ -203,7 +213,12 @@ function buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`, - value: oneOnOneChatReport, + value: { + ...oneOnOneChatReport, + pendingFields: { + createChat: existingOneOnOneChatReport ? null : CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + }, + }, }, { onyxMethod: CONST.ONYX.METHOD.MERGE, @@ -214,7 +229,10 @@ function buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`, value: { - [oneOnOneIOUReportAction.sequenceNumber]: oneOnOneIOUReportAction, + [oneOnOneIOUReportAction.sequenceNumber]: { + ...oneOnOneIOUReportAction, + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + }, }, }, ); From bd85c3188ff244de457419b59c3e912301753655 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 5 Oct 2022 17:20:05 -0600 Subject: [PATCH 014/100] add success and failure data --- src/libs/actions/IOU.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 312992374ed3..5ec16c748f8a 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -151,7 +151,6 @@ function buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, comment, ); - // @TODO: Add RBR pendingAction const optimisticData = [ { onyxMethod: CONST.ONYX.METHOD.MERGE, @@ -175,6 +174,9 @@ function buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, }, ]; + const successData = []; + const failureData = []; + // Loop through participants creating individual chats, iouReports and reportActionIDs as needed const splitAmount = amount / participants.length; _.each(participants, (email) => { @@ -223,6 +225,8 @@ function buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneChatReport.reportID}`, + + // @TODO: Do we need to add a pending action for iouReports? value: oneOnOneIOUReport, }, { @@ -237,8 +241,11 @@ function buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, }, ); + successData.push(); + failureData.push(); + // @TODO: build success and failure data - return {optimisticData}; + return {optimisticData, successData, failureData}; }); } From f590dfaaebd9b3efca30b4f81b9e558e147bd10c Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 6 Oct 2022 14:40:46 -0600 Subject: [PATCH 015/100] add success and failure data --- src/libs/actions/IOU.js | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 5ec16c748f8a..8493f30b5517 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -13,7 +13,7 @@ import asyncOpenURL from '../asyncOpenURL'; import Log from '../Log'; import * as API from '../API'; import * as ReportUtils from '../ReportUtils'; -import * as NumberUtils from '../NumberUtils'; +import DateUtils from '../DateUtils'; const iouReports = {}; Onyx.connect({ @@ -174,8 +174,31 @@ function buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, }, ]; - const successData = []; - const failureData = []; + const successData = [ + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${groupChatReport.reportID}`, + value: {pendingFields: {createChat: null}}, + }, + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${groupChatReport.reportID}`, + value: {[groupReportAction.sequenceNumber]: {pendingAction: null}}, + }, + ]; + + const failureData = [ + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${groupChatReport.reportID}`, + value: {pendingFields: {createChat: null}}, + }, + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${groupChatReport.reportID}`, + value: {[groupReportAction.sequenceNumber]: {pendingAction: null}}, + }, + ]; // Loop through participants creating individual chats, iouReports and reportActionIDs as needed const splitAmount = amount / participants.length; From 13b86b86ddaa6a912fcfa7b8e4b08066b2f8bdf0 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 6 Oct 2022 14:43:20 -0600 Subject: [PATCH 016/100] add success and failure data for individual chats --- src/libs/actions/IOU.js | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 8493f30b5517..c6b50ea39a73 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -248,8 +248,6 @@ function buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneChatReport.reportID}`, - - // @TODO: Do we need to add a pending action for iouReports? value: oneOnOneIOUReport, }, { @@ -264,10 +262,36 @@ function buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, }, ); - successData.push(); - failureData.push(); + successData.push( + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`, + value: {pendingFields: {createChat: null}}, + }, + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`, + value: { + [oneOnOneIOUReportAction.sequenceNumber]: {pendingAction: null}, + }, + }, + ); + + failureData.push( + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`, + value: {pendingFields: {createChat: null}}, + }, + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`, + value: { + [oneOnOneIOUReportAction.sequenceNumber]: {pendingAction: null}, + }, + }, + ); - // @TODO: build success and failure data return {optimisticData, successData, failureData}; }); } From bc76ff8db02510655c73fa8c1963b9b0bae820e2 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 6 Oct 2022 15:02:17 -0600 Subject: [PATCH 017/100] add jsdocs to buildSplitBillOnyxData; --- src/components/IOUConfirmationList.js | 2 ++ src/libs/actions/IOU.js | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/components/IOUConfirmationList.js b/src/components/IOUConfirmationList.js index 4ce82e163db4..d22688c14dc2 100755 --- a/src/components/IOUConfirmationList.js +++ b/src/components/IOUConfirmationList.js @@ -234,6 +234,8 @@ class IOUConfirmationList extends Component { // We should send in cents to API // Cents is temporary and there must be support for other currencies in the future amount: this.calculateAmount(selectedParticipants), + + // @TODO: Auth now expects each split to include iouReportID, chatReportID, transactionID and reportActionID })); splits.push({ diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index c6b50ea39a73..7350c9b11fb3 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -138,7 +138,12 @@ function createIOUTransaction(params) { } /** - * @param {Object} params + * @param {Array} participants + * @param {Int} amount + * @param {String} comment + * @param {String} currentUserEmail + * @param {String} currency + * @param {String} locale */ function buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, currency, locale) { // getChatByParticipants should be created in this PR https://github.com/Expensify/App/pull/11439/files @@ -296,11 +301,18 @@ function buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, }); } -function splitBill(report, participants, amount, currency, currentUserEmail, locale, comment) { +/** + * @param {Object} params + */ +// CreateIOUSplit(chatReportID, amount, splits, currency, comment, transactionID = 0, reportActionID = 0) +function splitBill(splits, report, participants, amount, currency, currentUserEmail, locale, comment) { const onyxData = buildSplitBillOnyxData(report, participants, amount, comment, currentUserEmail, currency, locale); // Call API - API.write('SplitBill', params, onyxData); + API.write('SplitBill', { + chatReportID: report.reportID, + + }, onyxData); } /** From 26697f458d1610d9ed9931beddd82cd88b461044 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 6 Oct 2022 15:02:55 -0600 Subject: [PATCH 018/100] fix return order --- src/libs/actions/IOU.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 7350c9b11fb3..34c817f421c8 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -238,7 +238,6 @@ function buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, comment, ); - // @TODO: Add RBR pendingAction optimisticData.push( { onyxMethod: CONST.ONYX.METHOD.MERGE, @@ -296,9 +295,9 @@ function buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, }, }, ); - - return {optimisticData, successData, failureData}; }); + + return {optimisticData, successData, failureData}; } /** From fca63c2d26c5194c35f0f809ed9db0fd188d6ed2 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 6 Oct 2022 15:54:21 -0600 Subject: [PATCH 019/100] create createBillSplits --- src/libs/actions/IOU.js | 106 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 102 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 34c817f421c8..9ab8669cb997 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -13,7 +13,7 @@ import asyncOpenURL from '../asyncOpenURL'; import Log from '../Log'; import * as API from '../API'; import * as ReportUtils from '../ReportUtils'; -import DateUtils from '../DateUtils'; +import * as OptionsListUtils from '../OptionsListUtils'; const iouReports = {}; Onyx.connect({ @@ -137,6 +137,96 @@ function createIOUTransaction(params) { }); } +/** + * Calculates the amount per user given a list of participants + * @param {Array} participants + * @param {Boolean} isDefaultUser + * @returns {Number} + */ +function calculateAmount(participants, isDefaultUser = false) { + // Convert to cents before working with iouAmount to avoid + // javascript subtraction with decimal problem -- when dealing with decimals, + // because they are encoded as IEEE 754 floating point numbers, some of the decimal + // numbers cannot be represented with perfect accuracy. + // Cents is temporary and there must be support for other currencies in the future + const iouAmount = Math.round(parseFloat(this.props.iouAmount * 100)); + const totalParticipants = participants.length + 1; + const amountPerPerson = Math.round(iouAmount / totalParticipants); + + if (!isDefaultUser) { return amountPerPerson; } + + const sumAmount = amountPerPerson * totalParticipants; + const difference = iouAmount - sumAmount; + + return iouAmount !== sumAmount ? (amountPerPerson + difference) : amountPerPerson; +} + +/** + * Gets splits for the transaction + * @param {Array} participants + * @param {String} currentUserLogin + * @returns {Array|null} + */ +function createBillSplits(participants, currentUserLogin, currency, locale, comment) { + // There can only be splits when there are multiple participants, so return early when there are not + // multiple participants + if (participants.length < 2) { + return null; + } + + const currentUserEmail = OptionsListUtils.addSMSDomainIfPhoneNumber(currentUserLogin); + const splits = _.map(participants, (participant) => { + const email = OptionsListUtils.addSMSDomainIfPhoneNumber(participant.login); + const amount = calculateAmount(participants); + const chatReport = ReportUtils.getChatByParticipants([currentUserEmail, email]) || ReportUtils.buildOptimisticChatReport([currentUserEmail, email]); + let iouReport; + if (chatReport.iouReportID) { + iouReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${chatReport.iouReportID}`]; + iouReport.total += amount; + } else { + iouReport = ReportUtils.buildOptimisticIOUReport( + currentUserEmail, + email, + amount, + chatReport.reportID, + currency, + locale, + ); + } + + const iouReportAction = ReportUtils.buildOptimisticIOUReportAction( + lodashGet(chatReport, 'maxSequenceNumber', 0) + 1, + CONST.IOU.REPORT_ACTION_TYPE.CREATE, + amount, + currency, + comment, + ); + + return { + email, + + // We should send in cents to API + // Cents is temporary and there must be support for other currencies in the future + amount: calculateAmount(participants), + + // @TODO: Auth now expects each split to include iouReportID, chatReportID, transactionID and reportActionID + // getChatByParticipants should be created in this PR https://github.com/Expensify/App/pull/11439/files + chatReportID: chatReport.reportID, + iouReportID: iouReport.reportID, + transactionID: iouReportAction.originalMessage.transactionID, + }; + }); + + splits.push({ + email: currentUserEmail, + + // The user is default and we should send in cents to API + // USD is temporary and there must be support for other currencies in the future + amount: this.calculateAmount(participants, true), + }); + return splits; +} + /** * @param {Array} participants * @param {Int} amount @@ -144,6 +234,8 @@ function createIOUTransaction(params) { * @param {String} currentUserEmail * @param {String} currency * @param {String} locale + * + * @return {Object} */ function buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, currency, locale) { // getChatByParticipants should be created in this PR https://github.com/Expensify/App/pull/11439/files @@ -206,6 +298,7 @@ function buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, ]; // Loop through participants creating individual chats, iouReports and reportActionIDs as needed + // @TODO: this splitAmount is wrong. const splitAmount = amount / participants.length; _.each(participants, (email) => { if (email === currentUserEmail) { @@ -305,12 +398,17 @@ function buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, */ // CreateIOUSplit(chatReportID, amount, splits, currency, comment, transactionID = 0, reportActionID = 0) function splitBill(splits, report, participants, amount, currency, currentUserEmail, locale, comment) { - const onyxData = buildSplitBillOnyxData(report, participants, amount, comment, currentUserEmail, currency, locale); + const onyxData = buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, currency, locale); // Call API API.write('SplitBill', { - chatReportID: report.reportID, - + chatReportID: null, + amount, + splits, + currency, + comment, + transactionID: null, + reportActionID: null, }, onyxData); } From b62cb936bcdf8dfbe8ece237860a308f6827cc11 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 6 Oct 2022 16:23:38 -0600 Subject: [PATCH 020/100] revert changes --- src/libs/actions/IOU.js | 90 ----------------------------------------- 1 file changed, 90 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 9ab8669cb997..c0c0f493181e 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -137,96 +137,6 @@ function createIOUTransaction(params) { }); } -/** - * Calculates the amount per user given a list of participants - * @param {Array} participants - * @param {Boolean} isDefaultUser - * @returns {Number} - */ -function calculateAmount(participants, isDefaultUser = false) { - // Convert to cents before working with iouAmount to avoid - // javascript subtraction with decimal problem -- when dealing with decimals, - // because they are encoded as IEEE 754 floating point numbers, some of the decimal - // numbers cannot be represented with perfect accuracy. - // Cents is temporary and there must be support for other currencies in the future - const iouAmount = Math.round(parseFloat(this.props.iouAmount * 100)); - const totalParticipants = participants.length + 1; - const amountPerPerson = Math.round(iouAmount / totalParticipants); - - if (!isDefaultUser) { return amountPerPerson; } - - const sumAmount = amountPerPerson * totalParticipants; - const difference = iouAmount - sumAmount; - - return iouAmount !== sumAmount ? (amountPerPerson + difference) : amountPerPerson; -} - -/** - * Gets splits for the transaction - * @param {Array} participants - * @param {String} currentUserLogin - * @returns {Array|null} - */ -function createBillSplits(participants, currentUserLogin, currency, locale, comment) { - // There can only be splits when there are multiple participants, so return early when there are not - // multiple participants - if (participants.length < 2) { - return null; - } - - const currentUserEmail = OptionsListUtils.addSMSDomainIfPhoneNumber(currentUserLogin); - const splits = _.map(participants, (participant) => { - const email = OptionsListUtils.addSMSDomainIfPhoneNumber(participant.login); - const amount = calculateAmount(participants); - const chatReport = ReportUtils.getChatByParticipants([currentUserEmail, email]) || ReportUtils.buildOptimisticChatReport([currentUserEmail, email]); - let iouReport; - if (chatReport.iouReportID) { - iouReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${chatReport.iouReportID}`]; - iouReport.total += amount; - } else { - iouReport = ReportUtils.buildOptimisticIOUReport( - currentUserEmail, - email, - amount, - chatReport.reportID, - currency, - locale, - ); - } - - const iouReportAction = ReportUtils.buildOptimisticIOUReportAction( - lodashGet(chatReport, 'maxSequenceNumber', 0) + 1, - CONST.IOU.REPORT_ACTION_TYPE.CREATE, - amount, - currency, - comment, - ); - - return { - email, - - // We should send in cents to API - // Cents is temporary and there must be support for other currencies in the future - amount: calculateAmount(participants), - - // @TODO: Auth now expects each split to include iouReportID, chatReportID, transactionID and reportActionID - // getChatByParticipants should be created in this PR https://github.com/Expensify/App/pull/11439/files - chatReportID: chatReport.reportID, - iouReportID: iouReport.reportID, - transactionID: iouReportAction.originalMessage.transactionID, - }; - }); - - splits.push({ - email: currentUserEmail, - - // The user is default and we should send in cents to API - // USD is temporary and there must be support for other currencies in the future - amount: this.calculateAmount(participants, true), - }); - return splits; -} - /** * @param {Array} participants * @param {Int} amount From 17ad8109b3cea3f1cb0f0636fed79ea39b4f4315 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 6 Oct 2022 16:30:07 -0600 Subject: [PATCH 021/100] createSplitsAndBuildOnyxData --- src/libs/actions/IOU.js | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index c0c0f493181e..66b9e4bc9125 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -147,7 +147,7 @@ function createIOUTransaction(params) { * * @return {Object} */ -function buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, currency, locale) { +function createSplitsAndBuildOnyxData(participants, amount, comment, currentUserEmail, currency, locale) { // getChatByParticipants should be created in this PR https://github.com/Expensify/App/pull/11439/files const existingGroupChatReport = ReportUtils.getChatByParticipants(participants); const groupChatReport = existingGroupChatReport || ReportUtils.buildOptimisticChatReport(participants); @@ -208,8 +208,9 @@ function buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, ]; // Loop through participants creating individual chats, iouReports and reportActionIDs as needed - // @TODO: this splitAmount is wrong. + // @TODO: this splitAmount is wrong. See how to calculate it in https://github.com/Expensify/App/blob/b62cb936bcdf8dfbe8ece237860a308f6827cc11/src/components/IOUConfirmationList.js#L272 const splitAmount = amount / participants.length; + const splits = [{email: currentUserEmail, amount: splitAmount}]; _.each(participants, (email) => { if (email === currentUserEmail) { return; @@ -298,9 +299,20 @@ function buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, }, }, ); + + splits.push({ + email, + amount: splitAmount, + iouReportID: oneOnOneIOUReport.reportID, + chatReportID: oneOnOneChatReport.reportID, + transactionID: oneOnOneIOUReportAction.originalMessage.transactionID, + reportActionID: oneOnOneIOUReportAction.reportActionID, + }); }); - return {optimisticData, successData, failureData}; + return { + optimisticData, successData, failureData, splits, + }; } /** @@ -308,7 +320,7 @@ function buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, */ // CreateIOUSplit(chatReportID, amount, splits, currency, comment, transactionID = 0, reportActionID = 0) function splitBill(splits, report, participants, amount, currency, currentUserEmail, locale, comment) { - const onyxData = buildSplitBillOnyxData(participants, amount, comment, currentUserEmail, currency, locale); + const onyxData = createSplitsAndBuildOnyxData(participants, amount, comment, currentUserEmail, currency, locale); // Call API API.write('SplitBill', { From 27faca430734a66576f14e9cd50e7b9c6a694e2a Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 6 Oct 2022 16:38:48 -0600 Subject: [PATCH 022/100] create IOU.calculateAmount --- src/libs/actions/IOU.js | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 66b9e4bc9125..bf08a4ad3275 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -137,6 +137,31 @@ function createIOUTransaction(params) { }); } +/** + * Calculates the amount per user given a list of participants + * @param {Array} participants + * @param {Int} total + * @param {Boolean} isDefaultUser + * @returns {Number} + */ +function calculateAmount(participants, total, isDefaultUser = false) { + // Convert to cents before working with iouAmount to avoid + // javascript subtraction with decimal problem -- when dealing with decimals, + // because they are encoded as IEEE 754 floating point numbers, some of the decimal + // numbers cannot be represented with perfect accuracy. + // Cents is temporary and there must be support for other currencies in the future + const iouAmount = Math.round(parseFloat(total * 100)); + const totalParticipants = participants.length + 1; + const amountPerPerson = Math.round(iouAmount / totalParticipants); + + if (!isDefaultUser) { return amountPerPerson; } + + const sumAmount = amountPerPerson * totalParticipants; + const difference = iouAmount - sumAmount; + + return iouAmount !== sumAmount ? (amountPerPerson + difference) : amountPerPerson; +} + /** * @param {Array} participants * @param {Int} amount @@ -208,10 +233,10 @@ function createSplitsAndBuildOnyxData(participants, amount, comment, currentUser ]; // Loop through participants creating individual chats, iouReports and reportActionIDs as needed - // @TODO: this splitAmount is wrong. See how to calculate it in https://github.com/Expensify/App/blob/b62cb936bcdf8dfbe8ece237860a308f6827cc11/src/components/IOUConfirmationList.js#L272 - const splitAmount = amount / participants.length; - const splits = [{email: currentUserEmail, amount: splitAmount}]; + const splitAmount = calculateAmount(participants, amount); + const splits = [{email: currentUserEmail, amount: calculateAmount(participants, amount, true)}]; _.each(participants, (email) => { + // @TODO: I think we need to get the email by calling OptionsListUtils.addSMSDomainIfPhoneNumber(participant.login), if (email === currentUserEmail) { return; } @@ -311,16 +336,16 @@ function createSplitsAndBuildOnyxData(participants, amount, comment, currentUser }); return { - optimisticData, successData, failureData, splits, + splits, + onyxData: {optimisticData, successData, failureData}, }; } /** * @param {Object} params */ -// CreateIOUSplit(chatReportID, amount, splits, currency, comment, transactionID = 0, reportActionID = 0) -function splitBill(splits, report, participants, amount, currency, currentUserEmail, locale, comment) { - const onyxData = createSplitsAndBuildOnyxData(participants, amount, comment, currentUserEmail, currency, locale); +function splitBill(participants, amount, currency, currentUserEmail, locale, comment) { + const {splits, onyxData} = createSplitsAndBuildOnyxData(participants, amount, comment, currentUserEmail, currency, locale); // Call API API.write('SplitBill', { From edd0041247f85b856a337b47fd44dd8a748f089f Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 6 Oct 2022 16:46:14 -0600 Subject: [PATCH 023/100] move calculateAmount to utils --- src/components/IOUConfirmationList.js | 35 ++++----------------------- src/libs/IOUUtils.js | 29 ++++++++++++++++++++++ src/libs/actions/IOU.js | 31 +++--------------------- 3 files changed, 37 insertions(+), 58 deletions(-) create mode 100644 src/libs/IOUUtils.js diff --git a/src/components/IOUConfirmationList.js b/src/components/IOUConfirmationList.js index d22688c14dc2..f4b7f69c9f58 100755 --- a/src/components/IOUConfirmationList.js +++ b/src/components/IOUConfirmationList.js @@ -17,6 +17,7 @@ import ROUTES from '../ROUTES'; import networkPropTypes from './networkPropTypes'; import {withNetwork} from './OnyxProvider'; import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from './withCurrentUserPersonalDetails'; +import * as IOUUtils from '../libs/IOUUtils'; const propTypes = { /** Callback to inform parent modal of success */ @@ -148,7 +149,7 @@ class IOUConfirmationList extends Component { getParticipantsWithAmount(participants) { return OptionsListUtils.getIOUConfirmationOptionsFromParticipants( participants, - this.props.numberFormat(this.calculateAmount(participants) / 100, { + this.props.numberFormat(IOUUtils.calculateAmount(participants, this.props.iouAmount) / 100, { style: 'currency', currency: this.props.iou.selectedCurrencyCode, }), @@ -182,7 +183,7 @@ class IOUConfirmationList extends Component { const formattedMyPersonalDetails = OptionsListUtils.getIOUConfirmationOptionsFromMyPersonalDetail( this.props.currentUserPersonalDetails, - this.props.numberFormat(this.calculateAmount(selectedParticipants, true) / 100, { + this.props.numberFormat(IOUUtils.calculateAmount(selectedParticipants, this.props.iouAmount, true) / 100, { style: 'currency', currency: this.props.iou.selectedCurrencyCode, }), @@ -233,9 +234,7 @@ class IOUConfirmationList extends Component { // We should send in cents to API // Cents is temporary and there must be support for other currencies in the future - amount: this.calculateAmount(selectedParticipants), - - // @TODO: Auth now expects each split to include iouReportID, chatReportID, transactionID and reportActionID + amount: IOUUtils.calculateAmount(selectedParticipants, this.props.iouAmount), })); splits.push({ @@ -243,7 +242,7 @@ class IOUConfirmationList extends Component { // The user is default and we should send in cents to API // USD is temporary and there must be support for other currencies in the future - amount: this.calculateAmount(selectedParticipants, true), + amount: IOUUtils.calculateAmount(selectedParticipants, this.props.iouAmount, true), }); return splits; } @@ -263,30 +262,6 @@ class IOUConfirmationList extends Component { ]; } - /** - * Calculates the amount per user given a list of participants - * @param {Array} participants - * @param {Boolean} isDefaultUser - * @returns {Number} - */ - calculateAmount(participants, isDefaultUser = false) { - // Convert to cents before working with iouAmount to avoid - // javascript subtraction with decimal problem -- when dealing with decimals, - // because they are encoded as IEEE 754 floating point numbers, some of the decimal - // numbers cannot be represented with perfect accuracy. - // Cents is temporary and there must be support for other currencies in the future - const iouAmount = Math.round(parseFloat(this.props.iouAmount * 100)); - const totalParticipants = participants.length + 1; - const amountPerPerson = Math.round(iouAmount / totalParticipants); - - if (!isDefaultUser) { return amountPerPerson; } - - const sumAmount = amountPerPerson * totalParticipants; - const difference = iouAmount - sumAmount; - - return iouAmount !== sumAmount ? (amountPerPerson + difference) : amountPerPerson; - } - /** * Toggle selected option's selected prop. * @param {Object} option diff --git a/src/libs/IOUUtils.js b/src/libs/IOUUtils.js new file mode 100644 index 000000000000..9d3b8fb31923 --- /dev/null +++ b/src/libs/IOUUtils.js @@ -0,0 +1,29 @@ +/** + * Calculates the amount per user given a list of participants + * @param {Array} participants + * @param {Int} total + * @param {Boolean} isDefaultUser + * @returns {Number} + */ +function calculateAmount(participants, total, isDefaultUser = false) { + // Convert to cents before working with iouAmount to avoid + // javascript subtraction with decimal problem -- when dealing with decimals, + // because they are encoded as IEEE 754 floating point numbers, some of the decimal + // numbers cannot be represented with perfect accuracy. + // Cents is temporary and there must be support for other currencies in the future + const iouAmount = Math.round(parseFloat(total * 100)); + const totalParticipants = participants.length + 1; + const amountPerPerson = Math.round(iouAmount / totalParticipants); + + if (!isDefaultUser) { return amountPerPerson; } + + const sumAmount = amountPerPerson * totalParticipants; + const difference = iouAmount - sumAmount; + + return iouAmount !== sumAmount ? (amountPerPerson + difference) : amountPerPerson; +} + +export { + // eslint-disable-next-line import/prefer-default-export + calculateAmount, +}; diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index bf08a4ad3275..34eedbc0831c 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -13,7 +13,7 @@ import asyncOpenURL from '../asyncOpenURL'; import Log from '../Log'; import * as API from '../API'; import * as ReportUtils from '../ReportUtils'; -import * as OptionsListUtils from '../OptionsListUtils'; +import * as IOUUtils from '../IOUUtils'; const iouReports = {}; Onyx.connect({ @@ -137,31 +137,6 @@ function createIOUTransaction(params) { }); } -/** - * Calculates the amount per user given a list of participants - * @param {Array} participants - * @param {Int} total - * @param {Boolean} isDefaultUser - * @returns {Number} - */ -function calculateAmount(participants, total, isDefaultUser = false) { - // Convert to cents before working with iouAmount to avoid - // javascript subtraction with decimal problem -- when dealing with decimals, - // because they are encoded as IEEE 754 floating point numbers, some of the decimal - // numbers cannot be represented with perfect accuracy. - // Cents is temporary and there must be support for other currencies in the future - const iouAmount = Math.round(parseFloat(total * 100)); - const totalParticipants = participants.length + 1; - const amountPerPerson = Math.round(iouAmount / totalParticipants); - - if (!isDefaultUser) { return amountPerPerson; } - - const sumAmount = amountPerPerson * totalParticipants; - const difference = iouAmount - sumAmount; - - return iouAmount !== sumAmount ? (amountPerPerson + difference) : amountPerPerson; -} - /** * @param {Array} participants * @param {Int} amount @@ -233,8 +208,8 @@ function createSplitsAndBuildOnyxData(participants, amount, comment, currentUser ]; // Loop through participants creating individual chats, iouReports and reportActionIDs as needed - const splitAmount = calculateAmount(participants, amount); - const splits = [{email: currentUserEmail, amount: calculateAmount(participants, amount, true)}]; + const splitAmount = IOUUtils.calculateAmount(participants, amount); + const splits = [{email: currentUserEmail, amount: IOUUtils.calculateAmount(participants, amount, true)}]; _.each(participants, (email) => { // @TODO: I think we need to get the email by calling OptionsListUtils.addSMSDomainIfPhoneNumber(participant.login), if (email === currentUserEmail) { From ee04fbdc8fb2acdad690c7381611d1651814bbb3 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 6 Oct 2022 17:02:17 -0600 Subject: [PATCH 024/100] add group data --- src/libs/actions/IOU.js | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 34eedbc0831c..9bb2b6f6cd9d 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -14,6 +14,7 @@ import Log from '../Log'; import * as API from '../API'; import * as ReportUtils from '../ReportUtils'; import * as IOUUtils from '../IOUUtils'; +import * as OptionsListUtils from '../OptionsListUtils'; const iouReports = {}; Onyx.connect({ @@ -141,13 +142,13 @@ function createIOUTransaction(params) { * @param {Array} participants * @param {Int} amount * @param {String} comment - * @param {String} currentUserEmail + * @param {String} currentUserLogin * @param {String} currency * @param {String} locale * * @return {Object} */ -function createSplitsAndBuildOnyxData(participants, amount, comment, currentUserEmail, currency, locale) { +function createSplitsAndBuildOnyxData(participants, amount, comment, currentUserLogin, currency, locale) { // getChatByParticipants should be created in this PR https://github.com/Expensify/App/pull/11439/files const existingGroupChatReport = ReportUtils.getChatByParticipants(participants); const groupChatReport = existingGroupChatReport || ReportUtils.buildOptimisticChatReport(participants); @@ -209,9 +210,11 @@ function createSplitsAndBuildOnyxData(participants, amount, comment, currentUser // Loop through participants creating individual chats, iouReports and reportActionIDs as needed const splitAmount = IOUUtils.calculateAmount(participants, amount); + const currentUserEmail = OptionsListUtils.addSMSDomainIfPhoneNumber(currentUserLogin); const splits = [{email: currentUserEmail, amount: IOUUtils.calculateAmount(participants, amount, true)}]; - _.each(participants, (email) => { - // @TODO: I think we need to get the email by calling OptionsListUtils.addSMSDomainIfPhoneNumber(participant.login), + + _.each(participants, (participant) => { + const email = OptionsListUtils.addSMSDomainIfPhoneNumber(participant.login); if (email === currentUserEmail) { return; } @@ -311,6 +314,11 @@ function createSplitsAndBuildOnyxData(participants, amount, comment, currentUser }); return { + groupData: { + chatReportID: groupChatReport.reportID, + transactionID: groupReportAction.originalMessage.transactionID, + reportActionID: groupReportAction.reportActionID, + }, splits, onyxData: {optimisticData, successData, failureData}, }; @@ -320,17 +328,17 @@ function createSplitsAndBuildOnyxData(participants, amount, comment, currentUser * @param {Object} params */ function splitBill(participants, amount, currency, currentUserEmail, locale, comment) { - const {splits, onyxData} = createSplitsAndBuildOnyxData(participants, amount, comment, currentUserEmail, currency, locale); + const {groupData, splits, onyxData} = createSplitsAndBuildOnyxData(participants, amount, comment, currentUserEmail, currency, locale); // Call API API.write('SplitBill', { - chatReportID: null, + chatReportID: groupData.chatReportID, amount, splits, currency, comment, - transactionID: null, - reportActionID: null, + transactionID: groupData.transactionID, + reportActionID: groupData.reportActionID, }, onyxData); } From b5efc0d344142af1555f95f80f3e508dbf785c51 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Fri, 7 Oct 2022 12:03:52 -0600 Subject: [PATCH 025/100] add logic to call correct command --- src/libs/actions/IOU.js | 45 ++++++++++++++++++++++++++------------- src/pages/iou/IOUModal.js | 17 ++++++++++++--- 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 9bb2b6f6cd9d..38810e1b12a8 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -140,15 +140,15 @@ function createIOUTransaction(params) { /** * @param {Array} participants + * @param {String} currentUserLogin * @param {Int} amount * @param {String} comment - * @param {String} currentUserLogin * @param {String} currency * @param {String} locale * * @return {Object} */ -function createSplitsAndBuildOnyxData(participants, amount, comment, currentUserLogin, currency, locale) { +function createSplitsAndBuildOnyxData(participants, currentUserLogin, amount, comment, currency, locale) { // getChatByParticipants should be created in this PR https://github.com/Expensify/App/pull/11439/files const existingGroupChatReport = ReportUtils.getChatByParticipants(participants); const groupChatReport = existingGroupChatReport || ReportUtils.buildOptimisticChatReport(participants); @@ -237,6 +237,7 @@ function createSplitsAndBuildOnyxData(participants, amount, comment, currentUser ); } + // @TODO: Add created report action const oneOnOneIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( lodashGet(oneOnOneChatReport, 'maxSequenceNumber', 0) + 1, CONST.IOU.REPORT_ACTION_TYPE.CREATE, @@ -325,12 +326,16 @@ function createSplitsAndBuildOnyxData(participants, amount, comment, currentUser } /** - * @param {Object} params + * @param {Array} participants + * @param {String} currentUserLogin + * @param {Int} amount + * @param {String} comment + * @param {String} currency + * @param {String} locale */ -function splitBill(participants, amount, currency, currentUserEmail, locale, comment) { - const {groupData, splits, onyxData} = createSplitsAndBuildOnyxData(participants, amount, comment, currentUserEmail, currency, locale); +function splitBill(participants, currentUserLogin, amount, comment, currency, locale) { + const {groupData, splits, onyxData} = createSplitsAndBuildOnyxData(participants, currentUserLogin, amount, comment, currency, locale); - // Call API API.write('SplitBill', { chatReportID: groupData.chatReportID, amount, @@ -343,17 +348,27 @@ function splitBill(participants, amount, currency, currentUserEmail, locale, com } /** - * Creates IOUSplit Transaction for Group DM - * - * @param {Object} params - * @param {Array} params.splits - * @param {String} params.comment - * @param {Number} params.amount - * @param {String} params.currency - * @param {String} params.reportID + * @param {Array} participants + * @param {String} currentUserLogin + * @param {Int} amount + * @param {String} comment + * @param {String} currency + * @param {String} locale */ -function splitBillAndOpenReport(params) { +function splitBillAndOpenReport(participants, currentUserLogin, amount, comment, currency, locale) { + const {groupData, splits, onyxData} = createSplitsAndBuildOnyxData(participants, currentUserLogin, amount, comment, currency, locale); + + API.write('SplitBillAndOpenReport', { + chatReportID: groupData.chatReportID, + amount, + splits, + currency, + comment, + transactionID: groupData.transactionID, + reportActionID: groupData.reportActionID, + }, onyxData); + Navigation.navigate(ROUTES.getReportRoute(groupData.chatReportID)); } /** diff --git a/src/pages/iou/IOUModal.js b/src/pages/iou/IOUModal.js index 6bf772a70421..e4f14c349e37 100755 --- a/src/pages/iou/IOUModal.js +++ b/src/pages/iou/IOUModal.js @@ -331,15 +331,26 @@ class IOUModal extends Component { return; } - if (splits) { + if (splits && reportID) { IOU.splitBill( - this.props.report, this.participants, + this.props.currentUserPersonalDetails.login, Math.round(this.state.amount * 100), + this.state.comment, this.props.iou.selectedCurrencyCode, - this.props.currentUserPersonalDetails.login, this.props.preferredLocale, + ); + return; + } + + if (splits) { + IOU.splitBillAndOpenReport( + this.participants, + this.props.currentUserPersonalDetails.login, + Math.round(this.state.amount * 100), this.state.comment, + this.props.iou.selectedCurrencyCode, + this.props.preferredLocale, ); return; } From b0b95ccb615ec615f201a2582437220057aba8f9 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Fri, 7 Oct 2022 12:26:40 -0600 Subject: [PATCH 026/100] add created report action; --- src/libs/actions/IOU.js | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 38810e1b12a8..b8122f87e04b 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -149,10 +149,13 @@ function createIOUTransaction(params) { * @return {Object} */ function createSplitsAndBuildOnyxData(participants, currentUserLogin, amount, comment, currency, locale) { + const currentUserEmail = OptionsListUtils.addSMSDomainIfPhoneNumber(currentUserLogin); + // getChatByParticipants should be created in this PR https://github.com/Expensify/App/pull/11439/files const existingGroupChatReport = ReportUtils.getChatByParticipants(participants); const groupChatReport = existingGroupChatReport || ReportUtils.buildOptimisticChatReport(participants); - const groupReportAction = ReportUtils.buildOptimisticIOUReportAction( + const groupCreatedReportAction = existingGroupChatReport && ReportUtils.buildOptimisticCreatedReportAction(currentUserEmail); + const groupIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( lodashGet(groupChatReport, 'maxSequenceNumber', 0) + 1, CONST.IOU.REPORT_ACTION_TYPE.CREATE, amount, @@ -174,10 +177,8 @@ function createSplitsAndBuildOnyxData(participants, currentUserLogin, amount, co onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${groupChatReport.reportID}`, value: { - [groupReportAction.sequenceNumber]: { - ...groupReportAction, - pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - }, + 0: groupCreatedReportAction, + [groupIOUReportAction.sequenceNumber]: groupIOUReportAction, }, }, ]; @@ -191,7 +192,10 @@ function createSplitsAndBuildOnyxData(participants, currentUserLogin, amount, co { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${groupChatReport.reportID}`, - value: {[groupReportAction.sequenceNumber]: {pendingAction: null}}, + value: { + 0: {pendingAction: null}, + [groupIOUReportAction.sequenceNumber]: {pendingAction: null}, + }, }, ]; @@ -204,13 +208,15 @@ function createSplitsAndBuildOnyxData(participants, currentUserLogin, amount, co { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${groupChatReport.reportID}`, - value: {[groupReportAction.sequenceNumber]: {pendingAction: null}}, + value: { + 0: {pendingAction: null}, + [groupIOUReportAction.sequenceNumber]: {pendingAction: null}, + }, }, ]; // Loop through participants creating individual chats, iouReports and reportActionIDs as needed const splitAmount = IOUUtils.calculateAmount(participants, amount); - const currentUserEmail = OptionsListUtils.addSMSDomainIfPhoneNumber(currentUserLogin); const splits = [{email: currentUserEmail, amount: IOUUtils.calculateAmount(participants, amount, true)}]; _.each(participants, (participant) => { @@ -237,7 +243,7 @@ function createSplitsAndBuildOnyxData(participants, currentUserLogin, amount, co ); } - // @TODO: Add created report action + const oneOnOneCreatedReportAction = existingOneOnOneChatReport && ReportUtils.buildOptimisticCreatedReportAction(currentUserEmail); const oneOnOneIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( lodashGet(oneOnOneChatReport, 'maxSequenceNumber', 0) + 1, CONST.IOU.REPORT_ACTION_TYPE.CREATE, @@ -266,10 +272,8 @@ function createSplitsAndBuildOnyxData(participants, currentUserLogin, amount, co onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`, value: { - [oneOnOneIOUReportAction.sequenceNumber]: { - ...oneOnOneIOUReportAction, - pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - }, + 0: oneOnOneCreatedReportAction, + [oneOnOneIOUReportAction.sequenceNumber]: oneOnOneIOUReportAction, }, }, ); @@ -284,6 +288,7 @@ function createSplitsAndBuildOnyxData(participants, currentUserLogin, amount, co onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`, value: { + 0: {pendingAction: null}, [oneOnOneIOUReportAction.sequenceNumber]: {pendingAction: null}, }, }, @@ -299,6 +304,7 @@ function createSplitsAndBuildOnyxData(participants, currentUserLogin, amount, co onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`, value: { + 0: {pendingAction: null}, [oneOnOneIOUReportAction.sequenceNumber]: {pendingAction: null}, }, }, @@ -317,8 +323,8 @@ function createSplitsAndBuildOnyxData(participants, currentUserLogin, amount, co return { groupData: { chatReportID: groupChatReport.reportID, - transactionID: groupReportAction.originalMessage.transactionID, - reportActionID: groupReportAction.reportActionID, + transactionID: groupIOUReportAction.originalMessage.transactionID, + reportActionID: groupIOUReportAction.reportActionID, }, splits, onyxData: {optimisticData, successData, failureData}, From c7b565674f4739ceed8c3ee8db046bb66009569d Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 11 Oct 2022 14:46:27 -0600 Subject: [PATCH 027/100] rename method --- src/libs/actions/IOU.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index b8122f87e04b..6654cdd38c7d 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -148,7 +148,7 @@ function createIOUTransaction(params) { * * @return {Object} */ -function createSplitsAndBuildOnyxData(participants, currentUserLogin, amount, comment, currency, locale) { +function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment, currency, locale) { const currentUserEmail = OptionsListUtils.addSMSDomainIfPhoneNumber(currentUserLogin); // getChatByParticipants should be created in this PR https://github.com/Expensify/App/pull/11439/files @@ -340,7 +340,7 @@ function createSplitsAndBuildOnyxData(participants, currentUserLogin, amount, co * @param {String} locale */ function splitBill(participants, currentUserLogin, amount, comment, currency, locale) { - const {groupData, splits, onyxData} = createSplitsAndBuildOnyxData(participants, currentUserLogin, amount, comment, currency, locale); + const {groupData, splits, onyxData} = createSplitsAndOnyxData(participants, currentUserLogin, amount, comment, currency, locale); API.write('SplitBill', { chatReportID: groupData.chatReportID, @@ -362,7 +362,7 @@ function splitBill(participants, currentUserLogin, amount, comment, currency, lo * @param {String} locale */ function splitBillAndOpenReport(participants, currentUserLogin, amount, comment, currency, locale) { - const {groupData, splits, onyxData} = createSplitsAndBuildOnyxData(participants, currentUserLogin, amount, comment, currency, locale); + const {groupData, splits, onyxData} = createSplitsAndOnyxData(participants, currentUserLogin, amount, comment, currency, locale); API.write('SplitBillAndOpenReport', { chatReportID: groupData.chatReportID, From 210adbb70b6f8557082d07eb5e39eeb34f706298 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 11 Oct 2022 15:03:57 -0600 Subject: [PATCH 028/100] rename chatReportID param --- src/libs/actions/IOU.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 6654cdd38c7d..7f9032c2bcf3 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -343,7 +343,7 @@ function splitBill(participants, currentUserLogin, amount, comment, currency, lo const {groupData, splits, onyxData} = createSplitsAndOnyxData(participants, currentUserLogin, amount, comment, currency, locale); API.write('SplitBill', { - chatReportID: groupData.chatReportID, + reportID: groupData.chatReportID, amount, splits, currency, @@ -365,7 +365,7 @@ function splitBillAndOpenReport(participants, currentUserLogin, amount, comment, const {groupData, splits, onyxData} = createSplitsAndOnyxData(participants, currentUserLogin, amount, comment, currency, locale); API.write('SplitBillAndOpenReport', { - chatReportID: groupData.chatReportID, + reportID: groupData.chatReportID, amount, splits, currency, From 1f8f521652875588621611539ad2aaffcc3fe559 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 11 Oct 2022 15:05:48 -0600 Subject: [PATCH 029/100] stringify splits --- src/libs/actions/IOU.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 7f9032c2bcf3..a7d9aeb9eecf 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -345,7 +345,7 @@ function splitBill(participants, currentUserLogin, amount, comment, currency, lo API.write('SplitBill', { reportID: groupData.chatReportID, amount, - splits, + splits: JSON.stringify(splits), currency, comment, transactionID: groupData.transactionID, @@ -367,7 +367,7 @@ function splitBillAndOpenReport(participants, currentUserLogin, amount, comment, API.write('SplitBillAndOpenReport', { reportID: groupData.chatReportID, amount, - splits, + splits: JSON.stringify(splits), currency, comment, transactionID: groupData.transactionID, From a14b1721a9934e7ca2c0cd7a12363075929d1405 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 11 Oct 2022 15:48:06 -0600 Subject: [PATCH 030/100] update params --- src/libs/actions/IOU.js | 8 ++++++-- src/pages/iou/IOUModal.js | 18 +++++++++--------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index a7d9aeb9eecf..41918d23f8e3 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -152,7 +152,8 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment const currentUserEmail = OptionsListUtils.addSMSDomainIfPhoneNumber(currentUserLogin); // getChatByParticipants should be created in this PR https://github.com/Expensify/App/pull/11439/files - const existingGroupChatReport = ReportUtils.getChatByParticipants(participants); + // const existingGroupChatReport = ReportUtils.getChatByParticipants(participants); + const existingGroupChatReport = false; const groupChatReport = existingGroupChatReport || ReportUtils.buildOptimisticChatReport(participants); const groupCreatedReportAction = existingGroupChatReport && ReportUtils.buildOptimisticCreatedReportAction(currentUserEmail); const groupIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( @@ -226,7 +227,8 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment } // getChatByParticipants should be created in this PR https://github.com/Expensify/App/pull/11439/files - const existingOneOnOneChatReport = ReportUtils.getChatByParticipants([currentUserEmail, email]); + // const existingOneOnOneChatReport = ReportUtils.getChatByParticipants([currentUserEmail, email]); + const existingOneOnOneChatReport = false; const oneOnOneChatReport = existingOneOnOneChatReport || ReportUtils.buildOptimisticChatReport([currentUserEmail, email]); let oneOnOneIOUReport; if (oneOnOneChatReport.iouReportID) { @@ -340,6 +342,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment * @param {String} locale */ function splitBill(participants, currentUserLogin, amount, comment, currency, locale) { + console.log(participants) const {groupData, splits, onyxData} = createSplitsAndOnyxData(participants, currentUserLogin, amount, comment, currency, locale); API.write('SplitBill', { @@ -362,6 +365,7 @@ function splitBill(participants, currentUserLogin, amount, comment, currency, lo * @param {String} locale */ function splitBillAndOpenReport(participants, currentUserLogin, amount, comment, currency, locale) { + console.log(participants) const {groupData, splits, onyxData} = createSplitsAndOnyxData(participants, currentUserLogin, amount, comment, currency, locale); API.write('SplitBillAndOpenReport', { diff --git a/src/pages/iou/IOUModal.js b/src/pages/iou/IOUModal.js index e4f14c349e37..04d445070779 100755 --- a/src/pages/iou/IOUModal.js +++ b/src/pages/iou/IOUModal.js @@ -318,16 +318,16 @@ class IOUModal extends Component { // Only splits from a group DM has a reportID // Check if reportID is a number + // @TODO: there are 3 conditionals here, which ones are correct? if (splits && CONST.REGEX.NUMBER.test(reportID)) { - IOU.splitBillAndOpenReport({ - comment: this.state.comment, - - // should send in cents to API - amount: Math.round(this.state.amount * 100), - currency: this.props.iou.selectedCurrencyCode, - splits, - reportID, - }); + IOU.splitBillAndOpenReport( + this.participants, + this.props.currentUserPersonalDetails.login, + Math.round(this.state.amount * 100), + this.state.comment, + this.props.iou.selectedCurrencyCode, + this.props.preferredLocale, + ); return; } From 69b30fb7f4e9f909a55cabbe7985b9a7c48dea40 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 11 Oct 2022 15:48:23 -0600 Subject: [PATCH 031/100] rm console log --- src/libs/actions/IOU.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 41918d23f8e3..edd3fac060e1 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -342,7 +342,6 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment * @param {String} locale */ function splitBill(participants, currentUserLogin, amount, comment, currency, locale) { - console.log(participants) const {groupData, splits, onyxData} = createSplitsAndOnyxData(participants, currentUserLogin, amount, comment, currency, locale); API.write('SplitBill', { @@ -365,7 +364,6 @@ function splitBill(participants, currentUserLogin, amount, comment, currency, lo * @param {String} locale */ function splitBillAndOpenReport(participants, currentUserLogin, amount, comment, currency, locale) { - console.log(participants) const {groupData, splits, onyxData} = createSplitsAndOnyxData(participants, currentUserLogin, amount, comment, currency, locale); API.write('SplitBillAndOpenReport', { From f09272c9171237395befd85cb3276825ad9cb07f Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 11 Oct 2022 15:50:29 -0600 Subject: [PATCH 032/100] pass participants --- src/libs/actions/IOU.js | 1 + src/pages/iou/IOUModal.js | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index edd3fac060e1..3d68422a4b0d 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -364,6 +364,7 @@ function splitBill(participants, currentUserLogin, amount, comment, currency, lo * @param {String} locale */ function splitBillAndOpenReport(participants, currentUserLogin, amount, comment, currency, locale) { + console.log(participants) const {groupData, splits, onyxData} = createSplitsAndOnyxData(participants, currentUserLogin, amount, comment, currency, locale); API.write('SplitBillAndOpenReport', { diff --git a/src/pages/iou/IOUModal.js b/src/pages/iou/IOUModal.js index 04d445070779..8c79bdae2e5f 100755 --- a/src/pages/iou/IOUModal.js +++ b/src/pages/iou/IOUModal.js @@ -321,7 +321,7 @@ class IOUModal extends Component { // @TODO: there are 3 conditionals here, which ones are correct? if (splits && CONST.REGEX.NUMBER.test(reportID)) { IOU.splitBillAndOpenReport( - this.participants, + this.state.participants, this.props.currentUserPersonalDetails.login, Math.round(this.state.amount * 100), this.state.comment, @@ -333,7 +333,7 @@ class IOUModal extends Component { if (splits && reportID) { IOU.splitBill( - this.participants, + this.state.participants, this.props.currentUserPersonalDetails.login, Math.round(this.state.amount * 100), this.state.comment, @@ -345,7 +345,7 @@ class IOUModal extends Component { if (splits) { IOU.splitBillAndOpenReport( - this.participants, + this.state.participants, this.props.currentUserPersonalDetails.login, Math.round(this.state.amount * 100), this.state.comment, From 7f6730d399dc4b652f374cb43d8d9c39e6f96fe4 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 11 Oct 2022 15:50:52 -0600 Subject: [PATCH 033/100] rm loggin --- src/libs/actions/IOU.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 3d68422a4b0d..edd3fac060e1 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -364,7 +364,6 @@ function splitBill(participants, currentUserLogin, amount, comment, currency, lo * @param {String} locale */ function splitBillAndOpenReport(participants, currentUserLogin, amount, comment, currency, locale) { - console.log(participants) const {groupData, splits, onyxData} = createSplitsAndOnyxData(participants, currentUserLogin, amount, comment, currency, locale); API.write('SplitBillAndOpenReport', { From 9b724ab398e03617b1f5c3853d7436dbe7eaed5e Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 11 Oct 2022 16:46:27 -0600 Subject: [PATCH 034/100] fix errors with participants and created action --- src/libs/actions/IOU.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index edd3fac060e1..16b8c1acdd80 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -154,8 +154,8 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment // getChatByParticipants should be created in this PR https://github.com/Expensify/App/pull/11439/files // const existingGroupChatReport = ReportUtils.getChatByParticipants(participants); const existingGroupChatReport = false; - const groupChatReport = existingGroupChatReport || ReportUtils.buildOptimisticChatReport(participants); - const groupCreatedReportAction = existingGroupChatReport && ReportUtils.buildOptimisticCreatedReportAction(currentUserEmail); + const groupChatReport = existingGroupChatReport || ReportUtils.buildOptimisticChatReport(_.pluck(participants, 'login')); + const groupCreatedReportAction = existingGroupChatReport ? {} : ReportUtils.buildOptimisticCreatedReportAction(currentUserEmail); const groupIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( lodashGet(groupChatReport, 'maxSequenceNumber', 0) + 1, CONST.IOU.REPORT_ACTION_TYPE.CREATE, @@ -178,7 +178,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${groupChatReport.reportID}`, value: { - 0: groupCreatedReportAction, + ...groupCreatedReportAction, [groupIOUReportAction.sequenceNumber]: groupIOUReportAction, }, }, @@ -229,7 +229,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment // getChatByParticipants should be created in this PR https://github.com/Expensify/App/pull/11439/files // const existingOneOnOneChatReport = ReportUtils.getChatByParticipants([currentUserEmail, email]); const existingOneOnOneChatReport = false; - const oneOnOneChatReport = existingOneOnOneChatReport || ReportUtils.buildOptimisticChatReport([currentUserEmail, email]); + const oneOnOneChatReport = existingOneOnOneChatReport || ReportUtils.buildOptimisticChatReport([email]); let oneOnOneIOUReport; if (oneOnOneChatReport.iouReportID) { oneOnOneIOUReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneChatReport.iouReportID}`]; @@ -245,7 +245,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment ); } - const oneOnOneCreatedReportAction = existingOneOnOneChatReport && ReportUtils.buildOptimisticCreatedReportAction(currentUserEmail); + const oneOnOneCreatedReportAction = existingOneOnOneChatReport ? {} : ReportUtils.buildOptimisticCreatedReportAction(currentUserEmail); const oneOnOneIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( lodashGet(oneOnOneChatReport, 'maxSequenceNumber', 0) + 1, CONST.IOU.REPORT_ACTION_TYPE.CREATE, @@ -274,7 +274,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`, value: { - 0: oneOnOneCreatedReportAction, + ...oneOnOneCreatedReportAction, [oneOnOneIOUReportAction.sequenceNumber]: oneOnOneIOUReportAction, }, }, @@ -317,7 +317,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment amount: splitAmount, iouReportID: oneOnOneIOUReport.reportID, chatReportID: oneOnOneChatReport.reportID, - transactionID: oneOnOneIOUReportAction.originalMessage.transactionID, + transactionID: oneOnOneIOUReportAction.originalMessage.IOUTransactionID, reportActionID: oneOnOneIOUReportAction.reportActionID, }); }); @@ -325,7 +325,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment return { groupData: { chatReportID: groupChatReport.reportID, - transactionID: groupIOUReportAction.originalMessage.transactionID, + transactionID: groupIOUReportAction.originalMessage.IOUTransactionID, reportActionID: groupIOUReportAction.reportActionID, }, splits, From bc410db500d24fc1f723625fac028615c9b8b3bf Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 11 Oct 2022 16:57:38 -0600 Subject: [PATCH 035/100] fix amount --- src/libs/actions/IOU.js | 4 ++-- src/pages/iou/IOUModal.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 16b8c1acdd80..669092769d23 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -159,7 +159,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment const groupIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( lodashGet(groupChatReport, 'maxSequenceNumber', 0) + 1, CONST.IOU.REPORT_ACTION_TYPE.CREATE, - amount, + IOUUtils.calculateAmount(participants, amount), comment, ); @@ -249,7 +249,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment const oneOnOneIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( lodashGet(oneOnOneChatReport, 'maxSequenceNumber', 0) + 1, CONST.IOU.REPORT_ACTION_TYPE.CREATE, - amount, + splitAmount, currency, comment, ); diff --git a/src/pages/iou/IOUModal.js b/src/pages/iou/IOUModal.js index 8c79bdae2e5f..de2240c0b6d4 100755 --- a/src/pages/iou/IOUModal.js +++ b/src/pages/iou/IOUModal.js @@ -323,7 +323,7 @@ class IOUModal extends Component { IOU.splitBillAndOpenReport( this.state.participants, this.props.currentUserPersonalDetails.login, - Math.round(this.state.amount * 100), + this.state.amount, this.state.comment, this.props.iou.selectedCurrencyCode, this.props.preferredLocale, @@ -335,7 +335,7 @@ class IOUModal extends Component { IOU.splitBill( this.state.participants, this.props.currentUserPersonalDetails.login, - Math.round(this.state.amount * 100), + this.state.amount, this.state.comment, this.props.iou.selectedCurrencyCode, this.props.preferredLocale, @@ -347,7 +347,7 @@ class IOUModal extends Component { IOU.splitBillAndOpenReport( this.state.participants, this.props.currentUserPersonalDetails.login, - Math.round(this.state.amount * 100), + this.state.amount, this.state.comment, this.props.iou.selectedCurrencyCode, this.props.preferredLocale, From 555aba8bb5642aad9095f0846db9c674883273c7 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 11 Oct 2022 17:01:35 -0600 Subject: [PATCH 036/100] fix group amount --- src/libs/actions/IOU.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 669092769d23..b657f69c7550 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -159,7 +159,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment const groupIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( lodashGet(groupChatReport, 'maxSequenceNumber', 0) + 1, CONST.IOU.REPORT_ACTION_TYPE.CREATE, - IOUUtils.calculateAmount(participants, amount), + Math.round(amount * 100), comment, ); @@ -365,7 +365,7 @@ function splitBill(participants, currentUserLogin, amount, comment, currency, lo */ function splitBillAndOpenReport(participants, currentUserLogin, amount, comment, currency, locale) { const {groupData, splits, onyxData} = createSplitsAndOnyxData(participants, currentUserLogin, amount, comment, currency, locale); - +debugger; API.write('SplitBillAndOpenReport', { reportID: groupData.chatReportID, amount, From 1b2919fe0c0c1db6eed511af871c9fec0b6cb3ef Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 11 Oct 2022 17:07:34 -0600 Subject: [PATCH 037/100] fix cached total --- src/libs/ReportUtils.js | 9 ++++----- src/libs/actions/IOU.js | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 2445df626ac0..a894983acaf5 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -647,11 +647,10 @@ function buildOptimisticReportAction(sequenceNumber, text, file) { * Builds an optimistic IOU report with a randomly generated reportID */ function buildOptimisticIOUReport(ownerEmail, recipientEmail, total, chatReportID, currency, locale) { - const formattedTotal = NumberFormatUtils.format(locale, - total, { - style: 'currency', - currency, - }); + const formattedTotal = NumberFormatUtils.format(locale, total / 100, { + style: 'currency', + currency, + }); return { cachedTotal: formattedTotal, chatReportID, diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index b657f69c7550..6723a7a028d1 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -365,7 +365,7 @@ function splitBill(participants, currentUserLogin, amount, comment, currency, lo */ function splitBillAndOpenReport(participants, currentUserLogin, amount, comment, currency, locale) { const {groupData, splits, onyxData} = createSplitsAndOnyxData(participants, currentUserLogin, amount, comment, currency, locale); -debugger; + API.write('SplitBillAndOpenReport', { reportID: groupData.chatReportID, amount, From dba44f56ba010fcb8ba7772ae55ee7aa91ff12c2 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 11 Oct 2022 17:40:58 -0600 Subject: [PATCH 038/100] pass existing ioureportid --- src/libs/ReportUtils.js | 2 +- src/libs/actions/IOU.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index a894983acaf5..92f99a161f8d 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -674,7 +674,7 @@ function buildOptimisticIOUReport(ownerEmail, recipientEmail, total, chatReportI * @param {String} comment - User comment for the IOU. * @param {String} paymentType - Only required if the IOUReportAction type is 'pay'. Can be oneOf(elsewhere, payPal, Expensify). * @param {String} existingIOUTransactionID - Only required if the IOUReportAction type is oneOf(cancel, decline). Generates a randomID as default. - * @param {Number} existingIOUReportID - Only required if the IOUReportActions type is oneOf(decline, cancel, pay). Generates a randomID as default. + * @param {Number} existingIOUReportID - Only required if we have an existing IOUReportID. Generates a randomID as default. * * @returns {Object} */ diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 6723a7a028d1..bff493f5018a 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -250,8 +250,10 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment lodashGet(oneOnOneChatReport, 'maxSequenceNumber', 0) + 1, CONST.IOU.REPORT_ACTION_TYPE.CREATE, splitAmount, - currency, comment, + '', + '', + oneOnOneIOUReport.reportID, ); optimisticData.push( From 6e76758b5444db8664e28f3149b89a820090f318 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 12 Oct 2022 11:29:01 -0600 Subject: [PATCH 039/100] rm useless conditional and update comments --- src/pages/iou/IOUModal.js | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/src/pages/iou/IOUModal.js b/src/pages/iou/IOUModal.js index de2240c0b6d4..204f4ce05b14 100755 --- a/src/pages/iou/IOUModal.js +++ b/src/pages/iou/IOUModal.js @@ -316,22 +316,9 @@ class IOUModal extends Component { createTransaction(splits) { const reportID = lodashGet(this.props, 'route.params.reportID', ''); - // Only splits from a group DM has a reportID - // Check if reportID is a number - // @TODO: there are 3 conditionals here, which ones are correct? + // IOUs created from a group report will have a reportID param in the route. + // Since the user is already viewing the report, we don't need to navigate them to the report if (splits && CONST.REGEX.NUMBER.test(reportID)) { - IOU.splitBillAndOpenReport( - this.state.participants, - this.props.currentUserPersonalDetails.login, - this.state.amount, - this.state.comment, - this.props.iou.selectedCurrencyCode, - this.props.preferredLocale, - ); - return; - } - - if (splits && reportID) { IOU.splitBill( this.state.participants, this.props.currentUserPersonalDetails.login, @@ -343,6 +330,7 @@ class IOUModal extends Component { return; } + // If the IOU is created from the global create menu, we also navigate the user to the group report if (splits) { IOU.splitBillAndOpenReport( this.state.participants, From 68d4d9d6f380a80cafc6368f9a4577666901c203 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 12 Oct 2022 11:39:15 -0600 Subject: [PATCH 040/100] enable confirm button when offline --- src/components/IOUConfirmationList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/IOUConfirmationList.js b/src/components/IOUConfirmationList.js index f4b7f69c9f58..a22f9c2733eb 100755 --- a/src/components/IOUConfirmationList.js +++ b/src/components/IOUConfirmationList.js @@ -307,7 +307,7 @@ class IOUConfirmationList extends Component { render() { const selectedParticipants = this.getSelectedParticipants(); const shouldShowSettlementButton = this.props.iouType === CONST.IOU.IOU_TYPE.SEND; - const shouldDisableButton = selectedParticipants.length === 0 || this.props.network.isOffline; + const shouldDisableButton = selectedParticipants.length === 0; const isLoading = this.props.iou.loading && !this.props.network.isOffline; const recipient = this.state.participants[0]; const canModifyParticipants = this.props.isIOUAttachedToExistingChatReport && this.props.hasMultipleParticipants; From f58c0d085ba1b11ec4ac7bc644aef076ba7667d0 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 12 Oct 2022 12:05:58 -0600 Subject: [PATCH 041/100] add split type --- src/CONST.js | 1 + src/libs/ReportUtils.js | 6 +++++- src/libs/actions/IOU.js | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/CONST.js b/src/CONST.js index 2de10a4ae73d..f255e7200bdc 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -650,6 +650,7 @@ const CONST = { REPORT_ACTION_TYPE: { PAY: 'pay', CREATE: 'create', + SPLIT: 'split', }, AMOUNT_MAX_LENGTH: 10, }, diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 92f99a161f8d..0a28f2902968 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -669,7 +669,7 @@ function buildOptimisticIOUReport(ownerEmail, recipientEmail, total, chatReportI * Builds an optimistic IOU reportAction object * * @param {Number} sequenceNumber - Caller is responsible for providing a best guess at what the next sequenceNumber will be. - * @param {String} type - IOUReportAction type. Can be oneOf(create, decline, cancel, pay). + * @param {String} type - IOUReportAction type. Can be oneOf(create, decline, cancel, pay, split). * @param {Number} amount - IOU amount in cents. * @param {String} comment - User comment for the IOU. * @param {String} paymentType - Only required if the IOUReportAction type is 'pay'. Can be oneOf(elsewhere, payPal, Expensify). @@ -700,6 +700,10 @@ function buildOptimisticIOUReportAction(sequenceNumber, type, amount, comment, p originalMessage.paymentType = paymentType; } + if (type === CONST.IOU.REPORT_ACTION_TYPE.SPLIT) { + delete originalMessage.IOUReportID; + } + return { actionName: CONST.REPORT.ACTIONS.TYPE.IOU, actorAccountID: currentUserAccountID, diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index bff493f5018a..d1feb250e83c 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -158,7 +158,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment const groupCreatedReportAction = existingGroupChatReport ? {} : ReportUtils.buildOptimisticCreatedReportAction(currentUserEmail); const groupIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( lodashGet(groupChatReport, 'maxSequenceNumber', 0) + 1, - CONST.IOU.REPORT_ACTION_TYPE.CREATE, + CONST.IOU.REPORT_ACTION_TYPE.SPLIT, Math.round(amount * 100), comment, ); From 9587c54ff5bd89149074dcb302e12b0734b56020 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 12 Oct 2022 12:25:14 -0600 Subject: [PATCH 042/100] create buildOptimisticIOUReportActionMessage --- src/libs/ReportUtils.js | 87 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 0a28f2902968..08c28f4dad79 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -692,12 +692,20 @@ function buildOptimisticIOUReportAction(sequenceNumber, type, amount, comment, p }; // We store amount, comment, currency in IOUDetails when type = pay + // let message; if (type === CONST.IOU.REPORT_ACTION_TYPE.PAY) { _.each(['amount', 'comment', 'currency'], (key) => { delete originalMessage[key]; }); originalMessage.IOUDetails = {amount, comment, currency}; originalMessage.paymentType = paymentType; + + // message = [{ + // html: '', + // text: '', + // isEdited: false, + // type: CONST.REPORT.MESSAGE.TYPE.COMMENT, + // }]; } if (type === CONST.IOU.REPORT_ACTION_TYPE.SPLIT) { @@ -713,6 +721,7 @@ function buildOptimisticIOUReportAction(sequenceNumber, type, amount, comment, p clientID: NumberUtils.generateReportActionClientID(), isAttachment: false, originalMessage, + // message, person: [{ style: 'strong', text: lodashGet(currentUserPersonalDetails, 'displayName', currentUserEmail), @@ -726,6 +735,84 @@ function buildOptimisticIOUReportAction(sequenceNumber, type, amount, comment, p }; } +/** + * + * @param {*} type + * @param {*} paymentType + * @param {*} actorEmail + * @param {*} originalMessage + * @returns {Array} + */ +function buildOptimisticIOUReportActionMessage(type, paymentType, actorEmail, originalMessage) { + $IOUDetails = $this->container['message']['IOUDetails'] ?? []; + $isSendRequest = !empty($IOUDetails); + if ($isSendRequest) { + $formattedAmount = ForexUtils::format(abs($originalMessage['amount']), $originalMessage['currency']); + } else { + $formattedAmount = ForexUtils::format(abs($this->container['message']['amount']), $this->container['message']['currency']); + } + + $comment = $this->container['message']['comment']; + switch ($type) { + case 'pay': + if ($isSendRequest) { + $comment = $originalMessage['comment']; + $message = 'Sent'; + $message .= $formattedAmount ? " {$formattedAmount}" : ''; + $message .= $formattedAmount && strlen($comment) ? " for {$comment}" : ''; + } else { + $message = 'Settled up'; + } + if ($paymentType === self::PAYMENT_TYPE_PAYPAL_ME) { + $message .= ' using PayPal.me'; + } elseif ($paymentType === self::PAYMENT_TYPE_VENMO) { + $message .= ' using Venmo'; + } elseif ($paymentType === self::PAYMENT_TYPE_EXPENSIFY) { + $message .= '!'; + } else { + $message .= ' elsewhere'; + } + break; + case 'create': + case 'split': + if (isset($this->container['message']['participants'])) { + $who = ArrayUtils::filter($this->container['message']['participants'], fn ($email) => $email !== $actorEmail); + } else { + // Newer actions have the participants in the message, but old ones do not + $actorAuthToken = AuthTokenManager::getEmailToken($actorEmail); + $chatReport = ReportStore::getByID($actorAuthToken, $this->getReportID(), true); + $who = $chatReport->getParticipants([$actorEmail, '__FAKE__', EMAIL_ACCOUNT_ID_0]); + } + $who = array_values(ArrayUtils::map(PersonalDetailsStore::getByEmails($who), fn (PersonalDetail $personalDetail) => $personalDetail->getFirstName() ?: $personalDetail->getEmail())); + if (count($who) === 1) { + $who = $who[0]; + } else { + $who = implode(', ', array_slice($who, 0, -1)).' and '.$who[count($who) - 1]; + } + if ($type === 'create') { + $message = "Requested $formattedAmount from $who".(strlen($comment) ? " for {$comment}" : ''); + } else { + $message = "Split $formattedAmount with $who".(strlen($comment) ? " for {$comment}" : ''); + } + break; + case 'cancel': + $message = "Cancelled the $formattedAmount request".(strlen($comment) ? " for {$comment}" : ''); + break; + case 'decline': + $message = "Declined the $formattedAmount request".(strlen($comment) ? " for {$comment}" : ''); + break; + default: + // This should only be hit for actions created before we standardized on having `type` + $message = 'This action was taken on old code and is not supported anymore'; + break; + } + $messages = []; + if ($message) { + $messages[] = ReportUtils::createHTMLCommentFragment($message, []); + } + return $messages; +} + /** * Builds an optimistic chat report with a randomly generated reportID and as much information as we currently have * From 12ff4a00a6d1f2eb9c02d594da69d0f439b061bb Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 12 Oct 2022 12:54:17 -0600 Subject: [PATCH 043/100] rm loading states --- src/components/IOUConfirmationList.js | 9 ---- src/libs/ReportUtils.js | 78 --------------------------- 2 files changed, 87 deletions(-) diff --git a/src/components/IOUConfirmationList.js b/src/components/IOUConfirmationList.js index a22f9c2733eb..7980a069c80d 100755 --- a/src/components/IOUConfirmationList.js +++ b/src/components/IOUConfirmationList.js @@ -14,8 +14,6 @@ import ButtonWithMenu from './ButtonWithMenu'; import Log from '../libs/Log'; import SettlementButton from './SettlementButton'; import ROUTES from '../ROUTES'; -import networkPropTypes from './networkPropTypes'; -import {withNetwork} from './OnyxProvider'; import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from './withCurrentUserPersonalDetails'; import * as IOUUtils from '../libs/IOUUtils'; @@ -80,9 +78,6 @@ const propTypes = { selectedCurrencyCode: PropTypes.string, }), - /** Information about the network */ - network: networkPropTypes.isRequired, - /** Current user session */ session: PropTypes.shape({ email: PropTypes.string.isRequired, @@ -308,7 +303,6 @@ class IOUConfirmationList extends Component { const selectedParticipants = this.getSelectedParticipants(); const shouldShowSettlementButton = this.props.iouType === CONST.IOU.IOU_TYPE.SEND; const shouldDisableButton = selectedParticipants.length === 0; - const isLoading = this.props.iou.loading && !this.props.network.isOffline; const recipient = this.state.participants[0]; const canModifyParticipants = this.props.isIOUAttachedToExistingChatReport && this.props.hasMultipleParticipants; return ( @@ -333,7 +327,6 @@ class IOUConfirmationList extends Component { ? ( this.confirm(value)} options={this.splitOrRequestOptions} /> @@ -360,7 +352,6 @@ IOUConfirmationList.defaultProps = defaultProps; export default compose( withLocalize, withWindowDimensions, - withNetwork(), withCurrentUserPersonalDetails, withOnyx({ iou: {key: ONYXKEYS.IOU}, diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 08c28f4dad79..8f6f421c3115 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -735,84 +735,6 @@ function buildOptimisticIOUReportAction(sequenceNumber, type, amount, comment, p }; } -/** - * - * @param {*} type - * @param {*} paymentType - * @param {*} actorEmail - * @param {*} originalMessage - * @returns {Array} - */ -function buildOptimisticIOUReportActionMessage(type, paymentType, actorEmail, originalMessage) { - $IOUDetails = $this->container['message']['IOUDetails'] ?? []; - $isSendRequest = !empty($IOUDetails); - if ($isSendRequest) { - $formattedAmount = ForexUtils::format(abs($originalMessage['amount']), $originalMessage['currency']); - } else { - $formattedAmount = ForexUtils::format(abs($this->container['message']['amount']), $this->container['message']['currency']); - } - - $comment = $this->container['message']['comment']; - switch ($type) { - case 'pay': - if ($isSendRequest) { - $comment = $originalMessage['comment']; - $message = 'Sent'; - $message .= $formattedAmount ? " {$formattedAmount}" : ''; - $message .= $formattedAmount && strlen($comment) ? " for {$comment}" : ''; - } else { - $message = 'Settled up'; - } - if ($paymentType === self::PAYMENT_TYPE_PAYPAL_ME) { - $message .= ' using PayPal.me'; - } elseif ($paymentType === self::PAYMENT_TYPE_VENMO) { - $message .= ' using Venmo'; - } elseif ($paymentType === self::PAYMENT_TYPE_EXPENSIFY) { - $message .= '!'; - } else { - $message .= ' elsewhere'; - } - break; - case 'create': - case 'split': - if (isset($this->container['message']['participants'])) { - $who = ArrayUtils::filter($this->container['message']['participants'], fn ($email) => $email !== $actorEmail); - } else { - // Newer actions have the participants in the message, but old ones do not - $actorAuthToken = AuthTokenManager::getEmailToken($actorEmail); - $chatReport = ReportStore::getByID($actorAuthToken, $this->getReportID(), true); - $who = $chatReport->getParticipants([$actorEmail, '__FAKE__', EMAIL_ACCOUNT_ID_0]); - } - $who = array_values(ArrayUtils::map(PersonalDetailsStore::getByEmails($who), fn (PersonalDetail $personalDetail) => $personalDetail->getFirstName() ?: $personalDetail->getEmail())); - if (count($who) === 1) { - $who = $who[0]; - } else { - $who = implode(', ', array_slice($who, 0, -1)).' and '.$who[count($who) - 1]; - } - if ($type === 'create') { - $message = "Requested $formattedAmount from $who".(strlen($comment) ? " for {$comment}" : ''); - } else { - $message = "Split $formattedAmount with $who".(strlen($comment) ? " for {$comment}" : ''); - } - break; - case 'cancel': - $message = "Cancelled the $formattedAmount request".(strlen($comment) ? " for {$comment}" : ''); - break; - case 'decline': - $message = "Declined the $formattedAmount request".(strlen($comment) ? " for {$comment}" : ''); - break; - default: - // This should only be hit for actions created before we standardized on having `type` - $message = 'This action was taken on old code and is not supported anymore'; - break; - } - $messages = []; - if ($message) { - $messages[] = ReportUtils::createHTMLCommentFragment($message, []); - } - return $messages; -} - /** * Builds an optimistic chat report with a randomly generated reportID and as much information as we currently have * From 1179bdf732041011906612337cc74a2b6d8dee33 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 12 Oct 2022 12:55:27 -0600 Subject: [PATCH 044/100] fix iou badge prop types --- src/components/IOUBadge.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/IOUBadge.js b/src/components/IOUBadge.js index 3a93f6f9f87e..ca945e076727 100644 --- a/src/components/IOUBadge.js +++ b/src/components/IOUBadge.js @@ -24,8 +24,8 @@ const propTypes = { const defaultProps = { iouReport: { - reportID: 0, - chatReportID: 0, + reportID: '', + chatReportID: '', total: 0, ownerEmail: null, currency: CONST.CURRENCY.USD, From b6c57a3ed69359a2521d6d04b2c8fcf2a63880b4 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 12 Oct 2022 12:56:30 -0600 Subject: [PATCH 045/100] add pending action to iouaction --- src/components/ReportActionItem/IOUAction.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/ReportActionItem/IOUAction.js b/src/components/ReportActionItem/IOUAction.js index 1baa2305b378..bc526e46dff7 100644 --- a/src/components/ReportActionItem/IOUAction.js +++ b/src/components/ReportActionItem/IOUAction.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; +import lodashGet from 'lodash/get'; import ONYXKEYS from '../../ONYXKEYS'; import IOUQuote from './IOUQuote'; import reportActionPropTypes from '../../pages/home/report/reportActionPropTypes'; @@ -47,6 +48,7 @@ const IOUAction = (props) => { {((props.isMostRecentIOUReportAction && Boolean(props.action.originalMessage.IOUReportID)) || (props.action.originalMessage.type === 'pay')) && ( Date: Wed, 12 Oct 2022 12:57:46 -0600 Subject: [PATCH 046/100] add pending action to ioupreview --- src/components/ReportActionItem/IOUPreview.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/ReportActionItem/IOUPreview.js b/src/components/ReportActionItem/IOUPreview.js index 121fd115b023..2e4e7438f9a6 100644 --- a/src/components/ReportActionItem/IOUPreview.js +++ b/src/components/ReportActionItem/IOUPreview.js @@ -81,6 +81,9 @@ const propTypes = { /** Information about the user accepting the terms for payments */ walletTerms: walletTermsPropTypes, + /** Pending action, if any */ + pendingAction: PropTypes.string, + ...withLocalizePropTypes, }; @@ -91,6 +94,7 @@ const defaultProps = { onPreviewPressed: () => {}, containerStyles: [], walletTerms: {}, + pendingAction: null, }; const IOUPreview = (props) => { @@ -132,7 +136,7 @@ const IOUPreview = (props) => { ? : ( { PaymentMethods.clearWalletTermsError(); From 9a182d9b6994c305ad1de33e9e958b0c3729c816 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 12 Oct 2022 13:26:06 -0600 Subject: [PATCH 047/100] create getIOUReportActionMessage --- src/libs/ReportUtils.js | 35 +++++++++++++++++++++++++---------- src/libs/actions/IOU.js | 2 ++ 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 8f6f421c3115..fd53df7d67d9 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -665,6 +665,28 @@ function buildOptimisticIOUReport(ownerEmail, recipientEmail, total, chatReportI }; } +function getIOUReportActionMessage(type, amount, participants, comment) { + const participantDisplayNames = _.each(participants, participant => lodashGet(allPersonalDetails, [participant, 'displayName'], participant)); + let iouMessage; + switch (type) { + case CONST.IOU.REPORT_ACTION_TYPE.CREATE: + iouMessage = `Requested ${amount} from ${participantDisplayNames}${comment && ` for ${comment}`}`; + break; + case CONST.IOU.REPORT_ACTION_TYPE.SPLIT: + iouMessage = `Split ${amount} with ${participantDisplayNames}${comment && ` for ${comment}`}`; + break; + default: + break; + } + + return [{ + html: iouMessage, + text: iouMessage, + isEdited: false, + type: CONST.REPORT.MESSAGE.TYPE.COMMENT, + }]; +} + /** * Builds an optimistic IOU reportAction object * @@ -672,13 +694,14 @@ function buildOptimisticIOUReport(ownerEmail, recipientEmail, total, chatReportI * @param {String} type - IOUReportAction type. Can be oneOf(create, decline, cancel, pay, split). * @param {Number} amount - IOU amount in cents. * @param {String} comment - User comment for the IOU. + * @param {Array} participants - An array with participants details. * @param {String} paymentType - Only required if the IOUReportAction type is 'pay'. Can be oneOf(elsewhere, payPal, Expensify). * @param {String} existingIOUTransactionID - Only required if the IOUReportAction type is oneOf(cancel, decline). Generates a randomID as default. * @param {Number} existingIOUReportID - Only required if we have an existing IOUReportID. Generates a randomID as default. * * @returns {Object} */ -function buildOptimisticIOUReportAction(sequenceNumber, type, amount, comment, paymentType = '', existingIOUTransactionID = '', existingIOUReportID = 0) { +function buildOptimisticIOUReportAction(sequenceNumber, type, amount, comment, participants, paymentType = '', existingIOUTransactionID = '', existingIOUReportID = 0) { const currency = lodashGet(currentUserPersonalDetails, 'localCurrencyCode'); const IOUTransactionID = existingIOUTransactionID || NumberUtils.rand64(); const IOUReportID = existingIOUReportID || generateReportID(); @@ -692,20 +715,12 @@ function buildOptimisticIOUReportAction(sequenceNumber, type, amount, comment, p }; // We store amount, comment, currency in IOUDetails when type = pay - // let message; if (type === CONST.IOU.REPORT_ACTION_TYPE.PAY) { _.each(['amount', 'comment', 'currency'], (key) => { delete originalMessage[key]; }); originalMessage.IOUDetails = {amount, comment, currency}; originalMessage.paymentType = paymentType; - - // message = [{ - // html: '', - // text: '', - // isEdited: false, - // type: CONST.REPORT.MESSAGE.TYPE.COMMENT, - // }]; } if (type === CONST.IOU.REPORT_ACTION_TYPE.SPLIT) { @@ -721,7 +736,7 @@ function buildOptimisticIOUReportAction(sequenceNumber, type, amount, comment, p clientID: NumberUtils.generateReportActionClientID(), isAttachment: false, originalMessage, - // message, + message: getIOUReportActionMessage(type, amount, participants, comment), person: [{ style: 'strong', text: lodashGet(currentUserPersonalDetails, 'displayName', currentUserEmail), diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index d1feb250e83c..a2ec5c95d28e 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -161,6 +161,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment CONST.IOU.REPORT_ACTION_TYPE.SPLIT, Math.round(amount * 100), comment, + participants, ); const optimisticData = [ @@ -251,6 +252,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment CONST.IOU.REPORT_ACTION_TYPE.CREATE, splitAmount, comment, + [participant], '', '', oneOnOneIOUReport.reportID, From a5d771e941449b50be992802d4b2233260537b23 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 12 Oct 2022 14:02:07 -0600 Subject: [PATCH 048/100] add translations to message --- src/languages/en.js | 2 ++ src/languages/es.js | 2 ++ src/libs/ReportUtils.js | 11 ++++++++--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/languages/en.js b/src/languages/en.js index eea9ccc81f65..24acbcbf611d 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -255,6 +255,8 @@ export default { split: ({amount}) => `Split ${amount}`, send: ({amount}) => `Send ${amount}`, noReimbursableExpenses: 'This report has an invalid amount', + requestedFrom: ({amount, from, comment}) => `Requested ${amount} from ${from}${comment && ` for ${comment}`}`, + splitWith: ({amount, from, comment}) => `Split ${amount} with ${from}${comment && ` for ${comment}`}`, error: { invalidSplit: 'Split amounts do not equal total amount', other: 'Unexpected error, please try again later', diff --git a/src/languages/es.js b/src/languages/es.js index 394010a83425..c26c0a3e0bd0 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -255,6 +255,8 @@ export default { split: ({amount}) => `Dividir ${amount}`, send: ({amount}) => `Enviar ${amount}`, noReimbursableExpenses: 'El monto de este informe es inválido', + requestedFrom: ({amount, from, comment}) => `Pidió ${amount} de ${from}${comment && ` para ${comment}`}`, + splitWith: ({amount, from, comment}) => `Dividir ${amount} con ${from}${comment && ` para ${comment}`}`, error: { invalidSplit: 'La suma de las partes no equivale al monto total', other: 'Error inesperado, por favor inténtalo más tarde', diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index fd53df7d67d9..49de28dd63cd 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -666,14 +666,18 @@ function buildOptimisticIOUReport(ownerEmail, recipientEmail, total, chatReportI } function getIOUReportActionMessage(type, amount, participants, comment) { - const participantDisplayNames = _.each(participants, participant => lodashGet(allPersonalDetails, [participant, 'displayName'], participant)); + const displayNames = _.map(participants, participant => lodashGet(participant, 'displayName', participant.email)); + const from = displayNames.length < 3 + ? displayNames.join(' and ') + : `${displayNames.slice(0, -1).join(', ')}, ${Localize.translateLocal('common.and')} ${_.last(displayNames)}`; + let iouMessage; switch (type) { case CONST.IOU.REPORT_ACTION_TYPE.CREATE: - iouMessage = `Requested ${amount} from ${participantDisplayNames}${comment && ` for ${comment}`}`; + iouMessage = Localize.translateLocal('iou.requestedFrom', {amount, from, comment}); break; case CONST.IOU.REPORT_ACTION_TYPE.SPLIT: - iouMessage = `Split ${amount} with ${participantDisplayNames}${comment && ` for ${comment}`}`; + iouMessage = Localize.translateLocal('iou.splitWith', {amount, from, comment}); break; default: break; @@ -723,6 +727,7 @@ function buildOptimisticIOUReportAction(sequenceNumber, type, amount, comment, p originalMessage.paymentType = paymentType; } + // IOUs of type split only exist in group DMs and those don't have an iouReport so we need to delete the IOUReportID key if (type === CONST.IOU.REPORT_ACTION_TYPE.SPLIT) { delete originalMessage.IOUReportID; } From 9bfba9dbb72f9255c5c6286e4a253cf52ef62e5b Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 12 Oct 2022 14:16:51 -0600 Subject: [PATCH 049/100] add formatted amount --- src/libs/ReportUtils.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 49de28dd63cd..847b53132800 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -665,8 +665,9 @@ function buildOptimisticIOUReport(ownerEmail, recipientEmail, total, chatReportI }; } -function getIOUReportActionMessage(type, amount, participants, comment) { - const displayNames = _.map(participants, participant => lodashGet(participant, 'displayName', participant.email)); +function getIOUReportActionMessage(type, total, participants, comment, currency) { + const amount = NumberFormatUtils.format(preferredLocale, total / 100, {style: 'currency', currency}); + const displayNames = _.map(participants, participant => lodashGet(participant, 'displayName', participant.login)); const from = displayNames.length < 3 ? displayNames.join(' and ') : `${displayNames.slice(0, -1).join(', ')}, ${Localize.translateLocal('common.and')} ${_.last(displayNames)}`; @@ -741,7 +742,7 @@ function buildOptimisticIOUReportAction(sequenceNumber, type, amount, comment, p clientID: NumberUtils.generateReportActionClientID(), isAttachment: false, originalMessage, - message: getIOUReportActionMessage(type, amount, participants, comment), + message: getIOUReportActionMessage(type, amount, participants, comment, currency), person: [{ style: 'strong', text: lodashGet(currentUserPersonalDetails, 'displayName', currentUserEmail), From 47e3fedf0dea280f7e3a056fba94b42c3b7abcb8 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 12 Oct 2022 14:43:12 -0600 Subject: [PATCH 050/100] add comment --- src/libs/ReportUtils.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 847b53132800..a0cfb259cd1f 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -667,7 +667,10 @@ function buildOptimisticIOUReport(ownerEmail, recipientEmail, total, chatReportI function getIOUReportActionMessage(type, total, participants, comment, currency) { const amount = NumberFormatUtils.format(preferredLocale, total / 100, {style: 'currency', currency}); - const displayNames = _.map(participants, participant => lodashGet(participant, 'displayName', participant.login)); + + // @TODO: we should get the display name for the participant, but that doesn't seem to be stored in the participants object + // so I'm using text instead + const displayNames = _.map(participants, participant => lodashGet(participant, 'text', participant.login)); const from = displayNames.length < 3 ? displayNames.join(' and ') : `${displayNames.slice(0, -1).join(', ')}, ${Localize.translateLocal('common.and')} ${_.last(displayNames)}`; From da9a8957bb8046fe7517b790a2e1241819215aeb Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 12 Oct 2022 14:57:51 -0600 Subject: [PATCH 051/100] send amount in cents to api --- src/libs/actions/IOU.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index a2ec5c95d28e..f03303c19d35 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -350,7 +350,7 @@ function splitBill(participants, currentUserLogin, amount, comment, currency, lo API.write('SplitBill', { reportID: groupData.chatReportID, - amount, + amount: Math.round(amount * 100), splits: JSON.stringify(splits), currency, comment, @@ -372,7 +372,7 @@ function splitBillAndOpenReport(participants, currentUserLogin, amount, comment, API.write('SplitBillAndOpenReport', { reportID: groupData.chatReportID, - amount, + amount: Math.round(amount * 100), splits: JSON.stringify(splits), currency, comment, From 74dac7e0730409592af6225ac3bbc94ae56902ed Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 13 Oct 2022 13:57:47 -0600 Subject: [PATCH 052/100] dismiss modal on split bill --- src/libs/actions/IOU.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index f03303c19d35..5909fb09954a 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -357,6 +357,8 @@ function splitBill(participants, currentUserLogin, amount, comment, currency, lo transactionID: groupData.transactionID, reportActionID: groupData.reportActionID, }, onyxData); + + Navigation.dismissModal(); } /** From eaef497b39d45e64c4de836ba9833794be631e47 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 13 Oct 2022 14:33:18 -0600 Subject: [PATCH 053/100] use getChatByParticipants --- src/libs/ReportUtils.js | 24 ++++++++++++++++++++++++ src/libs/actions/IOU.js | 9 ++------- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 24025cd0e1e4..5db5f24ed340 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -58,6 +58,13 @@ Onyx.connect({ }, }); +let allReports; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT, + waitForCollectionCallback: true, + callback: val => allReports = val, +}); + /** * Returns the concatenated title for the PrimaryLogins of a report * @@ -994,6 +1001,22 @@ function shouldReportBeInOptionList(report, reportIDFromRoute, isInGSDMode, curr return true; } +/** + * Attempts to find a report in onyx with the provided list of participants + * @param {Array} newParticipantList + * @returns {Array|undefined} + */ +function getChatByParticipants(newParticipantList) { + newParticipantList.sort(); + return _.find(allReports, (report) => { + // If the report has been deleted, or there are no participants (like an empty #admins room) then skip it + if (!report || !report.participants) { + return false; + } + return _.isEqual(newParticipantList, report.participants.sort()); + }); +} + export { getReportParticipantsTitle, isReportMessageAttachment, @@ -1034,4 +1057,5 @@ export { buildOptimisticIOUReportAction, buildOptimisticReportAction, shouldReportBeInOptionList, + getChatByParticipants, }; diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 5909fb09954a..36c68e36a6a6 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -150,10 +150,7 @@ function createIOUTransaction(params) { */ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment, currency, locale) { const currentUserEmail = OptionsListUtils.addSMSDomainIfPhoneNumber(currentUserLogin); - - // getChatByParticipants should be created in this PR https://github.com/Expensify/App/pull/11439/files - // const existingGroupChatReport = ReportUtils.getChatByParticipants(participants); - const existingGroupChatReport = false; + const existingGroupChatReport = ReportUtils.getChatByParticipants(participants); const groupChatReport = existingGroupChatReport || ReportUtils.buildOptimisticChatReport(_.pluck(participants, 'login')); const groupCreatedReportAction = existingGroupChatReport ? {} : ReportUtils.buildOptimisticCreatedReportAction(currentUserEmail); const groupIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( @@ -227,9 +224,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment return; } - // getChatByParticipants should be created in this PR https://github.com/Expensify/App/pull/11439/files - // const existingOneOnOneChatReport = ReportUtils.getChatByParticipants([currentUserEmail, email]); - const existingOneOnOneChatReport = false; + const existingOneOnOneChatReport = ReportUtils.getChatByParticipants([email]); const oneOnOneChatReport = existingOneOnOneChatReport || ReportUtils.buildOptimisticChatReport([email]); let oneOnOneIOUReport; if (oneOnOneChatReport.iouReportID) { From 5a19404816d0bc20d2ae7c8aa0b0905e10ca9145 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 13 Oct 2022 15:17:17 -0600 Subject: [PATCH 054/100] fix iouReport key --- src/libs/actions/IOU.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 36c68e36a6a6..990047225e13 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -266,7 +266,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment }, { onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneChatReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneIOUReport.reportID}`, value: oneOnOneIOUReport, }, { From 54b09d6f57b5b5559c936cdc1675737d717e03e5 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 13 Oct 2022 17:00:29 -0600 Subject: [PATCH 055/100] fix participants login list --- src/libs/actions/IOU.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 990047225e13..addbb1c60713 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -150,7 +150,8 @@ function createIOUTransaction(params) { */ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment, currency, locale) { const currentUserEmail = OptionsListUtils.addSMSDomainIfPhoneNumber(currentUserLogin); - const existingGroupChatReport = ReportUtils.getChatByParticipants(participants); + const participantLogins = _.map(participants, participant => OptionsListUtils.addSMSDomainIfPhoneNumber(participant.login)); + const existingGroupChatReport = ReportUtils.getChatByParticipants(participantLogins); const groupChatReport = existingGroupChatReport || ReportUtils.buildOptimisticChatReport(_.pluck(participants, 'login')); const groupCreatedReportAction = existingGroupChatReport ? {} : ReportUtils.buildOptimisticCreatedReportAction(currentUserEmail); const groupIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( From c77fab4af3cb0ab6fb455ef75b4a2e1c99cdb3cf Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 13 Oct 2022 17:17:54 -0600 Subject: [PATCH 056/100] remove getSplits --- src/components/IOUConfirmationList.js | 31 +-------------------------- src/pages/iou/IOUModal.js | 11 +++------- 2 files changed, 4 insertions(+), 38 deletions(-) diff --git a/src/components/IOUConfirmationList.js b/src/components/IOUConfirmationList.js index 7980a069c80d..e23e486c8bf4 100755 --- a/src/components/IOUConfirmationList.js +++ b/src/components/IOUConfirmationList.js @@ -213,35 +213,6 @@ class IOUConfirmationList extends Component { return sections; } - /** - * Gets splits for the transaction - * @returns {Array|null} - */ - getSplits() { - // There can only be splits when there are multiple participants, so return early when there are not - // multiple participants - if (!this.props.hasMultipleParticipants) { - return null; - } - const selectedParticipants = this.getSelectedParticipants(); - const splits = _.map(selectedParticipants, participant => ({ - email: OptionsListUtils.addSMSDomainIfPhoneNumber(participant.login), - - // We should send in cents to API - // Cents is temporary and there must be support for other currencies in the future - amount: IOUUtils.calculateAmount(selectedParticipants, this.props.iouAmount), - })); - - splits.push({ - email: OptionsListUtils.addSMSDomainIfPhoneNumber(this.props.currentUserPersonalDetails.login), - - // The user is default and we should send in cents to API - // USD is temporary and there must be support for other currencies in the future - amount: IOUUtils.calculateAmount(selectedParticipants, this.props.iouAmount, true), - }); - return splits; - } - /** * Returns selected options -- there is checkmark for every row in List for split flow * @returns {Array} @@ -295,7 +266,7 @@ class IOUConfirmationList extends Component { Log.info(`[IOU] Sending money via: ${paymentMethod}`); this.props.onSendMoney(paymentMethod); } else { - this.props.onConfirm(this.getSplits()); + this.props.onConfirm(); } } diff --git a/src/pages/iou/IOUModal.js b/src/pages/iou/IOUModal.js index 204f4ce05b14..274bf801d96c 100755 --- a/src/pages/iou/IOUModal.js +++ b/src/pages/iou/IOUModal.js @@ -308,17 +308,12 @@ class IOUModal extends Component { }); } - /** - * Create the IOU transaction - * - * @param {Array} [splits] - */ - createTransaction(splits) { + createTransaction() { const reportID = lodashGet(this.props, 'route.params.reportID', ''); // IOUs created from a group report will have a reportID param in the route. // Since the user is already viewing the report, we don't need to navigate them to the report - if (splits && CONST.REGEX.NUMBER.test(reportID)) { + if (this.props.hasMultipleParticipants && CONST.REGEX.NUMBER.test(reportID)) { IOU.splitBill( this.state.participants, this.props.currentUserPersonalDetails.login, @@ -331,7 +326,7 @@ class IOUModal extends Component { } // If the IOU is created from the global create menu, we also navigate the user to the group report - if (splits) { + if (this.props.hasMultipleParticipants) { IOU.splitBillAndOpenReport( this.state.participants, this.props.currentUserPersonalDetails.login, From a9daac932ed1579bd5d89c6fa2e4e0044188aa98 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 17 Oct 2022 15:37:42 -0600 Subject: [PATCH 057/100] pass clientID --- src/libs/actions/IOU.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index addbb1c60713..6a6f4ee41867 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -319,6 +319,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment chatReportID: oneOnOneChatReport.reportID, transactionID: oneOnOneIOUReportAction.originalMessage.IOUTransactionID, reportActionID: oneOnOneIOUReportAction.reportActionID, + clientID: oneOnOneIOUReportAction.sequenceNumber, }); }); @@ -327,6 +328,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment chatReportID: groupChatReport.reportID, transactionID: groupIOUReportAction.originalMessage.IOUTransactionID, reportActionID: groupIOUReportAction.reportActionID, + clientID: groupIOUReportAction.sequenceNumber, }, splits, onyxData: {optimisticData, successData, failureData}, @@ -352,6 +354,7 @@ function splitBill(participants, currentUserLogin, amount, comment, currency, lo comment, transactionID: groupData.transactionID, reportActionID: groupData.reportActionID, + clientID: groupData.sequenceNumber, }, onyxData); Navigation.dismissModal(); @@ -376,6 +379,7 @@ function splitBillAndOpenReport(participants, currentUserLogin, amount, comment, comment, transactionID: groupData.transactionID, reportActionID: groupData.reportActionID, + clientID: groupData.clientID, }, onyxData); Navigation.navigate(ROUTES.getReportRoute(groupData.chatReportID)); From b28f87f15937a1fdaf223c10b5c1c480480a6452 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 17 Oct 2022 15:40:07 -0600 Subject: [PATCH 058/100] fix clientid --- src/libs/actions/IOU.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 6a6f4ee41867..fff559c89e53 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -354,7 +354,7 @@ function splitBill(participants, currentUserLogin, amount, comment, currency, lo comment, transactionID: groupData.transactionID, reportActionID: groupData.reportActionID, - clientID: groupData.sequenceNumber, + clientID: groupData.clientID, }, onyxData); Navigation.dismissModal(); From 8f4d882249c532856793e54f0284eee0a56da302 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 17 Oct 2022 16:32:48 -0600 Subject: [PATCH 059/100] use correct clientID --- src/libs/actions/IOU.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index fff559c89e53..8d1eb0bc94ba 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -319,7 +319,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment chatReportID: oneOnOneChatReport.reportID, transactionID: oneOnOneIOUReportAction.originalMessage.IOUTransactionID, reportActionID: oneOnOneIOUReportAction.reportActionID, - clientID: oneOnOneIOUReportAction.sequenceNumber, + clientID: oneOnOneIOUReportAction.clientID, }); }); @@ -328,7 +328,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment chatReportID: groupChatReport.reportID, transactionID: groupIOUReportAction.originalMessage.IOUTransactionID, reportActionID: groupIOUReportAction.reportActionID, - clientID: groupIOUReportAction.sequenceNumber, + clientID: groupIOUReportAction.clientID, }, splits, onyxData: {optimisticData, successData, failureData}, From d23d84551d515813087c2711f779588e2ce58038 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 17 Oct 2022 18:37:04 -0600 Subject: [PATCH 060/100] convert clientID to string --- src/libs/actions/IOU.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 8d1eb0bc94ba..07b0a3c8d266 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -319,7 +319,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment chatReportID: oneOnOneChatReport.reportID, transactionID: oneOnOneIOUReportAction.originalMessage.IOUTransactionID, reportActionID: oneOnOneIOUReportAction.reportActionID, - clientID: oneOnOneIOUReportAction.clientID, + clientID: oneOnOneIOUReportAction.clientID.toString(), }); }); @@ -328,7 +328,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment chatReportID: groupChatReport.reportID, transactionID: groupIOUReportAction.originalMessage.IOUTransactionID, reportActionID: groupIOUReportAction.reportActionID, - clientID: groupIOUReportAction.clientID, + clientID: groupIOUReportAction.clientID.toString(), }, splits, onyxData: {optimisticData, successData, failureData}, From bf26ba6bca116680e79ce1acf40c0c7c1e698c76 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 18 Oct 2022 12:56:21 -0600 Subject: [PATCH 061/100] rm comment --- src/libs/ReportUtils.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 5db5f24ed340..0603c27e6f1b 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -670,8 +670,6 @@ function buildOptimisticIOUReport(ownerEmail, recipientEmail, total, chatReportI function getIOUReportActionMessage(type, total, participants, comment, currency) { const amount = NumberFormatUtils.format(preferredLocale, total / 100, {style: 'currency', currency}); - // @TODO: we should get the display name for the participant, but that doesn't seem to be stored in the participants object - // so I'm using text instead const displayNames = _.map(participants, participant => lodashGet(participant, 'text', participant.login)); const from = displayNames.length < 3 ? displayNames.join(' and ') From fe49af4b962257e93baec090d4d8a12c4108fdbb Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 18 Oct 2022 15:43:49 -0600 Subject: [PATCH 062/100] update sequence number --- src/libs/actions/IOU.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 07b0a3c8d266..b88c0697bd58 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -154,8 +154,9 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment const existingGroupChatReport = ReportUtils.getChatByParticipants(participantLogins); const groupChatReport = existingGroupChatReport || ReportUtils.buildOptimisticChatReport(_.pluck(participants, 'login')); const groupCreatedReportAction = existingGroupChatReport ? {} : ReportUtils.buildOptimisticCreatedReportAction(currentUserEmail); + const groupChatReportMaxSequenceNumber = lodashGet(groupChatReport, 'maxSequenceNumber', 0); const groupIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( - lodashGet(groupChatReport, 'maxSequenceNumber', 0) + 1, + groupChatReportMaxSequenceNumber + 1, CONST.IOU.REPORT_ACTION_TYPE.SPLIT, Math.round(amount * 100), comment, @@ -168,6 +169,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment key: `${ONYXKEYS.COLLECTION.REPORT}${groupChatReport.reportID}`, value: { ...groupChatReport, + maxSequenceNumber: groupChatReportMaxSequenceNumber + 1, pendingFields: { createChat: existingGroupChatReport ? null : CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, }, @@ -203,7 +205,10 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${groupChatReport.reportID}`, - value: {pendingFields: {createChat: null}}, + value: { + maxSequenceNumber: groupChatReportMaxSequenceNumber, + pendingFields: {createChat: null}, + }, }, { onyxMethod: CONST.ONYX.METHOD.MERGE, @@ -243,8 +248,9 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment } const oneOnOneCreatedReportAction = existingOneOnOneChatReport ? {} : ReportUtils.buildOptimisticCreatedReportAction(currentUserEmail); + const oneOnOneChatReportMaxSequenceNumber = lodashGet(oneOnOneChatReport, 'maxSequenceNumber', 0); const oneOnOneIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( - lodashGet(oneOnOneChatReport, 'maxSequenceNumber', 0) + 1, + oneOnOneChatReportMaxSequenceNumber + 1, CONST.IOU.REPORT_ACTION_TYPE.CREATE, splitAmount, comment, @@ -260,6 +266,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`, value: { ...oneOnOneChatReport, + maxSequenceNumber: oneOnOneChatReportMaxSequenceNumber + 1, pendingFields: { createChat: existingOneOnOneChatReport ? null : CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, }, @@ -300,7 +307,10 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`, - value: {pendingFields: {createChat: null}}, + value: { + maxSequenceNumber: oneOnOneChatReportMaxSequenceNumber, + pendingFields: {createChat: null}, + }, }, { onyxMethod: CONST.ONYX.METHOD.MERGE, From 029069591e382dd1ab2c9deb9e56ce8846b92d4c Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 18 Oct 2022 15:57:22 -0600 Subject: [PATCH 063/100] update ioureport in chatreport key --- src/libs/actions/IOU.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index b88c0697bd58..ac133f2e48cf 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -170,6 +170,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment value: { ...groupChatReport, maxSequenceNumber: groupChatReportMaxSequenceNumber + 1, + lastReadSequenceNumber: groupChatReportMaxSequenceNumber + 1, pendingFields: { createChat: existingGroupChatReport ? null : CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, }, @@ -207,6 +208,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment key: `${ONYXKEYS.COLLECTION.REPORT}${groupChatReport.reportID}`, value: { maxSequenceNumber: groupChatReportMaxSequenceNumber, + lastReadSequenceNumber: groupChatReportMaxSequenceNumber, pendingFields: {createChat: null}, }, }, @@ -245,6 +247,8 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment currency, locale, ); + oneOnOneChatReport.hasOutstandingIOU = true; + oneOnOneChatReport.iouReportID = oneOnOneIOUReport.reportID; } const oneOnOneCreatedReportAction = existingOneOnOneChatReport ? {} : ReportUtils.buildOptimisticCreatedReportAction(currentUserEmail); @@ -267,6 +271,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment value: { ...oneOnOneChatReport, maxSequenceNumber: oneOnOneChatReportMaxSequenceNumber + 1, + lastReadSequenceNumber: oneOnOneChatReportMaxSequenceNumber + 1, pendingFields: { createChat: existingOneOnOneChatReport ? null : CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, }, @@ -309,6 +314,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`, value: { maxSequenceNumber: oneOnOneChatReportMaxSequenceNumber, + lastReadSequenceNumber: oneOnOneChatReportMaxSequenceNumber, pendingFields: {createChat: null}, }, }, From 24ca13925b4b62d73cd2d7135e6ae59fe167c827 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 18 Oct 2022 16:20:20 -0600 Subject: [PATCH 064/100] compare numbers --- src/pages/iou/IOUTransactions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/iou/IOUTransactions.js b/src/pages/iou/IOUTransactions.js index 1532697fc1f3..103b08b115ee 100644 --- a/src/pages/iou/IOUTransactions.js +++ b/src/pages/iou/IOUTransactions.js @@ -75,7 +75,7 @@ class IOUTransactions extends Component { return ( {_.map(this.props.reportActions, (reportAction) => { - if (!reportAction.originalMessage || reportAction.originalMessage.IOUReportID !== this.props.iouReportID) { + if (!reportAction.originalMessage || Number(reportAction.originalMessage.IOUReportID) !== Number(this.props.iouReportID)) { return; } From bcc173e633fa88363daa605f7fe101caabb4100d Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 18 Oct 2022 16:54:42 -0600 Subject: [PATCH 065/100] fix iou transactions --- src/pages/iou/IOUTransactions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/iou/IOUTransactions.js b/src/pages/iou/IOUTransactions.js index 103b08b115ee..c9fb765dd922 100644 --- a/src/pages/iou/IOUTransactions.js +++ b/src/pages/iou/IOUTransactions.js @@ -55,7 +55,7 @@ class IOUTransactions extends Component { } const actionsForIOUReport = _.filter(this.props.reportActions, action => action.originalMessage - && action.originalMessage.type && action.originalMessage.IOUReportID === this.props.iouReportID); + && action.originalMessage.type && Number(action.originalMessage.IOUReportID) === Number(this.props.iouReportID)); const rejectedTransactionIDs = _.chain(actionsForIOUReport) .filter(action => _.contains(['cancel', 'decline'], action.originalMessage.type)) From 4385830b7a0251e5d68f40c1c76f1930ded942cf Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 19 Oct 2022 09:52:45 -0600 Subject: [PATCH 066/100] use lowercase usernames --- src/libs/actions/IOU.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index ac133f2e48cf..4923f778c00f 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -150,9 +150,9 @@ function createIOUTransaction(params) { */ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment, currency, locale) { const currentUserEmail = OptionsListUtils.addSMSDomainIfPhoneNumber(currentUserLogin); - const participantLogins = _.map(participants, participant => OptionsListUtils.addSMSDomainIfPhoneNumber(participant.login)); + const participantLogins = _.map(participants, participant => OptionsListUtils.addSMSDomainIfPhoneNumber(participant.login).toLowerCase()); const existingGroupChatReport = ReportUtils.getChatByParticipants(participantLogins); - const groupChatReport = existingGroupChatReport || ReportUtils.buildOptimisticChatReport(_.pluck(participants, 'login')); + const groupChatReport = existingGroupChatReport || ReportUtils.buildOptimisticChatReport(participantLogins); const groupCreatedReportAction = existingGroupChatReport ? {} : ReportUtils.buildOptimisticCreatedReportAction(currentUserEmail); const groupChatReportMaxSequenceNumber = lodashGet(groupChatReport, 'maxSequenceNumber', 0); const groupIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( @@ -227,7 +227,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment const splits = [{email: currentUserEmail, amount: IOUUtils.calculateAmount(participants, amount, true)}]; _.each(participants, (participant) => { - const email = OptionsListUtils.addSMSDomainIfPhoneNumber(participant.login); + const email = OptionsListUtils.addSMSDomainIfPhoneNumber(participant.login).toLowerCase(); if (email === currentUserEmail) { return; } From 95688458df86edf65a54f3f91cfe0564cbeae598 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 19 Oct 2022 17:47:53 -0600 Subject: [PATCH 067/100] use correct type, use waitForCollectionCallback --- src/libs/actions/IOU.js | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 4923f778c00f..945464001454 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -16,16 +16,11 @@ import * as ReportUtils from '../ReportUtils'; import * as IOUUtils from '../IOUUtils'; import * as OptionsListUtils from '../OptionsListUtils'; -const iouReports = {}; +let iouReports; Onyx.connect({ key: ONYXKEYS.COLLECTION.REPORT_IOUS, - callback: (iouReport, key) => { - if (!iouReport || !key || !iouReport.ownerEmail) { - return; - } - - iouReports[key] = iouReport; - }, + waitForCollectionCallback: true, + callback: val => iouReports = val, }); /** @@ -141,7 +136,7 @@ function createIOUTransaction(params) { /** * @param {Array} participants * @param {String} currentUserLogin - * @param {Int} amount + * @param {Number} amount * @param {String} comment * @param {String} currency * @param {String} locale @@ -354,7 +349,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment /** * @param {Array} participants * @param {String} currentUserLogin - * @param {Int} amount + * @param {Number} amount * @param {String} comment * @param {String} currency * @param {String} locale @@ -379,7 +374,7 @@ function splitBill(participants, currentUserLogin, amount, comment, currency, lo /** * @param {Array} participants * @param {String} currentUserLogin - * @param {Int} amount + * @param {Number} amount * @param {String} comment * @param {String} currency * @param {String} locale From 966677f06a7d6b0d8905871f3e4d32cc61097a12 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 19 Oct 2022 17:52:40 -0600 Subject: [PATCH 068/100] rm translation --- src/languages/en.js | 2 -- src/languages/es.js | 2 -- src/libs/ReportUtils.js | 6 +++--- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/languages/en.js b/src/languages/en.js index 1373ad6a7ebc..844f1b090c81 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -255,8 +255,6 @@ export default { split: ({amount}) => `Split ${amount}`, send: ({amount}) => `Send ${amount}`, noReimbursableExpenses: 'This report has an invalid amount', - requestedFrom: ({amount, from, comment}) => `Requested ${amount} from ${from}${comment && ` for ${comment}`}`, - splitWith: ({amount, from, comment}) => `Split ${amount} with ${from}${comment && ` for ${comment}`}`, error: { invalidSplit: 'Split amounts do not equal total amount', other: 'Unexpected error, please try again later', diff --git a/src/languages/es.js b/src/languages/es.js index 67b660d23ada..66d8ceb364c1 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -255,8 +255,6 @@ export default { split: ({amount}) => `Dividir ${amount}`, send: ({amount}) => `Enviar ${amount}`, noReimbursableExpenses: 'El monto de este informe es inválido', - requestedFrom: ({amount, from, comment}) => `Pidió ${amount} de ${from}${comment && ` para ${comment}`}`, - splitWith: ({amount, from, comment}) => `Dividir ${amount} con ${from}${comment && ` para ${comment}`}`, error: { invalidSplit: 'La suma de las partes no equivale al monto total', other: 'Error inesperado, por favor inténtalo más tarde', diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 0603c27e6f1b..0f090f6142ac 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -673,15 +673,15 @@ function getIOUReportActionMessage(type, total, participants, comment, currency) const displayNames = _.map(participants, participant => lodashGet(participant, 'text', participant.login)); const from = displayNames.length < 3 ? displayNames.join(' and ') - : `${displayNames.slice(0, -1).join(', ')}, ${Localize.translateLocal('common.and')} ${_.last(displayNames)}`; + : `${displayNames.slice(0, -1).join(', ')}, and ${_.last(displayNames)}`; let iouMessage; switch (type) { case CONST.IOU.REPORT_ACTION_TYPE.CREATE: - iouMessage = Localize.translateLocal('iou.requestedFrom', {amount, from, comment}); + iouMessage = `Requested ${amount} from ${from}${comment && ` for ${comment}`}`; break; case CONST.IOU.REPORT_ACTION_TYPE.SPLIT: - iouMessage = Localize.translateLocal('iou.splitWith', {amount, from, comment}); + iouMessage = `Split ${amount} with ${from}${comment && ` for ${comment}`}`; break; default: break; From c4674d2dee0fdc980f558eb1b8cce947df6e700c Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 20 Oct 2022 13:58:50 -0600 Subject: [PATCH 069/100] add lastVisitedTimestamp and cleanup --- src/libs/actions/IOU.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 945464001454..96c3b98ce613 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -166,6 +166,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment ...groupChatReport, maxSequenceNumber: groupChatReportMaxSequenceNumber + 1, lastReadSequenceNumber: groupChatReportMaxSequenceNumber + 1, + lastVisitedTimestamp: Date.now(), pendingFields: { createChat: existingGroupChatReport ? null : CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, }, @@ -185,7 +186,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${groupChatReport.reportID}`, - value: {pendingFields: {createChat: null}}, + value: null, }, { onyxMethod: CONST.ONYX.METHOD.MERGE, @@ -202,8 +203,6 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${groupChatReport.reportID}`, value: { - maxSequenceNumber: groupChatReportMaxSequenceNumber, - lastReadSequenceNumber: groupChatReportMaxSequenceNumber, pendingFields: {createChat: null}, }, }, @@ -308,8 +307,6 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`, value: { - maxSequenceNumber: oneOnOneChatReportMaxSequenceNumber, - lastReadSequenceNumber: oneOnOneChatReportMaxSequenceNumber, pendingFields: {createChat: null}, }, }, From 9ce4e2879b981bff136250fe7793888ce31a517a Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 20 Oct 2022 17:12:37 -0600 Subject: [PATCH 070/100] add comment --- src/libs/actions/IOU.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 96c3b98ce613..084556fd4cd5 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -134,6 +134,16 @@ function createIOUTransaction(params) { } /** + * Build the Onyx data and IOU split necessary for splitting a bill with 3+ users. + * 1. Build the optimistic Onyx data for the group chat, i.e. chatReport and iouReportAction creating the former if it doesn't yet exist. + * 2. Loop over the group chat participant list, building optimistic or updating existing chatReports, iouReports and iouReportActions between the user and each participant. + * We build both Onyx data and the IOU split that is sent as a request param and is used by Auth to create the chatReports, iouReports and iouReportActions in the database. + * The IOU split has the following shape: + * [ + * {email: 'currentUser', amount: 100}, + * {email: 'user2', amount: 100, iouReportID: '123', chatReportID: '123', transactionID: '123', reportActionID: '123', clientID: '123'}, + * {email: 'user3', amount: 100, iouReportID: '123', chatReportID: '123', transactionID: '123', reportActionID: '123', clientID: '123'} + * ] * @param {Array} participants * @param {String} currentUserLogin * @param {Number} amount From a4d7df665cc899d89cc4e1d3fccbfdf160cd6390 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Fri, 21 Oct 2022 15:11:42 -0600 Subject: [PATCH 071/100] create updateIOUOwnerAndTotal --- src/libs/IOUUtils.js | 38 ++++++++++++++++++++++++++++++++++++-- src/libs/actions/IOU.js | 8 ++++++-- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/libs/IOUUtils.js b/src/libs/IOUUtils.js index 9d3b8fb31923..81ab07e6780e 100644 --- a/src/libs/IOUUtils.js +++ b/src/libs/IOUUtils.js @@ -1,7 +1,9 @@ +import CONST from "../CONST"; + /** * Calculates the amount per user given a list of participants * @param {Array} participants - * @param {Int} total + * @param {Number} total * @param {Boolean} isDefaultUser * @returns {Number} */ @@ -23,7 +25,39 @@ function calculateAmount(participants, total, isDefaultUser = false) { return iouAmount !== sumAmount ? (amountPerPerson + difference) : amountPerPerson; } +/** + * The owner of the IOU report is the account who is owed money and the manager is the one who owes money! + * We need to update the owner and the report total in case the owner/manager swap. + * For example: if user1 owes user2 $10, then we have: {ownerEmail: user2, managerEmail: user1, total: $10 (owed to user2)} + * If user1 requests $17 from user2, then we have: {ownerEmail: user1, managerEmail: user2, total: $7 (owed to user1)} + * + * @param {Object} iouReport + * @param {String} actorEmail + * @param {Number} amount + * @param {String} type + * @returns {Object} + */ +function updateIOUOwnerAndTotal(iouReport, actorEmail, amount, type = CONST.IOU.REPORT_ACTION_TYPE.CREATE) { + const iouReportUpdate = {...iouReport}; + + if (actorEmail === iouReport.ownerEmail) { + iouReportUpdate.total += type === CONST.IOU.REPORT_ACTION_TYPE.CANCEL ? -amount : amount; + } else { + iouReportUpdate.total += type === CONST.IOU.REPORT_ACTION_TYPE.CANCEL ? amount : -amount; + } + + if (iouReportUpdate.total < 0) { + // The total sign has changed and hence we need to flip the manager and owner of the report. + const oldOwnerEmail = iouReport.ownerEmail; + iouReportUpdate.ownerEmail = iouReport.managerEmail; + iouReportUpdate.managerEmail = oldOwnerEmail; + iouReportUpdate.total = -iouReportUpdate.total; + } + + return iouReportUpdate; +} + export { - // eslint-disable-next-line import/prefer-default-export calculateAmount, + updateIOUOwnerAndTotal, }; diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 084556fd4cd5..1ff7da381964 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -240,8 +240,12 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment const oneOnOneChatReport = existingOneOnOneChatReport || ReportUtils.buildOptimisticChatReport([email]); let oneOnOneIOUReport; if (oneOnOneChatReport.iouReportID) { - oneOnOneIOUReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneChatReport.iouReportID}`]; - oneOnOneIOUReport.total += splitAmount; + oneOnOneIOUReport = IOUUtils.updateIOUOwnerAndTotal( + iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneChatReport.iouReportID}`], + currentUserEmail, + splitAmount, + ); + oneOnOneChatReport.hasOutstandingIOU = oneOnOneIOUReport.total !== 0; } else { oneOnOneIOUReport = ReportUtils.buildOptimisticIOUReport( currentUserEmail, From 8f84ef50307c054127d1b86cd3714e9d4ba08522 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Fri, 21 Oct 2022 15:16:35 -0600 Subject: [PATCH 072/100] fix style --- src/libs/IOUUtils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/IOUUtils.js b/src/libs/IOUUtils.js index 81ab07e6780e..6801ee850b4a 100644 --- a/src/libs/IOUUtils.js +++ b/src/libs/IOUUtils.js @@ -1,4 +1,4 @@ -import CONST from "../CONST"; +import CONST from '../CONST'; /** * Calculates the amount per user given a list of participants From 1a0da7913dc1927522d6b758706926897d42c6c1 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 24 Oct 2022 10:00:50 -0600 Subject: [PATCH 073/100] add comment to calculateTotal --- src/libs/IOUUtils.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libs/IOUUtils.js b/src/libs/IOUUtils.js index 6801ee850b4a..5effe56ec614 100644 --- a/src/libs/IOUUtils.js +++ b/src/libs/IOUUtils.js @@ -2,9 +2,9 @@ import CONST from '../CONST'; /** * Calculates the amount per user given a list of participants - * @param {Array} participants - * @param {Number} total - * @param {Boolean} isDefaultUser + * @param {Array} participants list of logins for the participants in the chat. It should not include the current user's login. + * @param {Number} total the IOU total amount + * @param {Boolean} isDefaultUser whether we are calculating the amount for the current user * @returns {Number} */ function calculateAmount(participants, total, isDefaultUser = false) { @@ -17,7 +17,9 @@ function calculateAmount(participants, total, isDefaultUser = false) { const totalParticipants = participants.length + 1; const amountPerPerson = Math.round(iouAmount / totalParticipants); - if (!isDefaultUser) { return amountPerPerson; } + if (!isDefaultUser) { + return amountPerPerson; + } const sumAmount = amountPerPerson * totalParticipants; const difference = iouAmount - sumAmount; From e50c6a201c5f739acba7df5a6d6a6a94b06894c2 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 24 Oct 2022 10:17:23 -0600 Subject: [PATCH 074/100] update jsdocs and comments --- src/libs/IOUUtils.js | 15 +++++++-------- src/libs/ReportUtils.js | 8 ++++++++ src/libs/actions/IOU.js | 4 ++-- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/libs/IOUUtils.js b/src/libs/IOUUtils.js index 5effe56ec614..23c699046d5c 100644 --- a/src/libs/IOUUtils.js +++ b/src/libs/IOUUtils.js @@ -2,9 +2,9 @@ import CONST from '../CONST'; /** * Calculates the amount per user given a list of participants - * @param {Array} participants list of logins for the participants in the chat. It should not include the current user's login. - * @param {Number} total the IOU total amount - * @param {Boolean} isDefaultUser whether we are calculating the amount for the current user + * @param {Array} participants - List of logins for the participants in the chat. It should not include the current user's login. + * @param {Number} total - IOU total amount + * @param {Boolean} isDefaultUser - Whether we are calculating the amount for the current user * @returns {Number} */ function calculateAmount(participants, total, isDefaultUser = false) { @@ -29,9 +29,9 @@ function calculateAmount(participants, total, isDefaultUser = false) { /** * The owner of the IOU report is the account who is owed money and the manager is the one who owes money! - * We need to update the owner and the report total in case the owner/manager swap. - * For example: if user1 owes user2 $10, then we have: {ownerEmail: user2, managerEmail: user1, total: $10 (owed to user2)} - * If user1 requests $17 from user2, then we have: {ownerEmail: user1, managerEmail: user2, total: $7 (owed to user1)} + * In case the owner/manager swap, we need to update the owner of the IOU report and the report total, since it is always positive. + * For example: if user1 owes user2 $10, then we have: {ownerEmail: user2, managerEmail: user1, total: $10 (a positive amount, owed to user2)} + * If user1 requests $17 from user2, then we have: {ownerEmail: user1, managerEmail: user2, total: $7 (still a positive amount, but now owed to user1)} * * @param {Object} iouReport * @param {String} actorEmail @@ -50,9 +50,8 @@ function updateIOUOwnerAndTotal(iouReport, actorEmail, amount, type = CONST.IOU. if (iouReportUpdate.total < 0) { // The total sign has changed and hence we need to flip the manager and owner of the report. - const oldOwnerEmail = iouReport.ownerEmail; iouReportUpdate.ownerEmail = iouReport.managerEmail; - iouReportUpdate.managerEmail = oldOwnerEmail; + iouReportUpdate.managerEmail = iouReport.ownerEmail; iouReportUpdate.total = -iouReportUpdate.total; } diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 8b8b3c170ba8..68043df01e41 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -667,6 +667,14 @@ function buildOptimisticIOUReport(ownerEmail, recipientEmail, total, chatReportI }; } +/** + * @param {String} type - IOUReportAction type. Can be oneOf(create, decline, cancel, pay, split) + * @param {Number} total - IOU total in cents + * @param {Array} participants - List of logins for the IOU participants, excluding the current user login + * @param {String} comment - IOU comment + * @param {String} currency - IOU currency + * @returns {Array} + */ function getIOUReportActionMessage(type, total, participants, comment, currency) { const amount = NumberFormatUtils.format(preferredLocale, total / 100, {style: 'currency', currency}); diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 1ff7da381964..dd2d777f101f 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -141,8 +141,8 @@ function createIOUTransaction(params) { * The IOU split has the following shape: * [ * {email: 'currentUser', amount: 100}, - * {email: 'user2', amount: 100, iouReportID: '123', chatReportID: '123', transactionID: '123', reportActionID: '123', clientID: '123'}, - * {email: 'user3', amount: 100, iouReportID: '123', chatReportID: '123', transactionID: '123', reportActionID: '123', clientID: '123'} + * {email: 'user2', amount: 100, iouReportID: '100', chatReportID: '110', transactionID: '120', reportActionID: '130', clientID: '140'}, + * {email: 'user3', amount: 100, iouReportID: '200', chatReportID: '210', transactionID: '220', reportActionID: '230', clientID: '240'} * ] * @param {Array} participants * @param {String} currentUserLogin From 893e40eacf9956d09e9866fbc175b61c312206e5 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 24 Oct 2022 16:20:33 -0600 Subject: [PATCH 075/100] add error handling --- src/languages/en.js | 1 + src/languages/es.js | 1 + src/libs/actions/IOU.js | 20 +++++++++++++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/languages/en.js b/src/languages/en.js index 2b9ebcb32aac..1e9a0c743831 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -260,6 +260,7 @@ export default { error: { invalidSplit: 'Split amounts do not equal total amount', other: 'Unexpected error, please try again later', + errorSplittingBill: 'Error splitting bill.', }, }, notificationPreferences: { diff --git a/src/languages/es.js b/src/languages/es.js index 1929d500c83c..96481526ce79 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -260,6 +260,7 @@ export default { error: { invalidSplit: 'La suma de las partes no equivale al monto total', other: 'Error inesperado, por favor inténtalo más tarde', + errorSplittingBill: 'Error al dividir la cuenta.', }, }, notificationPreferences: { diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index dd2d777f101f..23bbf4f7e7bc 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -15,6 +15,7 @@ import * as API from '../API'; import * as ReportUtils from '../ReportUtils'; import * as IOUUtils from '../IOUUtils'; import * as OptionsListUtils from '../OptionsListUtils'; +import DateUtils from '../DateUtils'; let iouReports; Onyx.connect({ @@ -214,6 +215,11 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment key: `${ONYXKEYS.COLLECTION.REPORT}${groupChatReport.reportID}`, value: { pendingFields: {createChat: null}, + errorFields: { + createChat: { + [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.errorSplittingBill'), + }, + }, }, }, { @@ -322,6 +328,13 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`, value: { pendingFields: {createChat: null}, + hasOutstandingIOU: false, + iouReportID: null, + errorFields: { + createChat: { + [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.errorSplittingBill'), + }, + }, }, }, { @@ -329,9 +342,14 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`, value: { 0: {pendingAction: null}, - [oneOnOneIOUReportAction.sequenceNumber]: {pendingAction: null}, + [oneOnOneIOUReportAction.sequenceNumber]: null, }, }, + { + onyxMethod: CONST.ONYX.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneIOUReport.reportID}`, + value: null, + }, ); splits.push({ From 904eccf95e133761ed7e10019d388b587c33b57d Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 24 Oct 2022 16:26:08 -0600 Subject: [PATCH 076/100] rm error copy --- src/languages/en.js | 1 - src/languages/es.js | 1 - src/libs/actions/IOU.js | 10 ---------- 3 files changed, 12 deletions(-) diff --git a/src/languages/en.js b/src/languages/en.js index 1e9a0c743831..2b9ebcb32aac 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -260,7 +260,6 @@ export default { error: { invalidSplit: 'Split amounts do not equal total amount', other: 'Unexpected error, please try again later', - errorSplittingBill: 'Error splitting bill.', }, }, notificationPreferences: { diff --git a/src/languages/es.js b/src/languages/es.js index 96481526ce79..1929d500c83c 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -260,7 +260,6 @@ export default { error: { invalidSplit: 'La suma de las partes no equivale al monto total', other: 'Error inesperado, por favor inténtalo más tarde', - errorSplittingBill: 'Error al dividir la cuenta.', }, }, notificationPreferences: { diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 23bbf4f7e7bc..d145ec511df0 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -215,11 +215,6 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment key: `${ONYXKEYS.COLLECTION.REPORT}${groupChatReport.reportID}`, value: { pendingFields: {createChat: null}, - errorFields: { - createChat: { - [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.errorSplittingBill'), - }, - }, }, }, { @@ -330,11 +325,6 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment pendingFields: {createChat: null}, hasOutstandingIOU: false, iouReportID: null, - errorFields: { - createChat: { - [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.errorSplittingBill'), - }, - }, }, }, { From 89aa4710e08c3469ee07acbec880c2dd535068df Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 24 Oct 2022 16:30:46 -0600 Subject: [PATCH 077/100] rm dateutils import --- src/libs/actions/IOU.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index d145ec511df0..6659a6dc03cb 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -15,7 +15,6 @@ import * as API from '../API'; import * as ReportUtils from '../ReportUtils'; import * as IOUUtils from '../IOUUtils'; import * as OptionsListUtils from '../OptionsListUtils'; -import DateUtils from '../DateUtils'; let iouReports; Onyx.connect({ From 9917c061e298dede7e200d02eb2b8293a2f0aa24 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 25 Oct 2022 09:07:52 -0600 Subject: [PATCH 078/100] add comment --- src/pages/iou/IOUTransactions.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pages/iou/IOUTransactions.js b/src/pages/iou/IOUTransactions.js index c9fb765dd922..ca95bb4ce14b 100644 --- a/src/pages/iou/IOUTransactions.js +++ b/src/pages/iou/IOUTransactions.js @@ -54,6 +54,7 @@ class IOUTransactions extends Component { return []; } + // iouReportIDs should be strings, but we still have places that send them as ints so we convert them both to Numbers for comparison const actionsForIOUReport = _.filter(this.props.reportActions, action => action.originalMessage && action.originalMessage.type && Number(action.originalMessage.IOUReportID) === Number(this.props.iouReportID)); @@ -75,6 +76,7 @@ class IOUTransactions extends Component { return ( {_.map(this.props.reportActions, (reportAction) => { + // iouReportIDs should be strings, but we still have places that send them as ints so we convert them both to Numbers for comparison if (!reportAction.originalMessage || Number(reportAction.originalMessage.IOUReportID) !== Number(this.props.iouReportID)) { return; } From d28dc1819dcd2131bdb0320c5b9190479ce849a4 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 25 Oct 2022 11:39:40 -0600 Subject: [PATCH 079/100] fix failure data --- src/libs/actions/IOU.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 6659a6dc03cb..58fbb258b17f 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -239,9 +239,11 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment const existingOneOnOneChatReport = ReportUtils.getChatByParticipants([email]); const oneOnOneChatReport = existingOneOnOneChatReport || ReportUtils.buildOptimisticChatReport([email]); let oneOnOneIOUReport; + let existingIOUReport; if (oneOnOneChatReport.iouReportID) { + existingIOUReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneChatReport.iouReportID}`]; oneOnOneIOUReport = IOUUtils.updateIOUOwnerAndTotal( - iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneChatReport.iouReportID}`], + existingIOUReport, currentUserEmail, splitAmount, ); @@ -322,8 +324,10 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`, value: { pendingFields: {createChat: null}, - hasOutstandingIOU: false, - iouReportID: null, + hasOutstandingIOU: existingOneOnOneChatReport ? existingOneOnOneChatReport.hasOutstandingIOU : false, + iouReportID: existingOneOnOneChatReport ? existingOneOnOneChatReport.iouReportID : null, + maxSequenceNumber: oneOnOneChatReportMaxSequenceNumber, + lastReadSequenceNumber: oneOnOneChatReportMaxSequenceNumber, }, }, { @@ -337,7 +341,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment { onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneIOUReport.reportID}`, - value: null, + value: existingOneOnOneChatReport.iouReportID ? existingIOUReport : null, }, ); From ef33a9d83ccfcfc492f54be6a5f4677515b40acb Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 25 Oct 2022 12:08:35 -0600 Subject: [PATCH 080/100] fix failure data --- src/libs/actions/IOU.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 58fbb258b17f..15e9faf852e8 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -341,7 +341,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment { onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneIOUReport.reportID}`, - value: existingOneOnOneChatReport.iouReportID ? existingIOUReport : null, + value: existingOneOnOneChatReport ? existingIOUReport.iouReportID : null, }, ); From c7f7623dfbf4df489bff5f527516760df67c5b63 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 25 Oct 2022 12:50:36 -0600 Subject: [PATCH 081/100] fix participant name --- src/libs/ReportUtils.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 68043df01e41..a8ea7289a8da 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -677,8 +677,8 @@ function buildOptimisticIOUReport(ownerEmail, recipientEmail, total, chatReportI */ function getIOUReportActionMessage(type, total, participants, comment, currency) { const amount = NumberFormatUtils.format(preferredLocale, total / 100, {style: 'currency', currency}); - - const displayNames = _.map(participants, participant => lodashGet(participant, 'text', participant.login)); + const isMultipleParticipantReport = participants.length > 1; + const displayNames = _.map(participants, participant => getDisplayNameForParticipant(allPersonalDetails[participant.login], isMultipleParticipantReport) || participant.login); const from = displayNames.length < 3 ? displayNames.join(' and ') : `${displayNames.slice(0, -1).join(', ')}, and ${_.last(displayNames)}`; From 07a35c34a6e68b965122d4f578d33e61b1081928 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 25 Oct 2022 13:25:30 -0600 Subject: [PATCH 082/100] fix prop type; --- src/pages/iouReportPropTypes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/iouReportPropTypes.js b/src/pages/iouReportPropTypes.js index 7e23b2674bbd..d6481cb1e871 100644 --- a/src/pages/iouReportPropTypes.js +++ b/src/pages/iouReportPropTypes.js @@ -5,7 +5,7 @@ export default PropTypes.shape({ reportID: PropTypes.string, /** The report ID of the chat associated with the IOU */ - chatReportID: PropTypes.number, + chatReportID: PropTypes.string, /** The total amount in cents */ total: PropTypes.number, From 421edab7f5e06f58dea42df3438e09d11d2810fe Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 25 Oct 2022 13:56:30 -0600 Subject: [PATCH 083/100] fix console error --- src/libs/actions/IOU.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 15e9faf852e8..f73e605ed1e1 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -196,7 +196,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${groupChatReport.reportID}`, - value: null, + value: {pendingFields: {createChat: null}}, }, { onyxMethod: CONST.ONYX.METHOD.MERGE, From 7638af116d71d6ed19f2a2c2667d759b5ba2b1fe Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 25 Oct 2022 15:46:33 -0600 Subject: [PATCH 084/100] fix console error --- src/libs/actions/IOU.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index f73e605ed1e1..48c94934eb6e 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -239,7 +239,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment const existingOneOnOneChatReport = ReportUtils.getChatByParticipants([email]); const oneOnOneChatReport = existingOneOnOneChatReport || ReportUtils.buildOptimisticChatReport([email]); let oneOnOneIOUReport; - let existingIOUReport; + let existingIOUReport = null; if (oneOnOneChatReport.iouReportID) { existingIOUReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneChatReport.iouReportID}`]; oneOnOneIOUReport = IOUUtils.updateIOUOwnerAndTotal( @@ -341,7 +341,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment { onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneIOUReport.reportID}`, - value: existingOneOnOneChatReport ? existingIOUReport.iouReportID : null, + value: existingIOUReport, }, ); From 406de2e1cc5848c49d34f5cf448b48d0e1acdffc Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 26 Oct 2022 12:10:58 -0600 Subject: [PATCH 085/100] update lastMessage in LHN --- src/libs/ReportUtils.js | 1 + src/libs/actions/IOU.js | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index a8ea7289a8da..32431c0be904 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -1064,4 +1064,5 @@ export { buildOptimisticReportAction, shouldReportBeInOptionList, getChatByParticipants, + getIOUReportActionMessage, }; diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 48c94934eb6e..01a7739b29c4 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -160,10 +160,12 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment const groupChatReport = existingGroupChatReport || ReportUtils.buildOptimisticChatReport(participantLogins); const groupCreatedReportAction = existingGroupChatReport ? {} : ReportUtils.buildOptimisticCreatedReportAction(currentUserEmail); const groupChatReportMaxSequenceNumber = lodashGet(groupChatReport, 'maxSequenceNumber', 0); + const amountInCents = Math.round(amount * 100); + const groupChatReportLastMessage = ReportUtils.getIOUReportActionMessage(CONST.IOU.REPORT_ACTION_TYPE.SPLIT, amountInCents, participants, comment, currency)[0]; const groupIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( groupChatReportMaxSequenceNumber + 1, CONST.IOU.REPORT_ACTION_TYPE.SPLIT, - Math.round(amount * 100), + amountInCents, comment, participants, ); @@ -177,6 +179,8 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment maxSequenceNumber: groupChatReportMaxSequenceNumber + 1, lastReadSequenceNumber: groupChatReportMaxSequenceNumber + 1, lastVisitedTimestamp: Date.now(), + lastMessageText: groupChatReportLastMessage.text, + lastMessageHtml: groupChatReportLastMessage.html, pendingFields: { createChat: existingGroupChatReport ? null : CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, }, @@ -238,6 +242,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment const existingOneOnOneChatReport = ReportUtils.getChatByParticipants([email]); const oneOnOneChatReport = existingOneOnOneChatReport || ReportUtils.buildOptimisticChatReport([email]); + const oneOnOneChatReportLastMessage = ReportUtils.getIOUReportActionMessage(CONST.IOU.REPORT_ACTION_TYPE.CREATE, splitAmount, [participant], comment, currency)[0]; let oneOnOneIOUReport; let existingIOUReport = null; if (oneOnOneChatReport.iouReportID) { @@ -282,6 +287,8 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment ...oneOnOneChatReport, maxSequenceNumber: oneOnOneChatReportMaxSequenceNumber + 1, lastReadSequenceNumber: oneOnOneChatReportMaxSequenceNumber + 1, + lastMessageText: oneOnOneChatReportLastMessage.text, + lastMessageHtml: oneOnOneChatReportLastMessage.html, pendingFields: { createChat: existingOneOnOneChatReport ? null : CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, }, From fb30878513062fc06fa1b3c50dc025291aaaf2d9 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 26 Oct 2022 12:59:01 -0600 Subject: [PATCH 086/100] clean up last message --- src/libs/actions/IOU.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 01a7739b29c4..ce3d4fb2a4dc 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -160,12 +160,10 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment const groupChatReport = existingGroupChatReport || ReportUtils.buildOptimisticChatReport(participantLogins); const groupCreatedReportAction = existingGroupChatReport ? {} : ReportUtils.buildOptimisticCreatedReportAction(currentUserEmail); const groupChatReportMaxSequenceNumber = lodashGet(groupChatReport, 'maxSequenceNumber', 0); - const amountInCents = Math.round(amount * 100); - const groupChatReportLastMessage = ReportUtils.getIOUReportActionMessage(CONST.IOU.REPORT_ACTION_TYPE.SPLIT, amountInCents, participants, comment, currency)[0]; const groupIOUReportAction = ReportUtils.buildOptimisticIOUReportAction( groupChatReportMaxSequenceNumber + 1, CONST.IOU.REPORT_ACTION_TYPE.SPLIT, - amountInCents, + Math.round(amount * 100), comment, participants, ); @@ -179,8 +177,8 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment maxSequenceNumber: groupChatReportMaxSequenceNumber + 1, lastReadSequenceNumber: groupChatReportMaxSequenceNumber + 1, lastVisitedTimestamp: Date.now(), - lastMessageText: groupChatReportLastMessage.text, - lastMessageHtml: groupChatReportLastMessage.html, + lastMessageText: groupIOUReportAction.message[0].text, + lastMessageHtml: groupIOUReportAction.message[0].html, pendingFields: { createChat: existingGroupChatReport ? null : CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, }, @@ -242,7 +240,6 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment const existingOneOnOneChatReport = ReportUtils.getChatByParticipants([email]); const oneOnOneChatReport = existingOneOnOneChatReport || ReportUtils.buildOptimisticChatReport([email]); - const oneOnOneChatReportLastMessage = ReportUtils.getIOUReportActionMessage(CONST.IOU.REPORT_ACTION_TYPE.CREATE, splitAmount, [participant], comment, currency)[0]; let oneOnOneIOUReport; let existingIOUReport = null; if (oneOnOneChatReport.iouReportID) { @@ -287,8 +284,8 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment ...oneOnOneChatReport, maxSequenceNumber: oneOnOneChatReportMaxSequenceNumber + 1, lastReadSequenceNumber: oneOnOneChatReportMaxSequenceNumber + 1, - lastMessageText: oneOnOneChatReportLastMessage.text, - lastMessageHtml: oneOnOneChatReportLastMessage.html, + lastMessageText: oneOnOneIOUReportAction.message[0].text, + lastMessageHtml: oneOnOneIOUReportAction.message[0].html, pendingFields: { createChat: existingOneOnOneChatReport ? null : CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, }, From 2362e4e4bf0ad727e2df74299217906320c08bb1 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 26 Oct 2022 13:31:25 -0600 Subject: [PATCH 087/100] update logic to select appropriate API command --- src/pages/iou/IOUModal.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/pages/iou/IOUModal.js b/src/pages/iou/IOUModal.js index 274bf801d96c..0c00120f2206 100755 --- a/src/pages/iou/IOUModal.js +++ b/src/pages/iou/IOUModal.js @@ -311,9 +311,13 @@ class IOUModal extends Component { createTransaction() { const reportID = lodashGet(this.props, 'route.params.reportID', ''); + // We use hasSelectedMultipleParticipants instead of props.hasMultipleParticipants because the user can start a Split Bill flow + // but select a single participant. We should still allow the user to finish the flow, but we should call the appropriate API command + const hasSelectedMultipleParticipants = this.state.participants.length > 1; + // IOUs created from a group report will have a reportID param in the route. // Since the user is already viewing the report, we don't need to navigate them to the report - if (this.props.hasMultipleParticipants && CONST.REGEX.NUMBER.test(reportID)) { + if (hasSelectedMultipleParticipants && CONST.REGEX.NUMBER.test(reportID)) { IOU.splitBill( this.state.participants, this.props.currentUserPersonalDetails.login, @@ -326,7 +330,7 @@ class IOUModal extends Component { } // If the IOU is created from the global create menu, we also navigate the user to the group report - if (this.props.hasMultipleParticipants) { + if (hasSelectedMultipleParticipants) { IOU.splitBillAndOpenReport( this.state.participants, this.props.currentUserPersonalDetails.login, From a4c60961fb20705f87c307eb1f0c727acb8426ed Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 27 Oct 2022 09:15:05 -0600 Subject: [PATCH 088/100] rm comment space --- src/pages/iou/IOUTransactions.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/iou/IOUTransactions.js b/src/pages/iou/IOUTransactions.js index 30de9080446e..f57499ffb6ea 100644 --- a/src/pages/iou/IOUTransactions.js +++ b/src/pages/iou/IOUTransactions.js @@ -54,7 +54,7 @@ class IOUTransactions extends Component { return []; } - // iouReportIDs should be strings, but we still have places that send them as ints so we convert them both to Numbers for comparison + // iouReportIDs should be strings, but we still have places that send them as ints so we convert them both to Numbers for comparison const actionsForIOUReport = _.filter(this.props.reportActions, action => action.originalMessage && action.originalMessage.type && Number(action.originalMessage.IOUReportID) === Number(this.props.iouReportID)); @@ -76,7 +76,7 @@ class IOUTransactions extends Component { return ( {_.map(this.props.reportActions, (reportAction) => { - // iouReportIDs should be strings, but we still have places that send them as ints so we convert them both to Numbers for comparison + // iouReportIDs should be strings, but we still have places that send them as ints so we convert them both to Numbers for comparison if (!reportAction.originalMessage || Number(reportAction.originalMessage.IOUReportID) !== Number(this.props.iouReportID)) { return; } From 57787310d47ec097a581ab82b6fec345ad5f35b9 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 27 Oct 2022 10:18:43 -0600 Subject: [PATCH 089/100] use set if we are creating a report --- src/libs/actions/IOU.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 26e9c1cda374..7ffc614274de 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -253,7 +253,9 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment const optimisticData = [ { - onyxMethod: CONST.ONYX.METHOD.MERGE, + // 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: existingGroupChatReport ? CONST.ONYX.METHOD.MERGE : CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT}${groupChatReport.reportID}`, value: { ...groupChatReport, @@ -268,7 +270,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment }, }, { - onyxMethod: CONST.ONYX.METHOD.MERGE, + onyxMethod: existingGroupChatReport ? CONST.ONYX.METHOD.MERGE : CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${groupChatReport.reportID}`, value: { ...groupCreatedReportAction, @@ -362,7 +364,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment optimisticData.push( { - onyxMethod: CONST.ONYX.METHOD.MERGE, + onyxMethod: existingOneOnOneChatReport ? CONST.ONYX.METHOD.MERGE : CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`, value: { ...oneOnOneChatReport, @@ -381,7 +383,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment value: oneOnOneIOUReport, }, { - onyxMethod: CONST.ONYX.METHOD.MERGE, + onyxMethod: existingOneOnOneChatReport ? CONST.ONYX.METHOD.MERGE : CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`, value: { ...oneOnOneCreatedReportAction, From 2e8e20f92d2c3ea9333d79841e606fa1162c2864 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 27 Oct 2022 10:20:43 -0600 Subject: [PATCH 090/100] use set for ioureport --- src/libs/actions/IOU.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 7ffc614274de..3a19d9b2471d 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -378,7 +378,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment }, }, { - onyxMethod: CONST.ONYX.METHOD.MERGE, + onyxMethod: existingOneOnOneChatReport ? CONST.ONYX.METHOD.MERGE : CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneIOUReport.reportID}`, value: oneOnOneIOUReport, }, From 28b5b8ad491f64bcefffee46886126bb3f1f1a12 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 27 Oct 2022 13:51:56 -0600 Subject: [PATCH 091/100] allow split with 2 participants --- src/pages/iou/IOUModal.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/pages/iou/IOUModal.js b/src/pages/iou/IOUModal.js index 94d1c8b7b0b5..0ee82cbfb7b8 100755 --- a/src/pages/iou/IOUModal.js +++ b/src/pages/iou/IOUModal.js @@ -311,13 +311,9 @@ class IOUModal extends Component { createTransaction() { const reportID = lodashGet(this.props, 'route.params.reportID', ''); - // We use hasSelectedMultipleParticipants instead of props.hasMultipleParticipants because the user can start a Split Bill flow - // but select a single participant. We should still allow the user to finish the flow, but we should call the appropriate API command - const hasSelectedMultipleParticipants = this.state.participants.length > 1; - // IOUs created from a group report will have a reportID param in the route. // Since the user is already viewing the report, we don't need to navigate them to the report - if (hasSelectedMultipleParticipants && CONST.REGEX.NUMBER.test(reportID)) { + if (this.props.hasMultipleParticipants && CONST.REGEX.NUMBER.test(reportID)) { IOU.splitBill( this.state.participants, this.props.currentUserPersonalDetails.login, @@ -330,7 +326,7 @@ class IOUModal extends Component { } // If the IOU is created from the global create menu, we also navigate the user to the group report - if (hasSelectedMultipleParticipants) { + if (this.props.hasMultipleParticipants) { IOU.splitBillAndOpenReport( this.state.participants, this.props.currentUserPersonalDetails.login, From 0e37011051bc5123d5be2554ca872956c23c90b0 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 27 Oct 2022 14:20:14 -0600 Subject: [PATCH 092/100] fix participant selection --- src/components/IOUConfirmationList.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/IOUConfirmationList.js b/src/components/IOUConfirmationList.js index 410ed97260f3..9213cff520b0 100755 --- a/src/components/IOUConfirmationList.js +++ b/src/components/IOUConfirmationList.js @@ -275,7 +275,8 @@ class IOUConfirmationList extends Component { const shouldShowSettlementButton = this.props.iouType === CONST.IOU.IOU_TYPE.SEND; const shouldDisableButton = selectedParticipants.length === 0; const recipient = this.state.participants[0]; - const canModifyParticipants = this.props.isIOUAttachedToExistingChatReport && this.props.hasMultipleParticipants; + const canModifyParticipants = !this.props.isIOUAttachedToExistingChatReport && this.props.hasMultipleParticipants; + return ( Date: Thu, 27 Oct 2022 15:52:03 -0600 Subject: [PATCH 093/100] add logic for single participant --- src/libs/actions/IOU.js | 179 +++++++++++++++++++++++----------------- 1 file changed, 103 insertions(+), 76 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 3a19d9b2471d..cc3e269dea65 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -251,23 +251,22 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment participants, ); + groupChatReport.maxSequenceNumber = groupChatReportMaxSequenceNumber + 1; + groupChatReport.lastReadSequenceNumber = groupChatReportMaxSequenceNumber + 1; + groupChatReport.lastVisitedTimestamp = Date.now(); + groupChatReport.lastMessageText = groupIOUReportAction.message[0].text; + groupChatReport.lastMessageHtml = groupIOUReportAction.message[0].html; + groupChatReport.pendingFields = { + createChat: existingGroupChatReport ? null : CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + }; + 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: existingGroupChatReport ? CONST.ONYX.METHOD.MERGE : CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT}${groupChatReport.reportID}`, - value: { - ...groupChatReport, - maxSequenceNumber: groupChatReportMaxSequenceNumber + 1, - lastReadSequenceNumber: groupChatReportMaxSequenceNumber + 1, - lastVisitedTimestamp: Date.now(), - lastMessageText: groupIOUReportAction.message[0].text, - lastMessageHtml: groupIOUReportAction.message[0].html, - pendingFields: { - createChat: existingGroupChatReport ? null : CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - }, - }, + value: groupChatReport, }, { onyxMethod: existingGroupChatReport ? CONST.ONYX.METHOD.MERGE : CONST.ONYX.METHOD.SET, @@ -317,13 +316,15 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment const splitAmount = IOUUtils.calculateAmount(participants, amount); const splits = [{email: currentUserEmail, amount: IOUUtils.calculateAmount(participants, amount, true)}]; + const hasMultipleParticipants = participants.length > 1; _.each(participants, (participant) => { const email = OptionsListUtils.addSMSDomainIfPhoneNumber(participant.login).toLowerCase(); if (email === currentUserEmail) { return; } - const existingOneOnOneChatReport = ReportUtils.getChatByParticipants([email]); + // If we only have one participant, the oneOnOneChatReport is the groupChatReport + const existingOneOnOneChatReport = hasMultipleParticipants ? ReportUtils.getChatByParticipants([email]) : groupChatReport; const oneOnOneChatReport = existingOneOnOneChatReport || ReportUtils.buildOptimisticChatReport([email]); let oneOnOneIOUReport; let existingIOUReport = null; @@ -362,78 +363,104 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment oneOnOneIOUReport.reportID, ); - optimisticData.push( - { - onyxMethod: existingOneOnOneChatReport ? CONST.ONYX.METHOD.MERGE : CONST.ONYX.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`, - value: { - ...oneOnOneChatReport, - maxSequenceNumber: oneOnOneChatReportMaxSequenceNumber + 1, - lastReadSequenceNumber: oneOnOneChatReportMaxSequenceNumber + 1, - lastMessageText: oneOnOneIOUReportAction.message[0].text, - lastMessageHtml: oneOnOneIOUReportAction.message[0].html, - pendingFields: { - createChat: existingOneOnOneChatReport ? null : CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + oneOnOneChatReport.maxSequenceNumber = oneOnOneChatReportMaxSequenceNumber + 1; + oneOnOneChatReport.lastReadSequenceNumber = oneOnOneChatReportMaxSequenceNumber + 1; + oneOnOneChatReport.lastMessageText = oneOnOneIOUReportAction.message[0].text; + oneOnOneChatReport.lastMessageHtml = oneOnOneIOUReportAction.message[0].html; + oneOnOneChatReport.pendingFields = { + createChat: existingOneOnOneChatReport ? null : CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + }; + + if (!hasMultipleParticipants) { + optimisticData[0].value = oneOnOneChatReport; + optimisticData[1].value = { + ...optimisticData[1].value, + [oneOnOneIOUReportAction.sequenceNumber]: oneOnOneIOUReportAction, + }; + successData[1].value = { + ...successData[1].value, + [oneOnOneIOUReportAction.sequenceNumber]: {pendingAction: null}, + }; + failureData[1].value = { + ...failureData[1].value, + [oneOnOneIOUReportAction.sequenceNumber]: {pendingAction: null}, + }; + } else { + optimisticData.push( + { + onyxMethod: existingOneOnOneChatReport ? CONST.ONYX.METHOD.MERGE : CONST.ONYX.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`, + value: { + ...oneOnOneChatReport, + maxSequenceNumber: oneOnOneChatReportMaxSequenceNumber + 1, + lastReadSequenceNumber: oneOnOneChatReportMaxSequenceNumber + 1, + lastMessageText: oneOnOneIOUReportAction.message[0].text, + lastMessageHtml: oneOnOneIOUReportAction.message[0].html, + pendingFields: { + createChat: existingOneOnOneChatReport ? null : CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + }, }, }, - }, - { - onyxMethod: existingOneOnOneChatReport ? CONST.ONYX.METHOD.MERGE : CONST.ONYX.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneIOUReport.reportID}`, - value: oneOnOneIOUReport, - }, - { - onyxMethod: existingOneOnOneChatReport ? CONST.ONYX.METHOD.MERGE : CONST.ONYX.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`, - value: { - ...oneOnOneCreatedReportAction, - [oneOnOneIOUReportAction.sequenceNumber]: oneOnOneIOUReportAction, + { + onyxMethod: existingOneOnOneChatReport ? CONST.ONYX.METHOD.MERGE : CONST.ONYX.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`, + value: { + ...oneOnOneCreatedReportAction, + [oneOnOneIOUReportAction.sequenceNumber]: oneOnOneIOUReportAction, + }, }, - }, - ); + ); - successData.push( - { - onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`, - value: {pendingFields: {createChat: null}}, - }, - { - onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`, - value: { - 0: {pendingAction: null}, - [oneOnOneIOUReportAction.sequenceNumber]: {pendingAction: null}, + successData.push( + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`, + value: {pendingFields: {createChat: null}}, }, - }, - ); + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`, + value: { + 0: {pendingAction: null}, + [oneOnOneIOUReportAction.sequenceNumber]: {pendingAction: null}, + }, + }, + ); - failureData.push( - { - onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`, - value: { - pendingFields: {createChat: null}, - hasOutstandingIOU: existingOneOnOneChatReport ? existingOneOnOneChatReport.hasOutstandingIOU : false, - iouReportID: existingOneOnOneChatReport ? existingOneOnOneChatReport.iouReportID : null, - maxSequenceNumber: oneOnOneChatReportMaxSequenceNumber, - lastReadSequenceNumber: oneOnOneChatReportMaxSequenceNumber, + failureData.push( + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`, + value: { + pendingFields: {createChat: null}, + hasOutstandingIOU: existingOneOnOneChatReport ? existingOneOnOneChatReport.hasOutstandingIOU : false, + iouReportID: existingOneOnOneChatReport ? existingOneOnOneChatReport.iouReportID : null, + maxSequenceNumber: oneOnOneChatReportMaxSequenceNumber, + lastReadSequenceNumber: oneOnOneChatReportMaxSequenceNumber, + }, }, - }, - { - onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`, - value: { - 0: {pendingAction: null}, - [oneOnOneIOUReportAction.sequenceNumber]: null, + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`, + value: { + 0: {pendingAction: null}, + [oneOnOneIOUReportAction.sequenceNumber]: {pendingAction: null}, + }, }, - }, - { - onyxMethod: CONST.ONYX.METHOD.SET, - key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneIOUReport.reportID}`, - value: existingIOUReport, - }, - ); + ); + } + + optimisticData.push({ + onyxMethod: existingOneOnOneChatReport ? CONST.ONYX.METHOD.MERGE : CONST.ONYX.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneIOUReport.reportID}`, + value: oneOnOneIOUReport, + }); + + failureData.push({ + onyxMethod: CONST.ONYX.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneIOUReport.reportID}`, + value: existingIOUReport, + }); splits.push({ email, From c0b50f1d6b81573848b59a4156fc72e60312626c Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 27 Oct 2022 15:55:17 -0600 Subject: [PATCH 094/100] add comment --- src/libs/actions/IOU.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index cc3e269dea65..5cb7526941a0 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -371,6 +371,8 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment createChat: existingOneOnOneChatReport ? null : CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, }; + // If we only have one other participant, we just need to update onyxData for the groupChatReport and add an iouReportAction of type = create + // If we have more participants, we need to push the new oneOnOneChaReport, the create reportAction and iouReportAction of type = create to onyxData if (!hasMultipleParticipants) { optimisticData[0].value = oneOnOneChatReport; optimisticData[1].value = { @@ -450,6 +452,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment ); } + // Regardless of the number of participants, we always want to push the iouReport update to onyxData optimisticData.push({ onyxMethod: existingOneOnOneChatReport ? CONST.ONYX.METHOD.MERGE : CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneIOUReport.reportID}`, From 0526e8c3ce9bbaeb7b14b256b47f84dd6293c2d6 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 27 Oct 2022 16:01:02 -0600 Subject: [PATCH 095/100] rm duplicate update --- src/libs/actions/IOU.js | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 5cb7526941a0..148b877c51e9 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -392,16 +392,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment { onyxMethod: existingOneOnOneChatReport ? CONST.ONYX.METHOD.MERGE : CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`, - value: { - ...oneOnOneChatReport, - maxSequenceNumber: oneOnOneChatReportMaxSequenceNumber + 1, - lastReadSequenceNumber: oneOnOneChatReportMaxSequenceNumber + 1, - lastMessageText: oneOnOneIOUReportAction.message[0].text, - lastMessageHtml: oneOnOneIOUReportAction.message[0].html, - pendingFields: { - createChat: existingOneOnOneChatReport ? null : CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - }, - }, + value: oneOnOneChatReport, }, { onyxMethod: existingOneOnOneChatReport ? CONST.ONYX.METHOD.MERGE : CONST.ONYX.METHOD.SET, From d5a75d20ad7a15786dafffbbddf0219fdf6b1e9d Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 27 Oct 2022 16:28:15 -0600 Subject: [PATCH 096/100] update set logic for iouReport --- src/libs/actions/IOU.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 148b877c51e9..9205a5d11319 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -445,7 +445,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment // Regardless of the number of participants, we always want to push the iouReport update to onyxData optimisticData.push({ - onyxMethod: existingOneOnOneChatReport ? CONST.ONYX.METHOD.MERGE : CONST.ONYX.METHOD.SET, + onyxMethod: ((hasMultipleParticipants && existingOneOnOneChatReport) || (!hasMultipleParticipants && existingGroupChatReport)) ? CONST.ONYX.METHOD.MERGE : CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneIOUReport.reportID}`, value: oneOnOneIOUReport, }); From c67c37e7ad037ba50ef6a1ee95ade5e6890bdcc3 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 27 Oct 2022 17:09:28 -0600 Subject: [PATCH 097/100] add comment --- src/libs/actions/IOU.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index d1c5b4888c6b..7e1aef363678 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -447,6 +447,9 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment // Regardless of the number of participants, we always want to push the iouReport update to onyxData optimisticData.push({ + // We want to use set in case we are creating the the optimistic chat. + // If we have multiple participants selected, we need to check if the 1:1 chat between the users already exists + // If we have only one other participant, the group chat is the 1:1 chat and we need to check if that already exists onyxMethod: ((hasMultipleParticipants && existingOneOnOneChatReport) || (!hasMultipleParticipants && existingGroupChatReport)) ? CONST.ONYX.METHOD.MERGE : CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneIOUReport.reportID}`, value: oneOnOneIOUReport, From b2f5442bcf9e684c9443787aa06649b6e915d40a Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Fri, 28 Oct 2022 09:46:28 -0600 Subject: [PATCH 098/100] fix loading spinner --- src/libs/actions/IOU.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 7e1aef363678..ab8aba0d546a 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -458,7 +458,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment failureData.push({ onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${oneOnOneIOUReport.reportID}`, - value: existingIOUReport, + value: existingIOUReport || oneOnOneIOUReport, }); splits.push({ From 272646610d6956499cadba734042b22d386adb9a Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Fri, 28 Oct 2022 13:48:43 -0600 Subject: [PATCH 099/100] early return for iouReport --- src/libs/actions/Report.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 5a4d3ef6ebe0..c780198899ee 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -357,6 +357,9 @@ function fetchIOUReportByID(iouReportID, chatReportID, shouldRedirectIfEmpty = f Navigation.navigate(ROUTES.REPORT); return; } + if (!iouReportObject) { + return; + } setLocalIOUReportData(iouReportObject); return iouReportObject; }); From d20ea607d4d4f085539597db4b354a14decd04e9 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Mon, 31 Oct 2022 10:33:35 -0600 Subject: [PATCH 100/100] fix selectedParticipants; --- src/components/IOUConfirmationList.js | 2 +- src/pages/iou/IOUModal.js | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components/IOUConfirmationList.js b/src/components/IOUConfirmationList.js index 9213cff520b0..4f4eb415ed4b 100755 --- a/src/components/IOUConfirmationList.js +++ b/src/components/IOUConfirmationList.js @@ -266,7 +266,7 @@ class IOUConfirmationList extends Component { Log.info(`[IOU] Sending money via: ${paymentMethod}`); this.props.onSendMoney(paymentMethod); } else { - this.props.onConfirm(); + this.props.onConfirm(selectedParticipants); } } diff --git a/src/pages/iou/IOUModal.js b/src/pages/iou/IOUModal.js index 0ee82cbfb7b8..157c21a28195 100755 --- a/src/pages/iou/IOUModal.js +++ b/src/pages/iou/IOUModal.js @@ -308,14 +308,17 @@ class IOUModal extends Component { }); } - createTransaction() { + /** + * @param {Array} selectedParticipants + */ + createTransaction(selectedParticipants) { const reportID = lodashGet(this.props, 'route.params.reportID', ''); // IOUs created from a group report will have a reportID param in the route. // Since the user is already viewing the report, we don't need to navigate them to the report if (this.props.hasMultipleParticipants && CONST.REGEX.NUMBER.test(reportID)) { IOU.splitBill( - this.state.participants, + selectedParticipants, this.props.currentUserPersonalDetails.login, this.state.amount, this.state.comment, @@ -328,7 +331,7 @@ class IOUModal extends Component { // If the IOU is created from the global create menu, we also navigate the user to the group report if (this.props.hasMultipleParticipants) { IOU.splitBillAndOpenReport( - this.state.participants, + selectedParticipants, this.props.currentUserPersonalDetails.login, this.state.amount, this.state.comment, @@ -342,7 +345,7 @@ class IOUModal extends Component { Math.round(this.state.amount * 100), this.props.iou.selectedCurrencyCode, this.props.currentUserPersonalDetails.login, - this.state.participants[0], + selectedParticipants[0], this.state.comment); }