From e1c03197369c48c97de67376459f4a21b5d2e828 Mon Sep 17 00:00:00 2001 From: Youssef Lourayad Date: Mon, 7 Aug 2023 19:38:31 +0100 Subject: [PATCH 01/43] Add approveMoneyRequest action --- src/libs/ReportActionsUtils.js | 7 +++++ src/libs/actions/IOU.js | 53 ++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/src/libs/ReportActionsUtils.js b/src/libs/ReportActionsUtils.js index 3cd5621e5e32..8391648df4a0 100644 --- a/src/libs/ReportActionsUtils.js +++ b/src/libs/ReportActionsUtils.js @@ -202,6 +202,12 @@ function getSortedReportActions(reportActions, shouldSortInDescendingOrder = fal .value(); } +function getReportMostRecentIOUTransactionID(reportID) { + const reportActions = _.filter(allReportActions[reportID], (action) => lodashGet(action, 'originalMessage.type') === CONST.IOU.REPORT_ACTION_TYPE.CREATE); + const sortedReportActions = getSortedReportActions(reportActions); + return _.last(sortedReportActions).originalMessage.IOUTransactionID; +} + /** * Finds most recent IOU request action ID. * @@ -566,6 +572,7 @@ export { getLastVisibleAction, getLastVisibleMessage, getMostRecentIOURequestActionID, + getReportMostRecentIOUTransactionID, extractLinksFromMessageHtml, isCreatedAction, isDeletedAction, diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 45fcd35eb839..de753e7016ae 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -1431,6 +1431,59 @@ function sendMoneyViaPaypal(report, amount, currency, comment, managerID, recipi asyncOpenURL(Promise.resolve(), buildPayPalPaymentUrl(amount, recipient.payPalMeAddress, currency)); } +function approveMoneyRequest(expenseReport) { + const IOUTransactionID = ReportActionsUtils.getReportMostRecentIOUTransactionID(expenseReport.reportID); + const optimisticIOUReportAction = ReportUtils.buildOptimisticApprovedReportAction(expenseReport.total, expenseReport.currency, expenseReport.reportID, IOUTransactionID); + + const optimisticReportActionsData = { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport.reportID}`, + value: { + [optimisticIOUReportAction.reportActionID]: { + ...optimisticIOUReportAction, + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + }, + }, + }; + const optimisticIOUReportData = { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport.reportID}`, + value: { + ...expenseReport, + lastMessageText: optimisticIOUReportAction.message[0].text, + lastMessageHtml: optimisticIOUReportAction.message[0].html, + statusNum: CONST.REPORT.STATUS.APPROVED, + }, + }; + const optimisticData = [optimisticIOUReportData, optimisticReportActionsData]; + + const successData = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport.reportID}`, + value: { + [optimisticIOUReportAction.reportActionID]: { + pendingAction: null, + }, + }, + }, + ]; + + const failureData = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport.reportID}`, + value: { + [expenseReport.reportActionID]: { + errors: ErrorUtils.getMicroSecondOnyxError('iou.error.other'), + }, + }, + }, + ]; + + API.write('ApproveMoneyRequest', {reportID: expenseReport.reportID, approvedReportActionID: optimisticIOUReportAction.reportActionID}, {optimisticData, successData, failureData}); +} + /** * @param {String} paymentType * @param {Object} chatReport From b1e77abbc8eb7c558bc6953bb4b48076d1c9a543 Mon Sep 17 00:00:00 2001 From: Youssef Lourayad Date: Mon, 7 Aug 2023 19:46:23 +0100 Subject: [PATCH 02/43] Add logic for showing the approve/settlement button --- src/components/MoneyReportHeader.js | 41 ++++++++++++++++++++++++++++- src/libs/ReportUtils.js | 10 ++++--- src/libs/SidebarUtils.js | 2 +- 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/components/MoneyReportHeader.js b/src/components/MoneyReportHeader.js index 71ac5e02467b..c2a70bd23fa6 100644 --- a/src/components/MoneyReportHeader.js +++ b/src/components/MoneyReportHeader.js @@ -58,7 +58,28 @@ function MoneyReportHeader(props) { const isPayer = Policy.isAdminOfFreePolicy([policy]) || (ReportUtils.isMoneyRequestReport(moneyRequestReport) && lodashGet(props.session, 'accountID', null) === moneyRequestReport.managerID); const reportTotal = ReportUtils.getMoneyRequestTotal(props.report); - const shouldShowSettlementButton = !isSettled && isPayer && !moneyRequestReport.isWaitingOnBankAccount && reportTotal !== 0; + const shouldShowSettlementButton = useMemo(() => { + if (ReportUtils.getPolicyType(moneyRequestReport, props.policies) === CONST.POLICY.TYPE.CORPORATE) { + return Policy.isAdminOfControlPolicy([policy]) && ReportUtils.isReportApproved(moneyRequestReport) && !ReportUtils.isSettled(moneyRequestReport.reportID); + } + + return ( + (Policy.isAdminOfFreePolicy([policy]) || + (ReportUtils.isMoneyRequestReport(moneyRequestReport) && lodashGet(props.session, 'accountID', null) === moneyRequestReport.managerID)) && + !ReportUtils.isSettled(moneyRequestReport) + ); + }, [moneyRequestReport, policy, props.policies, props.session]); + const shouldShowApprovedButton = useMemo(() => { + if (ReportUtils.getPolicyType(moneyRequestReport) !== CONST.POLICY.TYPE.CORPORATE) { + return false; + } + + return ( + ReportUtils.isReportManager(moneyRequestReport) && + lodashGet(moneyRequestReport, 'stateNum') === CONST.REPORT.STATE_NUM.PROCESSING && + lodashGet(moneyRequestReport, 'statusNum') === CONST.REPORT.STATUS.SUBMITTED + ); + }, [moneyRequestReport]); const bankAccountRoute = ReportUtils.getBankAccountRoute(props.chatReport); const shouldShowPaypal = Boolean(lodashGet(props.personalDetails, [moneyRequestReport.managerID, 'payPalMeAddress'])); const formattedAmount = CurrencyUtils.convertToDisplayString(reportTotal, props.report.currency); @@ -93,6 +114,15 @@ function MoneyReportHeader(props) { /> )} + {shouldShowApprovedButton && !props.isSmallScreenWidth && ( + +