From f43faa5b21053347fa6464d3ed0a568742bc6614 Mon Sep 17 00:00:00 2001 From: mkzie2 Date: Wed, 23 Apr 2025 09:07:19 +0700 Subject: [PATCH 1/5] fix: export to accounting displays even when connection fails --- src/components/MoneyReportHeader.tsx | 4 ++-- src/components/ReportActionItem/ReportPreview.tsx | 4 ++-- src/libs/PolicyUtils.ts | 9 ++++++++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index ea6d04759f0c..5a05335cb7cc 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -13,7 +13,7 @@ import {exportReportToCSV} from '@libs/actions/Report'; import {convertToDisplayString} from '@libs/CurrencyUtils'; import Navigation from '@libs/Navigation/Navigation'; import {buildOptimisticNextStepForPreventSelfApprovalsEnabled} from '@libs/NextStepUtils'; -import {getConnectedIntegration} from '@libs/PolicyUtils'; +import {getValidConnectedIntegration} from '@libs/PolicyUtils'; import {getIOUActionForTransactionID, getOriginalMessage, isDeletedAction, isMoneyRequestAction, isTrackExpenseAction} from '@libs/ReportActionsUtils'; import { canBeExported, @@ -163,7 +163,7 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea const [requestType, setRequestType] = useState(); const canAllowSettlement = hasUpdatedTotal(moneyRequestReport, policy); const policyType = policy?.type; - const connectedIntegration = getConnectedIntegration(policy); + const connectedIntegration = getValidConnectedIntegration(policy); const navigateBackToAfterDelete = useRef(); const hasScanningReceipt = getTransactionsWithReceipts(moneyRequestReport?.reportID).some((t) => isReceiptBeingScanned(t)); const hasOnlyPendingTransactions = useMemo(() => { diff --git a/src/components/ReportActionItem/ReportPreview.tsx b/src/components/ReportActionItem/ReportPreview.tsx index 7fd486c3d736..10ecbe0a1de1 100644 --- a/src/components/ReportActionItem/ReportPreview.tsx +++ b/src/components/ReportActionItem/ReportPreview.tsx @@ -33,7 +33,7 @@ import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import Navigation from '@libs/Navigation/Navigation'; import Parser from '@libs/Parser'; import Performance from '@libs/Performance'; -import {getConnectedIntegration} from '@libs/PolicyUtils'; +import {getValidConnectedIntegration} from '@libs/PolicyUtils'; import {getThumbnailAndImageURIs} from '@libs/ReceiptUtils'; import {getReportActionText} from '@libs/ReportActionsUtils'; import { @@ -473,7 +473,7 @@ function ReportPreview({ /* * Manual export */ - const connectedIntegration = getConnectedIntegration(policy); + const connectedIntegration = getValidConnectedIntegration(policy); const shouldShowExportIntegrationButton = !shouldShowPayButton && !shouldShowSubmitButton && connectedIntegration && isAdmin && canBeExported(iouReport); diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index a6510873ab54..09232a3663e9 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -32,7 +32,7 @@ import type { import type PolicyEmployee from '@src/types/onyx/PolicyEmployee'; import type {SearchPolicy} from '@src/types/onyx/SearchResults'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; -import {hasSynchronizationErrorMessage} from './actions/connections'; +import {hasSynchronizationErrorMessage, isAuthenticationError} from './actions/connections'; import {shouldShowQBOReimbursableExportDestinationAccountError} from './actions/connections/QuickbooksOnline'; import {getCurrentUserAccountID, getCurrentUserEmail} from './actions/Report'; import {getCategoryApproverRule} from './CategoryUtils'; @@ -1174,6 +1174,12 @@ function getConnectedIntegration(policy: Policy | undefined, accountingIntegrati return (accountingIntegrations ?? Object.values(CONST.POLICY.CONNECTIONS.NAME)).find((integration) => !!policy?.connections?.[integration]); } +function getValidConnectedIntegration(policy: Policy | undefined, accountingIntegrations?: ConnectionName[]) { + return (accountingIntegrations ?? Object.values(CONST.POLICY.CONNECTIONS.NAME)).find( + (integration) => !!policy?.connections?.[integration] && !isAuthenticationError(policy, integration), + ); +} + function hasIntegrationAutoSync(policy: Policy | undefined, connectedIntegration?: ConnectionName) { return (connectedIntegration && policy?.connections?.[connectedIntegration]?.config?.autoSync?.enabled) ?? false; } @@ -1425,6 +1431,7 @@ export { getAdminEmployees, getCleanedTagName, getConnectedIntegration, + getValidConnectedIntegration, getCountOfEnabledTagsOfList, getIneligibleInvitees, getMemberAccountIDsForWorkspace, From 4e3ba03bb5b27ca9cb03b329be6c7b3b04781984 Mon Sep 17 00:00:00 2001 From: mkzie2 Date: Wed, 23 Apr 2025 09:19:12 +0700 Subject: [PATCH 2/5] lint --- src/components/ReportActionItem/ReportPreview.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/components/ReportActionItem/ReportPreview.tsx b/src/components/ReportActionItem/ReportPreview.tsx index 10ecbe0a1de1..e8f7914afbb3 100644 --- a/src/components/ReportActionItem/ReportPreview.tsx +++ b/src/components/ReportActionItem/ReportPreview.tsx @@ -152,17 +152,19 @@ function ReportPreview({ shouldDisplayContextMenu = true, }: ReportPreviewProps) { const policy = usePolicy(policyID); - const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`); + const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`, {canBeMissing: true}); const [iouReport, transactions, violations] = useReportWithTransactionsAndViolations(iouReportID); const lastTransaction = transactions?.at(0); const transactionIDList = transactions?.map((reportTransaction) => reportTransaction.transactionID) ?? []; - const [userWallet] = useOnyx(ONYXKEYS.USER_WALLET); + const [userWallet] = useOnyx(ONYXKEYS.USER_WALLET, {canBeMissing: true}); const [invoiceReceiverPolicy] = useOnyx( - `${ONYXKEYS.COLLECTION.POLICY}${chatReport?.invoiceReceiver && 'policyID' in chatReport.invoiceReceiver ? chatReport.invoiceReceiver.policyID : CONST.DEFAULT_NUMBER_ID}`, + `${ONYXKEYS.COLLECTION.POLICY}${chatReport?.invoiceReceiver && 'policyID' in chatReport.invoiceReceiver && chatReport.invoiceReceiver.policyID}`, + {canBeMissing: true}, ); const [invoiceReceiverPersonalDetail] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, { selector: (personalDetails) => personalDetails?.[chatReport?.invoiceReceiver && 'accountID' in chatReport.invoiceReceiver ? chatReport.invoiceReceiver.accountID : CONST.DEFAULT_NUMBER_ID], + canBeMissing: true, }); const theme = useTheme(); const styles = useThemeStyles(); @@ -206,7 +208,7 @@ function ReportPreview({ const managerID = iouReport?.managerID ?? action.childManagerAccountID ?? CONST.DEFAULT_NUMBER_ID; const {totalDisplaySpend, reimbursableSpend} = getMoneyRequestSpendBreakdown(iouReport); - const [reports] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}`); + const [reports] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}`, {canBeMissing: true}); const iouSettled = isSettled(iouReportID, isOnSearch ? reports : undefined) || action?.childStatusNum === CONST.REPORT.STATUS_NUM.REIMBURSED; const previewMessageOpacity = useSharedValue(1); const previewMessageStyle = useAnimatedStyle(() => ({ @@ -425,7 +427,7 @@ function ReportPreview({ const shouldShowSubtitle = !isScanning && (shouldShowSingleRequestMerchantOrDescription || numberOfRequests > 1) && !isDisplayAmountZero(getDisplayAmount()); const isPayAtEndExpense = isPayAtEndExpenseReport(iouReportID, transactions); - const [archiveReason] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`, {selector: getArchiveReason}); + const [archiveReason] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`, {selector: getArchiveReason, canBeMissing: true}); const getPendingMessageProps: () => PendingMessageProps = () => { if (isPayAtEndExpense) { From 19e5a8549a6d993d5ca9047e2dc434c9b051e2cd Mon Sep 17 00:00:00 2001 From: mkzie2 Date: Mon, 5 May 2025 15:51:08 +0700 Subject: [PATCH 3/5] apply logic to old components --- src/components/MoneyReportHeaderOld.tsx | 4 ++-- src/components/ReportActionItem/ReportPreviewOld.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/MoneyReportHeaderOld.tsx b/src/components/MoneyReportHeaderOld.tsx index 923e976d2edc..6bb942e201b1 100644 --- a/src/components/MoneyReportHeaderOld.tsx +++ b/src/components/MoneyReportHeaderOld.tsx @@ -14,7 +14,7 @@ import useThemeStyles from '@hooks/useThemeStyles'; import {getIOUReportPreviewButtonType, getTotalAmountForIOUReportPreviewButton} from '@libs/MoneyRequestReportUtils'; import Navigation from '@libs/Navigation/Navigation'; import {buildOptimisticNextStepForPreventSelfApprovalsEnabled} from '@libs/NextStepUtils'; -import {getConnectedIntegration} from '@libs/PolicyUtils'; +import {getValidConnectedIntegration} from '@libs/PolicyUtils'; import {getOriginalMessage, isDeletedAction, isMoneyRequestAction, isTrackExpenseAction} from '@libs/ReportActionsUtils'; import { canBeExported, @@ -166,7 +166,7 @@ function MoneyReportHeaderOld({policy, report: moneyRequestReport, transactionTh const [requestType, setRequestType] = useState(); const canAllowSettlement = hasUpdatedTotal(moneyRequestReport, policy); const policyType = policy?.type; - const connectedIntegration = getConnectedIntegration(policy); + const connectedIntegration = getValidConnectedIntegration(policy); const navigateBackToAfterDelete = useRef(); const hasScanningReceipt = getTransactionsWithReceipts(moneyRequestReport?.reportID).some((t) => isReceiptBeingScanned(t)); const hasOnlyPendingTransactions = useMemo(() => { diff --git a/src/components/ReportActionItem/ReportPreviewOld.tsx b/src/components/ReportActionItem/ReportPreviewOld.tsx index ac9fdccaf513..65661b0f05c2 100644 --- a/src/components/ReportActionItem/ReportPreviewOld.tsx +++ b/src/components/ReportActionItem/ReportPreviewOld.tsx @@ -35,7 +35,7 @@ import {getIOUReportPreviewButtonType, getTotalAmountForIOUReportPreviewButton} import Navigation from '@libs/Navigation/Navigation'; import Parser from '@libs/Parser'; import Performance from '@libs/Performance'; -import {getConnectedIntegration} from '@libs/PolicyUtils'; +import {getValidConnectedIntegration} from '@libs/PolicyUtils'; import {getThumbnailAndImageURIs} from '@libs/ReceiptUtils'; import {getReportActionText} from '@libs/ReportActionsUtils'; import { @@ -463,7 +463,7 @@ function ReportPreviewOld({ /* * Manual export */ - const connectedIntegration = getConnectedIntegration(policy); + const connectedIntegration = getValidConnectedIntegration(policy); const shouldShowExportIntegrationButton = !shouldShowPayButton && !shouldShowSubmitButton && !!connectedIntegration && isAdmin && canBeExported(iouReport); From 0c51884ecd0486784ff03f2581493502da51c340 Mon Sep 17 00:00:00 2001 From: mkzie2 Date: Mon, 5 May 2025 16:13:51 +0700 Subject: [PATCH 4/5] apply logic to new UI preview --- src/libs/ReportPreviewActionUtils.ts | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/libs/ReportPreviewActionUtils.ts b/src/libs/ReportPreviewActionUtils.ts index b02aad268b78..9a12247a41af 100644 --- a/src/libs/ReportPreviewActionUtils.ts +++ b/src/libs/ReportPreviewActionUtils.ts @@ -4,15 +4,7 @@ import CONST from '@src/CONST'; import type {Policy, Report, ReportNameValuePairs, Transaction, TransactionViolation} from '@src/types/onyx'; import {isApprover as isApproverMember} from './actions/Policy/Member'; import {getCurrentUserAccountID} from './actions/Report'; -import { - arePaymentsEnabled, - getConnectedIntegration, - getCorrectedAutoReportingFrequency, - getSubmitToAccountID, - hasAccountingConnections, - hasIntegrationAutoSync, - isPrefferedExporter, -} from './PolicyUtils'; +import {arePaymentsEnabled, getCorrectedAutoReportingFrequency, getSubmitToAccountID, getValidConnectedIntegration, hasIntegrationAutoSync, isPrefferedExporter} from './PolicyUtils'; import { getMoneyRequestSpendBreakdown, getParentReport, @@ -138,13 +130,12 @@ function canExport(report: Report, violations: OnyxCollection Date: Mon, 5 May 2025 16:19:23 +0700 Subject: [PATCH 5/5] apply logic to new UI header --- src/libs/ReportPrimaryActionUtils.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/libs/ReportPrimaryActionUtils.ts b/src/libs/ReportPrimaryActionUtils.ts index 9515fd164b90..2706c3146e4c 100644 --- a/src/libs/ReportPrimaryActionUtils.ts +++ b/src/libs/ReportPrimaryActionUtils.ts @@ -6,10 +6,9 @@ import {isApprover as isApproverUtils} from './actions/Policy/Member'; import {getCurrentUserAccountID} from './actions/Report'; import { arePaymentsEnabled as arePaymentsEnabledUtils, - getConnectedIntegration, getCorrectedAutoReportingFrequency, getSubmitToAccountID, - hasAccountingConnections, + getValidConnectedIntegration, hasIntegrationAutoSync, isPrefferedExporter, } from './PolicyUtils'; @@ -159,8 +158,8 @@ function isExportAction(report: Report, policy?: Policy) { return false; } - const hasAccountingConnection = hasAccountingConnections(policy); - if (!hasAccountingConnection) { + const connectedIntegration = getValidConnectedIntegration(policy); + if (!connectedIntegration) { return false; } @@ -169,7 +168,6 @@ function isExportAction(report: Report, policy?: Policy) { return false; } - const connectedIntegration = getConnectedIntegration(policy); const syncEnabled = hasIntegrationAutoSync(policy, connectedIntegration); if (syncEnabled) { return false;