From 1b4218d6a51d4eccc0e2954474f9d008e911c557 Mon Sep 17 00:00:00 2001 From: Alberto Date: Mon, 5 Sep 2022 11:50:04 +0100 Subject: [PATCH 01/67] remove old API call and create skeleton of new one --- src/libs/actions/IOU.js | 43 ++++++++++++++++++++++++++++++++++++++ src/libs/actions/Report.js | 1 + src/libs/deprecatedAPI.js | 17 --------------- 3 files changed, 44 insertions(+), 17 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 55d4a019b95a..bcc58a325f96 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -121,6 +121,49 @@ function createIOUTransaction(params) { }); } +function requestMoney(params) { + const optimisticChatReport = Report.createOptimisticChatReport(); + const optimisticReportAction = Report.createOptimisticReportAction(); + const optimisticData = [ + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${params.chatReportID}`, + value: { + [params.reportActionID]: { + ...optimisticReportAction, + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + }, + }, + }, + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${params.chatReportID}`, + value: optimisticChatReport, + }, + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${params.iouReportID}`, + value: optimisticChatReport, + }, + ]; + const failureData = [ + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${params.chatReportID}`, + value: { + [params.reportActionID]: { + ...optimisticReportAction, + pendingAction: null, + error : { + [DateUtils.getMicroseconds()]: Localize.translateLocal(iou.error.genericCreateFailureMessage), + }, + }, + }, + }, + ]; + API.write('RequestMoney', params, {optimisticData, failureData}) +} + /** * Creates IOUSplit Transaction * diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index ce448bc0ed5d..0222f3cbd049 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -1589,6 +1589,7 @@ export { openReport, openPaymentDetailsPage, createOptimisticChatReport, + createOptimisticReportAction, updatePolicyRoomName, clearPolicyRoomNameErrors, }; diff --git a/src/libs/deprecatedAPI.js b/src/libs/deprecatedAPI.js index 26a25ff2c9e7..3dd114a7146e 100644 --- a/src/libs/deprecatedAPI.js +++ b/src/libs/deprecatedAPI.js @@ -331,22 +331,6 @@ function ValidateEmail(parameters) { return Network.post(commandName, parameters); } -/** - * Create a new IOUTransaction - * - * @param {Object} parameters - * @param {String} parameters.comment - * @param {Array} parameters.debtorEmail - * @param {String} parameters.currency - * @param {String} parameters.amount - * @returns {Promise} - */ -function CreateIOUTransaction(parameters) { - const commandName = 'CreateIOUTransaction'; - requireParameters(['comment', 'debtorEmail', 'currency', 'amount'], parameters, commandName); - return Network.post(commandName, parameters); -} - /** * Create a new IOU Split * @@ -633,7 +617,6 @@ export { User_IsUsingExpensifyCard, User_SecondaryLogin_Send, User_UploadAvatar, - CreateIOUTransaction, CreateIOUSplit, ValidateEmail, Wallet_Activate, From a5912bfe886a7962093b1bcec1381193f09131b4 Mon Sep 17 00:00:00 2001 From: Alberto Date: Mon, 5 Sep 2022 15:14:47 +0100 Subject: [PATCH 02/67] add fake data --- src/libs/actions/IOU.js | 23 ++++++++++++++--------- src/pages/iou/IOUModal.js | 2 +- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index bcc58a325f96..cd18ad6fef5d 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -10,6 +10,9 @@ import Growl from '../Growl'; import * as Localize from '../Localize'; import asyncOpenURL from '../asyncOpenURL'; import Log from '../Log'; +import DateUtils from '../DateUtils'; +import * as API from '../API'; +import {buildOptimisticIOUReportAction} from "../ReportUtils"; /** * Gets the IOU Reports for new transaction @@ -123,11 +126,12 @@ function createIOUTransaction(params) { function requestMoney(params) { const optimisticChatReport = Report.createOptimisticChatReport(); - const optimisticReportAction = Report.createOptimisticReportAction(); + const optimisticIOUReport = Report.createOptimisticChatReport(); + const optimisticReportAction = buildOptimisticIOUReportAction('create', params.amount, 'comment', '', '', optimisticIOUReport.reportID); const optimisticData = [ { onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${params.chatReportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${optimisticChatReport.reportID}`, value: { [params.reportActionID]: { ...optimisticReportAction, @@ -137,31 +141,31 @@ function requestMoney(params) { }, { onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${params.chatReportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${optimisticChatReport.reportID}`, value: optimisticChatReport, - }, + }, { onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${params.iouReportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${optimisticIOUReport.reportID}`, value: optimisticChatReport, }, ]; const failureData = [ { onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${params.chatReportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${optimisticChatReport.reportID}`, value: { [params.reportActionID]: { ...optimisticReportAction, pendingAction: null, - error : { - [DateUtils.getMicroseconds()]: Localize.translateLocal(iou.error.genericCreateFailureMessage), + error: { + [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.genericCreateFailureMessage'), }, }, }, }, ]; - API.write('RequestMoney', params, {optimisticData, failureData}) + API.write('RequestMoney', params, {optimisticData, failureData}); } /** @@ -368,6 +372,7 @@ export { createIOUSplit, createIOUSplitGroup, rejectTransaction, + requestMoney, payIOUReport, setIOUSelectedCurrency, }; diff --git a/src/pages/iou/IOUModal.js b/src/pages/iou/IOUModal.js index 53aaadc42b42..0cae3d636203 100755 --- a/src/pages/iou/IOUModal.js +++ b/src/pages/iou/IOUModal.js @@ -344,7 +344,7 @@ class IOUModal extends Component { return; } - IOU.createIOUTransaction({ + IOU.requestMoney({ comment: this.state.comment, // Send in cents to API. From da2704bdb84e619fd34767a6d77c0135c4a0cae0 Mon Sep 17 00:00:00 2001 From: Alberto Date: Mon, 5 Sep 2022 17:35:42 +0100 Subject: [PATCH 03/67] error message --- src/languages/en.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/languages/en.js b/src/languages/en.js index cfc3803a2c91..b3b5887aef12 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -247,6 +247,7 @@ export default { error: { invalidSplit: 'Split amounts do not equal total amount', other: 'Unexpected error, please try again later', + genericCreateFailureMessage: 'Unexpected error requesting money, please try again later', }, }, notificationPreferences: { From 84909389991f70fe21b7872c0dc49cebd695a7bb Mon Sep 17 00:00:00 2001 From: Alberto Date: Mon, 5 Sep 2022 17:45:00 +0100 Subject: [PATCH 04/67] use existing chat when available --- 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 cd18ad6fef5d..2d2edbd531db 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -125,13 +125,13 @@ function createIOUTransaction(params) { } function requestMoney(params) { - const optimisticChatReport = Report.createOptimisticChatReport(); + const chatReport = params.report ? params.report : Report.createOptimisticChatReport(); const optimisticIOUReport = Report.createOptimisticChatReport(); const optimisticReportAction = buildOptimisticIOUReportAction('create', params.amount, 'comment', '', '', optimisticIOUReport.reportID); const optimisticData = [ { onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${optimisticChatReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, value: { [params.reportActionID]: { ...optimisticReportAction, @@ -141,7 +141,7 @@ function requestMoney(params) { }, { onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${optimisticChatReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, value: optimisticChatReport, }, { @@ -153,7 +153,7 @@ function requestMoney(params) { const failureData = [ { onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${optimisticChatReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, value: { [params.reportActionID]: { ...optimisticReportAction, @@ -166,6 +166,7 @@ function requestMoney(params) { }, ]; API.write('RequestMoney', params, {optimisticData, failureData}); + Navigation.navigate(ROUTES.getReportRoute(chatReport.reportID)); } /** From ccd0e514b8ed7eaaa6bf5f6641f3ea1b6c712d5a Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 6 Sep 2022 17:13:14 +0100 Subject: [PATCH 05/67] remove unneeded code --- src/libs/actions/IOU.js | 34 +++++----------------------------- 1 file changed, 5 insertions(+), 29 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 2d2edbd531db..9fef7ddcde7d 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -12,7 +12,7 @@ import asyncOpenURL from '../asyncOpenURL'; import Log from '../Log'; import DateUtils from '../DateUtils'; import * as API from '../API'; -import {buildOptimisticIOUReportAction} from "../ReportUtils"; +import * as ReportUtils from '../ReportUtils'; /** * Gets the IOU Reports for new transaction @@ -101,33 +101,10 @@ function startLoadingAndResetError() { Onyx.merge(ONYXKEYS.IOU, {loading: true, creatingIOUTransaction: true, error: false}); } -/** - * Creates IOUSplit Transaction - * - * @param {Object} params - * @param {Number} params.amount - * @param {String} params.comment - * @param {String} params.currency - * @param {String} params.debtorEmail - */ -function createIOUTransaction(params) { - startLoadingAndResetError(); - DeprecatedAPI.CreateIOUTransaction(params) - .then((response) => { - if (response.jsonCode !== 200) { - processIOUErrorResponse(response); - return; - } - - getIOUReportsForNewTransaction([response]); - Navigation.navigate(ROUTES.getReportRoute(response.chatReportID)); - }); -} - function requestMoney(params) { - const chatReport = params.report ? params.report : Report.createOptimisticChatReport(); + const chatReport = params.reportID ? params.reportID : Report.createOptimisticChatReport(); const optimisticIOUReport = Report.createOptimisticChatReport(); - const optimisticReportAction = buildOptimisticIOUReportAction('create', params.amount, 'comment', '', '', optimisticIOUReport.reportID); + const optimisticReportAction = ReportUtils.buildOptimisticIOUReportAction('create', params.amount, 'comment', '', '', optimisticIOUReport.reportID); const optimisticData = [ { onyxMethod: CONST.ONYX.METHOD.MERGE, @@ -142,12 +119,12 @@ function requestMoney(params) { { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, - value: optimisticChatReport, + value: chatReport, }, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${optimisticIOUReport.reportID}`, - value: optimisticChatReport, + value: chatReport, }, ]; const failureData = [ @@ -369,7 +346,6 @@ function payIOUReport({ } export { - createIOUTransaction, createIOUSplit, createIOUSplitGroup, rejectTransaction, From cfd5408025cdcd68a2d146ebdec549e22ac0b5be Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 6 Sep 2022 17:21:45 +0100 Subject: [PATCH 06/67] add missing params --- src/libs/actions/IOU.js | 5 +++-- src/pages/iou/IOUModal.js | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 9fef7ddcde7d..3c97fbf57543 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -13,6 +13,7 @@ import Log from '../Log'; import DateUtils from '../DateUtils'; import * as API from '../API'; import * as ReportUtils from '../ReportUtils'; +import lodashGet from "lodash/get"; /** * Gets the IOU Reports for new transaction @@ -102,8 +103,8 @@ function startLoadingAndResetError() { } function requestMoney(params) { - const chatReport = params.reportID ? params.reportID : Report.createOptimisticChatReport(); - const optimisticIOUReport = Report.createOptimisticChatReport(); + const chatReport = lodashGet(params, 'report.reportID', null) ? params.report : Report.createOptimisticChatReport(params.participants); + const optimisticIOUReport = Report.createOptimisticChatReport(params.participants); const optimisticReportAction = ReportUtils.buildOptimisticIOUReportAction('create', params.amount, 'comment', '', '', optimisticIOUReport.reportID); const optimisticData = [ { diff --git a/src/pages/iou/IOUModal.js b/src/pages/iou/IOUModal.js index 0cae3d636203..e407f50a69f6 100755 --- a/src/pages/iou/IOUModal.js +++ b/src/pages/iou/IOUModal.js @@ -346,6 +346,8 @@ class IOUModal extends Component { IOU.requestMoney({ comment: this.state.comment, + participants: this.participants, + report: this.props.report, // Send in cents to API. amount: Math.round(this.state.amount * 100), From 5e489a2f01e12866da2b89bc54e5fb8d42fc401b Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 6 Sep 2022 17:22:05 +0100 Subject: [PATCH 07/67] style --- 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 3c97fbf57543..b2cb4d729678 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -13,7 +13,7 @@ import Log from '../Log'; import DateUtils from '../DateUtils'; import * as API from '../API'; import * as ReportUtils from '../ReportUtils'; -import lodashGet from "lodash/get"; +import lodashGet from 'lodash/get'; /** * Gets the IOU Reports for new transaction From 4da1f9dd65a23584aef852a4a5183a2edc4dc53e Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 7 Sep 2022 16:46:42 +0100 Subject: [PATCH 08/67] move to actual params --- src/libs/actions/IOU.js | 25 ++++++++++++++++++------- src/libs/actions/Report.js | 25 +++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index b2cb4d729678..865b05f3f841 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -14,6 +14,7 @@ import DateUtils from '../DateUtils'; import * as API from '../API'; import * as ReportUtils from '../ReportUtils'; import lodashGet from 'lodash/get'; +import * as NumberUtils from "../NumberUtils"; /** * Gets the IOU Reports for new transaction @@ -102,16 +103,17 @@ function startLoadingAndResetError() { Onyx.merge(ONYXKEYS.IOU, {loading: true, creatingIOUTransaction: true, error: false}); } -function requestMoney(params) { - const chatReport = lodashGet(params, 'report.reportID', null) ? params.report : Report.createOptimisticChatReport(params.participants); - const optimisticIOUReport = Report.createOptimisticChatReport(params.participants); - const optimisticReportAction = ReportUtils.buildOptimisticIOUReportAction('create', params.amount, 'comment', '', '', optimisticIOUReport.reportID); +function requestMoney(report, participants, amount, currency, debtorEmail, comment) { + const chatReport = lodashGet(report, 'reportID', null) ? report : Report.createOptimisticChatReport(participants); + const optimisticTransactionID = NumberUtils.rand64(); + const optimisticIOUReport = Report.buildOptimisticIOUReport(amount, chatReport.reportID, currency, 'en'); + const optimisticReportAction = ReportUtils.buildOptimisticIOUReportAction('create', amount, 'comment', '', '', optimisticIOUReport.reportID); const optimisticData = [ { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, value: { - [params.reportActionID]: { + [optimisticReportAction.reportActionID]: { ...optimisticReportAction, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, }, @@ -133,7 +135,7 @@ function requestMoney(params) { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, value: { - [params.reportActionID]: { + [optimisticReportAction.reportActionID]: { ...optimisticReportAction, pendingAction: null, error: { @@ -143,7 +145,16 @@ function requestMoney(params) { }, }, ]; - API.write('RequestMoney', params, {optimisticData, failureData}); + API.write('RequestMoney', { + debtorEmail, + amount, + currency, + comment, + iouReportID: optimisticIOUReport.reportID, + chatReportID: chatReport.reportID, + transactionID: optimisticTransactionID, + reportActionID: optimisticReportAction.reportActionID, + }, {optimisticData, failureData}); Navigation.navigate(ROUTES.getReportRoute(chatReport.reportID)); } diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 105ca3964226..ddbc181c2d2b 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -27,6 +27,7 @@ import * as Localize from '../Localize'; import DateUtils from '../DateUtils'; import * as ReportActionsUtils from '../ReportActionsUtils'; import * as NumberUtils from '../NumberUtils'; +import * as NumberFormatUtils from '../NumberFormatUtils'; let currentUserEmail; let currentUserAccountID; @@ -630,6 +631,29 @@ function createOptimisticChatReport( }; } +/* + * Creates an optimistic IOU report with a randomly generated reportID + */ +function buildOptimisticIOUReport(total, chatReportID, currency, locale) { + const formattedTotal = NumberFormatUtils.format(locale, + total, { + style: 'currency', + currency, + }); + return { + cachedTotal: formattedTotal, + chatReportID, + currency, + hasOutstandingIOU: true, + managerEmail: '__FAKE__', + ownerEmail: '__FAKE__', + reportID: ReportUtils.generateReportID(), + state: 'SUBMITTED', + stateNum: 1, + total, + }; +} + /** * Returns the necessary reportAction onyx data to indicate that the chat has been created optimistically * @param {String} ownerEmail @@ -1636,4 +1660,5 @@ export { createOptimisticCreatedReportAction, updatePolicyRoomName, clearPolicyRoomNameErrors, + buildOptimisticIOUReport, }; From 41f975d181e45277041a16f9cc97daa7da0808e7 Mon Sep 17 00:00:00 2001 From: Alberto Date: Thu, 8 Sep 2022 11:18:05 +0100 Subject: [PATCH 09/67] pass parameters --- src/libs/actions/IOU.js | 2 +- src/pages/iou/IOUModal.js | 16 ++++++---------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 865b05f3f841..2c3e98983f04 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -107,7 +107,7 @@ function requestMoney(report, participants, amount, currency, debtorEmail, comme const chatReport = lodashGet(report, 'reportID', null) ? report : Report.createOptimisticChatReport(participants); const optimisticTransactionID = NumberUtils.rand64(); const optimisticIOUReport = Report.buildOptimisticIOUReport(amount, chatReport.reportID, currency, 'en'); - const optimisticReportAction = ReportUtils.buildOptimisticIOUReportAction('create', amount, 'comment', '', '', optimisticIOUReport.reportID); + const optimisticReportAction = ReportUtils.buildOptimisticIOUReportAction('create', amount, 'comment', '', optimisticTransactionID, optimisticIOUReport.reportID); const optimisticData = [ { onyxMethod: CONST.ONYX.METHOD.MERGE, diff --git a/src/pages/iou/IOUModal.js b/src/pages/iou/IOUModal.js index e407f50a69f6..bbdad634be0f 100755 --- a/src/pages/iou/IOUModal.js +++ b/src/pages/iou/IOUModal.js @@ -344,16 +344,12 @@ class IOUModal extends Component { return; } - IOU.requestMoney({ - comment: this.state.comment, - participants: this.participants, - report: this.props.report, - - // Send in cents to API. - amount: Math.round(this.state.amount * 100), - currency: this.props.iou.selectedCurrencyCode, - debtorEmail: OptionsListUtils.addSMSDomainIfPhoneNumber(this.state.participants[0].login), - }); + IOU.requestMoney(this.props.report, + this.participants, + Math.round(this.state.amount * 100), + this.props.iou.selectedCurrencyCode, + OptionsListUtils.addSMSDomainIfPhoneNumber(this.state.participants[0].login), + this.state.comment); } render() { From 86ff05bde3de118fba0d054b028ded403f45514a Mon Sep 17 00:00:00 2001 From: Alberto Date: Thu, 8 Sep 2022 17:00:19 +0100 Subject: [PATCH 10/67] remove extra function --- src/libs/actions/Report.js | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index ddbc181c2d2b..105ca3964226 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -27,7 +27,6 @@ import * as Localize from '../Localize'; import DateUtils from '../DateUtils'; import * as ReportActionsUtils from '../ReportActionsUtils'; import * as NumberUtils from '../NumberUtils'; -import * as NumberFormatUtils from '../NumberFormatUtils'; let currentUserEmail; let currentUserAccountID; @@ -631,29 +630,6 @@ function createOptimisticChatReport( }; } -/* - * Creates an optimistic IOU report with a randomly generated reportID - */ -function buildOptimisticIOUReport(total, chatReportID, currency, locale) { - const formattedTotal = NumberFormatUtils.format(locale, - total, { - style: 'currency', - currency, - }); - return { - cachedTotal: formattedTotal, - chatReportID, - currency, - hasOutstandingIOU: true, - managerEmail: '__FAKE__', - ownerEmail: '__FAKE__', - reportID: ReportUtils.generateReportID(), - state: 'SUBMITTED', - stateNum: 1, - total, - }; -} - /** * Returns the necessary reportAction onyx data to indicate that the chat has been created optimistically * @param {String} ownerEmail @@ -1660,5 +1636,4 @@ export { createOptimisticCreatedReportAction, updatePolicyRoomName, clearPolicyRoomNameErrors, - buildOptimisticIOUReport, }; From 4b0979c3063457e20bd19ed89dcaa2ca6c889338 Mon Sep 17 00:00:00 2001 From: Alberto Date: Mon, 12 Sep 2022 11:40:28 +0200 Subject: [PATCH 11/67] Use existing IOU report when available --- src/libs/actions/IOU.js | 19 ++++++++++++++----- src/pages/iou/IOUModal.js | 1 + 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 2c3e98983f04..60ca2209963b 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -103,10 +103,19 @@ function startLoadingAndResetError() { Onyx.merge(ONYXKEYS.IOU, {loading: true, creatingIOUTransaction: true, error: false}); } -function requestMoney(report, participants, amount, currency, debtorEmail, comment) { - const chatReport = lodashGet(report, 'reportID', null) ? report : Report.createOptimisticChatReport(participants); +function requestMoney(report, participants, amount, currency, recipientEmail, debtorEmail, comment) { + const chatReport = lodashGet(report, 'reportID', null) ? report : Report.buildOptimisticChatReport(participants); const optimisticTransactionID = NumberUtils.rand64(); - const optimisticIOUReport = Report.buildOptimisticIOUReport(amount, chatReport.reportID, currency, 'en'); + const existingIOUReportID = chatReport.hasOutstandingIOU ? chatReport.iouReportID : 0; + let IOUReport = null; + if (existingIOUReportID) { + Onyx.connect({ + key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${existingIOUReportID}`, + callback: val => IOUReport = val, + }); + } else { + IOUReport = ReportUtils.buildOptimisticIOUReport(debtorEmail, recipientEmail, amount, chatReport.reportID, currency, 'en'); + } const optimisticReportAction = ReportUtils.buildOptimisticIOUReportAction('create', amount, 'comment', '', optimisticTransactionID, optimisticIOUReport.reportID); const optimisticData = [ { @@ -126,8 +135,8 @@ function requestMoney(report, participants, amount, currency, debtorEmail, comme }, { onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${optimisticIOUReport.reportID}`, - value: chatReport, + key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${IOUReport.reportID}`, + value: IOUReport, }, ]; const failureData = [ diff --git a/src/pages/iou/IOUModal.js b/src/pages/iou/IOUModal.js index bbdad634be0f..8b291ef5ae09 100755 --- a/src/pages/iou/IOUModal.js +++ b/src/pages/iou/IOUModal.js @@ -348,6 +348,7 @@ class IOUModal extends Component { this.participants, Math.round(this.state.amount * 100), this.props.iou.selectedCurrencyCode, + this.props.currentUserPersonalDetails.login, OptionsListUtils.addSMSDomainIfPhoneNumber(this.state.participants[0].login), this.state.comment); } From 706ab51edacd77088284b2cba1c019f058c178bf Mon Sep 17 00:00:00 2001 From: Alberto Date: Mon, 12 Sep 2022 14:34:34 +0200 Subject: [PATCH 12/67] load ious early --- src/libs/actions/IOU.js | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 60ca2209963b..ffd743d3c30c 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'; @@ -13,8 +14,19 @@ import Log from '../Log'; import DateUtils from '../DateUtils'; import * as API from '../API'; import * as ReportUtils from '../ReportUtils'; -import lodashGet from 'lodash/get'; -import * as NumberUtils from "../NumberUtils"; +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 @@ -106,17 +118,10 @@ function startLoadingAndResetError() { function requestMoney(report, participants, amount, currency, recipientEmail, debtorEmail, comment) { const chatReport = lodashGet(report, 'reportID', null) ? report : Report.buildOptimisticChatReport(participants); const optimisticTransactionID = NumberUtils.rand64(); - const existingIOUReportID = chatReport.hasOutstandingIOU ? chatReport.iouReportID : 0; - let IOUReport = null; - if (existingIOUReportID) { - Onyx.connect({ - key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${existingIOUReportID}`, - callback: val => IOUReport = val, - }); - } else { - IOUReport = ReportUtils.buildOptimisticIOUReport(debtorEmail, recipientEmail, amount, chatReport.reportID, currency, 'en'); - } - const optimisticReportAction = ReportUtils.buildOptimisticIOUReportAction('create', amount, 'comment', '', optimisticTransactionID, optimisticIOUReport.reportID); + console.log(recipientEmail); + const IOUReport = chatReport.hasOutstandingIOU ? iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${chatReport.iouReportID}`] + : ReportUtils.buildOptimisticIOUReport(recipientEmail, debtorEmail, amount, chatReport.reportID, currency, 'en'); + const optimisticReportAction = ReportUtils.buildOptimisticIOUReportAction('create', amount, 'comment', '', optimisticTransactionID, IOUReport.reportID); const optimisticData = [ { onyxMethod: CONST.ONYX.METHOD.MERGE, @@ -159,7 +164,7 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de amount, currency, comment, - iouReportID: optimisticIOUReport.reportID, + iouReportID: IOUReport.reportID, chatReportID: chatReport.reportID, transactionID: optimisticTransactionID, reportActionID: optimisticReportAction.reportActionID, From d1d04647370fb1fd27eede557f47d1b3bffbc4d3 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 13 Sep 2022 18:18:10 +0200 Subject: [PATCH 13/67] build better optimistic action --- src/libs/ReportUtils.js | 16 ++++++++++++++-- src/libs/actions/IOU.js | 3 +-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index e48939c5e7e9..8b44867231ca 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -607,8 +607,8 @@ function buildOptimisticIOUReport(ownerEmail, recipientEmail, total, chatReportI * * @returns {Object} */ -function buildOptimisticIOUReportAction(type, amount, comment, paymentType = '', existingIOUTransactionID = '', existingIOUReportID = 0) { - const currency = lodashGet(currentUserPersonalDetails, 'localCurrencyCode'); +function buildOptimisticIOUReportAction(type, amount, comment, iouCurrency = '', paymentType = '', existingIOUTransactionID = '', existingIOUReportID = 0, debtorEmail = '') { + const currency = iouCurrency || lodashGet(currentUserPersonalDetails, 'localCurrencyCode'); const IOUTransactionID = existingIOUTransactionID || NumberUtils.rand64(); const IOUReportID = existingIOUReportID || generateReportID(); const sequenceNumber = NumberUtils.generateReportActionSequenceNumber(); @@ -620,6 +620,17 @@ function buildOptimisticIOUReportAction(type, amount, comment, paymentType = '', IOUReportID, type, }; + const formattedTotal = NumberFormatUtils.format('en', + amount, { + style: 'currency', + currency, + }); + const message = [{ + type: CONST.REPORT.MESSAGE.TYPE.COMMENT, + isEdited: false, + html: `Requested ${formattedTotal} from ${debtorEmail}`, + text: `Requested ${formattedTotal} from ${debtorEmail}`, + }]; // We store amount, comment, currency in IOUDetails when type = pay if (type === CONST.IOU.REPORT_ACTION_TYPE.PAY) { @@ -641,6 +652,7 @@ function buildOptimisticIOUReportAction(type, amount, comment, paymentType = '', // We are changing that as we roll out the optimisticReportAction IDs and related refactors. clientID: sequenceNumber, isAttachment: false, + message, originalMessage, person: [{ style: 'strong', diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index ffd743d3c30c..91c8c29c4401 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -118,10 +118,9 @@ function startLoadingAndResetError() { function requestMoney(report, participants, amount, currency, recipientEmail, debtorEmail, comment) { const chatReport = lodashGet(report, 'reportID', null) ? report : Report.buildOptimisticChatReport(participants); const optimisticTransactionID = NumberUtils.rand64(); - console.log(recipientEmail); const IOUReport = chatReport.hasOutstandingIOU ? iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${chatReport.iouReportID}`] : ReportUtils.buildOptimisticIOUReport(recipientEmail, debtorEmail, amount, chatReport.reportID, currency, 'en'); - const optimisticReportAction = ReportUtils.buildOptimisticIOUReportAction('create', amount, 'comment', '', optimisticTransactionID, IOUReport.reportID); + const optimisticReportAction = ReportUtils.buildOptimisticIOUReportAction('create', amount, 'comment', currency, '', optimisticTransactionID, IOUReport.reportID, debtorEmail); const optimisticData = [ { onyxMethod: CONST.ONYX.METHOD.MERGE, From 9373c1d987414e302b9e1e8d82e4ae84d3601073 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 13 Sep 2022 19:33:34 +0200 Subject: [PATCH 14/67] handle total IOU owed --- src/libs/ReportUtils.js | 2 +- src/libs/actions/IOU.js | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 8b44867231ca..9315b12dccd5 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -621,7 +621,7 @@ function buildOptimisticIOUReportAction(type, amount, comment, iouCurrency = '', type, }; const formattedTotal = NumberFormatUtils.format('en', - amount, { + amount / 100, { style: 'currency', currency, }); diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 91c8c29c4401..c355388c4119 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -118,8 +118,13 @@ function startLoadingAndResetError() { function requestMoney(report, participants, amount, currency, recipientEmail, debtorEmail, comment) { const chatReport = lodashGet(report, 'reportID', null) ? report : Report.buildOptimisticChatReport(participants); const optimisticTransactionID = NumberUtils.rand64(); - const IOUReport = chatReport.hasOutstandingIOU ? iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${chatReport.iouReportID}`] - : ReportUtils.buildOptimisticIOUReport(recipientEmail, debtorEmail, amount, chatReport.reportID, currency, 'en'); + let IOUReport; + if (chatReport.hasOutstandingIOU) { + IOUReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${chatReport.iouReportID}`]; + IOUReport.total += amount; + } else { + IOUReport = ReportUtils.buildOptimisticIOUReport(recipientEmail, debtorEmail, amount, chatReport.reportID, currency, 'en'); + } const optimisticReportAction = ReportUtils.buildOptimisticIOUReportAction('create', amount, 'comment', currency, '', optimisticTransactionID, IOUReport.reportID, debtorEmail); const optimisticData = [ { @@ -164,7 +169,7 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de currency, comment, iouReportID: IOUReport.reportID, - chatReportID: chatReport.reportID, + reportID: chatReport.reportID, transactionID: optimisticTransactionID, reportActionID: optimisticReportAction.reportActionID, }, {optimisticData, failureData}); From 567595d8f61fc9a7fdd7e2a61fea5476bebab127 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 13 Sep 2022 19:49:51 +0200 Subject: [PATCH 15/67] Do not disable 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 33e8a668bd3d..6ccd7991b2c3 100755 --- a/src/components/IOUConfirmationList.js +++ b/src/components/IOUConfirmationList.js @@ -330,7 +330,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 1adea53a8c850c3c0cec87b99ed417cd97de8c00 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 13 Sep 2022 19:55:17 +0200 Subject: [PATCH 16/67] update comments --- src/libs/ReportUtils.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 9315b12dccd5..4dbab9850610 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -601,9 +601,11 @@ function buildOptimisticIOUReport(ownerEmail, recipientEmail, total, chatReportI * @param {String} type - IOUReportAction type. Can be oneOf(create, decline, cancel, pay). * @param {Number} amount - IOU amount in cents. * @param {String} comment - User comment for the IOU. + * @param {String} iouCurrency - Currency of 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 {String} debtorEmail - Email of the user that has to pay * * @returns {Object} */ From 464f4296847a1b19e18d9887921a0ee916849d97 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 13 Sep 2022 20:02:41 +0200 Subject: [PATCH 17/67] add translation --- src/languages/es.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/languages/es.js b/src/languages/es.js index 75554f7c91e8..c87e6aa6b32b 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -247,6 +247,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', + genericCreateFailureMessage: 'Error inesperado solicitando dinero, por favor inténtalo más tarde', }, }, notificationPreferences: { From e253231995cdd60601e7637b43e63a9c4922ee49 Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 14 Sep 2022 11:34:37 +0200 Subject: [PATCH 18/67] add JSDOc --- src/libs/actions/IOU.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index c355388c4119..a9c477b993f8 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -115,6 +115,17 @@ function startLoadingAndResetError() { Onyx.merge(ONYXKEYS.IOU, {loading: true, creatingIOUTransaction: true, error: false}); } +/** + * Request money from another user + * + * @param {Object} report + * @param {Array} participants + * @param {Number} amount + * @param {String} currency + * @param {String} recipientEmail + * @param {String} debtorEmail + * @param {String} comment + */ function requestMoney(report, participants, amount, currency, recipientEmail, debtorEmail, comment) { const chatReport = lodashGet(report, 'reportID', null) ? report : Report.buildOptimisticChatReport(participants); const optimisticTransactionID = NumberUtils.rand64(); From 0ad2e780c5ae5468f832cc9e497d112dd52f561f Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 14 Sep 2022 12:27:25 +0200 Subject: [PATCH 19/67] remove isLoading --- src/components/IOUConfirmationList.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/IOUConfirmationList.js b/src/components/IOUConfirmationList.js index 6ccd7991b2c3..eaf070d185fe 100755 --- a/src/components/IOUConfirmationList.js +++ b/src/components/IOUConfirmationList.js @@ -331,7 +331,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 ( @@ -357,7 +356,6 @@ class IOUConfirmationList extends Component { ? ( this.confirm(value)} options={this.splitOrRequestOptions} /> From ca213716bd0cd15ef36623fd350042a6c50b021f Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 14 Sep 2022 12:28:26 +0200 Subject: [PATCH 20/67] remove withNetwork --- src/components/IOUConfirmationList.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/IOUConfirmationList.js b/src/components/IOUConfirmationList.js index eaf070d185fe..0fe4c59ccaba 100755 --- a/src/components/IOUConfirmationList.js +++ b/src/components/IOUConfirmationList.js @@ -15,7 +15,6 @@ 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'; const propTypes = { @@ -381,7 +380,6 @@ IOUConfirmationList.defaultProps = defaultProps; export default compose( withLocalize, withWindowDimensions, - withNetwork(), withCurrentUserPersonalDetails, withOnyx({ iou: {key: ONYXKEYS.IOU}, From 175e8b93f175b2cdfa8705bbb6633e73f88b2bb0 Mon Sep 17 00:00:00 2001 From: Alberto Date: Thu, 15 Sep 2022 15:14:28 +0200 Subject: [PATCH 21/67] address a few comments --- src/libs/actions/IOU.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index a9c477b993f8..a3aabb5b634b 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -129,14 +129,14 @@ function startLoadingAndResetError() { function requestMoney(report, participants, amount, currency, recipientEmail, debtorEmail, comment) { const chatReport = lodashGet(report, 'reportID', null) ? report : Report.buildOptimisticChatReport(participants); const optimisticTransactionID = NumberUtils.rand64(); - let IOUReport; + let iouReport; if (chatReport.hasOutstandingIOU) { - IOUReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${chatReport.iouReportID}`]; + iouReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${chatReport.iouReportID}`]; IOUReport.total += amount; } else { - IOUReport = ReportUtils.buildOptimisticIOUReport(recipientEmail, debtorEmail, amount, chatReport.reportID, currency, 'en'); + iouReport = ReportUtils.buildOptimisticIOUReport(recipientEmail, debtorEmail, amount, chatReport.reportID, currency, 'en'); } - const optimisticReportAction = ReportUtils.buildOptimisticIOUReportAction('create', amount, 'comment', currency, '', optimisticTransactionID, IOUReport.reportID, debtorEmail); + const optimisticReportAction = ReportUtils.buildOptimisticIOUReportAction('create', amount, comment, currency, '', optimisticTransactionID, IOUReport.reportID, debtorEmail); const optimisticData = [ { onyxMethod: CONST.ONYX.METHOD.MERGE, @@ -155,8 +155,8 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de }, { onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${IOUReport.reportID}`, - value: IOUReport, + key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${iouReport.reportID}`, + value: iouReport, }, ]; const failureData = [ @@ -179,7 +179,7 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de amount, currency, comment, - iouReportID: IOUReport.reportID, + iouReportID: iouReport.reportID, reportID: chatReport.reportID, transactionID: optimisticTransactionID, reportActionID: optimisticReportAction.reportActionID, From 4dd741200a5b14ea95d392adfff2598aa77425b9 Mon Sep 17 00:00:00 2001 From: Alberto Date: Thu, 15 Sep 2022 15:25:02 +0200 Subject: [PATCH 22/67] missed a couple --- 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 a3aabb5b634b..450a5e1c077b 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -132,11 +132,11 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de let iouReport; if (chatReport.hasOutstandingIOU) { iouReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${chatReport.iouReportID}`]; - IOUReport.total += amount; + iouReport.total += amount; } else { iouReport = ReportUtils.buildOptimisticIOUReport(recipientEmail, debtorEmail, amount, chatReport.reportID, currency, 'en'); } - const optimisticReportAction = ReportUtils.buildOptimisticIOUReportAction('create', amount, comment, currency, '', optimisticTransactionID, IOUReport.reportID, debtorEmail); + const optimisticReportAction = ReportUtils.buildOptimisticIOUReportAction('create', amount, comment, currency, '', optimisticTransactionID, iouReport.reportID, debtorEmail); const optimisticData = [ { onyxMethod: CONST.ONYX.METHOD.MERGE, From b1e1fa7a7ba1d643d26fdfd383ac35a0463fca86 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 20 Sep 2022 16:07:24 +0200 Subject: [PATCH 23/67] do not show offline message --- 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 0fe4c59ccaba..7bafdb5ba188 100755 --- a/src/components/IOUConfirmationList.js +++ b/src/components/IOUConfirmationList.js @@ -349,7 +349,7 @@ class IOUConfirmationList extends Component { forceTextUnreadStyle autoFocus shouldTextInputAppearBelowOptions - shouldShowOfflineMessage + shouldShowOfflineMessage={false} optionHoveredStyle={canModifyParticipants ? styles.hoveredComponentBG : {}} footerContent={shouldShowSettlementButton ? ( From 39bfe27fadadd10c9b231bd447869ce4c5c8ca43 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 20 Sep 2022 16:19:15 +0200 Subject: [PATCH 24/67] rename reportID param --- 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 450a5e1c077b..c84a652ef9e9 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -180,7 +180,7 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de currency, comment, iouReportID: iouReport.reportID, - reportID: chatReport.reportID, + chatReportID: chatReport.reportID, transactionID: optimisticTransactionID, reportActionID: optimisticReportAction.reportActionID, }, {optimisticData, failureData}); From 25762458fa61cd995e43220d30f70453414ee326 Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 21 Sep 2022 12:21:49 +0200 Subject: [PATCH 25/67] correctly prevent preview transparency when not needed --- src/components/IOUConfirmationList.js | 3 --- src/components/ReportActionItem/IOUAction.js | 2 ++ src/components/ReportActionItem/IOUPreview.js | 6 +++++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/components/IOUConfirmationList.js b/src/components/IOUConfirmationList.js index 7bafdb5ba188..c19de8620dc8 100755 --- a/src/components/IOUConfirmationList.js +++ b/src/components/IOUConfirmationList.js @@ -78,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, 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')) && ( {}, containerStyles: [], walletTerms: {}, + pendingAction: null, }; const IOUPreview = (props) => { @@ -132,7 +136,7 @@ const IOUPreview = (props) => { ? : ( { PaymentMethods.clearWalletTermsError(); From 4b110f749d013463e458ee7d2844ac268222a88f Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 21 Sep 2022 12:22:14 +0200 Subject: [PATCH 26/67] remove unneeded import --- src/components/IOUConfirmationList.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/IOUConfirmationList.js b/src/components/IOUConfirmationList.js index c19de8620dc8..20f3962affd0 100755 --- a/src/components/IOUConfirmationList.js +++ b/src/components/IOUConfirmationList.js @@ -14,7 +14,6 @@ import ButtonWithMenu from './ButtonWithMenu'; import Log from '../libs/Log'; import SettlementButton from './SettlementButton'; import ROUTES from '../ROUTES'; -import networkPropTypes from './networkPropTypes'; import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from './withCurrentUserPersonalDetails'; const propTypes = { From 95161b5962fbd03a72c3fcd0e3c83352b3c60d46 Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 21 Sep 2022 15:13:25 +0200 Subject: [PATCH 27/67] Hide from main menu when offline --- .../sidebar/SidebarScreen/BaseSidebarScreen.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js index ff3b97c3f778..a37cbbc6da66 100644 --- a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js +++ b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js @@ -19,15 +19,21 @@ import Performance from '../../../../libs/Performance'; import * as Welcome from '../../../../libs/actions/Welcome'; import {sidebarPropTypes, sidebarDefaultProps} from './sidebarPropTypes'; import withDrawerState from '../../../../components/withDrawerState'; +import {withNetwork} from '../../../../components/OnyxProvider'; +import compose from '../../../../libs/compose'; +import networkPropTypes from '../../../../components/networkPropTypes'; const propTypes = { - /* Callback function when the menu is shown */ + /** Callback function when the menu is shown */ onShowCreateMenu: PropTypes.func, - /* Callback function before the menu is hidden */ + /** Callback function before the menu is hidden */ onHideCreateMenu: PropTypes.func, + /** Information about the network */ + network: networkPropTypes.isRequired, + ...sidebarPropTypes, }; const defaultProps = { @@ -151,7 +157,7 @@ class BaseSidebarScreen extends Component { onSelected: () => Navigation.navigate(ROUTES.IOU_SEND), }, ] : []), - ...(Permissions.canUseIOU(this.props.betas) ? [ + ...(Permissions.canUseIOU(this.props.betas) && !this.props.network.isOffline ? [ { icon: Expensicons.MoneyCircle, text: this.props.translate('iou.requestMoney'), @@ -187,4 +193,7 @@ class BaseSidebarScreen extends Component { BaseSidebarScreen.propTypes = propTypes; BaseSidebarScreen.defaultProps = defaultProps; -export default withDrawerState(BaseSidebarScreen); +export default compose( + withDrawerState, + withNetwork(), +)(BaseSidebarScreen); From 73979e8e054d4c976ab6d8646f7b2bd7503c143b Mon Sep 17 00:00:00 2001 From: Alberto Date: Fri, 23 Sep 2022 11:07:24 +0200 Subject: [PATCH 28/67] pass clientID --- src/libs/actions/IOU.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index c84a652ef9e9..30c2b98b9d4a 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -142,7 +142,7 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, value: { - [optimisticReportAction.reportActionID]: { + [optimisticReportAction.sequenceNumber]: { ...optimisticReportAction, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, }, @@ -164,7 +164,7 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, value: { - [optimisticReportAction.reportActionID]: { + [optimisticReportAction.sequenceNumber]: { ...optimisticReportAction, pendingAction: null, error: { @@ -183,6 +183,7 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de chatReportID: chatReport.reportID, transactionID: optimisticTransactionID, reportActionID: optimisticReportAction.reportActionID, + clientID: optimisticReportAction.sequenceNumber, }, {optimisticData, failureData}); Navigation.navigate(ROUTES.getReportRoute(chatReport.reportID)); } From 7c67a454d5f37feacd7cdb5c3e014f105da758b4 Mon Sep 17 00:00:00 2001 From: Alberto Date: Thu, 29 Sep 2022 16:05:40 +0200 Subject: [PATCH 29/67] several changes to fit new code after merge main --- src/libs/ReportUtils.js | 4 ++-- src/libs/actions/IOU.js | 18 ++++++++++++++---- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index b9d180eea278..4fdf0cd95435 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -664,6 +664,7 @@ function buildOptimisticIOUReport(ownerEmail, recipientEmail, total, chatReportI * @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 {Number} amount - IOU amount in cents. + * @param {String} currency - IOU currency. * @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. @@ -672,8 +673,7 @@ function buildOptimisticIOUReport(ownerEmail, recipientEmail, total, chatReportI * * @returns {Object} */ -function buildOptimisticIOUReportAction(sequenceNumber, type, amount, comment, paymentType = '', existingIOUTransactionID = '', existingIOUReportID = 0, debtorEmail = '') { - const currency = lodashGet(currentUserPersonalDetails, 'localCurrencyCode'); +function buildOptimisticIOUReportAction(sequenceNumber, type, amount, currency, comment, paymentType = '', existingIOUTransactionID = '', existingIOUReportID = 0, debtorEmail = '') { const IOUTransactionID = existingIOUTransactionID || NumberUtils.rand64(); const IOUReportID = existingIOUReportID || generateReportID(); const originalMessage = { diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index c797e9daf69f..884225dad177 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -140,6 +140,7 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de lodashGet(chatReport, 'maxSequenceNumber', 0) + 1, 'create', amount, + currency, comment, '', '', @@ -168,6 +169,17 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de value: iouReport, }, ]; + const successData = [ + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, + value: { + [optimisticReportAction.sequenceNumber]: { + pendingAction: null, + }, + }, + }, + ]; const failureData = [ { onyxMethod: CONST.ONYX.METHOD.MERGE, @@ -176,9 +188,7 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de [optimisticReportAction.sequenceNumber]: { ...optimisticReportAction, pendingAction: null, - error: { - [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.genericCreateFailureMessage'), - }, + error: Localize.translateLocal('iou.error.genericCreateFailureMessage'), }, }, }, @@ -193,7 +203,7 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de transactionID: optimisticTransactionID, reportActionID: optimisticReportAction.reportActionID, clientID: optimisticReportAction.sequenceNumber, - }, {optimisticData, failureData}); + }, {optimisticData, successData, failureData}); Navigation.navigate(ROUTES.getReportRoute(chatReport.reportID)); } From 35f4b6781bfeda2d280240367d0113dfb680004a Mon Sep 17 00:00:00 2001 From: Alberto Date: Thu, 29 Sep 2022 16:06:18 +0200 Subject: [PATCH 30/67] style --- 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 884225dad177..2e0f7a26dc85 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -11,7 +11,6 @@ import Growl from '../Growl'; import * as Localize from '../Localize'; import asyncOpenURL from '../asyncOpenURL'; import Log from '../Log'; -import DateUtils from '../DateUtils'; import * as API from '../API'; import * as ReportUtils from '../ReportUtils'; import * as NumberUtils from '../NumberUtils'; From 1c25dcd88d65bf8b543f6300ec4a75f466100ac3 Mon Sep 17 00:00:00 2001 From: Alberto Date: Thu, 6 Oct 2022 12:35:24 +0200 Subject: [PATCH 31/67] make report defaults strings --- src/components/IOUBadge.js | 4 ++-- src/pages/iouReportPropTypes.js | 2 +- 2 files changed, 3 insertions(+), 3 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, 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 69a992a65ce04f60f8e04d4e85f1b1ae65b5503e Mon Sep 17 00:00:00 2001 From: Alberto Date: Mon, 10 Oct 2022 15:03:32 +0200 Subject: [PATCH 32/67] use function to retrieve mas sequence number --- src/libs/actions/IOU.js | 2 +- src/libs/actions/Report.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 24d6a4279579..34d27d0dfba6 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -136,7 +136,7 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de iouReport = ReportUtils.buildOptimisticIOUReport(recipientEmail, debtorEmail, amount, chatReport.reportID, currency, 'en'); } const optimisticReportAction = ReportUtils.buildOptimisticIOUReportAction( - lodashGet(chatReport, 'maxSequenceNumber', 0) + 1, + Report.getMaxSequenceNumber(lodashGet(report, 'reportID', '0')) + 1, 'create', amount, currency, diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index fc9b2e5a8518..06093f99d7ca 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -1493,4 +1493,5 @@ export { updatePolicyRoomName, clearPolicyRoomNameErrors, clearIOUError, + getMaxSequenceNumber, }; From 77c9202c8525f90717c25d269cd78f9b5438458a Mon Sep 17 00:00:00 2001 From: Alberto Date: Mon, 10 Oct 2022 15:04:35 +0200 Subject: [PATCH 33/67] use random number instead --- 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 34d27d0dfba6..2054ae2ba37a 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -136,7 +136,7 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de iouReport = ReportUtils.buildOptimisticIOUReport(recipientEmail, debtorEmail, amount, chatReport.reportID, currency, 'en'); } const optimisticReportAction = ReportUtils.buildOptimisticIOUReportAction( - Report.getMaxSequenceNumber(lodashGet(report, 'reportID', '0')) + 1, + NumberUtils.generateReportActionClientID(), 'create', amount, currency, From 26eaef00672e94349aa36b438e3eb041455ff6b5 Mon Sep 17 00:00:00 2001 From: Alberto Date: Mon, 10 Oct 2022 15:09:38 +0200 Subject: [PATCH 34/67] remove unneeded export --- src/libs/actions/Report.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index 06093f99d7ca..fc9b2e5a8518 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -1493,5 +1493,4 @@ export { updatePolicyRoomName, clearPolicyRoomNameErrors, clearIOUError, - getMaxSequenceNumber, }; From 7760296d992ecfd6c1d75aee7f2ecc1e62c2b1eb Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 11 Oct 2022 13:23:20 +0200 Subject: [PATCH 35/67] add comments to optimistic action --- 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 116eac9593c0..08486ba29cc5 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -700,8 +700,8 @@ function buildOptimisticIOUReportAction(sequenceNumber, type, amount, currency, const message = [{ type: CONST.REPORT.MESSAGE.TYPE.COMMENT, isEdited: false, - html: `Requested ${formattedTotal} from ${debtorEmail}`, - text: `Requested ${formattedTotal} from ${debtorEmail}`, + html: comment ? `Requested ${formattedTotal} from ${debtorEmail} for ${comment}` : `Requested ${formattedTotal} from ${debtorEmail}`, + text: comment ? `Requested ${formattedTotal} from ${debtorEmail} for ${comment}` : `Requested ${formattedTotal} from ${debtorEmail}`, }]; // We store amount, comment, currency in IOUDetails when type = pay From caac0f7a12e478be7ff2b1127187cf69c7f6b4b8 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 11 Oct 2022 15:22:16 +0200 Subject: [PATCH 36/67] try best guess for sequence number --- src/libs/actions/IOU.js | 2 +- src/libs/actions/Report.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 2054ae2ba37a..251cafe4a088 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -136,7 +136,7 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de iouReport = ReportUtils.buildOptimisticIOUReport(recipientEmail, debtorEmail, amount, chatReport.reportID, currency, 'en'); } const optimisticReportAction = ReportUtils.buildOptimisticIOUReportAction( - NumberUtils.generateReportActionClientID(), + Report.getMaxSequenceNumber(chatReport.reportID), 'create', amount, currency, diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index fc9b2e5a8518..06093f99d7ca 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -1493,4 +1493,5 @@ export { updatePolicyRoomName, clearPolicyRoomNameErrors, clearIOUError, + getMaxSequenceNumber, }; From f3144af80e1868fc9ceb42d71122a0b4bdc9225f Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 11 Oct 2022 16:14:12 +0200 Subject: [PATCH 37/67] update maxSequenceNumber optimistically --- src/libs/actions/IOU.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 251cafe4a088..c1fdb7f8913b 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -135,8 +135,10 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de } else { iouReport = ReportUtils.buildOptimisticIOUReport(recipientEmail, debtorEmail, amount, chatReport.reportID, currency, 'en'); } + const newSequenceNumber = Report.getMaxSequenceNumber(chatReport.reportID) + 1; + chatReport.maxSequenceNumber = newSequenceNumber; const optimisticReportAction = ReportUtils.buildOptimisticIOUReportAction( - Report.getMaxSequenceNumber(chatReport.reportID), + newSequenceNumber, 'create', amount, currency, From 4804261fcbc3dfe541159b8f86d9e99ce763841d Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 11 Oct 2022 16:15:52 +0200 Subject: [PATCH 38/67] change parameter to string --- src/libs/ReportUtils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 341a144dbd9c..b007406fc6c3 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -676,7 +676,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 {String} existingIOUReportID - Only required if the IOUReportActions type is oneOf(decline, cancel, pay). Generates a randomID as default. * @param {String} debtorEmail - Email of the user that has to pay * * @returns {Object} From ded0bae8170c35ba454ff4a11c4c3a9418cd4e51 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 11 Oct 2022 16:18:44 +0200 Subject: [PATCH 39/67] improve header --- src/libs/ReportUtils.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index b007406fc6c3..c0f61c1ef989 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -643,8 +643,17 @@ function buildOptimisticReportAction(sequenceNumber, text, file) { }; } -/* +/** * Builds an optimistic IOU report with a randomly generated reportID + * + * @param {String} ownerEmail - Email of the person generating the IOU. + * @param {String} recipientEmail - Email of the person receiving the IOU. + * @param {Number} total - IOU amount in cents. + * @param {String} chatReportID - Report ID of the chat where the IOU is. + * @param {String} currency - IOU currency. + * @param {String} locale - Locale where the IOU is created + * + * @returns {Object} */ function buildOptimisticIOUReport(ownerEmail, recipientEmail, total, chatReportID, currency, locale) { const formattedTotal = NumberFormatUtils.format(locale, From beaf969b7fa805ec0dc6750ffe87eca80cb589df Mon Sep 17 00:00:00 2001 From: Alberto Date: Thu, 13 Oct 2022 11:39:54 +0200 Subject: [PATCH 40/67] correct default --- src/libs/ReportUtils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index c0f61c1ef989..42e2298cc88a 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -690,7 +690,7 @@ function buildOptimisticIOUReport(ownerEmail, recipientEmail, total, chatReportI * * @returns {Object} */ -function buildOptimisticIOUReportAction(sequenceNumber, type, amount, currency, comment, paymentType = '', existingIOUTransactionID = '', existingIOUReportID = 0, debtorEmail = '') { +function buildOptimisticIOUReportAction(sequenceNumber, type, amount, currency, comment, paymentType = '', existingIOUTransactionID = '', existingIOUReportID = '', debtorEmail = '') { const IOUTransactionID = existingIOUTransactionID || NumberUtils.rand64(); const IOUReportID = existingIOUReportID || generateReportID(); const originalMessage = { From 897d93b9b18d22a971db9880083a225d3ea27566 Mon Sep 17 00:00:00 2001 From: Alberto Date: Thu, 13 Oct 2022 15:52:05 +0200 Subject: [PATCH 41/67] spacing --- 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 c1fdb7f8913b..6b256e9c877f 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -118,7 +118,7 @@ function startLoadingAndResetError() { * Request money from another user * * @param {Object} report - * @param {Array} participants + * @param {Array} participants * @param {Number} amount * @param {String} currency * @param {String} recipientEmail From 48fe19a84396c1e90bcfe07969290099d8e707cb Mon Sep 17 00:00:00 2001 From: Alberto Date: Thu, 13 Oct 2022 17:48:44 +0200 Subject: [PATCH 42/67] Fix not displaying actions correctly --- src/pages/iou/IOUDetailsModal.js | 10 +++++----- src/pages/iou/IOUTransactions.js | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/pages/iou/IOUDetailsModal.js b/src/pages/iou/IOUDetailsModal.js index 606a16b9fd3c..17369e94891e 100644 --- a/src/pages/iou/IOUDetailsModal.js +++ b/src/pages/iou/IOUDetailsModal.js @@ -49,7 +49,7 @@ const propTypes = { /** IOU Report data object */ iouReport: PropTypes.shape({ /** ID for the chatReport that this IOU is linked to */ - chatReportID: PropTypes.number, + chatReportID: PropTypes.string, /** Manager is the person who currently owes money */ managerEmail: PropTypes.string, @@ -123,13 +123,13 @@ class IOUDetailsModal extends Component { diff --git a/src/pages/iou/IOUTransactions.js b/src/pages/iou/IOUTransactions.js index 1532697fc1f3..89df48d40e5b 100644 --- a/src/pages/iou/IOUTransactions.js +++ b/src/pages/iou/IOUTransactions.js @@ -16,10 +16,10 @@ const propTypes = { reportActions: PropTypes.shape(reportActionPropTypes), /** ReportID for the associated chat report */ - chatReportID: PropTypes.number.isRequired, + chatReportID: PropTypes.string.isRequired, /** ReportID for the associated IOU report */ - iouReportID: PropTypes.number.isRequired, + iouReportID: PropTypes.string.isRequired, /** Email for the authenticated user */ userEmail: PropTypes.string.isRequired, @@ -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 180ce4ad1a662a1d8740aedfa56d1180da19edbf Mon Sep 17 00:00:00 2001 From: Alberto Date: Thu, 13 Oct 2022 17:50:55 +0200 Subject: [PATCH 43/67] change type --- src/components/ReportTransaction.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/ReportTransaction.js b/src/components/ReportTransaction.js index c201434d9569..8e2aaeb165ab 100644 --- a/src/components/ReportTransaction.js +++ b/src/components/ReportTransaction.js @@ -15,11 +15,11 @@ import Button from './Button'; const propTypes = { /** The chatReport which the transaction is associated with */ /* eslint-disable-next-line react/no-unused-prop-types */ - chatReportID: PropTypes.number.isRequired, + chatReportID: PropTypes.string.isRequired, /** ID for the IOU report */ /* eslint-disable-next-line react/no-unused-prop-types */ - iouReportID: PropTypes.number.isRequired, + iouReportID: PropTypes.string.isRequired, /** The report action which we are displaying */ action: PropTypes.shape(reportActionPropTypes).isRequired, From 49d3ccf195d78c354f675ea16069a8ee934cfdee Mon Sep 17 00:00:00 2001 From: Alberto Date: Mon, 17 Oct 2022 11:18:55 +0200 Subject: [PATCH 44/67] 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 89df48d40e5b..fde787ae825f 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 7be5f73eae69c63f10009df47e0fe7ac21136396 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 18 Oct 2022 10:33:49 +0200 Subject: [PATCH 45/67] add locale and other minor improvements --- src/components/IOUConfirmationList.js | 1 - src/components/ReportActionItem/IOUPreview.js | 2 +- src/libs/ReportUtils.js | 11 ++++++----- src/libs/actions/IOU.js | 18 +++++++++++++----- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/components/IOUConfirmationList.js b/src/components/IOUConfirmationList.js index 4ac90c8f9509..77a4d5a752b2 100755 --- a/src/components/IOUConfirmationList.js +++ b/src/components/IOUConfirmationList.js @@ -345,7 +345,6 @@ class IOUConfirmationList extends Component { forceTextUnreadStyle autoFocus shouldTextInputAppearBelowOptions - shouldShowOfflineMessage={false} optionHoveredStyle={canModifyParticipants ? styles.hoveredComponentBG : {}} footerContent={shouldShowSettlementButton ? ( diff --git a/src/components/ReportActionItem/IOUPreview.js b/src/components/ReportActionItem/IOUPreview.js index 6ff4b9fceada..355c414e48aa 100644 --- a/src/components/ReportActionItem/IOUPreview.js +++ b/src/components/ReportActionItem/IOUPreview.js @@ -82,7 +82,7 @@ const propTypes = { walletTerms: walletTermsPropTypes, /** Pending action, if any */ - pendingAction: PropTypes.string, + pendingAction: PropTypes.oneOf(_.values(CONST.RED_BRICK_ROAD_PENDING_ACTION)), ...withLocalizePropTypes, }; diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index a0b76a3f7095..879764aa0995 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -642,7 +642,7 @@ function buildOptimisticReportAction(sequenceNumber, text, file) { * Builds an optimistic IOU report with a randomly generated reportID * * @param {String} ownerEmail - Email of the person generating the IOU. - * @param {String} recipientEmail - Email of the person receiving the IOU. + * @param {String} userEmail - Email of the other person participating in the IOU. * @param {Number} total - IOU amount in cents. * @param {String} chatReportID - Report ID of the chat where the IOU is. * @param {String} currency - IOU currency. @@ -650,7 +650,7 @@ function buildOptimisticReportAction(sequenceNumber, text, file) { * * @returns {Object} */ -function buildOptimisticIOUReport(ownerEmail, recipientEmail, total, chatReportID, currency, locale) { +function buildOptimisticIOUReport(ownerEmail, userEmail, total, chatReportID, currency, locale) { const formattedTotal = NumberFormatUtils.format(locale, total, { style: 'currency', @@ -661,7 +661,7 @@ function buildOptimisticIOUReport(ownerEmail, recipientEmail, total, chatReportI chatReportID, currency, hasOutstandingIOU: true, - managerEmail: recipientEmail, + managerEmail: userEmail, ownerEmail, reportID: generateReportID(), state: CONST.REPORT.STATE.SUBMITTED, @@ -682,10 +682,11 @@ function buildOptimisticIOUReport(ownerEmail, recipientEmail, total, chatReportI * @param {String} existingIOUTransactionID - Only required if the IOUReportAction type is oneOf(cancel, decline). Generates a randomID as default. * @param {String} existingIOUReportID - Only required if the IOUReportActions type is oneOf(decline, cancel, pay). Generates a randomID as default. * @param {String} debtorEmail - Email of the user that has to pay + * @param {String} locale - Locale of the user * * @returns {Object} */ -function buildOptimisticIOUReportAction(sequenceNumber, type, amount, currency, comment, paymentType = '', existingIOUTransactionID = '', existingIOUReportID = '', debtorEmail = '') { +function buildOptimisticIOUReportAction(sequenceNumber, type, amount, currency, comment, paymentType = '', existingIOUTransactionID = '', existingIOUReportID = '', debtorEmail = '', locale = 'en') { const IOUTransactionID = existingIOUTransactionID || NumberUtils.rand64(); const IOUReportID = existingIOUReportID || generateReportID(); const originalMessage = { @@ -696,7 +697,7 @@ function buildOptimisticIOUReportAction(sequenceNumber, type, amount, currency, IOUReportID, type, }; - const formattedTotal = NumberFormatUtils.format('en', + const formattedTotal = NumberFormatUtils.format(locale, amount / 100, { style: 'currency', currency, diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 6b256e9c877f..ba1bd9cc45ae 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -15,15 +15,22 @@ import * as API from '../API'; import * as ReportUtils from '../ReportUtils'; import * as NumberUtils from '../NumberUtils'; -const iouReports = {}; +let iouReports; Onyx.connect({ key: ONYXKEYS.COLLECTION.REPORT_IOUS, - callback: (iouReport, key) => { - if (!iouReport || !key || !iouReport.ownerEmail) { + waitForCollectionCallback: true, + callback: val => iouReports = val, +}); + +let preferredLocale = CONST.DEFAULT_LOCALE; +Onyx.connect({ + key: ONYXKEYS.NVP_PREFERRED_LOCALE, + callback: (val) => { + if (!val) { return; } - iouReports[key] = iouReport; + preferredLocale = val; }, }); @@ -133,7 +140,7 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de iouReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${chatReport.iouReportID}`]; iouReport.total += amount; } else { - iouReport = ReportUtils.buildOptimisticIOUReport(recipientEmail, debtorEmail, amount, chatReport.reportID, currency, 'en'); + iouReport = ReportUtils.buildOptimisticIOUReport(recipientEmail, debtorEmail, amount, chatReport.reportID, currency, preferredLocale); } const newSequenceNumber = Report.getMaxSequenceNumber(chatReport.reportID) + 1; chatReport.maxSequenceNumber = newSequenceNumber; @@ -147,6 +154,7 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de '', iouReport.reportID, debtorEmail, + preferredLocale, ); const optimisticData = [ { From 7a91acf3e0bf512276cecb262629b8b6b23e554d Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 18 Oct 2022 10:43:42 +0200 Subject: [PATCH 46/67] improvements to optimistic data generation --- src/CONST.js | 1 + src/libs/actions/IOU.js | 22 ++++++++++++++-------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/CONST.js b/src/CONST.js index 4a896d6332b1..a00f97ed69ae 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -654,6 +654,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 ba1bd9cc45ae..c0b58fc02cf7 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -134,7 +134,6 @@ function startLoadingAndResetError() { */ function requestMoney(report, participants, amount, currency, recipientEmail, debtorEmail, comment) { const chatReport = lodashGet(report, 'reportID', null) ? report : ReportUtils.buildOptimisticChatReport(participants); - const optimisticTransactionID = NumberUtils.rand64(); let iouReport; if (chatReport.hasOutstandingIOU) { iouReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${chatReport.iouReportID}`]; @@ -146,7 +145,7 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de chatReport.maxSequenceNumber = newSequenceNumber; const optimisticReportAction = ReportUtils.buildOptimisticIOUReportAction( newSequenceNumber, - 'create', + CONST.IOU.REPORT_ACTION_TYPE.CREATE, amount, currency, comment, @@ -161,16 +160,16 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, value: { - [optimisticReportAction.sequenceNumber]: { - ...optimisticReportAction, - pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - }, + [optimisticReportAction.sequenceNumber]: optimisticReportAction, }, }, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, - value: chatReport, + value: { + ...chatReport, + pendingFields: {createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}, + }, }, { onyxMethod: CONST.ONYX.METHOD.MERGE, @@ -188,6 +187,13 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de }, }, }, + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, + value: { + pendingFields: null, + }, + }, ]; const failureData = [ { @@ -209,7 +215,7 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de comment, iouReportID: iouReport.reportID, chatReportID: chatReport.reportID, - transactionID: optimisticTransactionID, + transactionID: NumberUtils.rand64(), reportActionID: optimisticReportAction.reportActionID, clientID: optimisticReportAction.sequenceNumber, }, {optimisticData, successData, failureData}); From fd44b8a3d4101bd4f2bb2a51974c20d39873f71d Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 18 Oct 2022 10:49:37 +0200 Subject: [PATCH 47/67] more comments addressed --- src/libs/actions/IOU.js | 8 ++++++++ src/pages/iou/IOUModal.js | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index c0b58fc02cf7..366ab49b397a 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -207,6 +207,14 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de }, }, }, + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, + value: { + ...chatReport, + pendingFields: null, + }, + }, ]; API.write('RequestMoney', { debtorEmail, diff --git a/src/pages/iou/IOUModal.js b/src/pages/iou/IOUModal.js index 5596670490f7..dad11d796e96 100755 --- a/src/pages/iou/IOUModal.js +++ b/src/pages/iou/IOUModal.js @@ -344,7 +344,7 @@ class IOUModal extends Component { } IOU.requestMoney(this.props.report, - this.participants, + this.state.participants, Math.round(this.state.amount * 100), this.props.iou.selectedCurrencyCode, this.props.currentUserPersonalDetails.login, From c70f141d66ce4514bc209be6f154ec5896e8908d Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 18 Oct 2022 11:05:17 +0200 Subject: [PATCH 48/67] fix long line --- src/libs/ReportUtils.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 879764aa0995..6bf3e4e20716 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -679,16 +679,16 @@ function buildOptimisticIOUReport(ownerEmail, userEmail, total, chatReportID, cu * @param {String} currency - IOU currency. * @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 {String} existingIOUReportID - Only required if the IOUReportActions type is oneOf(decline, cancel, pay). Generates a randomID as default. + * @param {String} iouTransactionID - Only required if the IOUReportAction type is oneOf(cancel, decline). Generates a randomID as default. + * @param {String} iouReportID - Only required if the IOUReportActions type is oneOf(decline, cancel, pay). Generates a randomID as default. * @param {String} debtorEmail - Email of the user that has to pay * @param {String} locale - Locale of the user * * @returns {Object} */ -function buildOptimisticIOUReportAction(sequenceNumber, type, amount, currency, comment, paymentType = '', existingIOUTransactionID = '', existingIOUReportID = '', debtorEmail = '', locale = 'en') { - const IOUTransactionID = existingIOUTransactionID || NumberUtils.rand64(); - const IOUReportID = existingIOUReportID || generateReportID(); +function buildOptimisticIOUReportAction(sequenceNumber, type, amount, currency, comment, paymentType = '', iouTransactionID = '', iouReportID = '', debtorEmail = '', locale = 'en') { + const IOUTransactionID = iouTransactionID || NumberUtils.rand64(); + const IOUReportID = iouReportID || generateReportID(); const originalMessage = { amount, comment, From 997d0debd29c48b51e55a0a0e1591572a5078566 Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 19 Oct 2022 11:23:18 +0200 Subject: [PATCH 49/67] Add chatReport functions --- src/libs/ReportUtils.js | 24 ++++++++++++++++++++++++ src/pages/NewChatPage.js | 19 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 6bf3e4e20716..087c53e3cfc3 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 * @@ -981,6 +988,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, @@ -1021,4 +1044,5 @@ export { buildOptimisticIOUReportAction, buildOptimisticReportAction, shouldReportBeInOptionList, + getChatByParticipants, }; diff --git a/src/pages/NewChatPage.js b/src/pages/NewChatPage.js index e4cb4d60f153..dc1cf1b9289a 100755 --- a/src/pages/NewChatPage.js +++ b/src/pages/NewChatPage.js @@ -8,6 +8,7 @@ import * as OptionsListUtils from '../libs/OptionsListUtils'; import ONYXKEYS from '../ONYXKEYS'; import styles from '../styles/styles'; import * as Report from '../libs/actions/Report'; +import * as ReportUtils from '../libs/ReportUtils'; import CONST from '../CONST'; import withWindowDimensions, {windowDimensionsPropTypes} from '../components/withWindowDimensions'; import HeaderWithCloseButton from '../components/HeaderWithCloseButton'; @@ -18,6 +19,7 @@ import withLocalize, {withLocalizePropTypes} from '../components/withLocalize'; import compose from '../libs/compose'; import personalDetailsPropType from './personalDetailsPropType'; import reportPropTypes from './reportPropTypes'; +import ROUTES from '../ROUTES'; const propTypes = { /** Whether screen is used to create group chat */ @@ -129,6 +131,23 @@ class NewChatPage extends Component { return sections; } + /** + * This will find an existing chat, or create a new one if none exists, for the given user or set of users. It will then navigate to this chat. + * + * @param {Array} userLogins list of user logins. + */ + getOrCreateChatReport(userLogins) { + const formattedUserLogins = _.map(userLogins, login => OptionsListUtils.addSMSDomainIfPhoneNumber(login).toLowerCase()); + let newChat = {}; + const chat = ReportUtils.getChatByParticipants(formattedUserLogins); + if (!chat) { + newChat = ReportUtils.buildOptimisticChatReport(formattedUserLogins); + } + const reportID = chat ? chat.reportID : newChat.reportID; + Report.openReport(reportID, newChat.participants, newChat); + Navigation.navigate(ROUTES.getReportRoute(reportID)); + } + /** * Removes a selected option from list if already selected. If not already selected add this option to the list. * @param {Object} option From 6f1d212b744b8c9a1b6e4ea9b9d006f37c55735e Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 19 Oct 2022 12:14:19 +0200 Subject: [PATCH 50/67] move function to Utils and use it: --- src/libs/ReportUtils.js | 21 +++++++++++++++++++++ src/libs/actions/IOU.js | 2 +- src/pages/NewChatPage.js | 17 ----------------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 087c53e3cfc3..0ddaf974ee84 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -15,6 +15,8 @@ import ROUTES from '../ROUTES'; import * as NumberUtils from './NumberUtils'; import * as NumberFormatUtils from './NumberFormatUtils'; import Permissions from './Permissions'; +import * as OptionsListUtils from "./OptionsListUtils"; +import * as Report from "./actions/Report"; let sessionEmail; Onyx.connect({ @@ -1004,6 +1006,24 @@ function getChatByParticipants(newParticipantList) { }); } +/** + * This will find an existing chat, or create a new one if none exists, for the given user or set of users. It will then navigate to this chat. + * + * @param {Array} userLogins list of user logins. + */ +function getOrCreateChatReport(userLogins) { + const formattedUserLogins = _.map(userLogins, login => OptionsListUtils.addSMSDomainIfPhoneNumber(login).toLowerCase()); + let newChat = {}; + const chat = this.getChatByParticipants(formattedUserLogins); + if (!chat) { + newChat = this.buildOptimisticChatReport(formattedUserLogins); + } + const reportID = chat ? chat.reportID : newChat.reportID; + Report.openReport(reportID, newChat.participants, newChat); + Navigation.navigate(ROUTES.getReportRoute(reportID)); + return newChat; +} + export { getReportParticipantsTitle, isReportMessageAttachment, @@ -1045,4 +1065,5 @@ export { buildOptimisticReportAction, shouldReportBeInOptionList, getChatByParticipants, + getOrCreateChatReport, }; diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 366ab49b397a..e2bf8dc5c27a 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -133,7 +133,7 @@ function startLoadingAndResetError() { * @param {String} comment */ function requestMoney(report, participants, amount, currency, recipientEmail, debtorEmail, comment) { - const chatReport = lodashGet(report, 'reportID', null) ? report : ReportUtils.buildOptimisticChatReport(participants); + const chatReport = lodashGet(report, 'reportID', null) ? report : ReportUtils.getOrCreateChatReport([recipientEmail, debtorEmail]); let iouReport; if (chatReport.hasOutstandingIOU) { iouReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${chatReport.iouReportID}`]; diff --git a/src/pages/NewChatPage.js b/src/pages/NewChatPage.js index dc1cf1b9289a..9f613b9c4bee 100755 --- a/src/pages/NewChatPage.js +++ b/src/pages/NewChatPage.js @@ -131,23 +131,6 @@ class NewChatPage extends Component { return sections; } - /** - * This will find an existing chat, or create a new one if none exists, for the given user or set of users. It will then navigate to this chat. - * - * @param {Array} userLogins list of user logins. - */ - getOrCreateChatReport(userLogins) { - const formattedUserLogins = _.map(userLogins, login => OptionsListUtils.addSMSDomainIfPhoneNumber(login).toLowerCase()); - let newChat = {}; - const chat = ReportUtils.getChatByParticipants(formattedUserLogins); - if (!chat) { - newChat = ReportUtils.buildOptimisticChatReport(formattedUserLogins); - } - const reportID = chat ? chat.reportID : newChat.reportID; - Report.openReport(reportID, newChat.participants, newChat); - Navigation.navigate(ROUTES.getReportRoute(reportID)); - } - /** * Removes a selected option from list if already selected. If not already selected add this option to the list. * @param {Object} option From 304fc8860418ab9eafe9f41714583aceecec1cf5 Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 19 Oct 2022 12:46:35 +0200 Subject: [PATCH 51/67] do not use that function anymore --- src/libs/ReportUtils.js | 18 ------------------ src/libs/actions/IOU.js | 10 +++++++++- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 0ddaf974ee84..9471bab1b426 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -1006,24 +1006,6 @@ function getChatByParticipants(newParticipantList) { }); } -/** - * This will find an existing chat, or create a new one if none exists, for the given user or set of users. It will then navigate to this chat. - * - * @param {Array} userLogins list of user logins. - */ -function getOrCreateChatReport(userLogins) { - const formattedUserLogins = _.map(userLogins, login => OptionsListUtils.addSMSDomainIfPhoneNumber(login).toLowerCase()); - let newChat = {}; - const chat = this.getChatByParticipants(formattedUserLogins); - if (!chat) { - newChat = this.buildOptimisticChatReport(formattedUserLogins); - } - const reportID = chat ? chat.reportID : newChat.reportID; - Report.openReport(reportID, newChat.participants, newChat); - Navigation.navigate(ROUTES.getReportRoute(reportID)); - return newChat; -} - export { getReportParticipantsTitle, isReportMessageAttachment, diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index e2bf8dc5c27a..b74c7ccc35fa 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -133,7 +133,15 @@ function startLoadingAndResetError() { * @param {String} comment */ function requestMoney(report, participants, amount, currency, recipientEmail, debtorEmail, comment) { - const chatReport = lodashGet(report, 'reportID', null) ? report : ReportUtils.getOrCreateChatReport([recipientEmail, debtorEmail]); + let chatReport = lodashGet(report, 'reportID', null); + let isNewChat = false; + if (!chatReport) { + chatReport = ReportUtils.getChatByParticipants([debtorEmail]); + } + if (!chatReport) { + chatReport = ReportUtils.buildOptimisticChatReport([debtorEmail]); + isNewChat = true; + } let iouReport; if (chatReport.hasOutstandingIOU) { iouReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${chatReport.iouReportID}`]; From 180172ac1074caff249dd490c9c4a42c9a5ba736 Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 19 Oct 2022 15:41:06 +0200 Subject: [PATCH 52/67] better create data for chat reports and whatnot --- src/libs/ReportUtils.js | 1 - src/libs/actions/IOU.js | 69 ++++++++++++++++++++++++----------------- 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 9471bab1b426..2b5641355eb4 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -1047,5 +1047,4 @@ export { buildOptimisticReportAction, shouldReportBeInOptionList, getChatByParticipants, - getOrCreateChatReport, }; diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index b74c7ccc35fa..2a786c42a432 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -133,7 +133,7 @@ function startLoadingAndResetError() { * @param {String} comment */ function requestMoney(report, participants, amount, currency, recipientEmail, debtorEmail, comment) { - let chatReport = lodashGet(report, 'reportID', null); + let chatReport = report; let isNewChat = false; if (!chatReport) { chatReport = ReportUtils.getChatByParticipants([debtorEmail]); @@ -163,7 +163,42 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de debtorEmail, preferredLocale, ); - const optimisticData = [ + let optimisticData = []; + let successData = []; + + // First, let's add the data we need just when we are creating a new chat report + if (isNewChat) { + optimisticData = [ + { + onyxMethod: CONST.ONYX.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, + value: { + ...chatReport, + isLoadingReportActions: true, + lastVisitedTimestamp: Date.now(), + pendingFields: {createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}, + }, + }, + { + onyxMethod: CONST.ONYX.METHOD.SET, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, + value: ReportUtils.buildOptimisticCreatedReportAction(recipientEmail), + }, + ]; + + successData = [ + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, + value: { + pendingFields: null, + }, + }, + ]; + } + + // Add Data that will be used in all cases + optimisticData = _.union(optimisticData, [ { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, @@ -171,21 +206,14 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de [optimisticReportAction.sequenceNumber]: optimisticReportAction, }, }, - { - onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, - value: { - ...chatReport, - pendingFields: {createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}, - }, - }, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${iouReport.reportID}`, value: iouReport, }, - ]; - const successData = [ + ]); + + successData = _.union(successData, [ { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, @@ -195,14 +223,7 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de }, }, }, - { - onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, - value: { - pendingFields: null, - }, - }, - ]; + ]); const failureData = [ { onyxMethod: CONST.ONYX.METHOD.MERGE, @@ -215,14 +236,6 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de }, }, }, - { - onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, - value: { - ...chatReport, - pendingFields: null, - }, - }, ]; API.write('RequestMoney', { debtorEmail, From 10b241365c19a1303d8e6b1dd45bd8c9cba2a371 Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 19 Oct 2022 15:43:40 +0200 Subject: [PATCH 53/67] enable money requests from the main menu --- .../home/sidebar/SidebarScreen/BaseSidebarScreen.js | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js index ad53af3f02af..881789870851 100644 --- a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js +++ b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js @@ -31,9 +31,6 @@ const propTypes = { /** Callback function before the menu is hidden */ onHideCreateMenu: PropTypes.func, - /** Information about the network */ - network: networkPropTypes.isRequired, - /** reportID in the current navigation state */ reportIDFromRoute: PropTypes.string, @@ -161,7 +158,7 @@ class BaseSidebarScreen extends Component { onSelected: () => Navigation.navigate(ROUTES.IOU_SEND), }, ] : []), - ...(Permissions.canUseIOU(this.props.betas) && !this.props.network.isOffline ? [ + ...(Permissions.canUseIOU(this.props.betas) ? [ { icon: Expensicons.MoneyCircle, text: this.props.translate('iou.requestMoney'), @@ -197,7 +194,4 @@ class BaseSidebarScreen extends Component { BaseSidebarScreen.propTypes = propTypes; BaseSidebarScreen.defaultProps = defaultProps; -export default compose( - withDrawerState, - withNetwork(), -)(BaseSidebarScreen); +export default withDrawerState(BaseSidebarScreen); From 29c8e4bde6c342c75d73c7546301b2bdbaffd1f7 Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 19 Oct 2022 17:33:17 +0200 Subject: [PATCH 54/67] correctly get char report --- 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 2a786c42a432..271e5572ec28 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -133,7 +133,7 @@ function startLoadingAndResetError() { * @param {String} comment */ function requestMoney(report, participants, amount, currency, recipientEmail, debtorEmail, comment) { - let chatReport = report; + let chatReport = lodashGet(report, 'reportID', null) ? report : null; let isNewChat = false; if (!chatReport) { chatReport = ReportUtils.getChatByParticipants([debtorEmail]); From 8839c386538b53ada9d18826cb369dbab6160ef8 Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 19 Oct 2022 17:34:56 +0200 Subject: [PATCH 55/67] cleanup --- src/libs/ReportUtils.js | 2 -- src/pages/NewChatPage.js | 2 -- src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js | 3 --- 3 files changed, 7 deletions(-) diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 2b5641355eb4..087c53e3cfc3 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -15,8 +15,6 @@ import ROUTES from '../ROUTES'; import * as NumberUtils from './NumberUtils'; import * as NumberFormatUtils from './NumberFormatUtils'; import Permissions from './Permissions'; -import * as OptionsListUtils from "./OptionsListUtils"; -import * as Report from "./actions/Report"; let sessionEmail; Onyx.connect({ diff --git a/src/pages/NewChatPage.js b/src/pages/NewChatPage.js index 9f613b9c4bee..e4cb4d60f153 100755 --- a/src/pages/NewChatPage.js +++ b/src/pages/NewChatPage.js @@ -8,7 +8,6 @@ import * as OptionsListUtils from '../libs/OptionsListUtils'; import ONYXKEYS from '../ONYXKEYS'; import styles from '../styles/styles'; import * as Report from '../libs/actions/Report'; -import * as ReportUtils from '../libs/ReportUtils'; import CONST from '../CONST'; import withWindowDimensions, {windowDimensionsPropTypes} from '../components/withWindowDimensions'; import HeaderWithCloseButton from '../components/HeaderWithCloseButton'; @@ -19,7 +18,6 @@ import withLocalize, {withLocalizePropTypes} from '../components/withLocalize'; import compose from '../libs/compose'; import personalDetailsPropType from './personalDetailsPropType'; import reportPropTypes from './reportPropTypes'; -import ROUTES from '../ROUTES'; const propTypes = { /** Whether screen is used to create group chat */ diff --git a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js index 881789870851..f87d3b7da745 100644 --- a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js +++ b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js @@ -19,9 +19,6 @@ import Performance from '../../../../libs/Performance'; import * as Welcome from '../../../../libs/actions/Welcome'; import {sidebarPropTypes, sidebarDefaultProps} from './sidebarPropTypes'; import withDrawerState from '../../../../components/withDrawerState'; -import {withNetwork} from '../../../../components/OnyxProvider'; -import compose from '../../../../libs/compose'; -import networkPropTypes from '../../../../components/networkPropTypes'; const propTypes = { From 2e701149131082376de7f5b2e052dfd5850901c8 Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 19 Oct 2022 17:58:18 +0200 Subject: [PATCH 56/67] cleanup --- src/libs/actions/IOU.js | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 271e5572ec28..7fa64a8dd0cc 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 NumberUtils from '../NumberUtils'; +import * as DateUtils from '../DateUtils'; let iouReports; Onyx.connect({ @@ -165,9 +166,11 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de ); let optimisticData = []; let successData = []; + let failureData = []; // First, let's add the data we need just when we are creating a new chat report if (isNewChat) { + const optimisticCreateAction = ReportUtils.buildOptimisticCreatedReportAction(recipientEmail); optimisticData = [ { onyxMethod: CONST.ONYX.METHOD.SET, @@ -177,16 +180,30 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de isLoadingReportActions: true, lastVisitedTimestamp: Date.now(), pendingFields: {createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}, + isOptimisticReport: true, }, }, { onyxMethod: CONST.ONYX.METHOD.SET, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, - value: ReportUtils.buildOptimisticCreatedReportAction(recipientEmail), + value: optimisticCreateAction, }, ]; successData = [ + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, + value: { + pendingFields: null, + isLoadingReportActions: false, + isOptimisticReport: false, + errorFields: null, + }, + }, + ]; + + failureData = [ { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, @@ -224,7 +241,7 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de }, }, ]); - const failureData = [ + failureData = _.union(failureData, [ { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, @@ -232,11 +249,13 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de [optimisticReportAction.sequenceNumber]: { ...optimisticReportAction, pendingAction: null, - error: Localize.translateLocal('iou.error.genericCreateFailureMessage'), + errors: { + [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.genericCreateFailureMessage'), + }, }, }, }, - ]; + ]); API.write('RequestMoney', { debtorEmail, amount, From 8ae152a46219f1fed132ec726c0adecd0a78a682 Mon Sep 17 00:00:00 2001 From: Alberto Date: Fri, 21 Oct 2022 11:41:25 +0200 Subject: [PATCH 57/67] Better handle create action cleanup --- src/libs/actions/IOU.js | 29 +++++++++++++++++++++-------- src/pages/iou/IOUModal.js | 1 - 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 7fa64a8dd0cc..f9a3f9ae9206 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -126,14 +126,13 @@ function startLoadingAndResetError() { * Request money from another user * * @param {Object} report - * @param {Array} participants * @param {Number} amount * @param {String} currency * @param {String} recipientEmail * @param {String} debtorEmail * @param {String} comment */ -function requestMoney(report, participants, amount, currency, recipientEmail, debtorEmail, comment) { +function requestMoney(report, amount, currency, recipientEmail, debtorEmail, comment) { let chatReport = lodashGet(report, 'reportID', null) ? report : null; let isNewChat = false; if (!chatReport) { @@ -173,18 +172,16 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de const optimisticCreateAction = ReportUtils.buildOptimisticCreatedReportAction(recipientEmail); optimisticData = [ { - onyxMethod: CONST.ONYX.METHOD.SET, + onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, value: { ...chatReport, - isLoadingReportActions: true, lastVisitedTimestamp: Date.now(), pendingFields: {createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}, - isOptimisticReport: true, }, }, { - onyxMethod: CONST.ONYX.METHOD.SET, + onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, value: optimisticCreateAction, }, @@ -196,11 +193,18 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, value: { pendingFields: null, - isLoadingReportActions: false, - isOptimisticReport: false, errorFields: null, }, }, + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, + value: { + 0: { + pendingAction: null, + }, + }, + }, ]; failureData = [ @@ -211,6 +215,15 @@ function requestMoney(report, participants, amount, currency, recipientEmail, de pendingFields: null, }, }, + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, + value: { + 0: { + pendingAction: null, + }, + }, + }, ]; } diff --git a/src/pages/iou/IOUModal.js b/src/pages/iou/IOUModal.js index dad11d796e96..265de9693ac8 100755 --- a/src/pages/iou/IOUModal.js +++ b/src/pages/iou/IOUModal.js @@ -344,7 +344,6 @@ class IOUModal extends Component { } IOU.requestMoney(this.props.report, - this.state.participants, Math.round(this.state.amount * 100), this.props.iou.selectedCurrencyCode, this.props.currentUserPersonalDetails.login, From c3e00587109cbc51cf23c0f8dfb9c40181e8205b Mon Sep 17 00:00:00 2001 From: Alberto Date: Fri, 21 Oct 2022 12:59:26 +0200 Subject: [PATCH 58/67] reorganize data build --- src/libs/actions/IOU.js | 126 ++++++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 62 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index f9a3f9ae9206..f3dfde126da3 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -163,31 +163,76 @@ function requestMoney(report, amount, currency, recipientEmail, debtorEmail, com debtorEmail, preferredLocale, ); - let optimisticData = []; - let successData = []; - let failureData = []; - // First, let's add the data we need just when we are creating a new chat report - if (isNewChat) { - const optimisticCreateAction = ReportUtils.buildOptimisticCreatedReportAction(recipientEmail); - optimisticData = [ - { - onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, - value: { - ...chatReport, - lastVisitedTimestamp: Date.now(), - pendingFields: {createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}, + // First, add Data that will be used in all cases + let optimisticData = [ + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, + value: { + ...chatReport, + lastVisitedTimestamp: Date.now(), + lastReadSequenceNumber: newSequenceNumber, + maxSequenceNumber: newSequenceNumber, + }, + }, + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, + value: { + [optimisticReportAction.sequenceNumber]: optimisticReportAction, + }, + }, + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${iouReport.reportID}`, + value: iouReport, + }, + ]; + + let successData = [ + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, + value: { + [optimisticReportAction.sequenceNumber]: { + pendingAction: null, }, }, + }, + ]; + let failureData = [ + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, + value: { + [optimisticReportAction.sequenceNumber]: { + ...optimisticReportAction, + pendingAction: null, + errors: { + [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.genericCreateFailureMessage'), + }, + }, + }, + }, + ]; + + // Now, let's add the data we need just when we are creating a new chat report + if (isNewChat) { + const optimisticCreateAction = ReportUtils.buildOptimisticCreatedReportAction(recipientEmail); + optimisticData[0].value = { + ...optimisticData[0].value, + pendingFields: {createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}, + }; + optimisticData.push( { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, value: optimisticCreateAction, }, - ]; + ); - successData = [ + successData.push( { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, @@ -205,9 +250,9 @@ function requestMoney(report, amount, currency, recipientEmail, debtorEmail, com }, }, }, - ]; + ); - failureData = [ + failureData.push( { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, @@ -224,51 +269,8 @@ function requestMoney(report, amount, currency, recipientEmail, debtorEmail, com }, }, }, - ]; + ); } - - // Add Data that will be used in all cases - optimisticData = _.union(optimisticData, [ - { - onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, - value: { - [optimisticReportAction.sequenceNumber]: optimisticReportAction, - }, - }, - { - onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_IOUS}${iouReport.reportID}`, - value: iouReport, - }, - ]); - - successData = _.union(successData, [ - { - onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, - value: { - [optimisticReportAction.sequenceNumber]: { - pendingAction: null, - }, - }, - }, - ]); - failureData = _.union(failureData, [ - { - onyxMethod: CONST.ONYX.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, - value: { - [optimisticReportAction.sequenceNumber]: { - ...optimisticReportAction, - pendingAction: null, - errors: { - [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.genericCreateFailureMessage'), - }, - }, - }, - }, - ]); API.write('RequestMoney', { debtorEmail, amount, From 6e725b2c5b240b0ab593afa18da8e4867d772cd4 Mon Sep 17 00:00:00 2001 From: Alberto Date: Fri, 21 Oct 2022 13:36:18 +0200 Subject: [PATCH 59/67] dateutils import --- 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 f3dfde126da3..d049369ba6a3 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -14,7 +14,7 @@ import Log from '../Log'; import * as API from '../API'; import * as ReportUtils from '../ReportUtils'; import * as NumberUtils from '../NumberUtils'; -import * as DateUtils from '../DateUtils'; +import DateUtils from '../DateUtils'; let iouReports; Onyx.connect({ From d63f4923d5c1b8dd2521903f7e8f316c62505c7f Mon Sep 17 00:00:00 2001 From: Alberto Date: Fri, 21 Oct 2022 13:51:07 +0200 Subject: [PATCH 60/67] use consts --- 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 d049369ba6a3..a827b36c4e3c 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -165,7 +165,7 @@ function requestMoney(report, amount, currency, recipientEmail, debtorEmail, com ); // First, add Data that will be used in all cases - let optimisticData = [ + const optimisticData = [ { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, @@ -190,7 +190,7 @@ function requestMoney(report, amount, currency, recipientEmail, debtorEmail, com }, ]; - let successData = [ + const successData = [ { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, @@ -201,7 +201,7 @@ function requestMoney(report, amount, currency, recipientEmail, debtorEmail, com }, }, ]; - let failureData = [ + const failureData = [ { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, From ef58ba72fde8b27b84cadd6014c1b4830e31b8a8 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 25 Oct 2022 13:42:58 +0200 Subject: [PATCH 61/67] Add new function to handle existing IOUs --- src/libs/IOUUtils.js | 36 ++++++++++++++++++++++++++++++++++++ src/libs/actions/IOU.js | 7 ++++++- 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 src/libs/IOUUtils.js diff --git a/src/libs/IOUUtils.js b/src/libs/IOUUtils.js new file mode 100644 index 000000000000..a32ec504e8a9 --- /dev/null +++ b/src/libs/IOUUtils.js @@ -0,0 +1,36 @@ +import CONST from '../CONST'; + +/** + * The owner of the IOU report is the account who is owed money and the manager is the one who owes money! + * 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 + * @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. + iouReportUpdate.ownerEmail = iouReport.managerEmail; + iouReportUpdate.managerEmail = iouReport.ownerEmail; + iouReportUpdate.total = -iouReportUpdate.total; + } + + return iouReportUpdate; +} + +export { + updateIOUOwnerAndTotal, +}; \ No newline at end of file diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index a827b36c4e3c..df25a8e09434 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 NumberUtils from '../NumberUtils'; +import * as IOUUtils from '../IOUUtils'; import DateUtils from '../DateUtils'; let iouReports; @@ -144,7 +145,11 @@ function requestMoney(report, amount, currency, recipientEmail, debtorEmail, com } let iouReport; if (chatReport.hasOutstandingIOU) { - iouReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${chatReport.iouReportID}`]; + iouReport = IOUUtils.updateIOUOwnerAndTotal( + iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${chatReport.iouReportID}`], + recipientEmail, + amount, + ); iouReport.total += amount; } else { iouReport = ReportUtils.buildOptimisticIOUReport(recipientEmail, debtorEmail, amount, chatReport.reportID, currency, preferredLocale); From edfd163686e612e01ec4728b8c5b8aca424ed3ee Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 25 Oct 2022 13:43:11 +0200 Subject: [PATCH 62/67] do not update total twice --- 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 df25a8e09434..e0fe8550cbe0 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -150,7 +150,6 @@ function requestMoney(report, amount, currency, recipientEmail, debtorEmail, com recipientEmail, amount, ); - iouReport.total += amount; } else { iouReport = ReportUtils.buildOptimisticIOUReport(recipientEmail, debtorEmail, amount, chatReport.reportID, currency, preferredLocale); } From 4986dea08e3992319dd7581b637ad531ebc5dd15 Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 25 Oct 2022 14:21:49 +0200 Subject: [PATCH 63/67] copy full file to reduce conflicts --- src/libs/IOUUtils.js | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/libs/IOUUtils.js b/src/libs/IOUUtils.js index a32ec504e8a9..23c699046d5c 100644 --- a/src/libs/IOUUtils.js +++ b/src/libs/IOUUtils.js @@ -1,5 +1,32 @@ 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 - IOU total amount + * @param {Boolean} isDefaultUser - Whether we are calculating the amount for the current user + * @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; +} + /** * The owner of the IOU report is the account who is owed money and the manager is the one who owes money! * 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. @@ -32,5 +59,6 @@ function updateIOUOwnerAndTotal(iouReport, actorEmail, amount, type = CONST.IOU. } export { + calculateAmount, updateIOUOwnerAndTotal, -}; \ No newline at end of file +}; From b542650b0b1bcf6ec30bca9894b6fe12cfb1613d Mon Sep 17 00:00:00 2001 From: Alberto Date: Tue, 25 Oct 2022 16:45:07 +0200 Subject: [PATCH 64/67] store iou in chat report correctly --- 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 e0fe8550cbe0..60fd32d8d593 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -154,7 +154,6 @@ function requestMoney(report, amount, currency, recipientEmail, debtorEmail, com iouReport = ReportUtils.buildOptimisticIOUReport(recipientEmail, debtorEmail, amount, chatReport.reportID, currency, preferredLocale); } const newSequenceNumber = Report.getMaxSequenceNumber(chatReport.reportID) + 1; - chatReport.maxSequenceNumber = newSequenceNumber; const optimisticReportAction = ReportUtils.buildOptimisticIOUReportAction( newSequenceNumber, CONST.IOU.REPORT_ACTION_TYPE.CREATE, @@ -178,6 +177,8 @@ function requestMoney(report, amount, currency, recipientEmail, debtorEmail, com lastVisitedTimestamp: Date.now(), lastReadSequenceNumber: newSequenceNumber, maxSequenceNumber: newSequenceNumber, + hasOutstandingIOU: true, + iouReportID: iouReport.reportID, }, }, { From 08d6217a587bbd67340a50d6d3439daa4a595387 Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 26 Oct 2022 12:21:56 +0200 Subject: [PATCH 65/67] correctly handle /bin/zsh IOUs --- src/libs/actions/IOU.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 60fd32d8d593..b32057550f4e 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -144,7 +144,8 @@ function requestMoney(report, amount, currency, recipientEmail, debtorEmail, com isNewChat = true; } let iouReport; - if (chatReport.hasOutstandingIOU) { + const originalIOUStatus = chatReport.hasOutstandingIOU; + if (originalIOUStatus) { iouReport = IOUUtils.updateIOUOwnerAndTotal( iouReports[`${ONYXKEYS.COLLECTION.REPORT_IOUS}${chatReport.iouReportID}`], recipientEmail, @@ -167,7 +168,7 @@ function requestMoney(report, amount, currency, recipientEmail, debtorEmail, com preferredLocale, ); - // First, add Data that will be used in all cases + // First, add data that will be used in all cases const optimisticData = [ { onyxMethod: CONST.ONYX.METHOD.MERGE, @@ -177,7 +178,7 @@ function requestMoney(report, amount, currency, recipientEmail, debtorEmail, com lastVisitedTimestamp: Date.now(), lastReadSequenceNumber: newSequenceNumber, maxSequenceNumber: newSequenceNumber, - hasOutstandingIOU: true, + hasOutstandingIOU: iouReport.total !== 0, iouReportID: iouReport.reportID, }, }, @@ -207,6 +208,13 @@ function requestMoney(report, amount, currency, recipientEmail, debtorEmail, com }, ]; const failureData = [ + { + onyxMethod: CONST.ONYX.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, + value: { + hasOutstandingIOU: originalIOUStatus, + }, + }, { onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, From 1031f7abb0a7736027aa0de6844107ee13c7bd1e Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 26 Oct 2022 20:37:20 +0200 Subject: [PATCH 66/67] update lastMessage --- 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 b32057550f4e..9bc2f8cbab3a 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -178,6 +178,8 @@ function requestMoney(report, amount, currency, recipientEmail, debtorEmail, com lastVisitedTimestamp: Date.now(), lastReadSequenceNumber: newSequenceNumber, maxSequenceNumber: newSequenceNumber, + lastMessageText: optimisticReportAction.message.text, + lastMessageHtml: optimisticReportAction.message.html, hasOutstandingIOU: iouReport.total !== 0, iouReportID: iouReport.reportID, }, From d1183adafb9c21cef66f31f594a4bb445b409581 Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 26 Oct 2022 21:50:45 +0200 Subject: [PATCH 67/67] treat message as an array --- 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 9bc2f8cbab3a..6d6806225918 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -178,8 +178,8 @@ function requestMoney(report, amount, currency, recipientEmail, debtorEmail, com lastVisitedTimestamp: Date.now(), lastReadSequenceNumber: newSequenceNumber, maxSequenceNumber: newSequenceNumber, - lastMessageText: optimisticReportAction.message.text, - lastMessageHtml: optimisticReportAction.message.html, + lastMessageText: optimisticReportAction.message[0].text, + lastMessageHtml: optimisticReportAction.message[0].html, hasOutstandingIOU: iouReport.total !== 0, iouReportID: iouReport.reportID, },