diff --git a/src/languages/en.ts b/src/languages/en.ts index 21f220b747f2..8cf5ddd9df66 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2477,6 +2477,10 @@ const translations = { setupPage: { title: 'Open this link to connect', body: 'To complete setup, open the following link on the computer where QuickBooks Desktop is running.', + setupErrorTitle: 'Something went wrong', + setupErrorBody1: "The QuickBooks Desktop connection isn't working at the moment. Please try again later or", + setupErrorBody2: 'if the problem persists.', + setupErrorBodyContactConcierge: 'reach out to Concierge', }, importDescription: 'Choose which coding configurations to import from QuickBooks Desktop to Expensify.', classes: 'Classes', @@ -3658,6 +3662,8 @@ const translations = { return "Can't connect to Xero."; case CONST.POLICY.CONNECTIONS.NAME.NETSUITE: return "Can't connect to NetSuite."; + case CONST.POLICY.CONNECTIONS.NAME.QBD: + return "Can't connect to QuickBooks Desktop."; default: { return "Can't connect to integration."; } diff --git a/src/languages/es.ts b/src/languages/es.ts index ac06741f467e..49fb7d9a1eba 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2502,6 +2502,10 @@ const translations = { setupPage: { title: 'Abre este enlace para conectar', body: 'Para completar la configuración, abre el siguiente enlace en la computadora donde se está ejecutando QuickBooks Desktop.', + setupErrorTitle: '¡Ups! Ha ocurrido un error', + setupErrorBody1: 'La conexión con QuickBooks Desktop no está funcionando en este momento. Por favor, inténtalo de nuevo más tarde o', + setupErrorBody2: 'si el problema persiste.', + setupErrorBodyContactConcierge: 'contacta con Concierge', }, importDescription: 'Elige que configuraciónes de codificación son importadas desde QuickBooks Desktop a Expensify.', classes: 'Clases', @@ -3663,6 +3667,8 @@ const translations = { return 'No se puede conectar a Xero.'; case CONST.POLICY.CONNECTIONS.NAME.NETSUITE: return 'No se puede conectar a NetSuite.'; + case CONST.POLICY.CONNECTIONS.NAME.QBD: + return 'No se puede conectar a QuickBooks Desktop.'; default: { return 'No se ha podido conectar a la integración.'; } diff --git a/src/libs/actions/connections/index.ts b/src/libs/actions/connections/index.ts index e4ef3e4ed047..b2cb6ffffe94 100644 --- a/src/libs/actions/connections/index.ts +++ b/src/libs/actions/connections/index.ts @@ -327,6 +327,21 @@ function isConnectionUnverified(policy: OnyxEntry, connectionName: Polic return !(policy?.connections?.[connectionName]?.lastSync?.isConnected ?? true); } +function setConnectionError(policyID: string, connectionName: PolicyConnectionName, errorMessage?: string) { + Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, { + connections: { + [connectionName]: { + lastSync: { + isSuccessful: false, + isConnected: false, + errorDate: new Date().toISOString(), + errorMessage, + }, + }, + }, + }); +} + function copyExistingPolicyConnection(connectedPolicyID: string, targetPolicyID: string, connectionName: ConnectionName) { let stageInProgress; switch (connectionName) { @@ -389,4 +404,5 @@ export { isConnectionUnverified, isConnectionInProgress, hasSynchronizationErrorMessage, + setConnectionError, }; diff --git a/src/pages/workspace/accounting/qbd/QuickBooksDesktopSetupPage.tsx b/src/pages/workspace/accounting/qbd/QuickBooksDesktopSetupPage.tsx index 559cdc0c7377..899629c4723f 100644 --- a/src/pages/workspace/accounting/qbd/QuickBooksDesktopSetupPage.tsx +++ b/src/pages/workspace/accounting/qbd/QuickBooksDesktopSetupPage.tsx @@ -8,16 +8,22 @@ import CopyTextToClipboard from '@components/CopyTextToClipboard'; import FixedFooter from '@components/FixedFooter'; import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import Icon from '@components/Icon'; +import * as Illustrations from '@components/Icon/Illustrations'; import ImageSVG from '@components/ImageSVG'; import ScreenWrapper from '@components/ScreenWrapper'; import Text from '@components/Text'; +import TextLink from '@components/TextLink'; +import useEnvironment from '@hooks/useEnvironment'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; +import {setConnectionError} from '@libs/actions/connections'; import * as QuickbooksDesktop from '@libs/actions/connections/QuickbooksDesktop'; import Navigation from '@libs/Navigation/Navigation'; import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; import * as PolicyAction from '@userActions/Policy/Policy'; +import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; @@ -26,20 +32,32 @@ type RequireQuickBooksDesktopModalProps = StackScreenProps(''); + const hasResultOfFetchingSetupLink = !!codatSetupLink || hasError; - const ContentWrapper = codatSetupLink ? ({children}: React.PropsWithChildren) => children : FullPageOfflineBlockingView; + const ContentWrapper = hasResultOfFetchingSetupLink ? ({children}: React.PropsWithChildren) => children : FullPageOfflineBlockingView; const fetchSetupLink = useCallback(() => { setIsLoading(true); + setHasError(false); // eslint-disable-next-line rulesdir/no-thenable-actions-in-views QuickbooksDesktop.getQuickbooksDesktopCodatSetupLink(policyID).then((response) => { - setCodatSetupLink(String(response?.setupUrl ?? '')); + if (response?.jsonCode) { + if (response.jsonCode === CONST.JSON_CODE.SUCCESS) { + setCodatSetupLink(String(response?.setupUrl ?? '')); + } else { + setConnectionError(policyID, CONST.POLICY.CONNECTIONS.NAME.QBD, translate('workspace.qbd.setupPage.setupErrorTitle')); + setHasError(true); + } + } + setIsLoading(false); }); - }, [policyID]); + }, [policyID, translate]); useEffect(() => { // Since QBD doesn't support Taxes, we should disable them from the LHN when connecting to QBD @@ -52,13 +70,16 @@ function RequireQuickBooksDesktopModal({route}: RequireQuickBooksDesktopModalPro useNetwork({ onReconnect: () => { - if (codatSetupLink) { + if (hasResultOfFetchingSetupLink) { return; } fetchSetupLink(); }, }); + const shouldShowLoading = isLoading || !hasResultOfFetchingSetupLink; + const shouldShowError = !shouldShowLoading && hasError; + return ( Navigation.dismissModal()} /> - {isLoading || !codatSetupLink ? ( - - ) : ( + {shouldShowLoading && } + {shouldShowError && ( + + + {translate('workspace.qbd.setupPage.setupErrorTitle')} + + {translate('workspace.qbd.setupPage.setupErrorBody1')}{' '} + + {translate('workspace.qbd.setupPage.setupErrorBodyContactConcierge')} + {' '} + {translate('workspace.qbd.setupPage.setupErrorBody2')} + + + )} + {!shouldShowLoading && !shouldShowError && (