diff --git a/src/components/ReportActionItem/IOUPreview.js b/src/components/ReportActionItem/IOUPreview.js index 0aa2aa16524e..9ce961acfcce 100644 --- a/src/components/ReportActionItem/IOUPreview.js +++ b/src/components/ReportActionItem/IOUPreview.js @@ -26,6 +26,7 @@ import * as OptionsListUtils from '../../libs/OptionsListUtils'; import * as CurrencyUtils from '../../libs/CurrencyUtils'; import * as IOUUtils from '../../libs/IOUUtils'; import * as ReportUtils from '../../libs/ReportUtils'; +import * as TransactionUtils from '../../libs/TransactionUtils'; import refPropTypes from '../refPropTypes'; import PressableWithFeedback from '../Pressable/PressableWithoutFeedback'; @@ -137,11 +138,8 @@ function IOUPreview(props) { // Pay button should only be visible to the manager of the report. const isCurrentUserManager = managerID === sessionAccountID; - const moneyRequestAction = ReportUtils.getMoneyRequestAction(props.action); - - const requestAmount = moneyRequestAction.amount; - const requestCurrency = moneyRequestAction.currency; - const requestComment = moneyRequestAction.comment.trim(); + const transaction = TransactionUtils.getLinkedTransaction(props.action); + const {amount: requestAmount, currency: requestCurrency, comment: requestComment} = ReportUtils.getTransactionDetails(transaction); const getSettledMessage = () => { switch (lodashGet(props.action, 'originalMessage.paymentType', '')) { diff --git a/src/components/ReportActionItem/MoneyRequestAction.js b/src/components/ReportActionItem/MoneyRequestAction.js index 5cd509856d1b..2e6d07743443 100644 --- a/src/components/ReportActionItem/MoneyRequestAction.js +++ b/src/components/ReportActionItem/MoneyRequestAction.js @@ -100,10 +100,7 @@ function MoneyRequestAction(props) { const participantAccountIDs = _.uniq([props.session.accountID, Number(props.action.actorAccountID)]); const thread = ReportUtils.buildOptimisticChatReport( participantAccountIDs, - props.translate(ReportActionsUtils.isSentMoneyReportAction(props.action) ? 'iou.threadSentMoneyReportName' : 'iou.threadRequestReportName', { - formattedAmount: ReportActionsUtils.getFormattedAmount(props.action), - comment: props.action.originalMessage.comment, - }), + ReportUtils.getTransactionReportName(props.action), '', lodashGet(props.iouReport, 'policyID', CONST.POLICY.OWNER_EMAIL_FAKE), CONST.POLICY.OWNER_ACCOUNT_ID_FAKE, diff --git a/src/components/ReportActionItem/MoneyRequestView.js b/src/components/ReportActionItem/MoneyRequestView.js index 8502b0fb2fea..c05cf14f2fc1 100644 --- a/src/components/ReportActionItem/MoneyRequestView.js +++ b/src/components/ReportActionItem/MoneyRequestView.js @@ -14,11 +14,11 @@ import MenuItemWithTopDescription from '../MenuItemWithTopDescription'; import styles from '../../styles/styles'; import * as ReportUtils from '../../libs/ReportUtils'; import * as ReportActionsUtils from '../../libs/ReportActionsUtils'; +import * as TransactionUtils from '../../libs/TransactionUtils'; import * as StyleUtils from '../../styles/StyleUtils'; import CONST from '../../CONST'; import * as Expensicons from '../Icon/Expensicons'; import iouReportPropTypes from '../../pages/iouReportPropTypes'; -import DateUtils from '../../libs/DateUtils'; import * as CurrencyUtils from '../../libs/CurrencyUtils'; import EmptyStateBackgroundImage from '../../../assets/images/empty-state_background-fade.png'; import useLocalize from '../../hooks/useLocalize'; @@ -65,12 +65,11 @@ function MoneyRequestView({report, parentReport, shouldShowHorizontalRule, polic const {translate} = useLocalize(); const parentReportAction = ReportActionsUtils.getParentReportAction(report); - const {amount: transactionAmount, currency: transactionCurrency, comment: transactionDescription} = ReportUtils.getMoneyRequestAction(parentReportAction); + const moneyRequestReport = parentReport; + const transaction = TransactionUtils.getLinkedTransaction(parentReportAction); + const {created: transactionDate, amount: transactionAmount, currency: transactionCurrency, comment: transactionDescription} = ReportUtils.getTransactionDetails(transaction); const formattedTransactionAmount = transactionAmount && transactionCurrency && CurrencyUtils.convertToDisplayString(transactionAmount, transactionCurrency); - const transactionDate = lodashGet(parentReportAction, ['created']); - const formattedTransactionDate = DateUtils.getDateStringFromISOTimestamp(transactionDate); - const moneyRequestReport = parentReport; const isSettled = ReportUtils.isSettled(moneyRequestReport.reportID); const isAdmin = Policy.isAdminOfFreePolicy([policy]) && ReportUtils.isExpenseReport(moneyRequestReport); const isRequestor = ReportUtils.isMoneyRequestReport(moneyRequestReport) && lodashGet(session, 'accountID', null) === parentReportAction.actorAccountID; @@ -117,7 +116,7 @@ function MoneyRequestView({report, parentReport, shouldShowHorizontalRule, polic /> Navigation.navigate(ROUTES.getEditRequestRoute(report.reportID, CONST.EDIT_REQUEST_FIELD.DATE))} diff --git a/src/libs/IOUUtils.js b/src/libs/IOUUtils.js index 91e3b09a587c..2042c6beda05 100644 --- a/src/libs/IOUUtils.js +++ b/src/libs/IOUUtils.js @@ -1,6 +1,6 @@ import _ from 'underscore'; import CONST from '../CONST'; -import * as ReportActionsUtils from './ReportActionsUtils'; +import * as TransactionUtils from './TransactionUtils'; import * as CurrencyUtils from './CurrencyUtils'; /** @@ -67,62 +67,17 @@ function updateIOUOwnerAndTotal(iouReport, actorAccountID, amount, currency, isD return iouReportUpdate; } -/** - * Returns the list of IOU actions depending on the type and whether or not they are pending. - * Used below so that we can decide if an IOU report is pending currency conversion. - * - * @param {Array} reportActions - * @param {Object} iouReport - * @param {String} type - iouReportAction type. Can be oneOf(create, delete, pay, split) - * @param {String} pendingAction - * @param {Boolean} filterRequestsInDifferentCurrency - * - * @returns {Array} - */ -function getIOUReportActions(reportActions, iouReport, type = '', pendingAction = '', filterRequestsInDifferentCurrency = false) { - return _.chain(reportActions) - .filter((action) => action.originalMessage && ReportActionsUtils.isMoneyRequestAction(action) && (!_.isEmpty(type) ? action.originalMessage.type === type : true)) - .filter((action) => action.originalMessage.IOUReportID.toString() === iouReport.reportID.toString()) - .filter((action) => (!_.isEmpty(pendingAction) ? action.pendingAction === pendingAction : true)) - .filter((action) => (filterRequestsInDifferentCurrency ? action.originalMessage.currency !== iouReport.currency : true)) - .value(); -} - /** * Returns whether or not an IOU report contains money requests in a different currency * that are either created or cancelled offline, and thus haven't been converted to the report's currency yet * - * @param {Array} reportActions * @param {Object} iouReport - * * @returns {Boolean} */ -function isIOUReportPendingCurrencyConversion(reportActions, iouReport) { - // Pending money requests that are in a different currency - const pendingRequestsInDifferentCurrency = _.chain(getIOUReportActions(reportActions, iouReport, CONST.IOU.REPORT_ACTION_TYPE.CREATE, CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, true)) - .map((action) => action.originalMessage.IOUTransactionID) - .sort() - .value(); - - // Pending deleted money requests that are in a different currency - const pendingDeletedRequestsInDifferentCurrency = _.chain( - getIOUReportActions(reportActions, iouReport, CONST.IOU.REPORT_ACTION_TYPE.DELETE, CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, true), - ) - .map((action) => action.originalMessage.IOUTransactionID) - .sort() - .value(); - - const hasPendingRequests = Boolean(pendingRequestsInDifferentCurrency.length || pendingDeletedRequestsInDifferentCurrency.length); - - // If we have pending money requests made offline, check if all of them have been cancelled offline - // In order to do that, we can grab transactionIDs of all the created and cancelled money requests and check if they're identical - if (hasPendingRequests && _.isEqual(pendingRequestsInDifferentCurrency, pendingDeletedRequestsInDifferentCurrency)) { - return false; - } - - // Not all requests made offline had been cancelled, - // simply return if we have any pending created or cancelled requests - return hasPendingRequests; +function isIOUReportPendingCurrencyConversion(iouReport) { + const reportTransactions = TransactionUtils.getAllReportTransactions(iouReport.reportID); + const pendingRequestsInDifferentCurrency = _.filter(reportTransactions, (transaction) => transaction.pendingAction && TransactionUtils.getCurrency(transaction) !== iouReport.currency); + return pendingRequestsInDifferentCurrency.length > 0; } /** @@ -134,4 +89,4 @@ function isValidMoneyRequestType(iouType) { return [CONST.IOU.MONEY_REQUEST_TYPE.REQUEST, CONST.IOU.MONEY_REQUEST_TYPE.SPLIT].includes(iouType); } -export {calculateAmount, updateIOUOwnerAndTotal, getIOUReportActions, isIOUReportPendingCurrencyConversion, isValidMoneyRequestType}; +export {calculateAmount, updateIOUOwnerAndTotal, isIOUReportPendingCurrencyConversion, isValidMoneyRequestType}; diff --git a/src/libs/ReportActionsUtils.js b/src/libs/ReportActionsUtils.js index 74f55d9b91b6..f68cfe6adeba 100644 --- a/src/libs/ReportActionsUtils.js +++ b/src/libs/ReportActionsUtils.js @@ -8,7 +8,6 @@ import * as CollectionUtils from './CollectionUtils'; import CONST from '../CONST'; import ONYXKEYS from '../ONYXKEYS'; import Log from './Log'; -import * as CurrencyUtils from './CurrencyUtils'; import isReportMessageAttachment from './isReportMessageAttachment'; const allReports = {}; @@ -153,19 +152,6 @@ function isSentMoneyReportAction(reportAction) { ); } -/** - * Returns the formatted amount of a money request. The request and money sent (from send money flow) have - * currency and amount in IOUDetails object. - * - * @param {Object} reportAction - * @returns {Number} - */ -function getFormattedAmount(reportAction) { - return lodashGet(reportAction, 'originalMessage.type', '') === CONST.IOU.REPORT_ACTION_TYPE.PAY && lodashGet(reportAction, 'originalMessage.IOUDetails', false) - ? CurrencyUtils.convertToDisplayString(lodashGet(reportAction, 'originalMessage.IOUDetails.amount', 0), lodashGet(reportAction, 'originalMessage.IOUDetails.currency', '')) - : CurrencyUtils.convertToDisplayString(lodashGet(reportAction, 'originalMessage.amount', 0), lodashGet(reportAction, 'originalMessage.currency', '')); -} - /** * Returns whether the thread is a transaction thread, which is any thread with IOU parent * report action from requesting money (type - create) or from sending money (type - pay with IOUDetails field) @@ -612,7 +598,6 @@ export { getParentReportAction, getParentReportActionInReport, isTransactionThread, - getFormattedAmount, isSentMoneyReportAction, isDeletedParentAction, isReportPreviewAction, diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 68cfe6a9e6ae..e8e0e8aab072 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -1094,32 +1094,6 @@ function getDisplayNamesWithTooltips(personalDetailsList, isMultipleParticipantR }); } -/** - * We get the amount, currency and comment money request value from the action.originalMessage. - * But for the send money action, the above value is put in the IOUDetails object. - * - * @param {Object} reportAction - * @param {Number} reportAction.amount - * @param {String} reportAction.currency - * @param {String} reportAction.comment - * @param {Object} [reportAction.IOUDetails] - * @returns {Object} - */ -function getMoneyRequestAction(reportAction = {}) { - const originalMessage = lodashGet(reportAction, 'originalMessage', {}); - let amount = originalMessage.amount || 0; - let currency = originalMessage.currency || CONST.CURRENCY.USD; - let comment = originalMessage.comment || ''; - - if (_.has(originalMessage, 'IOUDetails')) { - amount = lodashGet(originalMessage, 'IOUDetails.amount', 0); - currency = lodashGet(originalMessage, 'IOUDetails.currency', CONST.CURRENCY.USD); - comment = lodashGet(originalMessage, 'IOUDetails.comment', ''); - } - - return {amount, currency, comment}; -} - /** * Determines if a report has an IOU that is waiting for an action from the current user (either Pay or Add a credit bank account) * @@ -1229,6 +1203,32 @@ function getMoneyRequestReportName(report, policy = undefined) { return payerPaidAmountMesssage; } +/** + * Get the report given a reportID + * + * @param {String} reportID + * @returns {Object} + */ +function getReport(reportID) { + return lodashGet(allReports, `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, {}); +} + +/** + * Gets transaction created, amount, currency and comment + * + * @param {Object} transaction + * @returns {Object} + */ +function getTransactionDetails(transaction) { + const report = getReport(transaction.reportID); + return { + created: TransactionUtils.getCreated(transaction), + amount: TransactionUtils.getAmount(transaction, isExpenseReport(report)), + currency: TransactionUtils.getCurrency(transaction), + comment: TransactionUtils.getDescription(transaction), + }; +} + /** * Given a parent IOU report action get report name for the LHN. * @@ -1240,9 +1240,12 @@ function getTransactionReportName(reportAction) { return Localize.translateLocal('parentReportAction.deletedRequest'); } + const transaction = TransactionUtils.getLinkedTransaction(reportAction); + const {amount, currency, comment} = getTransactionDetails(transaction); + return Localize.translateLocal(ReportActionsUtils.isSentMoneyReportAction(reportAction) ? 'iou.threadSentMoneyReportName' : 'iou.threadRequestReportName', { - formattedAmount: ReportActionsUtils.getFormattedAmount(reportAction), - comment: lodashGet(reportAction, 'originalMessage.comment'), + formattedAmount: CurrencyUtils.convertToDisplayString(amount, currency), + comment, }); } @@ -1368,6 +1371,19 @@ function getModifiedExpenseOriginalMessage(oldTransaction, transactionChanges, i return originalMessage; } +/** + * Returns the parentReport if the given report is a thread. + * + * @param {Object} report + * @returns {Object} + */ +function getParentReport(report) { + if (!report || !report.parentReportID) { + return {}; + } + return lodashGet(allReports, `${ONYXKEYS.COLLECTION.REPORT}${report.parentReportID}`, {}); +} + /** * Get the title for a report. * @@ -1497,16 +1513,6 @@ function getParentNavigationSubtitle(report) { return {}; } -/** - * Get the report for a reportID - * - * @param {String} reportID - * @returns {Object} - */ -function getReport(reportID) { - return lodashGet(allReports, `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, {}); -} - /** * Navigate to the details page of a given report * @@ -2904,19 +2910,6 @@ function isReportDataReady() { return !_.isEmpty(allReports) && _.some(_.keys(allReports), (key) => allReports[key].reportID); } -/** - * Returns the parentReport if the given report is a thread. - * - * @param {Object} report - * @returns {Object} - */ -function getParentReport(report) { - if (!report || !report.parentReportID) { - return {}; - } - return lodashGet(allReports, `${ONYXKEYS.COLLECTION.REPORT}${report.parentReportID}`, {}); -} - /** * Find the parent report action in assignee report for a task report * Returns an empty object if assignee report is the same as the share destination report @@ -3248,7 +3241,6 @@ export { isReportDataReady, isSettled, isAllowedToComment, - getMoneyRequestAction, getBankAccountRoute, getParentReport, getTaskParentReportActionIDInAssigneeReport, @@ -3264,5 +3256,7 @@ export { shouldDisableSettings, shouldDisableRename, hasSingleParticipant, + getTransactionReportName, + getTransactionDetails, getTaskAssigneeChatOnyxData, }; diff --git a/src/libs/TransactionUtils.js b/src/libs/TransactionUtils.js index b424956cf4e0..a8fd828d07d4 100644 --- a/src/libs/TransactionUtils.js +++ b/src/libs/TransactionUtils.js @@ -157,4 +157,19 @@ function getCreated(transaction) { return ''; } -export {buildOptimisticTransaction, getUpdatedTransaction, getTransaction, getDescription, getAmount, getCurrency, getCreated}; +/** + * Get the details linked to the IOU reportAction + * + * @param {Object} reportAction + * @returns {Object} + */ +function getLinkedTransaction(reportAction = {}) { + const transactionID = lodashGet(reportAction, ['originalMessage', 'IOUTransactionID'], ''); + return allTransactions[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`] || {}; +} + +function getAllReportTransactions(reportID) { + return _.filter(allTransactions, (transaction) => transaction.reportID === reportID); +} + +export {buildOptimisticTransaction, getUpdatedTransaction, getTransaction, getDescription, getAmount, getCurrency, getCreated, getLinkedTransaction, getAllReportTransactions}; diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 3f8d17f3f730..c5e2c532a888 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -525,7 +525,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, currentUserAcco }, }, { - onyxMethod: Onyx.METHOD.MERGE, + onyxMethod: Onyx.METHOD.SET, key: `${ONYXKEYS.COLLECTION.TRANSACTION}${groupTransaction.transactionID}`, value: groupTransaction, }, @@ -866,17 +866,16 @@ function editMoneyRequest(transactionID, transactionThreadReportID, transactionC ]; // STEP 6: Call the API endpoint + const {created, amount, currency, comment} = ReportUtils.getTransactionDetails(updatedTransaction); API.write( 'EditMoneyRequest', { transactionID, reportActionID: updatedReportAction.reportActionID, - - // Using the getter methods here to ensure we pass modified field if present - created: TransactionUtils.getCreated(updatedTransaction), - amount: TransactionUtils.getAmount(updatedTransaction, isFromExpenseReport), - currency: TransactionUtils.getCurrency(updatedTransaction), - comment: TransactionUtils.getDescription(updatedTransaction), + created, + amount, + currency, + comment, }, {optimisticData, successData, failureData}, ); @@ -939,9 +938,15 @@ function deleteMoneyRequest(transactionID, reportAction, isSingleTransactionView updatedIOUReport = {...iouReport}; // Because of the Expense reports are stored as negative values, we add the total from the amount - updatedIOUReport.total += reportAction.originalMessage.amount; + updatedIOUReport.total += TransactionUtils.getAmount(transaction, true); } else { - updatedIOUReport = IOUUtils.updateIOUOwnerAndTotal(iouReport, reportAction.actorAccountID, reportAction.originalMessage.amount, reportAction.originalMessage.currency, true); + updatedIOUReport = IOUUtils.updateIOUOwnerAndTotal( + iouReport, + reportAction.actorAccountID, + TransactionUtils.getAmount(transaction, false), + TransactionUtils.getCurrency(transaction), + true, + ); } updatedIOUReport.lastMessageText = iouReportLastMessageText; diff --git a/src/pages/EditRequestPage.js b/src/pages/EditRequestPage.js index d7c4f0bb6ac7..d3c2cdc1841b 100644 --- a/src/pages/EditRequestPage.js +++ b/src/pages/EditRequestPage.js @@ -43,11 +43,8 @@ const defaultProps = { function EditRequestPage({report, route, parentReport}) { const parentReportAction = ReportActionsUtils.getParentReportAction(report); - const transactionID = lodashGet(parentReportAction, 'originalMessage.IOUTransactionID', ''); - const transaction = TransactionUtils.getTransaction(transactionID); - const transactionDescription = TransactionUtils.getDescription(transaction); - const transactionAmount = TransactionUtils.getAmount(transaction, ReportUtils.isExpenseReport(parentReport)); - const transactionCurrency = TransactionUtils.getCurrency(transaction); + const transaction = TransactionUtils.getLinkedTransaction(parentReportAction); + const {amount: transactionAmount, currency: transactionCurrency, comment: transactionDescription} = ReportUtils.getTransactionDetails(transaction); // Take only the YYYY-MM-DD value const transactionCreated = TransactionUtils.getCreated(transaction); @@ -66,7 +63,7 @@ function EditRequestPage({report, route, parentReport}) { // Update the transaction object and close the modal function editMoneyRequest(transactionChanges) { - IOU.editMoneyRequest(transactionID, report.reportID, transactionChanges); + IOU.editMoneyRequest(transaction.transactionID, report.reportID, transactionChanges); Navigation.dismissModal(); } diff --git a/src/pages/iou/SplitBillDetailsPage.js b/src/pages/iou/SplitBillDetailsPage.js index b638da091874..9e67d7ea2a87 100644 --- a/src/pages/iou/SplitBillDetailsPage.js +++ b/src/pages/iou/SplitBillDetailsPage.js @@ -3,7 +3,6 @@ import _ from 'underscore'; import {View} from 'react-native'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; -import lodashGet from 'lodash/get'; import styles from '../../styles/styles'; import ONYXKEYS from '../../ONYXKEYS'; import * as OptionsListUtils from '../../libs/OptionsListUtils'; @@ -18,6 +17,8 @@ import withReportAndReportActionOrNotFound from '../home/report/withReportAndRep import FullPageNotFoundView from '../../components/BlockingViews/FullPageNotFoundView'; import CONST from '../../CONST'; import HeaderWithBackButton from '../../components/HeaderWithBackButton'; +import * as TransactionUtils from '../../libs/TransactionUtils'; +import * as ReportUtils from '../../libs/ReportUtils'; const propTypes = { /* Onyx Props */ @@ -52,6 +53,7 @@ const defaultProps = { function SplitBillDetailsPage(props) { const reportAction = props.reportActions[`${props.route.params.reportActionID.toString()}`]; + const transaction = TransactionUtils.getLinkedTransaction(reportAction); const participantAccountIDs = reportAction.originalMessage.participantAccountIDs; const participants = OptionsListUtils.getParticipantsOptions( _.map(participantAccountIDs, (accountID) => ({accountID, selected: true})), @@ -59,9 +61,7 @@ function SplitBillDetailsPage(props) { ); const payeePersonalDetails = props.personalDetails[reportAction.actorAccountID]; const participantsExcludingPayee = _.filter(participants, (participant) => participant.accountID !== reportAction.actorAccountID); - const splitAmount = parseInt(lodashGet(reportAction, 'originalMessage.amount', 0), 10); - const splitComment = lodashGet(reportAction, 'originalMessage.comment'); - const splitCurrency = lodashGet(reportAction, 'originalMessage.currency'); + const {amount: splitAmount, currency: splitCurrency, comment: splitComment} = ReportUtils.getTransactionDetails(transaction); return ( diff --git a/tests/unit/IOUUtilsTest.js b/tests/unit/IOUUtilsTest.js index 0d40ee87424c..22790ebe721f 100644 --- a/tests/unit/IOUUtilsTest.js +++ b/tests/unit/IOUUtilsTest.js @@ -1,39 +1,10 @@ import Onyx from 'react-native-onyx'; import * as IOUUtils from '../../src/libs/IOUUtils'; import * as ReportUtils from '../../src/libs/ReportUtils'; -import * as NumberUtils from '../../src/libs/NumberUtils'; -import CONST from '../../src/CONST'; import ONYXKEYS from '../../src/ONYXKEYS'; import waitForPromisesToResolve from '../utils/waitForPromisesToResolve'; import currencyList from './currencyList.json'; - -let iouReport; -let reportActions; -const ownerAccountID = 5; -const managerEmail = 'manager@iou.com'; -const managerID = 10; - -function createIOUReportAction(type, amount, currency, isOffline = false, IOUTransactionID = NumberUtils.rand64()) { - const moneyRequestAction = ReportUtils.buildOptimisticIOUReportAction(type, amount, currency, 'Test comment', [managerEmail], IOUTransactionID, '', iouReport.reportID); - - // Default is to create requests online, if `isOffline` is not specified then we need to remove the pendingAction - if (!isOffline) { - moneyRequestAction.pendingAction = null; - } - - reportActions.push(moneyRequestAction); - return moneyRequestAction; -} - -function deleteMoneyRequest(moneyRequestAction, isOffline = false) { - createIOUReportAction( - CONST.IOU.REPORT_ACTION_TYPE.DELETE, - moneyRequestAction.originalMessage.amount, - moneyRequestAction.originalMessage.currency, - isOffline, - moneyRequestAction.originalMessage.IOUTransactionID, - ); -} +import * as TransactionUtils from '../../src/libs/TransactionUtils'; function initCurrencyList() { Onyx.init({ @@ -47,89 +18,44 @@ function initCurrencyList() { describe('IOUUtils', () => { describe('isIOUReportPendingCurrencyConversion', () => { - beforeEach(() => { - reportActions = []; - const chatReportID = ReportUtils.generateReportID(); - const amount = 1000; - const currency = 'USD'; - - iouReport = ReportUtils.buildOptimisticIOUReport(ownerAccountID, managerID, amount, chatReportID, currency); - - // The starting point of all tests is the IOUReport containing a single non-pending transaction in USD - // All requests in the tests are assumed to be online, unless isOffline is specified - createIOUReportAction('create', amount, currency); + beforeAll(() => { + Onyx.init({ + keys: ONYXKEYS, + }); }); test('Requesting money offline in a different currency will show the pending conversion message', () => { - // Request money offline in AED - createIOUReportAction('create', 100, 'AED', true); - - // We requested money offline in a different currency, we don't know the total of the iouReport until we're back online - expect(IOUUtils.isIOUReportPendingCurrencyConversion(reportActions, iouReport)).toBe(true); - }); - - test('IOUReport is not pending conversion when all requests made offline have been deleted', () => { - // Create two requests offline - const moneyRequestA = createIOUReportAction('create', 1000, 'AED', true); - const moneyRequestB = createIOUReportAction('create', 1000, 'AED', true); - - // Delete both requests - deleteMoneyRequest(moneyRequestA, true); - deleteMoneyRequest(moneyRequestB, true); - - // Both requests made offline have been deleted, total won't update so no need to show a pending conversion message - expect(IOUUtils.isIOUReportPendingCurrencyConversion(reportActions, iouReport)).toBe(false); + const iouReport = ReportUtils.buildOptimisticIOUReport(1, 2, 100, 1, 'USD'); + const usdPendingTransaction = TransactionUtils.buildOptimisticTransaction(100, 'USD', iouReport.reportID); + const aedPendingTransaction = TransactionUtils.buildOptimisticTransaction(100, 'AED', iouReport.reportID); + + return Onyx.mergeCollection(ONYXKEYS.COLLECTION.TRANSACTION, { + [`${ONYXKEYS.COLLECTION.TRANSACTION}${usdPendingTransaction.transactionID}`]: usdPendingTransaction, + [`${ONYXKEYS.COLLECTION.TRANSACTION}${aedPendingTransaction.transactionID}`]: aedPendingTransaction, + }).then(() => { + // We requested money offline in a different currency, we don't know the total of the iouReport until we're back online + expect(IOUUtils.isIOUReportPendingCurrencyConversion(iouReport)).toBe(true); + }); }); - test('Deleting a request made online shows the preview', () => { - // Request money online in AED - const moneyRequest = createIOUReportAction('create', 1000, 'AED'); - - // Delete it offline - deleteMoneyRequest(moneyRequest, true); - - // We don't know what the total is because we need to subtract the converted amount of the offline request from the total - expect(IOUUtils.isIOUReportPendingCurrencyConversion(reportActions, iouReport)).toBe(true); - }); - - test("Deleting a request made offline while there's a previous one made online will not show the pending conversion message", () => { - // Request money online in AED - createIOUReportAction('create', 1000, 'AED'); - - // Another request offline - const moneyRequestOffline = createIOUReportAction('create', 1000, 'AED', true); - - // Delete the request made offline - deleteMoneyRequest(moneyRequestOffline, true); - - expect(IOUUtils.isIOUReportPendingCurrencyConversion(reportActions, iouReport)).toBe(false); - }); - - test('Deleting a request made online while we have one made offline will show the pending conversion message', () => { - // Request money online in AED - const moneyRequestOnline = createIOUReportAction('create', 1000, 'AED'); - - // Request money again but offline - createIOUReportAction('create', 1000, 'AED', true); - - // Delete the request made online - deleteMoneyRequest(moneyRequestOnline, true); - - // We don't know what the total is because we need to subtract the converted amount of the offline request from the total - expect(IOUUtils.isIOUReportPendingCurrencyConversion(reportActions, iouReport)).toBe(true); - }); - - test("Deleting a request offline in the report's currency when we have requests in a different currency does not show the pending conversion message", () => { - // Request money in the report's currency (USD) - const onlineMoneyRequestInUSD = createIOUReportAction('create', 1000, 'USD'); - - // Request money online in a different currency - createIOUReportAction('create', 2000, 'AED'); - - // Delete the USD request offline - deleteMoneyRequest(onlineMoneyRequestInUSD, true); - - expect(IOUUtils.isIOUReportPendingCurrencyConversion(reportActions, iouReport)).toBe(false); + test('Requesting money online in a different currency will not show the pending conversion message', () => { + const iouReport = ReportUtils.buildOptimisticIOUReport(2, 3, 100, 1, 'USD'); + const usdPendingTransaction = TransactionUtils.buildOptimisticTransaction(100, 'USD', iouReport.reportID); + const aedPendingTransaction = TransactionUtils.buildOptimisticTransaction(100, 'AED', iouReport.reportID); + + return Onyx.mergeCollection(ONYXKEYS.COLLECTION.TRANSACTION, { + [`${ONYXKEYS.COLLECTION.TRANSACTION}${usdPendingTransaction.transactionID}`]: { + ...usdPendingTransaction, + pendingAction: null, + }, + [`${ONYXKEYS.COLLECTION.TRANSACTION}${aedPendingTransaction.transactionID}`]: { + ...aedPendingTransaction, + pendingAction: null, + }, + }).then(() => { + // We requested money online in a different currency, we know the iouReport total and there's no need to show the pending conversion message + expect(IOUUtils.isIOUReportPendingCurrencyConversion(iouReport)).toBe(false); + }); }); });