Skip to content

Commit

Permalink
Merge pull request #11 from software-mansion-labs/filip-solecki/XeroI…
Browse files Browse the repository at this point in the history
…mportPage

Filip solecki/xero import page
  • Loading branch information
rushatgabhane authored May 1, 2024
2 parents 5f50430 + 942e81d commit 1f1b126
Show file tree
Hide file tree
Showing 19 changed files with 352 additions and 29 deletions.
8 changes: 8 additions & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,14 @@ const ROUTES = {
route: 'r/:reportID/transaction/:transactionID/receipt',
getRoute: (reportID: string, transactionID: string) => `r/${reportID}/transaction/${transactionID}/receipt` as const,
},
POLICY_ACCOUNTING_XERO_IMPORT: {
route: 'settings/workspaces/:policyID/accounting/xero/import',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/xero/import` as const,
},
POLICY_ACCOUNTING_XERO_ORGANIZATION: {
route: 'settings/workspaces/:policyID/accounting/xero/organization/:currentOrganizationID',
getRoute: (policyID: string, currentOrganizationID: string) => `settings/workspaces/${policyID}/accounting/xero/organization/${currentOrganizationID}` 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,
Expand Down
2 changes: 2 additions & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ const SCREENS = {
QUICKBOOKS_ONLINE_ADVANCED: 'Policy_Accounting_Quickbooks_Online_Advanced',
QUICKBOOKS_ONLINE_ACCOUNT_SELECTOR: 'Policy_Accounting_Quickbooks_Online_Account_Selector',
QUICKBOOKS_ONLINE_INVOICE_ACCOUNT_SELECTOR: 'Policy_Accounting_Quickbooks_Online_Invoice_Account_Selector',
XERO_IMPORT: 'Policy_Accounting_Xero_Import',
XERO_ORGANIZATION: 'Policy_Accounting_Xero_Customers',
},
INITIAL: 'Workspace_Initial',
PROFILE: 'Workspace_Profile',
Expand Down
16 changes: 11 additions & 5 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1883,17 +1883,12 @@ export default {
`You have been invited to ${workspaceName || 'a workspace'}! Download the Expensify mobile app at use.expensify.com/download to start tracking your expenses.`,
},
qbo: {
import: 'Import',
importDescription: 'Choose which coding configurations are imported from QuickBooks Online to Expensify.',
classes: 'Classes',
accounts: 'Chart of accounts',
locations: 'Locations',
taxes: 'Taxes',
customers: 'Customers/Projects',
imported: 'Imported',
displayedAs: 'Displayed as',
notImported: 'Not imported',
importedAsTags: 'Imported, displayed as tags',
importedAsReportFields: 'Imported, displayed as report fields',
accountsDescription: 'Chart of Accounts import as categories when connected to an accounting integration, this cannot be disabled.',
accountsSwitchTitle: 'Enable newly imported Chart of Accounts.',
Expand Down Expand Up @@ -1993,6 +1988,13 @@ export default {
'If you are exporting invoices from Expensify to Quickbooks Online, this is the account the invoice will appear against once marked as paid.',
},
},
xero: {
organization: 'Xero organization',
organizationDescription: 'Select the organization in Xero you are importing data from.',
importDescription: 'Choose which coding configurations are imported from Xero to Expensify.',
trackingCategories: 'Tracking categories',
customers: 'Re-bill customers',
},
type: {
free: 'Free',
control: 'Control',
Expand Down Expand Up @@ -2221,6 +2223,10 @@ export default {
}
}
},
accounts: 'Chart of accounts',
taxes: 'Taxes',
imported: 'Imported',
importedAsTags: 'Imported, displayed as tags',
disconnectPrompt: (integrationToConnect?: ConnectionName, currentIntegration?: ConnectionName): string => {
switch (integrationToConnect) {
case CONST.POLICY.CONNECTIONS.NAME.QBO:
Expand Down
16 changes: 11 additions & 5 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1907,17 +1907,12 @@ export default {
`¡Has sido invitado a ${workspaceName}! Descargue la aplicación móvil Expensify en use.expensify.com/download para comenzar a rastrear sus gastos.`,
},
qbo: {
import: 'Importación',
importDescription: 'Elige que configuraciónes de codificación son importadas desde QuickBooks Online a Expensify.',
classes: 'Clases',
accounts: 'Plan de cuentas',
locations: 'Lugares',
taxes: 'Impuestos',
customers: 'Clientes/Proyectos',
imported: 'Importado',
displayedAs: 'Mostrado como',
notImported: 'No importado',
importedAsTags: 'Importado, mostrado como etiqueta',
importedAsReportFields: 'Importado, mostrado como campo de informe',
accountsDescription: 'Los planes de cuentas se importan como categorías cuando está conectado con una integración de contaduría, esto no se puede desactivar.',
accountsSwitchTitle: 'Habilita el plan de cuentas recien importado',
Expand Down Expand Up @@ -2020,6 +2015,13 @@ export default {
'Si está exportando facturas de Expensify a Quickbooks Online, ésta es la cuenta en la que aparecerá la factura una vez marcada como pagada.',
},
},
xero: {
organization: 'Organización Xero',
organizationDescription: 'Seleccione la organización en Xero desde la que está importando los datos.',
importDescription: 'Elija qué configuraciones de codificación se importan de Xero a Expensify.',
trackingCategories: 'Categorías de seguimiento',
customers: 'Volver a facturar a los clientes',
},
type: {
free: 'Gratis',
control: 'Control',
Expand Down Expand Up @@ -2216,6 +2218,10 @@ export default {
}
}
},
accounts: 'Plan de cuentas',
taxes: 'Impuestos',
imported: 'Importado',
importedAsTags: 'Importado, mostrado como etiqueta',
disconnectPrompt: (integrationToConnect?: ConnectionName, currentIntegration?: ConnectionName): string => {
switch (integrationToConnect) {
case CONST.POLICY.CONNECTIONS.NAME.QBO:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,9 @@ const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorP
require('../../../../pages/workspace/accounting/qbo/advanced/QuickbooksAccountSelectPage').default as React.ComponentType,
[SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_INVOICE_ACCOUNT_SELECTOR]: () =>
require('../../../../pages/workspace/accounting/qbo/advanced/QuickbooksInvoiceAccountSelectPage').default as React.ComponentType,

[SCREENS.WORKSPACE.ACCOUNTING.XERO_IMPORT]: () => require('../../../../pages/workspace/accounting/xero/XeroImportPage').default as React.ComponentType,
[SCREENS.WORKSPACE.ACCOUNTING.XERO_ORGANIZATION]: () => require('../../../../pages/workspace/accounting/xero/XeroOrganizationConfigurationPage').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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial<Record<FullScreenName, string[]>> = {
SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_ADVANCED,
SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_ACCOUNT_SELECTOR,
SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_INVOICE_ACCOUNT_SELECTOR,
SCREENS.WORKSPACE.ACCOUNTING.XERO_IMPORT,
SCREENS.WORKSPACE.ACCOUNTING.XERO_ORGANIZATION,
],
[SCREENS.WORKSPACE.TAXES]: [
SCREENS.WORKSPACE.TAXES_SETTINGS,
Expand Down
2 changes: 2 additions & 0 deletions src/libs/Navigation/linkingConfig/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,8 @@ const config: LinkingOptions<RootStackParamList>['config'] = {
[SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_INVOICE_ACCOUNT_SELECTOR]: {
path: ROUTES.WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_INVOICE_ACCOUNT_SELECTOR.route,
},
[SCREENS.WORKSPACE.ACCOUNTING.XERO_IMPORT]: {path: ROUTES.POLICY_ACCOUNTING_XERO_IMPORT.route},
[SCREENS.WORKSPACE.ACCOUNTING.XERO_ORGANIZATION]: {path: ROUTES.POLICY_ACCOUNTING_XERO_ORGANIZATION.route},
[SCREENS.WORKSPACE.DESCRIPTION]: {
path: ROUTES.WORKSPACE_PROFILE_DESCRIPTION.route,
},
Expand Down
7 changes: 7 additions & 0 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,13 @@ type SettingsNavigatorParamList = {
[SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_EXPORT_PREFERRED_EXPORTER]: {
policyID: string;
};
[SCREENS.WORKSPACE.ACCOUNTING.XERO_IMPORT]: {
policyID: string;
};
[SCREENS.WORKSPACE.ACCOUNTING.XERO_ORGANIZATION]: {
policyID: string;
organizationID: string;
};
[SCREENS.GET_ASSISTANCE]: {
backTo: Routes;
};
Expand Down
5 changes: 3 additions & 2 deletions src/pages/workspace/WorkspaceMoreFeaturesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import CONST from '@src/CONST';
import type {TranslationPaths} from '@src/languages/types';
import type SCREENS from '@src/SCREENS';
import type {PendingAction} from '@src/types/onyx/OnyxCommon';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
import type IconAsset from '@src/types/utils/IconAsset';
import AccessOrNotFoundWrapper from './AccessOrNotFoundWrapper';
import type {WithPolicyAndFullscreenLoadingProps} from './withPolicyAndFullscreenLoading';
Expand Down Expand Up @@ -47,8 +48,8 @@ function WorkspaceMoreFeaturesPage({policy, route}: WorkspaceMoreFeaturesPagePro
const {isSmallScreenWidth} = useWindowDimensions();
const {translate} = useLocalize();
const {canUseAccountingIntegrations} = usePermissions();
const hasAccountingConnection = !!policy?.areConnectionsEnabled && !!policy?.connections;
const isSyncTaxEnabled = !!policy?.connections?.quickbooksOnline?.config?.syncTax;
const hasAccountingConnection = !!policy?.areConnectionsEnabled && !isEmptyObject(policy?.connections);
const isSyncTaxEnabled = !!policy?.connections?.quickbooksOnline?.config.syncTax || !!policy?.connections?.xero?.config.importTaxRates;

const spendItems: Item[] = [
{
Expand Down
37 changes: 35 additions & 2 deletions src/pages/workspace/accounting/PolicyAccountingPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type {Policy, PolicyConnectionSyncProgress} from '@src/types/onyx';
import type {PolicyConnectionName} from '@src/types/onyx/Policy';
import type {PolicyConnectionName, Tenant} from '@src/types/onyx/Policy';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
import type IconAsset from '@src/types/utils/IconAsset';

Expand Down Expand Up @@ -91,7 +91,7 @@ function accountingIntegrationData(
integrationToDisconnect={integrationToDisconnect}
/>
),
onImportPagePress: () => {},
onImportPagePress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_IMPORT.getRoute(policyID)),
onExportPagePress: () => {},
onAdvancedPagePress: () => {},
};
Expand All @@ -114,6 +114,18 @@ function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccounting
const connectedIntegration = accountingIntegrations.find((integration) => !!policy?.connections?.[integration]) ?? connectionSyncProgress?.connectionName;
const policyID = policy?.id ?? '';

const policyConnectedToXero = connectedIntegration === CONST.POLICY.CONNECTIONS.NAME.XERO;

const tenants = useMemo<Tenant[]>(() => {
// Due to the way optional chain is being handled in this useMemo we are forced to use this approach to properly handle undefined values
// eslint-disable-next-line @typescript-eslint/prefer-optional-chain
if (!policy || !policy.connections || !policy.connections.xero || !policy.connections.xero.data) {
return [];
}
return policy?.connections?.xero?.data?.tenants ?? [];
}, [policy]);
const currentXeroOrganization = tenants.find((tenant) => tenant.id === policy?.connections?.xero.config.tenantID);

const overflowMenu: ThreeDotsMenuProps['menuItems'] = useMemo(
() => [
{
Expand Down Expand Up @@ -185,6 +197,24 @@ function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccounting
</View>
),
},
...(policyConnectedToXero
? [
{
description: translate('workspace.xero.organization'),
iconRight: Expensicons.ArrowRight,
title: currentXeroOrganization?.name,
wrapperStyle: [styles.sectionMenuItemTopDescription],
shouldShowRightIcon: tenants.length > 1,
shouldShowDescriptionOnTop: true,
onPress: () => {
if (!(tenants.length > 1)) {
return;
}
Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_ORGANIZATION.getRoute(policyID, currentXeroOrganization?.id ?? ''));
},
},
]
: []),
...(isEmptyObject(policy?.connections)
? []
: [
Expand Down Expand Up @@ -217,9 +247,12 @@ function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccounting
}, [
connectedIntegration,
connectionSyncProgress?.stageInProgress,
currentXeroOrganization,
tenants,
isSyncInProgress,
overflowMenu,
policy?.connections,
policyConnectedToXero,
policyID,
styles,
theme.spinner,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function QuickbooksChartOfAccountsPage({policy}: WithPolicyProps) {
shouldEnableMaxHeight
testID={QuickbooksChartOfAccountsPage.displayName}
>
<HeaderWithBackButton title={translate('workspace.qbo.accounts')} />
<HeaderWithBackButton title={translate('workspace.accounting.accounts')} />
<ScrollView contentContainerStyle={[styles.pb2, styles.ph5]}>
<Text style={styles.pb5}>{translate('workspace.qbo.accountsDescription')}</Text>
<View style={[styles.flexRow, styles.mb2, styles.alignItemsCenter, styles.justifyContentBetween]}>
Expand All @@ -43,7 +43,7 @@ function QuickbooksChartOfAccountsPage({policy}: WithPolicyProps) {
<OfflineWithFeedback pendingAction={pendingFields?.enableNewCategories}>
<View style={[styles.flex1, styles.alignItemsEnd, styles.pl3]}>
<Switch
accessibilityLabel={translate('workspace.qbo.accounts')}
accessibilityLabel={translate('workspace.accounting.accounts')}
isOn={isSwitchOn}
onToggle={() =>
Connections.updatePolicyConnectionConfig(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ function QuickbooksClassesPage({policy}: WithPolicyProps) {
<Text style={styles.pb5}>{translate('workspace.qbo.classesDescription')}</Text>
<View style={[styles.flexRow, styles.mb4, styles.alignItemsCenter, styles.justifyContentBetween]}>
<View style={styles.flex1}>
<Text fontSize={variables.fontSizeNormal}>{translate('workspace.qbo.import')}</Text>
<Text fontSize={variables.fontSizeNormal}>{translate('workspace.accounting.import')}</Text>
</View>
<OfflineWithFeedback pendingAction={pendingFields?.syncClasses}>
<View style={[styles.flex1, styles.alignItemsEnd, styles.pl3]}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ function QuickbooksCustomersPage({policy}: WithPolicyProps) {
<Text style={styles.pb5}>{translate('workspace.qbo.customersDescription')}</Text>
<View style={[styles.flexRow, styles.mb4, styles.alignItemsCenter, styles.justifyContentBetween]}>
<View style={styles.flex1}>
<Text fontSize={variables.fontSizeNormal}>{translate('workspace.qbo.import')}</Text>
<Text fontSize={variables.fontSizeNormal}>{translate('workspace.accounting.import')}</Text>
</View>
<OfflineWithFeedback pendingAction={pendingFields?.syncCustomers}>
<View style={[styles.flex1, styles.alignItemsEnd, styles.pl3]}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@ function QuickbooksImportPage({policy}: WithPolicyProps) {
const {translate} = useLocalize();
const styles = useThemeStyles();
const quickbooksOnlineConfigTitles = {
[CONST.INTEGRATION_ENTITY_MAP_TYPES.DEFAULT]: translate('workspace.qbo.imported'),
[CONST.INTEGRATION_ENTITY_MAP_TYPES.IMPORTED]: translate('workspace.qbo.imported'),
[CONST.INTEGRATION_ENTITY_MAP_TYPES.DEFAULT]: translate('workspace.accounting.imported'),
[CONST.INTEGRATION_ENTITY_MAP_TYPES.IMPORTED]: translate('workspace.accounting.imported'),
[CONST.INTEGRATION_ENTITY_MAP_TYPES.NOT_IMPORTED]: translate('workspace.qbo.notImported'),
[CONST.INTEGRATION_ENTITY_MAP_TYPES.NONE]: translate('workspace.qbo.notImported'),
[CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG]: translate('workspace.qbo.importedAsTags'),
[CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG]: translate('workspace.accounting.importedAsTags'),
[CONST.INTEGRATION_ENTITY_MAP_TYPES.REPORT_FIELD]: translate('workspace.qbo.importedAsReportFields'),
};
const policyID = policy?.id ?? '';
const {syncClasses, syncCustomers, syncLocations, syncTaxes, enableNewCategories, pendingFields} = policy?.connections?.quickbooksOnline?.config ?? {};

const sections = [
{
description: translate('workspace.qbo.accounts'),
description: translate('workspace.accounting.accounts'),
action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_CHART_OF_ACCOUNTS.getRoute(policyID)),
hasError: Boolean(policy?.errors?.enableNewCategories),
title: enableNewCategories,
Expand Down Expand Up @@ -61,7 +61,7 @@ function QuickbooksImportPage({policy}: WithPolicyProps) {

if (policy?.connections?.quickbooksOnline.data.country !== CONST.COUNTRY.US) {
sections.push({
description: translate('workspace.qbo.taxes'),
description: translate('workspace.accounting.taxes'),
action: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_TAXES.getRoute(policyID)),
hasError: Boolean(policy?.errors?.syncTaxes),
title: syncTaxes,
Expand All @@ -80,7 +80,7 @@ function QuickbooksImportPage({policy}: WithPolicyProps) {
shouldEnableMaxHeight
testID={QuickbooksImportPage.displayName}
>
<HeaderWithBackButton title={translate('workspace.qbo.import')} />
<HeaderWithBackButton title={translate('workspace.accounting.import')} />
<ScrollView contentContainerStyle={styles.pb2}>
<Text style={[styles.ph5, styles.pb5]}>{translate('workspace.qbo.importDescription')}</Text>
{sections.map((section) => (
Expand Down
Loading

0 comments on commit 1f1b126

Please sign in to comment.