From 35bb4e3586f1a6ab9ca4faa09c2268171882b314 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Mon, 12 Aug 2024 20:56:32 +0200 Subject: [PATCH 1/6] feat: add ToggleCardContinuousReconciliation command --- src/ONYXKEYS.ts | 2 +- ...oggleCardContinuousReconciliationParams.ts | 9 +++ src/libs/API/parameters/index.ts | 1 + src/libs/API/types.ts | 2 + src/libs/actions/Card.ts | 60 +++++++++++++++++++ .../reconciliation/CardReconciliationPage.tsx | 4 +- .../WorkspaceSettlementAccountPage.tsx | 6 +- src/types/onyx/Policy.ts | 10 ++++ src/types/onyx/index.ts | 3 +- 9 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 src/libs/API/parameters/ToggleCardContinuousReconciliationParams.ts diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index e06a2413bb4a..f7320389f4f7 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -739,7 +739,7 @@ type OnyxCollectionValuesMapping = { [ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END]: OnyxTypes.BillingGraceEndPeriod; [ONYXKEYS.COLLECTION.PRIVATE_EXPENSIFY_CARD_SETTINGS]: OnyxTypes.ExpensifyCardSettings; [ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST]: OnyxTypes.WorkspaceCardsList; - [ONYXKEYS.COLLECTION.EXPENSIFY_CARD_CONTINUOUS_RECONCILIATION_CONNECTION]: OnyxTypes.PolicyConnectionName; + [ONYXKEYS.COLLECTION.EXPENSIFY_CARD_CONTINUOUS_RECONCILIATION_CONNECTION]: OnyxTypes.ReconciliationConnectionSettings; [ONYXKEYS.COLLECTION.EXPENSIFY_CARD_USE_CONTINUOUS_RECONCILIATION]: boolean; }; diff --git a/src/libs/API/parameters/ToggleCardContinuousReconciliationParams.ts b/src/libs/API/parameters/ToggleCardContinuousReconciliationParams.ts new file mode 100644 index 000000000000..fc10384fa0f0 --- /dev/null +++ b/src/libs/API/parameters/ToggleCardContinuousReconciliationParams.ts @@ -0,0 +1,9 @@ +import type {ReconciliationConnectionSettings} from '@src/types/onyx/Policy'; + +type ToggleCardContinuousReconciliationParams = { + workspaceAccountID: number; + shouldUseContinuousReconciliation: boolean; + reconciliationSettings?: ReconciliationConnectionSettings; +}; + +export default ToggleCardContinuousReconciliationParams; diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts index 2954bfb4bc1c..88aae79d82c2 100644 --- a/src/libs/API/parameters/index.ts +++ b/src/libs/API/parameters/index.ts @@ -271,3 +271,4 @@ export type {default as UpdateExpensifyCardLimitParams} from './UpdateExpensifyC export type {CreateWorkspaceApprovalParams, UpdateWorkspaceApprovalParams, RemoveWorkspaceApprovalParams} from './WorkspaceApprovalParams'; export type {default as StartIssueNewCardFlowParams} from './StartIssueNewCardFlowParams'; export type {default as ConfigureExpensifyCardsForPolicyParams} from './ConfigureExpensifyCardsForPolicyParams'; +export type {default as ToggleCardContinuousReconciliationParams} from './ToggleCardContinuousReconciliationParams'; diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index 22cc0b8ff56d..b3e9d7fd2ac9 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -326,6 +326,7 @@ const WRITE_COMMANDS = { UPDATE_WORKSPACE_APPROVAL: 'UpdateWorkspaceApproval', REMOVE_WORKSPACE_APPROVAL: 'RemoveWorkspaceApproval', CONFIGURE_EXPENSIFY_CARDS_FOR_POLICY: 'ConfigureExpensifyCardsForPolicy', + TOGGLE_CARD_CONTINUOUS_RECONCILIATION: 'ToggleCardContinuousReconciliation', } as const; type WriteCommand = ValueOf; @@ -658,6 +659,7 @@ type WriteCommandParameters = { [WRITE_COMMANDS.UPDATE_WORKSPACE_APPROVAL]: Parameters.UpdateWorkspaceApprovalParams; [WRITE_COMMANDS.REMOVE_WORKSPACE_APPROVAL]: Parameters.RemoveWorkspaceApprovalParams; [WRITE_COMMANDS.CONFIGURE_EXPENSIFY_CARDS_FOR_POLICY]: Parameters.ConfigureExpensifyCardsForPolicyParams; + [WRITE_COMMANDS.TOGGLE_CARD_CONTINUOUS_RECONCILIATION]: Parameters.ToggleCardContinuousReconciliationParams; }; const READ_COMMANDS = { diff --git a/src/libs/actions/Card.ts b/src/libs/actions/Card.ts index 916ffd07a82a..c09bdb9cc85c 100644 --- a/src/libs/actions/Card.ts +++ b/src/libs/actions/Card.ts @@ -16,6 +16,7 @@ import * as NetworkStore from '@libs/Network/NetworkStore'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {ExpensifyCardDetails, IssueNewCardData, IssueNewCardStep} from '@src/types/onyx/Card'; +import type {ReconciliationConnectionSettings} from '@src/types/onyx/Policy'; type ReplacementReason = 'damaged' | 'stolen'; @@ -394,6 +395,64 @@ function configureExpensifyCardsForPolicy(policyID: string, bankAccountID?: numb API.write(WRITE_COMMANDS.CONFIGURE_EXPENSIFY_CARDS_FOR_POLICY, parameters); } +function toggleContinuousReconciliation(workspaceAccountID: number, shouldUseContinuousReconciliation: boolean, reconciliationSettings?: ReconciliationConnectionSettings) { + const parameters = shouldUseContinuousReconciliation + ? { + workspaceAccountID, + shouldUseContinuousReconciliation, + } + : { + workspaceAccountID, + shouldUseContinuousReconciliation, + reconciliationSettings, + }; + + const optimisticData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.EXPENSIFY_CARD_USE_CONTINUOUS_RECONCILIATION}${workspaceAccountID}`, + value: true, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.EXPENSIFY_CARD_CONTINUOUS_RECONCILIATION_CONNECTION}${workspaceAccountID}`, + value: reconciliationSettings ?? null, + }, + ]; + + const successData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.EXPENSIFY_CARD_USE_CONTINUOUS_RECONCILIATION}${workspaceAccountID}`, + value: true, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.EXPENSIFY_CARD_CONTINUOUS_RECONCILIATION_CONNECTION}${workspaceAccountID}`, + value: reconciliationSettings ?? null, + }, + ]; + + const failureData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.EXPENSIFY_CARD_USE_CONTINUOUS_RECONCILIATION}${workspaceAccountID}`, + value: false, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.EXPENSIFY_CARD_CONTINUOUS_RECONCILIATION_CONNECTION}${workspaceAccountID}`, + value: null, + }, + ]; + + API.write(WRITE_COMMANDS.TOGGLE_CARD_CONTINUOUS_RECONCILIATION, parameters, { + optimisticData, + successData, + failureData, + }); +} + export { requestReplacementExpensifyCard, activatePhysicalExpensifyCard, @@ -407,5 +466,6 @@ export { updateSettlementAccount, startIssueNewCardFlow, configureExpensifyCardsForPolicy, + toggleContinuousReconciliation, }; export type {ReplacementReason}; diff --git a/src/pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx b/src/pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx index 5d469baa11ca..011078a9e00b 100644 --- a/src/pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx +++ b/src/pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx @@ -26,7 +26,7 @@ function CardReconciliationPage({policy, route}: CardReconciliationPageProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); - const [reconciliationConnection] = useOnyx(`${ONYXKEYS.COLLECTION.EXPENSIFY_CARD_CONTINUOUS_RECONCILIATION_CONNECTION}${policy?.workspaceAccountID}`); + const [reconciliationConnectionSettings] = useOnyx(`${ONYXKEYS.COLLECTION.EXPENSIFY_CARD_CONTINUOUS_RECONCILIATION_CONNECTION}${policy?.workspaceAccountID}`); const [isContinuousReconciliationOn] = useOnyx(`${ONYXKEYS.COLLECTION.EXPENSIFY_CARD_USE_CONTINUOUS_RECONCILIATION}${policy?.workspaceAccountID}`); const [cardSettings] = useOnyx(`${ONYXKEYS.COLLECTION.PRIVATE_EXPENSIFY_CARD_SETTINGS}${policy?.workspaceAccountID}`); const [bankAccountList] = useOnyx(ONYXKEYS.BANK_ACCOUNT_LIST); @@ -101,7 +101,7 @@ function CardReconciliationPage({policy, route}: CardReconciliationPageProps) { {translate('common.conjunctionFor')} {CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY[connection]} )} - {!!reconciliationConnection && ( + {!!reconciliationConnectionSettings?.bankAccountID && ( {translate('workspace.expensifyCard.settlementAccountInfoPt1')}{' '} - Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_RECONCILIATION_ACCOUNT_SETTINGS.getRoute(policyID, reconciliationConnection))}> + Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_RECONCILIATION_ACCOUNT_SETTINGS.getRoute(policyID, connectionName))}> {translate('workspace.expensifyCard.reconciliationAccount')} {' '} {`(${CONST.MASKED_PAN_PREFIX}${getLastFourDigits(paymentBankAccountNumber)}) `} diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index c717d6579cc8..4d14220f7b69 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -1573,6 +1573,15 @@ type PolicyConnectionSyncProgress = { timestamp: string; }; +/** Expensify Card Reconciliation Settings */ +type ReconciliationConnectionSettings = { + /** Name of the connection */ + connectionName: ConnectionName; + + /** Reconciliation account ID */ + bankAccountID: number; +}; + export default Policy; export type { @@ -1625,4 +1634,5 @@ export type { SageIntacctConnectionsConfig, SageIntacctExportConfig, ACHAccount, + ReconciliationConnectionSettings, }; diff --git a/src/types/onyx/index.ts b/src/types/onyx/index.ts index 0bbff2e5f7f6..5f6a6f35d8fe 100644 --- a/src/types/onyx/index.ts +++ b/src/types/onyx/index.ts @@ -44,7 +44,7 @@ import type {PersonalDetailsList, PersonalDetailsMetadata} from './PersonalDetai import type PersonalDetails from './PersonalDetails'; import type PlaidData from './PlaidData'; import type Policy from './Policy'; -import type {PolicyConnectionName, PolicyConnectionSyncProgress, PolicyReportField, TaxRate, TaxRates, TaxRatesWithDefault} from './Policy'; +import type {PolicyConnectionName, PolicyConnectionSyncProgress, PolicyReportField, ReconciliationConnectionSettings, TaxRate, TaxRates, TaxRatesWithDefault} from './Policy'; import type {PolicyCategories, PolicyCategory} from './PolicyCategory'; import type {PolicyEmployeeList} from './PolicyEmployee'; import type PolicyEmployee from './PolicyEmployee'; @@ -220,4 +220,5 @@ export type { ApprovalWorkflow, MobileSelectionMode, WorkspaceTooltip, + ReconciliationConnectionSettings, }; From a152ce80f8b5cbf2dd26421e6721192222da6714 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Mon, 12 Aug 2024 21:03:22 +0200 Subject: [PATCH 2/6] minor fixes --- .../reconciliation/CardReconciliationPage.tsx | 16 ++++++++-------- src/types/onyx/Policy.ts | 3 --- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx b/src/pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx index 011078a9e00b..48c863072887 100644 --- a/src/pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx +++ b/src/pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx @@ -15,6 +15,7 @@ import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; import ToggleSettingOptionRow from '@pages/workspace/workflows/ToggleSettingsOptionRow'; +import * as Card from '@userActions/Card'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; @@ -26,9 +27,10 @@ function CardReconciliationPage({policy, route}: CardReconciliationPageProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); - const [reconciliationConnectionSettings] = useOnyx(`${ONYXKEYS.COLLECTION.EXPENSIFY_CARD_CONTINUOUS_RECONCILIATION_CONNECTION}${policy?.workspaceAccountID}`); - const [isContinuousReconciliationOn] = useOnyx(`${ONYXKEYS.COLLECTION.EXPENSIFY_CARD_USE_CONTINUOUS_RECONCILIATION}${policy?.workspaceAccountID}`); - const [cardSettings] = useOnyx(`${ONYXKEYS.COLLECTION.PRIVATE_EXPENSIFY_CARD_SETTINGS}${policy?.workspaceAccountID}`); + const workspaceAccountID = policy?.workspaceAccountID ?? -1; + + const [isContinuousReconciliationOn] = useOnyx(`${ONYXKEYS.COLLECTION.EXPENSIFY_CARD_USE_CONTINUOUS_RECONCILIATION}${workspaceAccountID}`); + const [cardSettings] = useOnyx(`${ONYXKEYS.COLLECTION.PRIVATE_EXPENSIFY_CARD_SETTINGS}${workspaceAccountID}`); const [bankAccountList] = useOnyx(ONYXKEYS.BANK_ACCOUNT_LIST); const paymentBankAccountID = cardSettings?.paymentBankAccountID ?? 0; @@ -40,10 +42,8 @@ function CardReconciliationPage({policy, route}: CardReconciliationPageProps) { // eslint-disable-next-line rulesdir/prefer-early-return const toggleContinuousReconciliation = () => { - if (!isContinuousReconciliationOn) { - Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_RECONCILIATION_ACCOUNT_SETTINGS.getRoute(policyID, connection)); - } - // TODO: add API call when it's supported https://github.com/Expensify/Expensify/issues/407834 + Card.toggleContinuousReconciliation(workspaceAccountID, true, {connectionName: connection}); + Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_RECONCILIATION_ACCOUNT_SETTINGS.getRoute(policyID, connection)); }; const navigateToAdvancedSettings = useCallback(() => { @@ -101,7 +101,7 @@ function CardReconciliationPage({policy, route}: CardReconciliationPageProps) { {translate('common.conjunctionFor')} {CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY[connection]} )} - {!!reconciliationConnectionSettings?.bankAccountID && ( + {!!paymentBankAccountID && isContinuousReconciliationOn && ( Date: Wed, 14 Aug 2024 13:46:05 +0200 Subject: [PATCH 3/6] fix: last improvements --- src/CONST.ts | 6 +++++ src/ONYXKEYS.ts | 2 +- src/ROUTES.ts | 5 ++-- ...oggleCardContinuousReconciliationParams.ts | 4 +-- src/libs/AccountingUtils.ts | 27 +++++++++++++++++++ src/libs/Navigation/types.ts | 4 +-- src/libs/actions/Card.ts | 16 +++++------ .../reconciliation/CardReconciliationPage.tsx | 23 +++++++++------- .../WorkspaceSettlementAccountPage.tsx | 9 ++++--- src/types/onyx/Policy.ts | 7 ----- 10 files changed, 68 insertions(+), 35 deletions(-) create mode 100644 src/libs/AccountingUtils.ts diff --git a/src/CONST.ts b/src/CONST.ts index 829a26c5cb96..33324a60cd2f 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -2130,6 +2130,12 @@ const CONST = { NETSUITE: 'netsuite', SAGE_INTACCT: 'intacct', }, + ROUTE: { + QBO: 'quickbooks-online', + XERO: 'xero', + NETSUITE: 'netsuite', + SAGE_INTACCT: 'sage-intacct', + }, NAME_USER_FRIENDLY: { netsuite: 'NetSuite', quickbooksOnline: 'Quickbooks Online', diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index 4b8c6a2bcf4a..acfa3a70c032 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -745,7 +745,7 @@ type OnyxCollectionValuesMapping = { [ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END]: OnyxTypes.BillingGraceEndPeriod; [ONYXKEYS.COLLECTION.PRIVATE_EXPENSIFY_CARD_SETTINGS]: OnyxTypes.ExpensifyCardSettings; [ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST]: OnyxTypes.WorkspaceCardsList; - [ONYXKEYS.COLLECTION.EXPENSIFY_CARD_CONTINUOUS_RECONCILIATION_CONNECTION]: OnyxTypes.ReconciliationConnectionSettings; + [ONYXKEYS.COLLECTION.EXPENSIFY_CARD_CONTINUOUS_RECONCILIATION_CONNECTION]: OnyxTypes.PolicyConnectionName; [ONYXKEYS.COLLECTION.EXPENSIFY_CARD_USE_CONTINUOUS_RECONCILIATION]: boolean; }; diff --git a/src/ROUTES.ts b/src/ROUTES.ts index d525cc0ee790..0056253b3dd8 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -714,11 +714,12 @@ const ROUTES = { }, WORKSPACE_ACCOUNTING_CARD_RECONCILIATION: { route: 'settings/workspaces/:policyID/accounting/:connection/card-reconciliation', - getRoute: (policyID: string, connection?: ConnectionName) => `settings/workspaces/${policyID}/accounting/${connection}/card-reconciliation` as const, + getRoute: (policyID: string, connection?: ValueOf) => `settings/workspaces/${policyID}/accounting/${connection}/card-reconciliation` as const, }, WORKSPACE_ACCOUNTING_RECONCILIATION_ACCOUNT_SETTINGS: { route: 'settings/workspaces/:policyID/accounting/:connection/card-reconciliation/account', - getRoute: (policyID: string, connection?: ConnectionName) => `settings/workspaces/${policyID}/accounting/${connection}/card-reconciliation/account` as const, + getRoute: (policyID: string, connection?: ValueOf) => + `settings/workspaces/${policyID}/accounting/${connection}/card-reconciliation/account` as const, }, WORKSPACE_CATEGORIES: { route: 'settings/workspaces/:policyID/categories', diff --git a/src/libs/API/parameters/ToggleCardContinuousReconciliationParams.ts b/src/libs/API/parameters/ToggleCardContinuousReconciliationParams.ts index fc10384fa0f0..7433418058bd 100644 --- a/src/libs/API/parameters/ToggleCardContinuousReconciliationParams.ts +++ b/src/libs/API/parameters/ToggleCardContinuousReconciliationParams.ts @@ -1,9 +1,7 @@ -import type {ReconciliationConnectionSettings} from '@src/types/onyx/Policy'; - type ToggleCardContinuousReconciliationParams = { workspaceAccountID: number; shouldUseContinuousReconciliation: boolean; - reconciliationSettings?: ReconciliationConnectionSettings; + expensifyCardContinuousReconciliationConnection?: string; }; export default ToggleCardContinuousReconciliationParams; diff --git a/src/libs/AccountingUtils.ts b/src/libs/AccountingUtils.ts new file mode 100644 index 000000000000..fe472752978a --- /dev/null +++ b/src/libs/AccountingUtils.ts @@ -0,0 +1,27 @@ +import type {ValueOf} from 'type-fest'; +import CONST from '@src/CONST'; +import type {ConnectionName} from '@src/types/onyx/Policy'; + +const ROUTE_NAME_MAPPING = { + [CONST.POLICY.CONNECTIONS.ROUTE.QBO]: CONST.POLICY.CONNECTIONS.NAME.QBO, + [CONST.POLICY.CONNECTIONS.ROUTE.XERO]: CONST.POLICY.CONNECTIONS.NAME.XERO, + [CONST.POLICY.CONNECTIONS.ROUTE.SAGE_INTACCT]: CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT, + [CONST.POLICY.CONNECTIONS.ROUTE.NETSUITE]: CONST.POLICY.CONNECTIONS.NAME.NETSUITE, +}; + +const NAME_ROUTE_MAPPING = { + [CONST.POLICY.CONNECTIONS.NAME.QBO]: CONST.POLICY.CONNECTIONS.ROUTE.QBO, + [CONST.POLICY.CONNECTIONS.NAME.XERO]: CONST.POLICY.CONNECTIONS.ROUTE.XERO, + [CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT]: CONST.POLICY.CONNECTIONS.ROUTE.SAGE_INTACCT, + [CONST.POLICY.CONNECTIONS.NAME.NETSUITE]: CONST.POLICY.CONNECTIONS.ROUTE.NETSUITE, +}; + +function getConnectionNameFromRouteParam(routeParam: ValueOf) { + return ROUTE_NAME_MAPPING[routeParam]; +} + +function getRouteParamForConnection(connectionName: ConnectionName) { + return NAME_ROUTE_MAPPING[connectionName]; +} + +export {getConnectionNameFromRouteParam, getRouteParamForConnection}; diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 25a12c47eadd..63a5ef3d4a9a 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -620,11 +620,11 @@ type SettingsNavigatorParamList = { }; [SCREENS.WORKSPACE.ACCOUNTING.CARD_RECONCILIATION]: { policyID: string; - connection: ValueOf; + connection: ValueOf; }; [SCREENS.WORKSPACE.ACCOUNTING.RECONCILIATION_ACCOUNT_SETTINGS]: { policyID: string; - connection: ValueOf; + connection: ValueOf; }; [SCREENS.GET_ASSISTANCE]: { backTo: Routes; diff --git a/src/libs/actions/Card.ts b/src/libs/actions/Card.ts index 2c48d0ae0af7..b3eb70de8f23 100644 --- a/src/libs/actions/Card.ts +++ b/src/libs/actions/Card.ts @@ -16,7 +16,7 @@ import * as NetworkStore from '@libs/Network/NetworkStore'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {ExpensifyCardDetails, IssueNewCardData, IssueNewCardStep} from '@src/types/onyx/Card'; -import type {ReconciliationConnectionSettings} from '@src/types/onyx/Policy'; +import type {ConnectionName} from '@src/types/onyx/Policy'; type ReplacementReason = 'damaged' | 'stolen'; @@ -419,28 +419,28 @@ function issueExpensifyCard(policyID: string, feedCountry: string, data?: IssueN API.write(WRITE_COMMANDS.CREATE_ADMIN_ISSUED_VIRTUAL_CARD, parameters); } -function toggleContinuousReconciliation(workspaceAccountID: number, shouldUseContinuousReconciliation: boolean, reconciliationSettings?: ReconciliationConnectionSettings) { +function toggleContinuousReconciliation(workspaceAccountID: number, shouldUseContinuousReconciliation: boolean, connectionName: ConnectionName) { const parameters = shouldUseContinuousReconciliation ? { workspaceAccountID, shouldUseContinuousReconciliation, + expensifyCardContinuousReconciliationConnection: connectionName, } : { workspaceAccountID, shouldUseContinuousReconciliation, - reconciliationSettings, }; const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.EXPENSIFY_CARD_USE_CONTINUOUS_RECONCILIATION}${workspaceAccountID}`, - value: true, + value: shouldUseContinuousReconciliation, }, { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.EXPENSIFY_CARD_CONTINUOUS_RECONCILIATION_CONNECTION}${workspaceAccountID}`, - value: reconciliationSettings ?? null, + value: connectionName, }, ]; @@ -448,12 +448,12 @@ function toggleContinuousReconciliation(workspaceAccountID: number, shouldUseCon { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.EXPENSIFY_CARD_USE_CONTINUOUS_RECONCILIATION}${workspaceAccountID}`, - value: true, + value: shouldUseContinuousReconciliation, }, { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.EXPENSIFY_CARD_CONTINUOUS_RECONCILIATION_CONNECTION}${workspaceAccountID}`, - value: reconciliationSettings ?? null, + value: connectionName, }, ]; @@ -461,7 +461,7 @@ function toggleContinuousReconciliation(workspaceAccountID: number, shouldUseCon { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.EXPENSIFY_CARD_USE_CONTINUOUS_RECONCILIATION}${workspaceAccountID}`, - value: false, + value: !shouldUseContinuousReconciliation, }, { onyxMethod: Onyx.METHOD.MERGE, diff --git a/src/pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx b/src/pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx index 48c863072887..2843ec0dbf7f 100644 --- a/src/pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx +++ b/src/pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx @@ -9,6 +9,7 @@ import Text from '@components/Text'; import TextLink from '@components/TextLink'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; +import * as AccountingUtils from '@libs/AccountingUtils'; import Navigation from '@navigation/Navigation'; import type {SettingsNavigatorParamList} from '@navigation/types'; import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper'; @@ -20,6 +21,7 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; +import type {ConnectionName} from '@src/types/onyx/Policy'; type CardReconciliationPageProps = WithPolicyConnectionsProps & StackScreenProps; @@ -38,26 +40,29 @@ function CardReconciliationPage({policy, route}: CardReconciliationPageProps) { const policyID = policy?.id ?? '-1'; const {connection} = route.params; - const autoSync = !!policy?.connections?.[connection]?.config?.autoSync?.enabled; + const connectionName = AccountingUtils.getConnectionNameFromRouteParam(connection) as ConnectionName; + const autoSync = !!policy?.connections?.[connectionName]?.config?.autoSync?.enabled; // eslint-disable-next-line rulesdir/prefer-early-return - const toggleContinuousReconciliation = () => { - Card.toggleContinuousReconciliation(workspaceAccountID, true, {connectionName: connection}); - Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_RECONCILIATION_ACCOUNT_SETTINGS.getRoute(policyID, connection)); + const toggleContinuousReconciliation = (value: boolean) => { + Card.toggleContinuousReconciliation(workspaceAccountID, value, connectionName); + if (value) { + Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_RECONCILIATION_ACCOUNT_SETTINGS.getRoute(policyID, connection)); + } }; const navigateToAdvancedSettings = useCallback(() => { switch (connection) { - case CONST.POLICY.CONNECTIONS.NAME.QBO: + case CONST.POLICY.CONNECTIONS.ROUTE.QBO: Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_ADVANCED.getRoute(policyID)); break; - case CONST.POLICY.CONNECTIONS.NAME.XERO: + case CONST.POLICY.CONNECTIONS.ROUTE.XERO: Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_ADVANCED.getRoute(policyID)); break; - case CONST.POLICY.CONNECTIONS.NAME.NETSUITE: + case CONST.POLICY.CONNECTIONS.ROUTE.NETSUITE: Navigation.navigate(ROUTES.POLICY_ACCOUNTING_NETSUITE_ADVANCED.getRoute(policyID)); break; - case CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT: + case CONST.POLICY.CONNECTIONS.ROUTE.SAGE_INTACCT: Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_ADVANCED.getRoute(policyID)); break; default: @@ -98,7 +103,7 @@ function CardReconciliationPage({policy, route}: CardReconciliationPageProps) { > {translate('workspace.accounting.autoSync').toLowerCase()} {' '} - {translate('common.conjunctionFor')} {CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY[connection]} + {translate('common.conjunctionFor')} {CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY[connectionName]} )} {!!paymentBankAccountID && isContinuousReconciliationOn && ( diff --git a/src/pages/workspace/expensifyCard/WorkspaceSettlementAccountPage.tsx b/src/pages/workspace/expensifyCard/WorkspaceSettlementAccountPage.tsx index 17ead5fa014d..b75226ed4636 100644 --- a/src/pages/workspace/expensifyCard/WorkspaceSettlementAccountPage.tsx +++ b/src/pages/workspace/expensifyCard/WorkspaceSettlementAccountPage.tsx @@ -13,6 +13,7 @@ import Text from '@components/Text'; import TextLink from '@components/TextLink'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; +import * as AccountingUtils from '@libs/AccountingUtils'; import {getLastFourDigits} from '@libs/BankAccountUtils'; import * as CardUtils from '@libs/CardUtils'; import * as PolicyUtils from '@libs/PolicyUtils'; @@ -25,6 +26,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import type {BankName} from '@src/types/onyx/Bank'; +import type {ConnectionName} from '@src/types/onyx/Policy'; type WorkspaceSettlementAccountPageProps = StackScreenProps; @@ -37,9 +39,10 @@ function WorkspaceSettlementAccountPage({route}: WorkspaceSettlementAccountPageP const [bankAccountsList] = useOnyx(ONYXKEYS.BANK_ACCOUNT_LIST); const [cardSettings] = useOnyx(`${ONYXKEYS.COLLECTION.PRIVATE_EXPENSIFY_CARD_SETTINGS}${workspaceAccountID}`); const [isUsedContinuousReconciliation] = useOnyx(`${ONYXKEYS.COLLECTION.EXPENSIFY_CARD_USE_CONTINUOUS_RECONCILIATION}${workspaceAccountID}`); - const [reconciliationConnectionSettings] = useOnyx(`${ONYXKEYS.COLLECTION.EXPENSIFY_CARD_CONTINUOUS_RECONCILIATION_CONNECTION}${workspaceAccountID}`); + const [reconciliationConnection] = useOnyx(`${ONYXKEYS.COLLECTION.EXPENSIFY_CARD_CONTINUOUS_RECONCILIATION_CONNECTION}${workspaceAccountID}`); - const connectionName = reconciliationConnectionSettings?.connectionName ?? ''; + const connectionName = reconciliationConnection ?? ''; + const connectionParam = AccountingUtils.getRouteParamForConnection(connectionName as ConnectionName); const paymentBankAccountID = cardSettings?.paymentBankAccountID ?? 0; const paymentBankAccountNumber = bankAccountsList?.[paymentBankAccountID.toString()]?.accountData?.accountNumber ?? ''; @@ -99,7 +102,7 @@ function WorkspaceSettlementAccountPage({route}: WorkspaceSettlementAccountPageP {isUsedContinuousReconciliation && ( {translate('workspace.expensifyCard.settlementAccountInfoPt1')}{' '} - Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_RECONCILIATION_ACCOUNT_SETTINGS.getRoute(policyID, connectionName))}> + Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_RECONCILIATION_ACCOUNT_SETTINGS.getRoute(policyID, connectionParam))}> {translate('workspace.expensifyCard.reconciliationAccount')} {' '} {`(${CONST.MASKED_PAN_PREFIX}${getLastFourDigits(paymentBankAccountNumber)}) `} diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index fffafdc4d794..3311959cf8bf 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -1576,12 +1576,6 @@ type PolicyConnectionSyncProgress = { timestamp: string; }; -/** Expensify Card Reconciliation Settings */ -type ReconciliationConnectionSettings = { - /** Name of the connection */ - connectionName: ConnectionName; -}; - export default Policy; export type { @@ -1634,5 +1628,4 @@ export type { SageIntacctConnectionsConfig, SageIntacctExportConfig, ACHAccount, - ReconciliationConnectionSettings, }; From 6196c611b989c146c003bbed29dc5b0845e02b64 Mon Sep 17 00:00:00 2001 From: Agata Kosior Date: Wed, 14 Aug 2024 14:26:23 +0200 Subject: [PATCH 4/6] fix: typecheck --- src/pages/workspace/accounting/PolicyAccountingPage.tsx | 4 ++-- .../reconciliation/ReconciliationAccountSettingsPage.tsx | 4 +++- src/types/onyx/index.ts | 3 +-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx index ffde9cb25de0..9daec587d104 100644 --- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx +++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx @@ -106,7 +106,7 @@ function accountingIntegrationData( ), onImportPagePress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_IMPORT.getRoute(policyID)), onExportPagePress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_EXPORT.getRoute(policyID)), - onCardReconciliationPagePress: () => Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_CARD_RECONCILIATION.getRoute(policyID, CONST.POLICY.CONNECTIONS.NAME.QBO)), + onCardReconciliationPagePress: () => Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_CARD_RECONCILIATION.getRoute(policyID, CONST.POLICY.CONNECTIONS.ROUTE.QBO)), onAdvancedPagePress: () => Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_ADVANCED.getRoute(policyID)), }; case CONST.POLICY.CONNECTIONS.NAME.XERO: @@ -187,7 +187,7 @@ function accountingIntegrationData( ? CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE_VENDOR : CONST.SAGE_INTACCT_CONFIG.NON_REIMBURSABLE_CREDIT_CARD_VENDOR, ], - onCardReconciliationPagePress: () => Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_CARD_RECONCILIATION.getRoute(policyID, CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT)), + onCardReconciliationPagePress: () => Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_CARD_RECONCILIATION.getRoute(policyID, CONST.POLICY.CONNECTIONS.ROUTE.SAGE_INTACCT)), onAdvancedPagePress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_ADVANCED.getRoute(policyID)), subscribedAdvancedSettings: [ CONST.SAGE_INTACCT_CONFIG.AUTO_SYNC_ENABLED, diff --git a/src/pages/workspace/accounting/reconciliation/ReconciliationAccountSettingsPage.tsx b/src/pages/workspace/accounting/reconciliation/ReconciliationAccountSettingsPage.tsx index 58b4107779f8..1d2468e2e4e4 100644 --- a/src/pages/workspace/accounting/reconciliation/ReconciliationAccountSettingsPage.tsx +++ b/src/pages/workspace/accounting/reconciliation/ReconciliationAccountSettingsPage.tsx @@ -8,6 +8,7 @@ import Text from '@components/Text'; import TextLink from '@components/TextLink'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; +import * as AccountingUtils from '@libs/AccountingUtils'; import {getLastFourDigits} from '@libs/BankAccountUtils'; import * as PolicyUtils from '@libs/PolicyUtils'; import Navigation from '@navigation/Navigation'; @@ -26,6 +27,7 @@ function ReconciliationAccountSettingsPage({route}: ReconciliationAccountSetting const {translate} = useLocalize(); const workspaceAccountID = PolicyUtils.getWorkspaceAccountID(policyID); + const connectionName = AccountingUtils.getConnectionNameFromRouteParam(connection); const [bankAccountList] = useOnyx(ONYXKEYS.BANK_ACCOUNT_LIST); const [cardSettings] = useOnyx(`${ONYXKEYS.COLLECTION.PRIVATE_EXPENSIFY_CARD_SETTINGS}${workspaceAccountID}`); @@ -58,7 +60,7 @@ function ReconciliationAccountSettingsPage({route}: ReconciliationAccountSetting policyID={policyID} featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED} contentContainerStyle={[styles.flex1, styles.pb2]} - connectionName={connection} + connectionName={connectionName} shouldUseScrollView={false} > {translate('workspace.accounting.chooseReconciliationAccount.chooseBankAccount')} diff --git a/src/types/onyx/index.ts b/src/types/onyx/index.ts index b04524acff98..2bb129708981 100644 --- a/src/types/onyx/index.ts +++ b/src/types/onyx/index.ts @@ -44,7 +44,7 @@ import type {PersonalDetailsList, PersonalDetailsMetadata} from './PersonalDetai import type PersonalDetails from './PersonalDetails'; import type PlaidData from './PlaidData'; import type Policy from './Policy'; -import type {PolicyConnectionName, PolicyConnectionSyncProgress, PolicyReportField, ReconciliationConnectionSettings, TaxRate, TaxRates, TaxRatesWithDefault} from './Policy'; +import type {PolicyConnectionName, PolicyConnectionSyncProgress, PolicyReportField, TaxRate, TaxRates, TaxRatesWithDefault} from './Policy'; import type {PolicyCategories, PolicyCategory} from './PolicyCategory'; import type {PolicyEmployeeList} from './PolicyEmployee'; import type PolicyEmployee from './PolicyEmployee'; @@ -220,5 +220,4 @@ export type { ApprovalWorkflowOnyx, MobileSelectionMode, WorkspaceTooltip, - ReconciliationConnectionSettings, }; From 8ae3f7f90cdde3f66b8e3add1eef4be137462009 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Fri, 16 Aug 2024 11:59:19 +0200 Subject: [PATCH 5/6] Remove extra eslint disable --- .../accounting/reconciliation/CardReconciliationPage.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx b/src/pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx index 2843ec0dbf7f..9bc8bdfe80a9 100644 --- a/src/pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx +++ b/src/pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx @@ -43,7 +43,6 @@ function CardReconciliationPage({policy, route}: CardReconciliationPageProps) { const connectionName = AccountingUtils.getConnectionNameFromRouteParam(connection) as ConnectionName; const autoSync = !!policy?.connections?.[connectionName]?.config?.autoSync?.enabled; - // eslint-disable-next-line rulesdir/prefer-early-return const toggleContinuousReconciliation = (value: boolean) => { Card.toggleContinuousReconciliation(workspaceAccountID, value, connectionName); if (value) { From 007b76ecec6c5ca778f91785d18f504a100b9115 Mon Sep 17 00:00:00 2001 From: VickyStash Date: Mon, 19 Aug 2024 13:57:57 +0200 Subject: [PATCH 6/6] Update failureData --- src/libs/actions/Card.ts | 4 ++-- .../accounting/reconciliation/CardReconciliationPage.tsx | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/Card.ts b/src/libs/actions/Card.ts index e9015f383c4d..4430730f7222 100644 --- a/src/libs/actions/Card.ts +++ b/src/libs/actions/Card.ts @@ -498,7 +498,7 @@ function openCardDetailsPage(cardID: number) { API.read(READ_COMMANDS.OPEN_CARD_DETAILS_PAGE, parameters); } -function toggleContinuousReconciliation(workspaceAccountID: number, shouldUseContinuousReconciliation: boolean, connectionName: ConnectionName) { +function toggleContinuousReconciliation(workspaceAccountID: number, shouldUseContinuousReconciliation: boolean, connectionName: ConnectionName, oldConnectionName?: ConnectionName) { const parameters = shouldUseContinuousReconciliation ? { workspaceAccountID, @@ -545,7 +545,7 @@ function toggleContinuousReconciliation(workspaceAccountID: number, shouldUseCon { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.EXPENSIFY_CARD_CONTINUOUS_RECONCILIATION_CONNECTION}${workspaceAccountID}`, - value: null, + value: oldConnectionName ?? null, }, ]; diff --git a/src/pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx b/src/pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx index 9bc8bdfe80a9..c907095c4301 100644 --- a/src/pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx +++ b/src/pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx @@ -33,6 +33,7 @@ function CardReconciliationPage({policy, route}: CardReconciliationPageProps) { const [isContinuousReconciliationOn] = useOnyx(`${ONYXKEYS.COLLECTION.EXPENSIFY_CARD_USE_CONTINUOUS_RECONCILIATION}${workspaceAccountID}`); const [cardSettings] = useOnyx(`${ONYXKEYS.COLLECTION.PRIVATE_EXPENSIFY_CARD_SETTINGS}${workspaceAccountID}`); + const [currentConnectionName] = useOnyx(`${ONYXKEYS.COLLECTION.EXPENSIFY_CARD_CONTINUOUS_RECONCILIATION_CONNECTION}${workspaceAccountID}`); const [bankAccountList] = useOnyx(ONYXKEYS.BANK_ACCOUNT_LIST); const paymentBankAccountID = cardSettings?.paymentBankAccountID ?? 0; @@ -44,7 +45,7 @@ function CardReconciliationPage({policy, route}: CardReconciliationPageProps) { const autoSync = !!policy?.connections?.[connectionName]?.config?.autoSync?.enabled; const toggleContinuousReconciliation = (value: boolean) => { - Card.toggleContinuousReconciliation(workspaceAccountID, value, connectionName); + Card.toggleContinuousReconciliation(workspaceAccountID, value, connectionName, currentConnectionName); if (value) { Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_RECONCILIATION_ACCOUNT_SETTINGS.getRoute(policyID, connection)); }