Skip to content

Commit

Permalink
Merge pull request #24345 from Expensify/cmartins-replaceOriginalMessage
Browse files Browse the repository at this point in the history
Migrate reportAction.originalMessage to transactions
  • Loading branch information
mountiny authored Aug 16, 2023
2 parents 0b2d5c8 + 4d90f2c commit b6c970e
Show file tree
Hide file tree
Showing 11 changed files with 132 additions and 261 deletions.
8 changes: 3 additions & 5 deletions src/components/ReportActionItem/IOUPreview.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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', '')) {
Expand Down
5 changes: 1 addition & 4 deletions src/components/ReportActionItem/MoneyRequestAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
11 changes: 5 additions & 6 deletions src/components/ReportActionItem/MoneyRequestView.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -117,7 +116,7 @@ function MoneyRequestView({report, parentReport, shouldShowHorizontalRule, polic
/>
<MenuItemWithTopDescription
description={translate('common.date')}
title={formattedTransactionDate}
title={transactionDate}
disabled={isSettled || !canEdit}
shouldShowRightIcon={canEdit}
onPress={() => Navigation.navigate(ROUTES.getEditRequestRoute(report.reportID, CONST.EDIT_REQUEST_FIELD.DATE))}
Expand Down
57 changes: 6 additions & 51 deletions src/libs/IOUUtils.js
Original file line number Diff line number Diff line change
@@ -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';

/**
Expand Down Expand Up @@ -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;
}

/**
Expand All @@ -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};
15 changes: 0 additions & 15 deletions src/libs/ReportActionsUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {};
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -612,7 +598,6 @@ export {
getParentReportAction,
getParentReportActionInReport,
isTransactionThread,
getFormattedAmount,
isSentMoneyReportAction,
isDeletedParentAction,
isReportPreviewAction,
Expand Down
98 changes: 46 additions & 52 deletions src/libs/ReportUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
*
Expand Down Expand Up @@ -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.
*
Expand All @@ -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,
});
}

Expand Down Expand Up @@ -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.
*
Expand Down Expand Up @@ -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
*
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -3248,7 +3241,6 @@ export {
isReportDataReady,
isSettled,
isAllowedToComment,
getMoneyRequestAction,
getBankAccountRoute,
getParentReport,
getTaskParentReportActionIDInAssigneeReport,
Expand All @@ -3264,5 +3256,7 @@ export {
shouldDisableSettings,
shouldDisableRename,
hasSingleParticipant,
getTransactionReportName,
getTransactionDetails,
getTaskAssigneeChatOnyxData,
};
17 changes: 16 additions & 1 deletion src/libs/TransactionUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Loading

0 comments on commit b6c970e

Please sign in to comment.