From 299cbe1c0c2d382bfdc6d0f5e532812ce1404237 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Wed, 20 Aug 2025 00:19:52 +0530 Subject: [PATCH 1/8] Only show "Go to Expensify Classic to manage your settings" for Certinia. Signed-off-by: krishna2323 --- src/CONST/index.ts | 4 ++++ src/libs/PolicyUtils.ts | 5 +++-- src/pages/workspace/accounting/PolicyAccountingPage.tsx | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/CONST/index.ts b/src/CONST/index.ts index ac194f55a87a..49b8fe69ab28 100755 --- a/src/CONST/index.ts +++ b/src/CONST/index.ts @@ -2993,6 +2993,10 @@ const CONST = { NETSUITE: 'netsuite', SAGE_INTACCT: 'intacct', }, + UNSUPPORTED_NAMES: { + // Integrations that still require Expensify Classic + FINANCIALFORCE: 'financialForce', + }, ROUTE: { QBO: 'quickbooks-online', XERO: 'xero', diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 7f92542bf49a..6ed0970a8cad 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -1269,8 +1269,9 @@ function hasIntegrationAutoSync(policy: Policy | undefined, connectedIntegration return (connectedIntegration && policy?.connections?.[connectedIntegration]?.config?.autoSync?.enabled) ?? false; } -function hasUnsupportedIntegration(policy: Policy | undefined, accountingIntegrations?: ConnectionName[]) { - return !(accountingIntegrations ?? Object.values(CONST.POLICY.CONNECTIONS.NAME)).some((integration) => !!policy?.connections?.[integration]); +function hasUnsupportedIntegration(policy: Policy | undefined) { + // Check if policy has any connections that are in the UNSUPPORTED_NAMES list + return Object.values(CONST.POLICY.CONNECTIONS.UNSUPPORTED_NAMES).some((integration) => !!(policy?.connections as Record)?.[integration]); } function getCurrentConnectionName(policy: Policy | undefined): string | undefined { diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx index a3b296a790a4..5243271bff43 100644 --- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx +++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx @@ -104,7 +104,7 @@ function PolicyAccountingPage({policy}: PolicyAccountingPageProps) { ); const hasSyncError = shouldShowSyncError(policy, isSyncInProgress); - const hasUnsupportedNDIntegration = !isEmptyObject(policy?.connections) && hasUnsupportedIntegration(policy, accountingIntegrations); + const hasUnsupportedNDIntegration = !isEmptyObject(policy?.connections) && hasUnsupportedIntegration(policy); const tenants = useMemo(() => getXeroTenants(policy), [policy]); const currentXeroOrganization = findCurrentXeroOrganization(tenants, policy?.connections?.xero?.config?.tenantID); From 21feca241496be2719d72819c55e561e9d44dc09 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Tue, 26 Aug 2025 05:33:33 +0530 Subject: [PATCH 2/8] update hasAccountingConnections function. Signed-off-by: krishna2323 --- src/CONST/index.ts | 1 - src/libs/PolicyUtils.ts | 2 +- src/pages/workspace/WorkspaceMoreFeaturesPage.tsx | 4 ++-- src/pages/workspace/reports/WorkspaceReportsPage.tsx | 8 +++----- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/CONST/index.ts b/src/CONST/index.ts index 060caa8c4051..d26009db49c1 100755 --- a/src/CONST/index.ts +++ b/src/CONST/index.ts @@ -3004,7 +3004,6 @@ const CONST = { SAGE_INTACCT: 'intacct', }, UNSUPPORTED_NAMES: { - // Integrations that still require Expensify Classic FINANCIALFORCE: 'financialForce', }, ROUTE: { diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 446fa545a49c..46cef371de32 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -610,7 +610,7 @@ function isControlOnAdvancedApprovalMode(policy: OnyxInputOrEntry): bool * Whether the policy has active accounting integration connections */ function hasAccountingConnections(policy: OnyxEntry) { - return !isEmptyObject(policy?.connections); + return !isEmptyObject(policy?.connections) && !!getCurrentConnectionName(policy); } function getPolicyEmployeeListByIdWithoutCurrentUser(policies: OnyxCollection>, currentPolicyID?: string, currentUserAccountID?: number) { diff --git a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx index a578f306e1e7..4c75976214c4 100644 --- a/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx +++ b/src/pages/workspace/WorkspaceMoreFeaturesPage.tsx @@ -21,7 +21,7 @@ import {getLatestErrorField} from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types'; import type {WorkspaceSplitNavigatorParamList} from '@libs/Navigation/types'; -import {getDistanceRateCustomUnit, getPerDiemCustomUnit, isControlPolicy} from '@libs/PolicyUtils'; +import {getDistanceRateCustomUnit, getPerDiemCustomUnit, hasAccountingConnections, isControlPolicy} from '@libs/PolicyUtils'; import {enablePolicyCategories} from '@userActions/Policy/Category'; import {enablePolicyDistanceRates} from '@userActions/Policy/DistanceRate'; import {enablePerDiem} from '@userActions/Policy/PerDiem'; @@ -79,7 +79,7 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro const {shouldUseNarrowLayout} = useResponsiveLayout(); const {translate} = useLocalize(); const {isBetaEnabled} = usePermissions(); - const hasAccountingConnection = !isEmptyObject(policy?.connections); + const hasAccountingConnection = hasAccountingConnections(policy); const isAccountingEnabled = !!policy?.areConnectionsEnabled || !isEmptyObject(policy?.connections); const isSyncTaxEnabled = !!policy?.connections?.quickbooksOnline?.config?.syncTax || diff --git a/src/pages/workspace/reports/WorkspaceReportsPage.tsx b/src/pages/workspace/reports/WorkspaceReportsPage.tsx index 868af9d3d7d9..65ee7cf1f933 100644 --- a/src/pages/workspace/reports/WorkspaceReportsPage.tsx +++ b/src/pages/workspace/reports/WorkspaceReportsPage.tsx @@ -41,7 +41,6 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; -import {isEmptyObject} from '@src/types/utils/EmptyObject'; type ReportFieldForList = ListItem & { fieldID: string; @@ -83,15 +82,14 @@ function WorkspaceReportFieldsPage({ // eslint-disable-next-line @typescript-eslint/no-unused-vars return Object.fromEntries(Object.entries(policy.fieldList).filter(([_, value]) => value.fieldID !== 'text_title')); }, [policy]); - const hasAccountingConnection = !isEmptyObject(policy?.connections); const [isOrganizeWarningModalOpen, setIsOrganizeWarningModalOpen] = useState(false); const onDisabledOrganizeSwitchPress = useCallback(() => { - if (!hasAccountingConnection) { + if (!hasReportAccountingConnections) { return; } setIsOrganizeWarningModalOpen(true); - }, [hasAccountingConnection]); + }, [hasReportAccountingConnections]); const fetchReportFields = useCallback(() => { openPolicyReportFieldsPage(policyID); @@ -273,7 +271,7 @@ function WorkspaceReportFieldsPage({ } enablePolicyReportFields(policyID, isEnabled); }} - disabled={hasAccountingConnection} + disabled={hasReportAccountingConnections} disabledAction={onDisabledOrganizeSwitchPress} subMenuItems={ !!policy?.areReportFieldsEnabled && ( From 6fd94af1888d418eea92bb3817a23e1569eeaeb4 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Thu, 28 Aug 2025 11:13:54 +0530 Subject: [PATCH 3/8] lock workspace features when accounting is financialForce. Signed-off-by: krishna2323 --- src/libs/PolicyUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 46cef371de32..bfcdfdc5bd05 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -610,7 +610,7 @@ function isControlOnAdvancedApprovalMode(policy: OnyxInputOrEntry): bool * Whether the policy has active accounting integration connections */ function hasAccountingConnections(policy: OnyxEntry) { - return !isEmptyObject(policy?.connections) && !!getCurrentConnectionName(policy); + return !isEmptyObject(policy?.connections) && (!!getCurrentConnectionName(policy) || hasUnsupportedIntegration(policy)); } function getPolicyEmployeeListByIdWithoutCurrentUser(policies: OnyxCollection>, currentPolicyID?: string, currentUserAccountID?: number) { From 19a9096af7ef9a26019b8bc70d757768d04e6ff5 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Mon, 1 Sep 2025 12:46:07 +0530 Subject: [PATCH 4/8] rever unrelated changes. Signed-off-by: krishna2323 --- src/CONST/index.ts | 5 ++++- src/libs/PolicyUtils.ts | 8 ++++++-- src/pages/workspace/accounting/PolicyAccountingPage.tsx | 4 ++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/CONST/index.ts b/src/CONST/index.ts index c53d62c84bdf..dda460feb40f 100755 --- a/src/CONST/index.ts +++ b/src/CONST/index.ts @@ -3022,9 +3022,12 @@ const CONST = { NETSUITE: 'netsuite', SAGE_INTACCT: 'intacct', }, - UNSUPPORTED_NAMES: { + SUPPORTED_ONLY_ON_OLDDOT: { FINANCIALFORCE: 'financialForce', }, + UNSUPPORTED_NAMES: { + GENERIC_INDIRECT_CONNECTION: 'generic_indirect_connection', + }, ROUTE: { QBO: 'quickbooks-online', XERO: 'xero', diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 0f2cf4d20283..c5d0f22c661b 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -610,7 +610,7 @@ function isControlOnAdvancedApprovalMode(policy: OnyxInputOrEntry): bool * Whether the policy has active accounting integration connections */ function hasAccountingConnections(policy: OnyxEntry) { - return !isEmptyObject(policy?.connections) && (!!getCurrentConnectionName(policy) || hasUnsupportedIntegration(policy)); + return !isEmptyObject(policy?.connections) && !hasUnsupportedIntegration(policy); } function getPolicyEmployeeListByIdWithoutCurrentUser(policies: OnyxCollection>, currentPolicyID?: string, currentUserAccountID?: number) { @@ -1288,10 +1288,13 @@ function hasIntegrationAutoSync(policy: Policy | undefined, connectedIntegration } function hasUnsupportedIntegration(policy: Policy | undefined) { - // Check if policy has any connections that are in the UNSUPPORTED_NAMES list return Object.values(CONST.POLICY.CONNECTIONS.UNSUPPORTED_NAMES).some((integration) => !!(policy?.connections as Record)?.[integration]); } +function hasSupportedOnlyOnOldDotIntegration(policy: Policy | undefined) { + return Object.values(CONST.POLICY.CONNECTIONS.SUPPORTED_ONLY_ON_OLDDOT).some((integration) => !!(policy?.connections as Record)?.[integration]); +} + function getCurrentConnectionName(policy: Policy | undefined): string | undefined { const accountingIntegrations = Object.values(CONST.POLICY.CONNECTIONS.NAME); const connectionKey = accountingIntegrations.find((integration) => !!policy?.connections?.[integration]); @@ -1666,6 +1669,7 @@ export { getTagApproverRule, getDomainNameForPolicy, hasUnsupportedIntegration, + hasSupportedOnlyOnOldDotIntegration, getWorkflowApprovalsUnavailable, getNetSuiteImportCustomFieldLabel, getActivePolicy, diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx index 5243271bff43..f369a4aab40e 100644 --- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx +++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx @@ -41,7 +41,7 @@ import { getIntegrationLastSuccessfulDate, getXeroTenants, hasAccountingConnections, - hasUnsupportedIntegration, + hasSupportedOnlyOnOldDotIntegration, isControlPolicy, settingsPendingAction, shouldShowSyncError, @@ -104,7 +104,7 @@ function PolicyAccountingPage({policy}: PolicyAccountingPageProps) { ); const hasSyncError = shouldShowSyncError(policy, isSyncInProgress); - const hasUnsupportedNDIntegration = !isEmptyObject(policy?.connections) && hasUnsupportedIntegration(policy); + const hasUnsupportedNDIntegration = !isEmptyObject(policy?.connections) && hasSupportedOnlyOnOldDotIntegration(policy); const tenants = useMemo(() => getXeroTenants(policy), [policy]); const currentXeroOrganization = findCurrentXeroOrganization(tenants, policy?.connections?.xero?.config?.tenantID); From fa0a2bba1dd7137d9e302d401a63a5c64baf2c40 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Tue, 2 Sep 2025 23:10:19 +0530 Subject: [PATCH 5/8] only show locked icons on supported integrations on ND and FinancialForce. Signed-off-by: krishna2323 --- src/libs/PolicyUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index c5d0f22c661b..52315259cc36 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -610,7 +610,7 @@ function isControlOnAdvancedApprovalMode(policy: OnyxInputOrEntry): bool * Whether the policy has active accounting integration connections */ function hasAccountingConnections(policy: OnyxEntry) { - return !isEmptyObject(policy?.connections) && !hasUnsupportedIntegration(policy); + return !isEmptyObject(policy?.connections) && (!!getCurrentConnectionName(policy) || hasSupportedOnlyOnOldDotIntegration(policy)); } function getPolicyEmployeeListByIdWithoutCurrentUser(policies: OnyxCollection>, currentPolicyID?: string, currentUserAccountID?: number) { From b49b0e8b8aed86b220fd59171a67b5019c6c6ff0 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Tue, 9 Sep 2025 00:20:41 +0530 Subject: [PATCH 6/8] rename hasReportAccountingConnections variable. Signed-off-by: krishna2323 --- src/pages/workspace/reports/WorkspaceReportsPage.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/pages/workspace/reports/WorkspaceReportsPage.tsx b/src/pages/workspace/reports/WorkspaceReportsPage.tsx index d8f8eb163831..97767d711bff 100644 --- a/src/pages/workspace/reports/WorkspaceReportsPage.tsx +++ b/src/pages/workspace/reports/WorkspaceReportsPage.tsx @@ -30,7 +30,7 @@ import {getLatestErrorField} from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types'; import type {WorkspaceSplitNavigatorParamList} from '@libs/Navigation/types'; -import {getConnectedIntegration, getCurrentConnectionName, hasAccountingConnections, isControlPolicy, shouldShowSyncError} from '@libs/PolicyUtils'; +import {getConnectedIntegration, getCurrentConnectionName, hasAccountingConnections as hasAccountingConnectionsPolicyUtils, isControlPolicy, shouldShowSyncError} from '@libs/PolicyUtils'; import {getReportFieldTypeTranslationKey} from '@libs/WorkspaceReportFieldUtils'; import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; import ToggleSettingOptionRow from '@pages/workspace/workflows/ToggleSettingsOptionRow'; @@ -71,7 +71,7 @@ function WorkspaceReportFieldsPage({ const connectedIntegration = getConnectedIntegration(policy) ?? connectionSyncProgress?.connectionName; const isConnectionVerified = connectedIntegration && !isConnectionUnverified(policy, connectedIntegration); const currentConnectionName = getCurrentConnectionName(policy); - const hasReportAccountingConnections = hasAccountingConnections(policy); + const hasAccountingConnections = hasAccountingConnectionsPolicyUtils(policy); const filteredPolicyFieldList = useMemo(() => { if (!policy?.fieldList) { return {}; @@ -82,11 +82,11 @@ function WorkspaceReportFieldsPage({ const [isOrganizeWarningModalOpen, setIsOrganizeWarningModalOpen] = useState(false); const onDisabledOrganizeSwitchPress = useCallback(() => { - if (!hasReportAccountingConnections) { + if (!hasAccountingConnections) { return; } setIsOrganizeWarningModalOpen(true); - }, [hasReportAccountingConnections]); + }, [hasAccountingConnections]); const fetchReportFields = useCallback(() => { openPolicyReportFieldsPage(policyID); @@ -266,7 +266,7 @@ function WorkspaceReportFieldsPage({ } enablePolicyReportFields(policyID, isEnabled); }} - disabled={hasReportAccountingConnections} + disabled={hasAccountingConnections} disabledAction={onDisabledOrganizeSwitchPress} subMenuItems={ !!policy?.areReportFieldsEnabled && ( @@ -278,7 +278,7 @@ function WorkspaceReportFieldsPage({ keyExtractor={keyExtractor} /> - {!hasReportAccountingConnections && ( + {!hasAccountingConnections && ( Navigation.navigate(ROUTES.WORKSPACE_CREATE_REPORT_FIELD.getRoute(policyID))} title={translate('workspace.reportFields.addField')} From 412355aa9a1d885bc0f667145a97bf9e32a66f44 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Wed, 10 Sep 2025 03:29:53 +0530 Subject: [PATCH 7/8] minor update. Signed-off-by: krishna2323 --- src/libs/PolicyUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 52315259cc36..888419372ea2 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -610,7 +610,7 @@ function isControlOnAdvancedApprovalMode(policy: OnyxInputOrEntry): bool * Whether the policy has active accounting integration connections */ function hasAccountingConnections(policy: OnyxEntry) { - return !isEmptyObject(policy?.connections) && (!!getCurrentConnectionName(policy) || hasSupportedOnlyOnOldDotIntegration(policy)); + return !!getCurrentConnectionName(policy) || hasSupportedOnlyOnOldDotIntegration(policy); } function getPolicyEmployeeListByIdWithoutCurrentUser(policies: OnyxCollection>, currentPolicyID?: string, currentUserAccountID?: number) { From f0220723ae79d0f836d2b3d589d0db9d61db48c8 Mon Sep 17 00:00:00 2001 From: krishna2323 Date: Wed, 10 Sep 2025 03:33:17 +0530 Subject: [PATCH 8/8] update comment. Signed-off-by: krishna2323 --- src/libs/PolicyUtils.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 888419372ea2..4aeb908dc8dd 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -607,7 +607,9 @@ function isControlOnAdvancedApprovalMode(policy: OnyxInputOrEntry): bool } /** - * Whether the policy has active accounting integration connections + * Whether the policy has active accounting integration connections. + * `getCurrentConnectionName` only returns connections supported in NewDot. + * `hasSupportedOnlyOnOldDotIntegration` detects connections that are supported only on OldDot. */ function hasAccountingConnections(policy: OnyxEntry) { return !!getCurrentConnectionName(policy) || hasSupportedOnlyOnOldDotIntegration(policy);