Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate reportAction.originalMessage to transactions #24345

Merged
merged 50 commits into from
Aug 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
2d0469d
create getTransaction
luacmartins Aug 9, 2023
6c8ca4c
add jsdocs
luacmartins Aug 9, 2023
ad95fb0
refactor getFormattedAmount
luacmartins Aug 9, 2023
f5b5a01
update logic and rename to getMoneyRequestDetails
luacmartins Aug 9, 2023
12fbdd7
replace usages of getMoneyRequestAction
luacmartins Aug 9, 2023
f595a75
replace missed instance
luacmartins Aug 9, 2023
ad49161
refactor logic to retrieve transaction
luacmartins Aug 9, 2023
4bcd072
refactor SplitBillDetailsPage
luacmartins Aug 9, 2023
a1448ff
refactor getIOUReportActions
luacmartins Aug 9, 2023
10dcaf2
refactor MoneyRequestAction
luacmartins Aug 9, 2023
acb4efb
refactor getTransactionReportName
luacmartins Aug 9, 2023
a6fd68a
fix comment bugs
luacmartins Aug 9, 2023
e067001
export getTransactionReportName
luacmartins Aug 9, 2023
b2f4406
update split case
luacmartins Aug 9, 2023
8969b05
add transaction default
luacmartins Aug 9, 2023
2fc39f2
Merge branch 'main' into cmartins-replaceOriginalMessage
luacmartins Aug 10, 2023
00f61c2
rename method to getLinkedTransaction
luacmartins Aug 10, 2023
29ed60b
add getAllReportTransactions
luacmartins Aug 11, 2023
d4cf7ef
resolve conflicts
luacmartins Aug 11, 2023
e7c2cac
fix style
luacmartins Aug 11, 2023
e910c83
resolve conflicts
luacmartins Aug 14, 2023
b6b9a8b
rm unused component
luacmartins Aug 14, 2023
523d61b
use transactionUtils methods
luacmartins Aug 14, 2023
901370e
rm getMoneyRequestDetails
luacmartins Aug 14, 2023
b31a098
refactor SplitBillDetailsPage
luacmartins Aug 14, 2023
e0f37f6
rm unused import
luacmartins Aug 14, 2023
cd0e7e4
update getTransactionReportName
luacmartins Aug 14, 2023
94cba00
rm unused import
luacmartins Aug 14, 2023
7bfd673
add default currency
luacmartins Aug 14, 2023
7629ba0
use parentReport for transaction thread
luacmartins Aug 14, 2023
ba3b7df
rm getAllReportTransactions
luacmartins Aug 14, 2023
946b907
rm allTransactions
luacmartins Aug 14, 2023
63c8695
add getTransactionDetails
luacmartins Aug 15, 2023
4930a80
refactor usages of transactionutils
luacmartins Aug 15, 2023
a1aef03
fix style
luacmartins Aug 15, 2023
e9b05e2
move getLinkedTransaction to TransactionUtils;
luacmartins Aug 15, 2023
5356802
update comments
luacmartins Aug 15, 2023
7c72468
create getAllReportTransactions, refactor isIOUReportPendingCurrencyC…
luacmartins Aug 15, 2023
c70f193
fix tests
luacmartins Aug 15, 2023
98dc4a0
fix styles
luacmartins Aug 15, 2023
bc9413f
Merge branch 'main' into cmartins-replaceOriginalMessage
luacmartins Aug 15, 2023
079a0e8
rm getIOUReportActions
luacmartins Aug 15, 2023
66b0fac
rm unused import
luacmartins Aug 15, 2023
d7c8910
fix editMoneyRequest params
luacmartins Aug 15, 2023
88b2b64
use getCreated
luacmartins Aug 15, 2023
add8d3c
update date default
luacmartins Aug 15, 2023
b629521
use onyx set
luacmartins Aug 16, 2023
fa20e6b
resolve conflicts
luacmartins Aug 16, 2023
356ea9b
resolve conflicts
luacmartins Aug 16, 2023
4d90f2c
use getters
luacmartins Aug 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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}`, {});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we returning {} for missing reports? 😬 wouldn't null or undefined be better in these cases?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is much more intuitive for me to check if a report is missing with report === null than Object.keys(report) === 0

Copy link
Contributor

@aldo-expensify aldo-expensify Sep 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, I see that you just moved around this function and it was already like that 😿 , feel free to ignore me

}

/**
* 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 {};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}
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