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

[QBD] Handle the syncing for QBD #50500

Merged
12 changes: 12 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2382,6 +2382,7 @@ const CONST = {
SYNC_STAGE_NAME: {
STARTING_IMPORT_QBO: 'startingImportQBO',
STARTING_IMPORT_XERO: 'startingImportXero',
STARTING_IMPORT_QBD: 'startingImportQBD',
QBO_IMPORT_MAIN: 'quickbooksOnlineImportMain',
QBO_IMPORT_CUSTOMERS: 'quickbooksOnlineImportCustomers',
QBO_IMPORT_EMPLOYEES: 'quickbooksOnlineImportEmployees',
Expand All @@ -2398,6 +2399,17 @@ const CONST = {
QBO_SYNC_APPLY_CUSTOMERS: 'quickbooksOnlineSyncApplyCustomers',
QBO_SYNC_APPLY_PEOPLE: 'quickbooksOnlineSyncApplyEmployees',
QBO_SYNC_APPLY_CLASSES_LOCATIONS: 'quickbooksOnlineSyncApplyClassesLocations',
QBD_IMPORT_TITLE: 'quickbooksDesktopImportTitle',
QBD_IMPORT_ACCOUNTS: 'quickbooksDesktopImportAccounts',
QBD_IMPORT_APPROVE_CERTIFICATE: 'quickbooksDesktopImportApproveCertificate',
QBD_IMPORT_DIMENSIONS: 'quickbooksDesktopImportDimensions',
QBD_IMPORT_CLASSES: 'quickbooksDesktopImportClasses',
QBD_IMPORT_CUSTOMERS: 'quickbooksDesktopImportCustomers',
QBD_IMPORT_VENDORS: 'quickbooksDesktopImportVendors',
QBD_IMPORT_EMPLOYEES: 'quickbooksDesktopImportEmployees',
QBD_IMPORT_MORE: 'quickbooksDesktopImportMore',
QBD_IMPORT_GENERIC: 'quickbooksDesktopImportSavePolicy',
QBD_WEB_CONNECTOR_REMINDER: 'quickbooksDesktopWebConnectorReminder',
JOB_DONE: 'jobDone',
XERO_SYNC_STEP: 'xeroSyncStep',
XERO_SYNC_XERO_REIMBURSED_REPORTS: 'xeroSyncXeroReimbursedReports',
Expand Down
19 changes: 19 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3589,6 +3589,7 @@ const translations = {
other: 'Other integrations',
syncNow: 'Sync now',
disconnect: 'Disconnect',
reinstall: 'Reinstall connector',
disconnectTitle: ({connectionName}: OptionalParam<ConnectionNameParams> = {}) => {
const integrationName =
connectionName && CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY[connectionName] ? CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY[connectionName] : 'integration';
Expand Down Expand Up @@ -3637,14 +3638,18 @@ const translations = {
syncStageName: ({stage}: SyncStageNameConnectionsParams) => {
switch (stage) {
case 'quickbooksOnlineImportCustomers':
case 'quickbooksDesktopImportCustomers':
return 'Importing customers';
case 'quickbooksOnlineImportEmployees':
case 'netSuiteSyncImportEmployees':
case 'intacctImportEmployees':
case 'quickbooksDesktopImportEmployees':
return 'Importing employees';
case 'quickbooksOnlineImportAccounts':
case 'quickbooksDesktopImportAccounts':
return 'Importing accounts';
case 'quickbooksOnlineImportClasses':
case 'quickbooksDesktopImportClasses':
return 'Importing classes';
case 'quickbooksOnlineImportLocations':
return 'Importing locations';
Expand All @@ -3663,6 +3668,19 @@ const translations = {
return 'Importing Xero data';
case 'startingImportQBO':
return 'Importing QuickBooks Online data';
case 'startingImportQBD':
case 'quickbooksDesktopImportMore':
return 'Importing QuickBooks Desktop data';
case 'quickbooksDesktopImportTitle':
return 'Importing title';
case 'quickbooksDesktopImportApproveCertificate':
return 'Importing approve ceritificate';
case 'quickbooksDesktopImportDimensions':
return 'Importing dimensions';
case 'quickbooksDesktopImportSavePolicy':
return 'Importing save policy';
case 'quickbooksDesktopWebConnectorReminder':
return 'Still syncing data with QuickBooks... Please make sure the Web Connector is running';
case 'quickbooksOnlineSyncTitle':
return 'Syncing QuickBooks Online data';
case 'quickbooksOnlineSyncLoadData':
Expand Down Expand Up @@ -3736,6 +3754,7 @@ const translations = {
case 'netSuiteSyncImportSubsidiaries':
return 'Importing subsidiaries';
case 'netSuiteSyncImportVendors':
case 'quickbooksDesktopImportVendors':
return 'Importing vendors';
case 'intacctCheckConnection':
return 'Checking Sage Intacct connection';
Expand Down
19 changes: 19 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3595,6 +3595,7 @@ const translations = {
other: 'Otras integraciones',
syncNow: 'Sincronizar ahora',
disconnect: 'Desconectar',
reinstall: 'Reinstalar el conector',
disconnectTitle: ({connectionName}: OptionalParam<ConnectionNameParams> = {}) => {
const integrationName =
connectionName && CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY[connectionName] ? CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY[connectionName] : 'integración';
Expand Down Expand Up @@ -3642,14 +3643,18 @@ const translations = {
syncStageName: ({stage}: SyncStageNameConnectionsParams) => {
switch (stage) {
case 'quickbooksOnlineImportCustomers':
case 'quickbooksDesktopImportCustomers':
return 'Importando clientes';
case 'quickbooksOnlineImportEmployees':
case 'netSuiteSyncImportEmployees':
case 'intacctImportEmployees':
case 'quickbooksDesktopImportEmployees':
return 'Importando empleados';
case 'quickbooksOnlineImportAccounts':
case 'quickbooksDesktopImportAccounts':
return 'Importando cuentas';
case 'quickbooksOnlineImportClasses':
case 'quickbooksDesktopImportClasses':
return 'Importando clases';
case 'quickbooksOnlineImportLocations':
return 'Importando localidades';
Expand All @@ -3668,6 +3673,19 @@ const translations = {
return 'Importando datos desde Xero';
case 'startingImportQBO':
return 'Importando datos desde QuickBooks Online';
case 'startingImportQBD':
case 'quickbooksDesktopImportMore':
return 'Importando datos desde QuickBooks Desktop';
case 'quickbooksDesktopImportTitle':
return 'Importando título';
case 'quickbooksDesktopImportApproveCertificate':
return 'Importando certificado de aprobación';
case 'quickbooksDesktopImportDimensions':
return 'Importando dimensiones';
case 'quickbooksDesktopImportSavePolicy':
return 'Importando política de guardado';
case 'quickbooksDesktopWebConnectorReminder':
return 'Aún sincronizando datos con QuickBooks... Por favor, asegúrate de que el Conector Web esté en funcionamiento';
Comment on lines +3676 to +3688
Copy link
Contributor Author

Choose a reason for hiding this comment

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

case 'quickbooksOnlineSyncTitle':
return 'Sincronizando datos desde QuickBooks Online';
case 'quickbooksOnlineSyncLoadData':
Expand Down Expand Up @@ -3735,6 +3753,7 @@ const translations = {
case 'netSuiteSyncImportSubsidiaries':
return 'Importando subsidiarias';
case 'netSuiteSyncImportVendors':
case 'quickbooksDesktopImportVendors':
return 'Importando proveedores';
case 'netSuiteSyncExpensifyReimbursedReports':
return 'Marcando facturas y recibos de NetSuite como pagados';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
type SyncPolicyToQuickbooksDesktopParams = {
policyID: string;
idempotencyKey: string;
forceDataRefresh?: boolean;
};

export default SyncPolicyToQuickbooksDesktopParams;
1 change: 1 addition & 0 deletions src/libs/API/parameters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export type {default as OpenPolicyInitialPageParams} from './OpenPolicyInitialPa
export type {default as SyncPolicyToQuickbooksOnlineParams} from './SyncPolicyToQuickbooksOnlineParams';
export type {default as SyncPolicyToXeroParams} from './SyncPolicyToXeroParams';
export type {default as SyncPolicyToNetSuiteParams} from './SyncPolicyToNetSuiteParams';
export type {default as SyncPolicyToQuickbooksDesktopParams} from './SyncPolicyToQuickbooksDesktopParams';
export type {default as DeleteContactMethodParams} from './DeleteContactMethodParams';
export type {default as DeletePaymentBankAccountParams} from './DeletePaymentBankAccountParams';
export type {default as DeletePaymentCardParams} from './DeletePaymentCardParams';
Expand Down
2 changes: 2 additions & 0 deletions src/libs/API/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,7 @@ const READ_COMMANDS = {
SYNC_POLICY_TO_XERO: 'SyncPolicyToXero',
SYNC_POLICY_TO_NETSUITE: 'SyncPolicyToNetSuite',
SYNC_POLICY_TO_SAGE_INTACCT: 'SyncPolicyToSageIntacct',
SYNC_POLICY_TO_QUICKBOOKS_DESKTOP: 'SyncPolicyToQuickbooksDesktop',
OPEN_REIMBURSEMENT_ACCOUNT_PAGE: 'OpenReimbursementAccountPage',
OPEN_WORKSPACE_VIEW: 'OpenWorkspaceView',
GET_MAPBOX_ACCESS_TOKEN: 'GetMapboxAccessToken',
Expand Down Expand Up @@ -921,6 +922,7 @@ type ReadCommandParameters = {
[READ_COMMANDS.SYNC_POLICY_TO_XERO]: Parameters.SyncPolicyToXeroParams;
[READ_COMMANDS.SYNC_POLICY_TO_NETSUITE]: Parameters.SyncPolicyToNetSuiteParams;
[READ_COMMANDS.SYNC_POLICY_TO_SAGE_INTACCT]: Parameters.SyncPolicyToNetSuiteParams;
[READ_COMMANDS.SYNC_POLICY_TO_QUICKBOOKS_DESKTOP]: Parameters.SyncPolicyToQuickbooksDesktopParams;
[READ_COMMANDS.OPEN_REIMBURSEMENT_ACCOUNT_PAGE]: Parameters.OpenReimbursementAccountPageParams;
[READ_COMMANDS.OPEN_WORKSPACE_VIEW]: Parameters.OpenWorkspaceViewParams;
[READ_COMMANDS.GET_MAPBOX_ACCESS_TOKEN]: null;
Expand Down
37 changes: 24 additions & 13 deletions src/libs/actions/connections/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import isObject from 'lodash/isObject';
import type {OnyxEntry, OnyxUpdate} from 'react-native-onyx';
import Onyx from 'react-native-onyx';
import * as API from '@libs/API';
import type {RemovePolicyConnectionParams, UpdateManyPolicyConnectionConfigurationsParams, UpdatePolicyConnectionConfigParams} from '@libs/API/parameters';
import type {
RemovePolicyConnectionParams,
SyncPolicyToQuickbooksDesktopParams,
UpdateManyPolicyConnectionConfigurationsParams,
UpdatePolicyConnectionConfigParams,
} from '@libs/API/parameters';
import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types';
import * as ErrorUtils from '@libs/ErrorUtils';
import CONST from '@src/CONST';
Expand Down Expand Up @@ -163,6 +168,9 @@ function getSyncConnectionParameters(connectionName: PolicyConnectionName) {
case CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT: {
return {readCommand: READ_COMMANDS.SYNC_POLICY_TO_SAGE_INTACCT, stageInProgress: CONST.POLICY.CONNECTIONS.SYNC_STAGE_NAME.SAGE_INTACCT_SYNC_CHECK_CONNECTION};
}
case CONST.POLICY.CONNECTIONS.NAME.QBD: {
return {readCommand: READ_COMMANDS.SYNC_POLICY_TO_QUICKBOOKS_DESKTOP, stageInProgress: CONST.POLICY.CONNECTIONS.SYNC_STAGE_NAME.STARTING_IMPORT_QBD};
}
default:
return undefined;
}
Expand All @@ -173,8 +181,9 @@ function getSyncConnectionParameters(connectionName: PolicyConnectionName) {
*
* @param policyID - ID of the policy for which the sync is needed
* @param connectionName - Name of the connection, QBO/Xero
* @param forceDataRefresh - If true, it will trigger a full data refresh
*/
function syncConnection(policyID: string, connectionName: PolicyConnectionName | undefined) {
function syncConnection(policyID: string, connectionName: PolicyConnectionName | undefined, forceDataRefresh = false) {
if (!connectionName) {
return;
}
Expand Down Expand Up @@ -203,17 +212,19 @@ function syncConnection(policyID: string, connectionName: PolicyConnectionName |
},
];

API.read(
syncConnectionData.readCommand,
{
policyID,
idempotencyKey: policyID,
},
{
optimisticData,
failureData,
},
);
const parameters: SyncPolicyToQuickbooksDesktopParams = {
policyID,
idempotencyKey: policyID,
};

if (connectionName === CONST.POLICY.CONNECTIONS.NAME.QBD) {
parameters.forceDataRefresh = forceDataRefresh;
}

API.read(syncConnectionData.readCommand, parameters, {
optimisticData,
failureData,
});
}

function updateManyPolicyConnectionConfigs<TConnectionName extends ConnectionNameExceptNetSuite, TConfigUpdate extends Partial<Connections[TConnectionName]['config']>>(
Expand Down
18 changes: 16 additions & 2 deletions src/pages/workspace/accounting/PolicyAccountingPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,23 @@ function PolicyAccountingPage({policy}: PolicyAccountingPageProps) {

const tenants = useMemo(() => getXeroTenants(policy), [policy]);
const currentXeroOrganization = findCurrentXeroOrganization(tenants, policy?.connections?.xero?.config?.tenantID);
const shouldShowSynchronizationError = !!synchronizationError;
const shouldShowReinstallConnectorMenuItem = shouldShowSynchronizationError && connectedIntegration === CONST.POLICY.CONNECTIONS.NAME.QBD;

const overflowMenu: ThreeDotsMenuProps['menuItems'] = useMemo(
() => [
...(shouldShowReinstallConnectorMenuItem
? [
{
icon: Expensicons.CircularArrowBackwards,
text: translate('workspace.accounting.reinstall'),
onSelected: () => startIntegrationFlow({name: CONST.POLICY.CONNECTIONS.NAME.QBD}),
shouldCallAfterModalHide: true,
disabled: isOffline,
iconRight: Expensicons.NewWindow,
},
]
: []),
...(shouldShowEnterCredentials
? [
{
Expand All @@ -133,7 +147,7 @@ function PolicyAccountingPage({policy}: PolicyAccountingPageProps) {
shouldCallAfterModalHide: true,
},
],
[shouldShowEnterCredentials, translate, isOffline, policyID, connectedIntegration, startIntegrationFlow],
[shouldShowEnterCredentials, shouldShowReinstallConnectorMenuItem, translate, isOffline, policyID, connectedIntegration, startIntegrationFlow],
);

useFocusEffect(
Expand Down Expand Up @@ -269,7 +283,6 @@ function PolicyAccountingPage({policy}: PolicyAccountingPageProps) {
if (!connectedIntegration) {
return [];
}
const shouldShowSynchronizationError = !!synchronizationError;
const shouldHideConfigurationOptions = isConnectionUnverified(policy, connectedIntegration);
const integrationData = getAccountingIntegrationData(connectedIntegration, policyID, translate, policy, undefined, undefined, undefined, canUseNetSuiteUSATax);
const iconProps = integrationData?.icon ? {icon: integrationData.icon, iconType: CONST.ICON_TYPE_AVATAR} : {};
Expand Down Expand Up @@ -364,6 +377,7 @@ function PolicyAccountingPage({policy}: PolicyAccountingPageProps) {
isSyncInProgress,
connectedIntegration,
synchronizationError,
shouldShowSynchronizationError,
policyID,
translate,
styles.sectionMenuItemTopDescription,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,38 @@
import React from 'react';
import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator';
import type {StackScreenProps} from '@react-navigation/stack';
import {useEffect} from 'react';
import {useOnyx} from 'react-native-onyx';
import {isConnectionInProgress, syncConnection} from '@libs/actions/connections';
import Navigation from '@libs/Navigation/Navigation';
import type {SettingsNavigatorParamList} from '@libs/Navigation/types';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';

function QuickBooksDesktopSetupFlowSyncPage() {
// TODO: [QBD] will be implemented in https://github.com/Expensify/App/issues/49698
return <FullScreenLoadingIndicator />;
type QuickBooksDesktopSetupFlowSyncPageProps = StackScreenProps<SettingsNavigatorParamList, typeof SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_DESKTOP_SETUP_REQUIRED_DEVICE_MODAL>;

function QuickBooksDesktopSetupFlowSyncPage({route}: QuickBooksDesktopSetupFlowSyncPageProps) {
const policyID: string = route.params.policyID;
const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID ?? '-1'}`);
const [connectionSyncProgress] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CONNECTION_SYNC_PROGRESS}${policyID ?? '-1'}`);

useEffect(() => {
if (!policyID) {
return;
}

const isSyncInProgress = isConnectionInProgress(connectionSyncProgress, policy);
if (!isSyncInProgress) {
syncConnection(policyID, CONST.POLICY.CONNECTIONS.NAME.QBD, true);
}

Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING.getRoute(policyID));

// disabling this rule, as we want this to run only on the first render
// eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps
}, []);

return null;
}

QuickBooksDesktopSetupFlowSyncPage.displayName = 'QuickBooksDesktopSetupFlowSyncPage';
Expand Down
Loading