diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index b06b05dac7e1..fc25d1f13b50 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -445,6 +445,9 @@ const ONYXKEYS = { /** The bank account that Expensify Card payments will be reconciled against */ SHARED_NVP_EXPENSIFY_CARD_CONTINUOUS_RECONCILIATION_CONNECTION: 'sharedNVP_expensifyCard_continuousReconciliationConnection_', + + /** If continuous reconciliation is enabled */ + SHARED_NVP_EXPENSIFY_CARD_USE_CONTINUOUS_RECONCILIATION: 'sharedNVP_expensifyCard_useContinuousReconciliation_', }, /** List of Form ids */ @@ -693,6 +696,7 @@ type OnyxCollectionValuesMapping = { [ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_EXPENSIFY_CARD_SETTINGS]: OnyxTypes.ExpensifyCardSettings; [ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST]: OnyxTypes.WorkspaceCardsList; [ONYXKEYS.COLLECTION.SHARED_NVP_EXPENSIFY_CARD_CONTINUOUS_RECONCILIATION_CONNECTION]: OnyxTypes.BankAccount; + [ONYXKEYS.COLLECTION.SHARED_NVP_EXPENSIFY_CARD_USE_CONTINUOUS_RECONCILIATION]: boolean; }; type OnyxValuesMapping = { diff --git a/src/languages/en.ts b/src/languages/en.ts index 8761366685ee..9c066b59715b 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -3144,6 +3144,10 @@ export default { reimbursedReports: 'Sync reimbursed reports', cardReconciliation: 'Card reconciliation', reconciliationAccount: 'Reconciliation account', + continuousReconciliation: 'Continuous Reconciliation', + saveHoursOnReconciliation: + 'Save hours on reconciliation each accounting period by having Expensify continuously reconcile Expensify Card statements and settlements on your behalf.', + enableContinuousReconciliation: 'In order to enable Continuous Reconciliation, please enable ', chooseReconciliationAccount: { chooseBankAccount: 'Choose the bank account that your Expensify Card payments will be reconciled against.', accountMatches: 'Make sure this account matches your ', diff --git a/src/languages/es.ts b/src/languages/es.ts index 75d23c8691e3..2076d04af16b 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -3132,6 +3132,10 @@ export default { reimbursedReports: 'Sincronizar informes reembolsados', cardReconciliation: 'Conciliación de tarjetas', reconciliationAccount: 'Cuenta de conciliación', + continuousReconciliation: 'Conciliación continua', + saveHoursOnReconciliation: + 'Ahorra horas de conciliación en cada período contable haciendo que Expensify concilie continuamente los extractos y liquidaciones de la Tarjeta Expensify en tu nombre.', + enableContinuousReconciliation: 'Para activar la Conciliación Continua, activa la ', chooseReconciliationAccount: { chooseBankAccount: 'Elige la cuenta bancaria con la que se conciliarán los pagos de tu Tarjeta Expensify.', accountMatches: 'Asegúrate de que esta cuenta coincide con ', diff --git a/src/pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx b/src/pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx index 27f31f587944..f6304b7e439a 100644 --- a/src/pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx +++ b/src/pages/workspace/accounting/reconciliation/CardReconciliationPage.tsx @@ -1,19 +1,64 @@ -import React from 'react'; +import type {StackScreenProps} from '@react-navigation/stack'; +import React, {useCallback} from 'react'; +import {useOnyx} from 'react-native-onyx'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import ScreenWrapper from '@components/ScreenWrapper'; import ScrollView from '@components/ScrollView'; +import Text from '@components/Text'; +import TextLink from '@components/TextLink'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; +import Navigation from '@navigation/Navigation'; +import type {SettingsNavigatorParamList} from '@navigation/types'; 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 CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; +import type SCREENS from '@src/SCREENS'; -function CardReconciliationPage({policy}: WithPolicyConnectionsProps) { +type CardReconciliationPageProps = WithPolicyConnectionsProps & StackScreenProps; + +function CardReconciliationPage({policy, route}: CardReconciliationPageProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); + const [reconciliationConnection] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_EXPENSIFY_CARD_CONTINUOUS_RECONCILIATION_CONNECTION}${policy?.id}`); + const [isContinuousReconciliationOn] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_EXPENSIFY_CARD_USE_CONTINUOUS_RECONCILIATION}${policy?.id}`); + const policyID = policy?.id ?? '-1'; + const {connection} = route.params; + const autoSync = !!policy?.connections?.[connection]?.config?.autoSync.enabled; + + // 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 + }; + + const navigateToAdvancedSettings = useCallback(() => { + switch (connection) { + case CONST.POLICY.CONNECTIONS.NAME.QBO: + Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_ADVANCED.getRoute(policyID)); + break; + case CONST.POLICY.CONNECTIONS.NAME.XERO: + Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_ADVANCED.getRoute(policyID)); + break; + case CONST.POLICY.CONNECTIONS.NAME.NETSUITE: + Navigation.navigate(ROUTES.POLICY_ACCOUNTING_NETSUITE_ADVANCED.getRoute(policyID)); + break; + case CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT: + Navigation.navigate(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_ADVANCED.getRoute(policyID)); + break; + default: + break; + } + }, [connection, policyID]); return ( - + + + {!autoSync && ( + + {translate('workspace.accounting.enableContinuousReconciliation')} + + {translate('workspace.accounting.autoSync').toLowerCase()} + {' '} + {translate('common.conjunctionFor')} {CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY[connection]} + + )} + {!!reconciliationConnection && ( + + )} + ); diff --git a/src/pages/workspace/withPolicy.tsx b/src/pages/workspace/withPolicy.tsx index 5dea1664589d..09a5e5b42466 100644 --- a/src/pages/workspace/withPolicy.tsx +++ b/src/pages/workspace/withPolicy.tsx @@ -41,6 +41,7 @@ type PolicyRoute = RouteProp< | typeof SCREENS.WORKSPACE.REPORT_FIELDS_LIST_VALUES | typeof SCREENS.WORKSPACE.REPORT_FIELDS_EDIT_INITIAL_VALUE | typeof SCREENS.WORKSPACE.REPORT_FIELDS_VALUE_SETTINGS + | typeof SCREENS.WORKSPACE.ACCOUNTING.CARD_RECONCILIATION >; function getPolicyIDFromRoute(route: PolicyRoute): string {