Skip to content

Commit

Permalink
Merge pull request #41475 from rushatgabhane/advanced-page
Browse files Browse the repository at this point in the history
[Wave Collect][Xero] Main advanced settings page
lakchote authored May 3, 2024
2 parents ee8f9c6 + 2e2581c commit 0ae357e
Showing 13 changed files with 149 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
@@ -1268,6 +1268,8 @@ const CONST = {
},

XERO_CONFIG: {
AUTO_SYNC: 'autoSync',
SYNC: 'sync',
IMPORT_CUSTOMERS: 'importCustomers',
IMPORT_TAX_RATES: 'importTaxRates',
},
4 changes: 4 additions & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
@@ -786,6 +786,10 @@ const ROUTES = {
route: 'settings/workspaces/:policyID/accounting/xero/import/taxes',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/import/taxes` as const,
},
POLICY_ACCOUNTING_XERO_ADVANCED: {
route: 'settings/workspaces/:policyID/accounting/xero/advanced',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/advanced` as const,
},
POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_IMPORT: {
route: 'settings/workspaces/:policyID/accounting/quickbooks-online/import',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/quickbooks-online/import` as const,
1 change: 1 addition & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
@@ -239,6 +239,7 @@ const SCREENS = {
XERO_ORGANIZATION: 'Policy_Accounting_Xero_Customers',
XERO_CUSTOMER: 'Policy_Acounting_Xero_Import_Customer',
XERO_TAXES: 'Policy_Accounting_Xero_Taxes',
XERO_ADVANCED: 'Policy_Accounting_Xero_Advanced',
},
INITIAL: 'Workspace_Initial',
PROFILE: 'Workspace_Profile',
6 changes: 5 additions & 1 deletion src/components/ConnectionLayout.tsx
Original file line number Diff line number Diff line change
@@ -51,7 +51,11 @@ function ConnectionLayout({displayName, headerTitle, children, title, subtitle,
onBackButtonPress={() => Navigation.goBack()}
/>
<ScrollView contentContainerStyle={[styles.pb2, styles.ph5]}>
<View style={[styles.pb2]}>{title && <Text style={styles.pb5}>{translate(title)}</Text>}</View>
{title && (
<View style={[styles.pb2]}>
<Text style={styles.pb5}>{translate(title)}</Text>
</View>
)}
{subtitle && <Text style={styles.textLabelSupporting}>{translate(subtitle)}</Text>}
{children}
</ScrollView>
10 changes: 10 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
@@ -2001,6 +2001,16 @@ export default {
customersDescription: 'Import customer contacts. Billable expenses need tags for export. Expenses will carry the customer information to Xero for sales invoices.',
taxesDescription: 'Choose whether to import tax rates and tax defaults from your accounting integration.',
notImported: 'Not imported',
advancedConfig: {
advanced: 'Advanced',
autoSync: 'Auto-Sync',
autoSyncDescription: 'Sync Xero and Expensify automatically every day.',
purchaseBillStatusTitle: 'Set purchase bill status (optional)',
reimbursedReports: 'Sync reimbursed reports',
reimbursedReportsDescription: 'Any time a report is paid using Expensify ACH, the corresponding bill payment will be created in the Xero account below.',
xeroBillPaymentAccount: 'Xero Bill Payment Account',
xeroInvoiceCollectionAccount: 'Xero Invoice Collections Account',
},
},
type: {
free: 'Free',
11 changes: 11 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
@@ -2034,6 +2034,17 @@ export default {
'Importar contactos de clientes. Los gastos facturables necesitan etiquetas para la exportación. Los gastos llevarán la información del cliente a Xero para las facturas de ventas.',
taxesDescription: 'Elige si quires importar las tasas de impuestos y los impuestos por defecto de tu integración de contaduría.',
notImported: 'No importado',
advancedConfig: {
advanced: 'Avanzado',
autoSync: 'Autosincronización',
autoSyncDescription: 'Sincroniza Xero y Expensify automáticamente todos los días.',
purchaseBillStatusTitle: 'Set purchase bill status (optional)',
reimbursedReports: 'Sincronizar informes reembolsados',
reimbursedReportsDescription:
'Cada vez que se pague un informe utilizando Expensify ACH, se creará el correspondiente pago de la factura en la cuenta de Xero indicadas a continuación.',
xeroBillPaymentAccount: 'Cuenta de pago de las facturas de Xero',
xeroInvoiceCollectionAccount: 'Cuenta de cobro de las facturas Xero',
},
},
type: {
free: 'Gratis',
Original file line number Diff line number Diff line change
@@ -299,6 +299,7 @@ const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorP
[SCREENS.WORKSPACE.ACCOUNTING.XERO_ORGANIZATION]: () => require('../../../../pages/workspace/accounting/xero/XeroOrganizationConfigurationPage').default as React.ComponentType,
[SCREENS.WORKSPACE.ACCOUNTING.XERO_CUSTOMER]: () => require('../../../../pages/workspace/accounting/xero/import/XeroCustomerConfigurationPage').default as React.ComponentType,
[SCREENS.WORKSPACE.ACCOUNTING.XERO_TAXES]: () => require('../../../../pages/workspace/accounting/xero/XeroTaxesConfigurationPage').default as React.ComponentType,
[SCREENS.WORKSPACE.ACCOUNTING.XERO_ADVANCED]: () => require('../../../../pages/workspace/accounting/xero/advanced/XeroAdvancedPage').default as React.ComponentType,
[SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_FREQUENCY]: () => require('../../../../pages/workspace/workflows/WorkspaceAutoReportingFrequencyPage').default as React.ComponentType,
[SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_MONTHLY_OFFSET]: () =>
require('../../../../pages/workspace/workflows/WorkspaceAutoReportingMonthlyOffsetPage').default as React.ComponentType,
Original file line number Diff line number Diff line change
@@ -44,6 +44,7 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial<Record<FullScreenName, string[]>> = {
SCREENS.WORKSPACE.ACCOUNTING.XERO_ORGANIZATION,
SCREENS.WORKSPACE.ACCOUNTING.XERO_CUSTOMER,
SCREENS.WORKSPACE.ACCOUNTING.XERO_TAXES,
SCREENS.WORKSPACE.ACCOUNTING.XERO_ADVANCED,
],
[SCREENS.WORKSPACE.TAXES]: [
SCREENS.WORKSPACE.TAXES_SETTINGS,
1 change: 1 addition & 0 deletions src/libs/Navigation/linkingConfig/config.ts
Original file line number Diff line number Diff line change
@@ -331,6 +331,7 @@ const config: LinkingOptions<RootStackParamList>['config'] = {
[SCREENS.WORKSPACE.ACCOUNTING.XERO_ORGANIZATION]: {path: ROUTES.POLICY_ACCOUNTING_XERO_ORGANIZATION.route},
[SCREENS.WORKSPACE.ACCOUNTING.XERO_CUSTOMER]: {path: ROUTES.POLICY_ACCOUNTING_XERO_CUSTOMER.route},
[SCREENS.WORKSPACE.ACCOUNTING.XERO_TAXES]: {path: ROUTES.POLICY_ACCOUNTING_XERO_TAXES.route},
[SCREENS.WORKSPACE.ACCOUNTING.XERO_ADVANCED]: {path: ROUTES.POLICY_ACCOUNTING_XERO_ADVANCED.route},
[SCREENS.WORKSPACE.DESCRIPTION]: {
path: ROUTES.WORKSPACE_PROFILE_DESCRIPTION.route,
},
3 changes: 3 additions & 0 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
@@ -324,6 +324,9 @@ type SettingsNavigatorParamList = {
[SCREENS.WORKSPACE.ACCOUNTING.XERO_TAXES]: {
policyID: string;
};
[SCREENS.WORKSPACE.ACCOUNTING.XERO_ADVANCED]: {
policyID: string;
};
[SCREENS.GET_ASSISTANCE]: {
backTo: Routes;
};
5 changes: 5 additions & 0 deletions src/libs/actions/Policy.ts
Original file line number Diff line number Diff line change
@@ -729,6 +729,10 @@ function clearQBOErrorField(policyID: string, fieldName: string) {
Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {connections: {quickbooksOnline: {config: {errorFields: {[fieldName]: null}}}}});
}

function clearXeroErrorField(policyID: string, fieldName: string) {
Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {connections: {xero: {config: {errorFields: {[fieldName]: null}}}}});
}

function setWorkspaceReimbursement(policyID: string, reimbursementChoice: ValueOf<typeof CONST.POLICY.REIMBURSEMENT_CHOICES>, reimburserEmail: string) {
const policy = getPolicy(policyID);

@@ -5148,6 +5152,7 @@ export {
renamePolicyTag,
clearPolicyTagErrors,
clearQBOErrorField,
clearXeroErrorField,
clearWorkspaceReimbursementErrors,
deleteWorkspaceCategories,
deletePolicyTags,
2 changes: 1 addition & 1 deletion src/pages/workspace/accounting/PolicyAccountingPage.tsx
Original file line number Diff line number Diff line change
@@ -93,7 +93,7 @@ function accountingIntegrationData(
),
onImportPagePress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_IMPORT.getRoute(policyID)),
onExportPagePress: () => {},
onAdvancedPagePress: () => {},
onAdvancedPagePress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_ADVANCED.getRoute(policyID)),
};
default:
return undefined;
104 changes: 104 additions & 0 deletions src/pages/workspace/accounting/xero/advanced/XeroAdvancedPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import React from 'react';
import ConnectionLayout from '@components/ConnectionLayout';
import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as Connections from '@libs/actions/connections';
import * as ErrorUtils from '@libs/ErrorUtils';
import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections';
import withPolicyConnections from '@pages/workspace/withPolicyConnections';
import ToggleSettingOptionRow from '@pages/workspace/workflows/ToggleSettingsOptionRow';
import * as Policy from '@userActions/Policy';
import CONST from '@src/CONST';

function XeroAdvancedPage({policy}: WithPolicyConnectionsProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();

const policyID = policy?.id ?? '';
const xeroConfig = policy?.connections?.xero?.config;
const {autoSync, pendingFields, sync} = xeroConfig ?? {};
const xeroData = policy?.connections?.xero?.data;

return (
<ConnectionLayout
displayName={XeroAdvancedPage.displayName}
headerTitle="workspace.xero.advancedConfig.advanced"
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]}
policyID={policyID}
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
>
<ToggleSettingOptionRow
key={translate('workspace.xero.advancedConfig.autoSync')}
title={translate('workspace.xero.advancedConfig.autoSync')}
subtitle={translate('workspace.xero.advancedConfig.autoSyncDescription')}
shouldPlaceSubtitleBelowSwitch
wrapperStyle={styles.mv3}
isActive={Boolean(autoSync?.enabled)}
onToggle={() =>
Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.XERO, CONST.XERO_CONFIG.AUTO_SYNC, {
enabled: !autoSync?.enabled,
})
}
pendingAction={pendingFields?.autoSync}
errors={ErrorUtils.getLatestErrorField(xeroConfig ?? {}, CONST.XERO_CONFIG.AUTO_SYNC)}
onCloseError={() => Policy.clearXeroErrorField(policyID, CONST.XERO_CONFIG.AUTO_SYNC)}
/>
<OfflineWithFeedback pendingAction={pendingFields?.export}>
<MenuItemWithTopDescription
shouldShowRightIcon
title={xeroConfig?.export.billStatus.purchase}
description={translate('workspace.xero.advancedConfig.purchaseBillStatusTitle')}
key={translate('workspace.xero.advancedConfig.purchaseBillStatusTitle')}
wrapperStyle={[styles.sectionMenuItemTopDescription]}
onPress={() => {}}
/>
</OfflineWithFeedback>
<ToggleSettingOptionRow
key={translate('workspace.xero.advancedConfig.reimbursedReports')}
title={translate('workspace.xero.advancedConfig.reimbursedReports')}
subtitle={translate('workspace.xero.advancedConfig.reimbursedReportsDescription')}
shouldPlaceSubtitleBelowSwitch
wrapperStyle={styles.mv3}
isActive={Boolean(sync?.syncReimbursedReports)}
onToggle={() =>
Connections.updatePolicyConnectionConfig(policyID, CONST.POLICY.CONNECTIONS.NAME.XERO, CONST.XERO_CONFIG.SYNC, {
syncReimbursedReports: !sync?.syncReimbursedReports,
})
}
pendingAction={pendingFields?.sync}
errors={ErrorUtils.getLatestErrorField(xeroConfig ?? {}, CONST.XERO_CONFIG.SYNC)}
onCloseError={() => Policy.clearXeroErrorField(policyID, CONST.XERO_CONFIG.SYNC)}
/>
{sync?.syncReimbursedReports && (
<>
<OfflineWithFeedback pendingAction={pendingFields?.sync}>
<MenuItemWithTopDescription
shouldShowRightIcon
title={String(xeroData?.bankAccounts)}
description={translate('workspace.xero.advancedConfig.xeroBillPaymentAccount')}
key={translate('workspace.xero.advancedConfig.xeroBillPaymentAccount')}
wrapperStyle={[styles.sectionMenuItemTopDescription]}
onPress={() => {}}
/>
</OfflineWithFeedback>
<OfflineWithFeedback pendingAction={pendingFields?.sync}>
<MenuItemWithTopDescription
shouldShowRightIcon
title={String(xeroData?.bankAccounts)}
description={translate('workspace.xero.advancedConfig.xeroInvoiceCollectionAccount')}
key={translate('workspace.xero.advancedConfig.xeroInvoiceCollectionAccount')}
wrapperStyle={[styles.sectionMenuItemTopDescription]}
onPress={() => {}}
/>
</OfflineWithFeedback>
</>
)}
</ConnectionLayout>
);
}

XeroAdvancedPage.displayName = 'XeroAdvancedPage';

export default withPolicyConnections(XeroAdvancedPage);

0 comments on commit 0ae357e

Please sign in to comment.