diff --git a/src/CONST.ts b/src/CONST.ts index a3df980ff5dd..d5680ce34b6f 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -1580,6 +1580,7 @@ const CONST = { TRACKING_CATEGORY_OPTIONS: { DEFAULT: 'DEFAULT', TAG: 'TAG', + REPORT_FIELD: 'REPORT_FIELD', }, }, @@ -1632,6 +1633,12 @@ const CONST = { JOURNAL_ENTRY: 'journal_entry', }, + QUICKBOOKS_NON_REIMBURSABLE_ACCOUNT_TYPE: { + CREDIT_CARD: 'credit_card', + DEBIT_CARD: 'debit_card', + VENDOR_BILL: 'bill', + }, + QUICKBOOKS_DESKTOP_REIMBURSABLE_ACCOUNT_TYPE: { VENDOR_BILL: 'VENDOR_BILL', CHECK: 'CHECK', diff --git a/src/ROUTES.ts b/src/ROUTES.ts index e6984d6c757b..c346da6cadcb 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -1450,14 +1450,26 @@ const ROUTES = { route: 'settings/workspaces/:policyID/accounting/quickbooks-online/import/classes', getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/quickbooks-online/import/classes` as const, }, + POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_CLASSES_DISPLAYED_AS: { + route: 'settings/workspaces/:policyID/accounting/quickbooks-online/import/classes/displayed-as', + getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/quickbooks-online/import/classes/displayed-as` as const, + }, POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_CUSTOMERS: { route: 'settings/workspaces/:policyID/accounting/quickbooks-online/import/customers', getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/quickbooks-online/import/customers` as const, }, + POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_CUSTOMERS_DISPLAYED_AS: { + route: 'settings/workspaces/:policyID/accounting/quickbooks-online/import/customers/displayed-as', + getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/quickbooks-online/import/customers/displayed-as` as const, + }, POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_LOCATIONS: { route: 'settings/workspaces/:policyID/accounting/quickbooks-online/import/locations', getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/quickbooks-online/import/locations` as const, }, + POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_LOCATIONS_DISPLAYED_AS: { + route: 'settings/workspaces/:policyID/accounting/quickbooks-online/import/locations/displayed-as', + getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/quickbooks-online/import/locations/displayed-as` as const, + }, POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_TAXES: { route: 'settings/workspaces/:policyID/accounting/quickbooks-online/import/taxes', getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/quickbooks-online/import/taxes` as const, diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 7f04b861dec5..2e44c5ed5695 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -332,6 +332,9 @@ 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', + QUICKBOOKS_ONLINE_CLASSES_DISPLAYED_AS: 'Policy_Accounting_Quickbooks_Online_Import_Classes_Displayed_As', + QUICKBOOKS_ONLINE_CUSTOMERS_DISPLAYED_AS: 'Policy_Accounting_Quickbooks_Online_Import_Customers_Displayed_As', + QUICKBOOKS_ONLINE_LOCATIONS_DISPLAYED_AS: 'Policy_Accounting_Quickbooks_Online_Import_Locations_Displayed_As', QUICKBOOKS_DESKTOP_COMPANY_CARD_EXPENSE_ACCOUNT_SELECT: 'Workspace_Accounting_Quickbooks_Desktop_Export_Company_Card_Expense_Account_Select', QUICKBOOKS_DESKTOP_COMPANY_CARD_EXPENSE_ACCOUNT_COMPANY_CARD_SELECT: 'Workspace_Accounting_Quickbooks_Desktop_Export_Company_Card_Expense_Select', QUICKBOOKS_DESKTOP_COMPANY_CARD_EXPENSE_ACCOUNT: 'Workspace_Accounting_Quickbooks_Desktop_Export_Company_Card_Expense', diff --git a/src/languages/en.ts b/src/languages/en.ts index d32d52ca5688..5daecbc98e5f 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2431,12 +2431,9 @@ const translations = { "We'll create an itemized vendor bill for each Expensify report and add it to the account below. If this period is closed, we'll post to the 1st of the next open period.", deepDiveExpensifyCard: 'Expensify Card transactions will automatically export to an "Expensify Card Liability Account" created with', deepDiveExpensifyCardIntegration: 'our integration.', - outOfPocketLocationEnabledDescription: - 'QuickBooks Desktop doesn’t support locations on vendor bills or checks. As you have locations enabled on your workspace, these export options are unavailable.', outOfPocketTaxEnabledDescription: "QuickBooks Desktop doesn't support taxes on journal entry exports. As you have taxes enabled on your workspace, this export option is unavailable.", outOfPocketTaxEnabledError: 'Journal entries are unavailable when taxes are enabled. Please choose a different export option.', - outOfPocketLocationEnabledError: 'Vendor bills are unavailable when locations are enabled. Please choose a different export option.', accounts: { [CONST.QUICKBOOKS_DESKTOP_NON_REIMBURSABLE_EXPORT_ACCOUNT_TYPE.CREDIT_CARD]: 'Credit card', [CONST.QUICKBOOKS_DESKTOP_REIMBURSABLE_ACCOUNT_TYPE.VENDOR_BILL]: 'Vendor bill', @@ -2504,10 +2501,8 @@ const translations = { customersDescription: 'Choose how to handle QuickBooks Online customers/projects in Expensify.', locationsDescription: 'Choose how to handle QuickBooks Online locations in Expensify.', taxesDescription: 'Choose how to handle QuickBooks Online taxes in Expensify.', - locationsAdditionalDescription: - 'QuickBooks Online doesn’t support locations on vendor bills or checks. As you have locations enabled on your workspace, these export options are unavailable.', - outOfPocketLocationEnabledDescription: - 'QuickBooks Online doesn’t support locations on vendor bills or checks. As you have locations enabled on your workspace, these export options are unavailable.', + locationsLineItemsRestrictionDescription: + "QuickBooks Online does not support Locations at the line-level for Checks or Vendor Bills. If you'd like to have locations at the line-level, make sure you are using Journal Entries and Credit/Debit Card expenses.", taxesJournalEntrySwitchNote: "QuickBooks Online doesn't support taxes on journal entries. Please change your export option to vendor bill or check.", exportDescription: 'Configure how Expensify data exports to QuickBooks Online.', date: 'Export date', @@ -2557,7 +2552,6 @@ const translations = { outOfPocketTaxEnabledDescription: "QuickBooks Online doesn't support taxes on journal entry exports. As you have taxes enabled on your workspace, this export option is unavailable.", outOfPocketTaxEnabledError: 'Journal entries are unavailable when taxes are enabled. Please choose a different export option.', - outOfPocketLocationEnabledError: 'Vendor bills are unavailable when locations are enabled. Please choose a different export option.', advancedConfig: { autoSyncDescription: 'Expensify will automatically sync with QuickBooks Online every day.', inviteEmployees: 'Invite employees', @@ -2612,8 +2606,9 @@ const translations = { notImported: 'Not imported', notConfigured: 'Not configured', trackingCategoriesOptions: { - default: 'Xero contact default', - tag: 'Tags', + [CONST.XERO_CONFIG.TRACKING_CATEGORY_OPTIONS.DEFAULT]: 'Xero contact default', + [CONST.XERO_CONFIG.TRACKING_CATEGORY_OPTIONS.TAG]: 'Tags', + [CONST.XERO_CONFIG.TRACKING_CATEGORY_OPTIONS.REPORT_FIELD]: 'Report fields', }, exportDescription: 'Configure how Expensify data exports to Xero.', purchaseBill: 'Purchase bill', diff --git a/src/languages/es.ts b/src/languages/es.ts index b7725389e18f..c38e9052bd60 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2454,12 +2454,9 @@ const translations = { 'Crearemos una factura de proveedor desglosada para cada informe de Expensify y la añadiremos a la cuenta a continuación. Si este periodo está cerrado, lo contabilizaremos el 1º del siguiente periodo abierto.', deepDiveExpensifyCard: 'Las transacciones de la Tarjeta Expensify se exportarán automáticamente a una "Cuenta de Responsabilidad de la Tarjeta Expensify" creada con', deepDiveExpensifyCardIntegration: 'nuestra integración.', - outOfPocketLocationEnabledDescription: - 'QuickBooks Desktop no permite lugares en facturas de proveedores o cheques. Como tienes activadas los lugares en tu espacio de trabajo, estas opciones de exportación no están disponibles.', outOfPocketTaxEnabledDescription: 'QuickBooks Desktop no admite impuestos en las exportaciones de asientos contables. Como tienes impuestos habilitados en tu espacio de trabajo, esta opción de exportación no está disponible.', outOfPocketTaxEnabledError: 'Los asientos contables no están disponibles cuando los impuestos están habilitados. Por favor, selecciona otra opción de exportación.', - outOfPocketLocationEnabledError: 'Las facturas de proveedores no están disponibles cuando las ubicaciones están habilitadas. Por favor, selecciona otra opción de exportación.', accounts: { [CONST.QUICKBOOKS_DESKTOP_NON_REIMBURSABLE_EXPORT_ACCOUNT_TYPE.CREDIT_CARD]: 'Tarjeta de crédito', [CONST.QUICKBOOKS_DESKTOP_REIMBURSABLE_ACCOUNT_TYPE.VENDOR_BILL]: 'Factura del proveedor', @@ -2528,10 +2525,10 @@ const translations = { classesDescription: 'Elige cómo gestionar las clases de QuickBooks Online en Expensify.', customersDescription: 'Elige cómo gestionar los clientes/proyectos de QuickBooks Online en Expensify.', locationsDescription: 'Elige cómo gestionar los lugares de QuickBooks Online en Expensify.', + locationsLineItemsRestrictionDescription: + 'QuickBooks Online no admite Ubicaciones a nivel de línea para cheques o facturas de proveedores. Si deseas tener ubicaciones a nivel de línea, asegúrate de estar usando asientos contables y gastos con tarjetas de crédito/débito.', taxesDescription: 'Elige cómo gestionar los impuestos de QuickBooks Online en Expensify.', taxesJournalEntrySwitchNote: 'QuickBooks Online no permite impuestos en los asientos contables. Por favor, cambia la opción de exportación a factura de proveedor o cheque.', - locationsAdditionalDescription: - 'QuickBooks Online no permite lugares en facturas de proveedores o cheques. Como tienes activadas los lugares en tu espacio de trabajo, estas opciones de exportación no están disponibles.', exportInvoices: 'Exportar facturas a', exportDescription: 'Configura cómo se exportan los datos de Expensify a QuickBooks Online.', date: 'Fecha de exportación', @@ -2580,10 +2577,6 @@ const translations = { outOfPocketTaxEnabledDescription: 'QuickBooks Online no permite impuestos en las exportaciones de entradas a los asientos contables. Como tienes los impuestos activados en tu espacio de trabajo, esta opción de exportación no está disponible.', outOfPocketTaxEnabledError: 'La anotacion en el diario no está disponible cuando los impuestos están activados. Por favor, selecciona otra opción de exportación diferente.', - outOfPocketLocationEnabledError: - 'Las facturas de proveedores no están disponibles cuando las ubicaciones están activadas. Por favor, selecciona otra opción de exportación diferente.', - outOfPocketLocationEnabledDescription: - 'QuickBooks Online no permite lugares en facturas de proveedores o cheques. Como tienes activadas los lugares en tu espacio de trabajo, estas opciones de exportación no están disponibles.', advancedConfig: { autoSyncDescription: 'Expensify se sincronizará automáticamente con QuickBooks Online todos los días.', @@ -2644,8 +2637,9 @@ const translations = { notImported: 'No importado', notConfigured: 'No configurado', trackingCategoriesOptions: { - default: 'Contacto de Xero por defecto', - tag: 'Etiquetas', + [CONST.XERO_CONFIG.TRACKING_CATEGORY_OPTIONS.DEFAULT]: 'Contacto de Xero por defecto', + [CONST.XERO_CONFIG.TRACKING_CATEGORY_OPTIONS.TAG]: 'Etiquetas', + [CONST.XERO_CONFIG.TRACKING_CATEGORY_OPTIONS.REPORT_FIELD]: 'Campos de informes', }, exportDescription: 'Configura cómo se exportan los datos de Expensify a Xero.', purchaseBill: 'Factura de compra', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 2ee1f7d19be9..35f67e0253c6 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -381,6 +381,12 @@ const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorP [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_TAXES]: () => require<ReactComponentModule>('../../../../pages/workspace/accounting/qbo/import/QuickbooksTaxesPage').default, [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_LOCATIONS]: () => require<ReactComponentModule>('../../../../pages/workspace/accounting/qbo/import/QuickbooksLocationsPage').default, [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_CLASSES]: () => require<ReactComponentModule>('../../../../pages/workspace/accounting/qbo/import/QuickbooksClassesPage').default, + [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_CLASSES_DISPLAYED_AS]: () => + require<ReactComponentModule>('../../../../pages/workspace/accounting/qbo/import/QuickbooksClassesDisplayedAsPage').default, + [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_CUSTOMERS_DISPLAYED_AS]: () => + require<ReactComponentModule>('../../../../pages/workspace/accounting/qbo/import/QuickbooksCustomersDisplayedAsPage').default, + [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_LOCATIONS_DISPLAYED_AS]: () => + require<ReactComponentModule>('../../../../pages/workspace/accounting/qbo/import/QuickbooksLocationsDisplayedAsPage').default, [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_ADVANCED]: () => require<ReactComponentModule>('../../../../pages/workspace/accounting/qbo/advanced/QuickbooksAdvancedPage').default, [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_ACCOUNT_SELECTOR]: () => require<ReactComponentModule>('../../../../pages/workspace/accounting/qbo/advanced/QuickbooksAccountSelectPage').default, diff --git a/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts b/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts index 39fa05cf87d4..60cb6f53f697 100755 --- a/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts +++ b/src/libs/Navigation/linkingConfig/FULL_SCREEN_TO_RHP_MAPPING.ts @@ -45,6 +45,9 @@ 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.QUICKBOOKS_ONLINE_CLASSES_DISPLAYED_AS, + SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_CUSTOMERS_DISPLAYED_AS, + SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_LOCATIONS_DISPLAYED_AS, SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_DESKTOP_COMPANY_CARD_EXPENSE_ACCOUNT_SELECT, SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_DESKTOP_COMPANY_CARD_EXPENSE_ACCOUNT_COMPANY_CARD_SELECT, SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_DESKTOP_COMPANY_CARD_EXPENSE_ACCOUNT, diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 39da189af13c..6f551d7cc41c 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -383,6 +383,15 @@ 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.QUICKBOOKS_ONLINE_CLASSES_DISPLAYED_AS]: { + path: ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_CLASSES_DISPLAYED_AS.route, + }, + [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_CUSTOMERS_DISPLAYED_AS]: { + path: ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_CUSTOMERS_DISPLAYED_AS.route, + }, + [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_LOCATIONS_DISPLAYED_AS]: { + path: ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_LOCATIONS_DISPLAYED_AS.route, + }, [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_DESKTOP_COMPANY_CARD_EXPENSE_ACCOUNT_SELECT]: { path: ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_DESKTOP_COMPANY_CARD_EXPENSE_ACCOUNT_SELECT.route, }, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 087df82c684f..3de07f2c801f 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -1455,6 +1455,15 @@ type FullScreenNavigatorParamList = { [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_INVOICE_ACCOUNT_SELECTOR]: { policyID: string; }; + [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_CLASSES_DISPLAYED_AS]: { + policyID: string; + }; + [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_CUSTOMERS_DISPLAYED_AS]: { + policyID: string; + }; + [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_LOCATIONS_DISPLAYED_AS]: { + policyID: string; + }; [SCREENS.WORKSPACE.EXPENSIFY_CARD]: { policyID: string; }; diff --git a/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseEntitySelectPage.tsx b/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseEntitySelectPage.tsx index 0fd977fb5b13..53114de806ea 100644 --- a/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseEntitySelectPage.tsx +++ b/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseEntitySelectPage.tsx @@ -18,18 +18,17 @@ import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import type {Account, QBOReimbursableExportAccountType} from '@src/types/onyx/Policy'; -function Footer({isTaxEnabled, isLocationsEnabled}: {isTaxEnabled: boolean; isLocationsEnabled: boolean}) { +function Footer({isTaxEnabled}: {isTaxEnabled: boolean}) { const styles = useThemeStyles(); const {translate} = useLocalize(); - if (!isTaxEnabled && !isLocationsEnabled) { + if (!isTaxEnabled) { return null; } return ( <View style={[styles.gap2, styles.mt2, styles.ph5]}> {isTaxEnabled && <Text style={styles.mutedNormalTextLabel}>{translate('workspace.qbo.outOfPocketTaxEnabledDescription')}</Text>} - {isLocationsEnabled && <Text style={styles.mutedNormalTextLabel}>{translate('workspace.qbo.outOfPocketLocationEnabledDescription')}</Text>} </View> ); } @@ -43,11 +42,9 @@ function QuickbooksOutOfPocketExpenseEntitySelectPage({policy}: WithPolicyConnec const styles = useThemeStyles(); const qboConfig = policy?.connections?.quickbooksOnline?.config; const {bankAccounts, accountPayable, journalEntryAccounts} = policy?.connections?.quickbooksOnline?.data ?? {}; - const isLocationsEnabled = !!(qboConfig?.syncLocations && qboConfig?.syncLocations !== CONST.INTEGRATION_ENTITY_MAP_TYPES.NONE); const isTaxesEnabled = !!qboConfig?.syncTax; const shouldShowTaxError = isTaxesEnabled && qboConfig?.reimbursableExpensesExportDestination === CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.JOURNAL_ENTRY; - const shouldShowLocationError = isLocationsEnabled && qboConfig?.reimbursableExpensesExportDestination !== CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.JOURNAL_ENTRY; - const hasErrors = !!qboConfig?.errorFields?.reimbursableExpensesExportDestination && (shouldShowTaxError || shouldShowLocationError); + const hasErrors = !!qboConfig?.errorFields?.reimbursableExpensesExportDestination && shouldShowTaxError; const policyID = policy?.id ?? '-1'; const data: MenuItem[] = useMemo( @@ -57,7 +54,7 @@ function QuickbooksOutOfPocketExpenseEntitySelectPage({policy}: WithPolicyConnec text: translate(`workspace.qbo.accounts.check`), keyForList: CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.CHECK, isSelected: qboConfig?.reimbursableExpensesExportDestination === CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.CHECK, - isShown: !isLocationsEnabled, + isShown: qboConfig?.syncLocations !== CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG, accounts: bankAccounts ?? [], }, { @@ -73,11 +70,11 @@ function QuickbooksOutOfPocketExpenseEntitySelectPage({policy}: WithPolicyConnec text: translate(`workspace.qbo.accounts.bill`), keyForList: CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.VENDOR_BILL, isSelected: qboConfig?.reimbursableExpensesExportDestination === CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.VENDOR_BILL, - isShown: !isLocationsEnabled, + isShown: qboConfig?.syncLocations !== CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG, accounts: accountPayable ?? [], }, ], - [qboConfig?.reimbursableExpensesExportDestination, isTaxesEnabled, translate, isLocationsEnabled, bankAccounts, accountPayable, journalEntryAccounts], + [qboConfig?.reimbursableExpensesExportDestination, qboConfig?.syncLocations, translate, bankAccounts, accountPayable, journalEntryAccounts, isTaxesEnabled], ); const sections = useMemo(() => [{data: data.filter((item) => item.isShown)}], [data]); @@ -128,12 +125,7 @@ function QuickbooksOutOfPocketExpenseEntitySelectPage({policy}: WithPolicyConnec } errorRowStyles={[styles.ph5, styles.pv3]} onClose={() => clearQBOErrorField(policyID, CONST.QUICKBOOKS_CONFIG.REIMBURSABLE_EXPENSES_EXPORT_DESTINATION)} - listFooterContent={ - <Footer - isTaxEnabled={isTaxesEnabled} - isLocationsEnabled={isLocationsEnabled} - /> - } + listFooterContent={<Footer isTaxEnabled={isTaxesEnabled} />} /> ); } diff --git a/src/pages/workspace/accounting/qbo/import/QuickbooksClassesDisplayedAsPage.tsx b/src/pages/workspace/accounting/qbo/import/QuickbooksClassesDisplayedAsPage.tsx new file mode 100644 index 000000000000..808fd924bbd0 --- /dev/null +++ b/src/pages/workspace/accounting/qbo/import/QuickbooksClassesDisplayedAsPage.tsx @@ -0,0 +1,79 @@ +import React, {useCallback, useMemo} from 'react'; +import RadioListItem from '@components/SelectionList/RadioListItem'; +import type {ListItem} from '@components/SelectionList/types'; +import SelectionScreen from '@components/SelectionScreen'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import * as QuickbooksOnline from '@libs/actions/connections/QuickbooksOnline'; +import * as ErrorUtils from '@libs/ErrorUtils'; +import Navigation from '@libs/Navigation/Navigation'; +import {settingsPendingAction} from '@libs/PolicyUtils'; +import type {WithPolicyProps} from '@pages/workspace/withPolicy'; +import withPolicyConnections from '@pages/workspace/withPolicyConnections'; +import {clearQBOErrorField} from '@userActions/Policy/Policy'; +import CONST from '@src/CONST'; +import ROUTES from '@src/ROUTES'; + +type CardListItem = ListItem & { + value: keyof typeof CONST.INTEGRATION_ENTITY_MAP_TYPES; +}; + +function QuickbooksClassesDisplayedAsPage({policy}: WithPolicyProps) { + const {translate} = useLocalize(); + const styles = useThemeStyles(); + const policyID = policy?.id ?? '-1'; + const qboConfig = policy?.connections?.quickbooksOnline?.config; + + const data: CardListItem[] = useMemo( + () => [ + { + value: CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG, + text: translate('workspace.common.tags'), + keyForList: CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG, + isSelected: qboConfig?.syncClasses === CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG, + }, + { + value: CONST.INTEGRATION_ENTITY_MAP_TYPES.REPORT_FIELD, + text: translate('workspace.common.reportFields'), + keyForList: CONST.INTEGRATION_ENTITY_MAP_TYPES.REPORT_FIELD, + isSelected: qboConfig?.syncClasses === CONST.INTEGRATION_ENTITY_MAP_TYPES.REPORT_FIELD, + }, + ], + [qboConfig?.syncClasses, translate], + ); + + const selectDisplayedAs = useCallback( + (row: CardListItem) => { + if (row.value !== qboConfig?.syncClasses) { + QuickbooksOnline.updateQuickbooksOnlineSyncClasses(policyID, row.value, qboConfig?.syncClasses); + } + Navigation.goBack(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_CLASSES.getRoute(policyID)); + }, + [qboConfig?.syncClasses, policyID], + ); + + return ( + <SelectionScreen + policyID={policyID} + accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN]} + featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED} + displayName={QuickbooksClassesDisplayedAsPage.displayName} + sections={data.length ? [{data}] : []} + listItem={RadioListItem} + onBackButtonPress={() => Navigation.goBack(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_CLASSES.getRoute(policyID))} + onSelectRow={selectDisplayedAs} + shouldSingleExecuteRowSelect + initiallyFocusedOptionKey={data.find((item) => item.isSelected)?.keyForList} + title="workspace.common.displayedAs" + connectionName={CONST.POLICY.CONNECTIONS.NAME.QBO} + pendingAction={settingsPendingAction([CONST.QUICKBOOKS_CONFIG.SYNC_CLASSES], qboConfig?.pendingFields)} + errors={ErrorUtils.getLatestErrorField(qboConfig, CONST.QUICKBOOKS_CONFIG.SYNC_CLASSES)} + errorRowStyles={[styles.ph5, styles.pv3]} + onClose={() => clearQBOErrorField(policyID, CONST.QUICKBOOKS_CONFIG.SYNC_CLASSES)} + /> + ); +} + +QuickbooksClassesDisplayedAsPage.displayName = 'QuickbooksClassesDisplayedAsPage'; + +export default withPolicyConnections(QuickbooksClassesDisplayedAsPage); diff --git a/src/pages/workspace/accounting/qbo/import/QuickbooksClassesPage.tsx b/src/pages/workspace/accounting/qbo/import/QuickbooksClassesPage.tsx index 70eb9bf8cdb5..ae72999ad975 100644 --- a/src/pages/workspace/accounting/qbo/import/QuickbooksClassesPage.tsx +++ b/src/pages/workspace/accounting/qbo/import/QuickbooksClassesPage.tsx @@ -1,12 +1,13 @@ 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 QuickbooksOnline from '@libs/actions/connections/QuickbooksOnline'; import * as ErrorUtils from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; -import {settingsPendingAction} from '@libs/PolicyUtils'; +import {areSettingsInErrorFields, settingsPendingAction} from '@libs/PolicyUtils'; import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; import ToggleSettingOptionRow from '@pages/workspace/workflows/ToggleSettingsOptionRow'; @@ -50,12 +51,16 @@ function QuickbooksClassesPage({policy}: WithPolicyProps) { onCloseError={() => clearQBOErrorField(policyID, CONST.QUICKBOOKS_CONFIG.SYNC_CLASSES)} /> {isSwitchOn && ( - <MenuItemWithTopDescription - interactive={false} - title={isReportFieldsSelected ? translate('workspace.common.reportFields') : translate('workspace.common.tags')} - description={translate('workspace.common.displayedAs')} - wrapperStyle={[styles.sectionMenuItemTopDescription, styles.mt4]} - /> + <OfflineWithFeedback pendingAction={settingsPendingAction([CONST.QUICKBOOKS_CONFIG.SYNC_CLASSES], qboConfig?.pendingFields)}> + <MenuItemWithTopDescription + title={isReportFieldsSelected ? translate('workspace.common.reportFields') : translate('workspace.common.tags')} + description={translate('workspace.common.displayedAs')} + onPress={() => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_CLASSES_DISPLAYED_AS.getRoute(policyID))} + shouldShowRightIcon + wrapperStyle={[styles.sectionMenuItemTopDescription, styles.mt4]} + brickRoadIndicator={areSettingsInErrorFields([CONST.QUICKBOOKS_CONFIG.SYNC_CLASSES], qboConfig?.errorFields) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined} + /> + </OfflineWithFeedback> )} </ConnectionLayout> ); diff --git a/src/pages/workspace/accounting/qbo/import/QuickbooksCustomersDisplayedAsPage.tsx b/src/pages/workspace/accounting/qbo/import/QuickbooksCustomersDisplayedAsPage.tsx new file mode 100644 index 000000000000..9c05247d9d98 --- /dev/null +++ b/src/pages/workspace/accounting/qbo/import/QuickbooksCustomersDisplayedAsPage.tsx @@ -0,0 +1,79 @@ +import React, {useCallback, useMemo} from 'react'; +import RadioListItem from '@components/SelectionList/RadioListItem'; +import type {ListItem} from '@components/SelectionList/types'; +import SelectionScreen from '@components/SelectionScreen'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import * as QuickbooksOnline from '@libs/actions/connections/QuickbooksOnline'; +import * as ErrorUtils from '@libs/ErrorUtils'; +import Navigation from '@libs/Navigation/Navigation'; +import {settingsPendingAction} from '@libs/PolicyUtils'; +import type {WithPolicyProps} from '@pages/workspace/withPolicy'; +import withPolicyConnections from '@pages/workspace/withPolicyConnections'; +import {clearQBOErrorField} from '@userActions/Policy/Policy'; +import CONST from '@src/CONST'; +import ROUTES from '@src/ROUTES'; + +type CardListItem = ListItem & { + value: keyof typeof CONST.INTEGRATION_ENTITY_MAP_TYPES; +}; + +function QuickbooksCustomersDisplayedAsPage({policy}: WithPolicyProps) { + const {translate} = useLocalize(); + const styles = useThemeStyles(); + const policyID = policy?.id ?? '-1'; + const qboConfig = policy?.connections?.quickbooksOnline?.config; + + const data: CardListItem[] = useMemo( + () => [ + { + value: CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG, + text: translate('workspace.common.tags'), + keyForList: CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG, + isSelected: qboConfig?.syncCustomers === CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG, + }, + { + value: CONST.INTEGRATION_ENTITY_MAP_TYPES.REPORT_FIELD, + text: translate('workspace.common.reportFields'), + keyForList: CONST.INTEGRATION_ENTITY_MAP_TYPES.REPORT_FIELD, + isSelected: qboConfig?.syncCustomers === CONST.INTEGRATION_ENTITY_MAP_TYPES.REPORT_FIELD, + }, + ], + [qboConfig?.syncCustomers, translate], + ); + + const selectDisplayedAs = useCallback( + (row: CardListItem) => { + if (row.value !== qboConfig?.syncCustomers) { + QuickbooksOnline.updateQuickbooksOnlineSyncCustomers(policyID, row.value, qboConfig?.syncCustomers); + } + Navigation.goBack(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_CUSTOMERS.getRoute(policyID)); + }, + [qboConfig?.syncCustomers, policyID], + ); + + return ( + <SelectionScreen + policyID={policyID} + accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN]} + featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED} + displayName={QuickbooksCustomersDisplayedAsPage.displayName} + sections={data.length ? [{data}] : []} + listItem={RadioListItem} + onBackButtonPress={() => Navigation.goBack(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_CUSTOMERS.getRoute(policyID))} + onSelectRow={(selection) => selectDisplayedAs(selection as CardListItem)} + shouldSingleExecuteRowSelect + initiallyFocusedOptionKey={data.find((item) => item.isSelected)?.keyForList} + title="workspace.common.displayedAs" + connectionName={CONST.POLICY.CONNECTIONS.NAME.QBO} + pendingAction={settingsPendingAction([CONST.QUICKBOOKS_CONFIG.SYNC_CUSTOMERS], qboConfig?.pendingFields)} + errors={ErrorUtils.getLatestErrorField(qboConfig, CONST.QUICKBOOKS_CONFIG.SYNC_CUSTOMERS)} + errorRowStyles={[styles.ph5, styles.pv3]} + onClose={() => clearQBOErrorField(policyID, CONST.QUICKBOOKS_CONFIG.SYNC_CUSTOMERS)} + /> + ); +} + +QuickbooksCustomersDisplayedAsPage.displayName = 'QuickbooksCustomersDisplayedAsPage'; + +export default withPolicyConnections(QuickbooksCustomersDisplayedAsPage); diff --git a/src/pages/workspace/accounting/qbo/import/QuickbooksCustomersPage.tsx b/src/pages/workspace/accounting/qbo/import/QuickbooksCustomersPage.tsx index 67a326858379..8b842e737de6 100644 --- a/src/pages/workspace/accounting/qbo/import/QuickbooksCustomersPage.tsx +++ b/src/pages/workspace/accounting/qbo/import/QuickbooksCustomersPage.tsx @@ -1,12 +1,13 @@ 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 QuickbooksOnline from '@libs/actions/connections/QuickbooksOnline'; import * as ErrorUtils from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; -import {settingsPendingAction} from '@libs/PolicyUtils'; +import {areSettingsInErrorFields, settingsPendingAction} from '@libs/PolicyUtils'; import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; import ToggleSettingOptionRow from '@pages/workspace/workflows/ToggleSettingsOptionRow'; @@ -49,12 +50,16 @@ function QuickbooksCustomersPage({policy}: WithPolicyProps) { onCloseError={() => clearQBOErrorField(policyID, CONST.QUICKBOOKS_CONFIG.SYNC_CUSTOMERS)} /> {isSwitchOn && ( - <MenuItemWithTopDescription - interactive={false} - title={isReportFieldsSelected ? translate('workspace.common.reportFields') : translate('workspace.common.tags')} - description={translate('workspace.common.displayedAs')} - wrapperStyle={[styles.sectionMenuItemTopDescription, styles.mt4]} - /> + <OfflineWithFeedback pendingAction={settingsPendingAction([CONST.QUICKBOOKS_CONFIG.SYNC_CUSTOMERS], qboConfig?.pendingFields)}> + <MenuItemWithTopDescription + title={isReportFieldsSelected ? translate('workspace.common.reportFields') : translate('workspace.common.tags')} + description={translate('workspace.common.displayedAs')} + onPress={() => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_CUSTOMERS_DISPLAYED_AS.getRoute(policyID))} + shouldShowRightIcon + wrapperStyle={[styles.sectionMenuItemTopDescription, styles.mt4]} + brickRoadIndicator={areSettingsInErrorFields([CONST.QUICKBOOKS_CONFIG.SYNC_CUSTOMERS], qboConfig?.errorFields) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined} + /> + </OfflineWithFeedback> )} </ConnectionLayout> ); diff --git a/src/pages/workspace/accounting/qbo/import/QuickbooksImportPage.tsx b/src/pages/workspace/accounting/qbo/import/QuickbooksImportPage.tsx index 56089d9d25d5..aa2a3156038f 100644 --- a/src/pages/workspace/accounting/qbo/import/QuickbooksImportPage.tsx +++ b/src/pages/workspace/accounting/qbo/import/QuickbooksImportPage.tsx @@ -1,11 +1,13 @@ -import React from 'react'; +import React, {useEffect} 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 QuickbooksOnline from '@libs/actions/connections/QuickbooksOnline'; import * as PolicyUtils from '@libs/PolicyUtils'; import Navigation from '@navigation/Navigation'; +import {shouldSwitchLocationsToReportFields} from '@pages/workspace/accounting/qbo/utils'; import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; import CONST from '@src/CONST'; @@ -22,7 +24,16 @@ function QuickbooksImportPage({policy}: WithPolicyProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const policyID = policy?.id ?? '-1'; - const {syncClasses, syncCustomers, syncLocations, syncTax, pendingFields, errorFields} = policy?.connections?.quickbooksOnline?.config ?? {}; + const qboConfig = policy?.connections?.quickbooksOnline?.config; + const {syncClasses, syncCustomers, syncLocations, syncTax, pendingFields, errorFields} = qboConfig ?? {}; + + // If we previously selected tags but now we have the line items restriction for locations, we need to switch to report fields + useEffect(() => { + if (!shouldSwitchLocationsToReportFields(qboConfig)) { + return; + } + QuickbooksOnline.updateQuickbooksOnlineSyncLocations(policyID, CONST.INTEGRATION_ENTITY_MAP_TYPES.REPORT_FIELD, qboConfig?.syncLocations); + }, [qboConfig, policyID]); const sections: QBOSectionType[] = [ { diff --git a/src/pages/workspace/accounting/qbo/import/QuickbooksLocationsDisplayedAsPage.tsx b/src/pages/workspace/accounting/qbo/import/QuickbooksLocationsDisplayedAsPage.tsx new file mode 100644 index 000000000000..a974ac64b6ec --- /dev/null +++ b/src/pages/workspace/accounting/qbo/import/QuickbooksLocationsDisplayedAsPage.tsx @@ -0,0 +1,86 @@ +import React, {useCallback, useMemo} from 'react'; +import RadioListItem from '@components/SelectionList/RadioListItem'; +import type {ListItem} from '@components/SelectionList/types'; +import SelectionScreen from '@components/SelectionScreen'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import * as QuickbooksOnline from '@libs/actions/connections/QuickbooksOnline'; +import * as ErrorUtils from '@libs/ErrorUtils'; +import Navigation from '@libs/Navigation/Navigation'; +import {settingsPendingAction} from '@libs/PolicyUtils'; +import type {WithPolicyProps} from '@pages/workspace/withPolicy'; +import withPolicyConnections from '@pages/workspace/withPolicyConnections'; +import {clearQBOErrorField} from '@userActions/Policy/Policy'; +import CONST from '@src/CONST'; +import ROUTES from '@src/ROUTES'; + +type CardListItem = ListItem & { + value: keyof typeof CONST.INTEGRATION_ENTITY_MAP_TYPES; +}; + +function QuickbooksLocationsDisplayedAsPage({policy}: WithPolicyProps) { + const {translate} = useLocalize(); + const styles = useThemeStyles(); + const policyID = policy?.id ?? '-1'; + const qboConfig = policy?.connections?.quickbooksOnline?.config; + + const data: CardListItem[] = useMemo(() => { + const items: CardListItem[] = []; + + if ( + qboConfig?.reimbursableExpensesExportDestination === CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.JOURNAL_ENTRY && + qboConfig?.nonReimbursableExpensesExportDestination === CONST.QUICKBOOKS_NON_REIMBURSABLE_ACCOUNT_TYPE.CREDIT_CARD + ) { + items.push({ + value: CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG, + text: translate('workspace.common.tags'), + keyForList: CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG, + isSelected: qboConfig?.syncLocations === CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG, + }); + } + + items.push({ + value: CONST.INTEGRATION_ENTITY_MAP_TYPES.REPORT_FIELD, + text: translate('workspace.common.reportFields'), + keyForList: CONST.INTEGRATION_ENTITY_MAP_TYPES.REPORT_FIELD, + isSelected: qboConfig?.syncLocations === CONST.INTEGRATION_ENTITY_MAP_TYPES.REPORT_FIELD, + }); + + return items; + }, [qboConfig?.syncLocations, qboConfig?.reimbursableExpensesExportDestination, qboConfig?.nonReimbursableExpensesExportDestination, translate]); + + const selectDisplayedAs = useCallback( + (row: CardListItem) => { + if (row.value !== qboConfig?.syncLocations) { + QuickbooksOnline.updateQuickbooksOnlineSyncLocations(policyID, row.value, qboConfig?.syncLocations); + } + Navigation.goBack(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_LOCATIONS.getRoute(policyID)); + }, + [qboConfig?.syncLocations, policyID], + ); + + return ( + <SelectionScreen + policyID={policyID} + accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN]} + featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED} + displayName={QuickbooksLocationsDisplayedAsPage.displayName} + sections={data.length ? [{data}] : []} + listItem={RadioListItem} + onBackButtonPress={() => Navigation.goBack(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_LOCATIONS.getRoute(policyID))} + onSelectRow={(selection) => selectDisplayedAs(selection as CardListItem)} + shouldSingleExecuteRowSelect + initiallyFocusedOptionKey={data.find((item) => item.isSelected)?.keyForList} + title="workspace.common.displayedAs" + connectionName={CONST.POLICY.CONNECTIONS.NAME.QBO} + pendingAction={settingsPendingAction([CONST.QUICKBOOKS_CONFIG.SYNC_LOCATIONS], qboConfig?.pendingFields)} + errors={ErrorUtils.getLatestErrorField(qboConfig, CONST.QUICKBOOKS_CONFIG.SYNC_LOCATIONS)} + errorRowStyles={[styles.ph5, styles.pv3]} + onClose={() => clearQBOErrorField(policyID, CONST.QUICKBOOKS_CONFIG.SYNC_LOCATIONS)} + /> + ); +} + +QuickbooksLocationsDisplayedAsPage.displayName = 'QuickbooksLocationsDisplayedAsPage'; + +export default withPolicyConnections(QuickbooksLocationsDisplayedAsPage); diff --git a/src/pages/workspace/accounting/qbo/import/QuickbooksLocationsPage.tsx b/src/pages/workspace/accounting/qbo/import/QuickbooksLocationsPage.tsx index f619dfc2772e..c84421382f82 100644 --- a/src/pages/workspace/accounting/qbo/import/QuickbooksLocationsPage.tsx +++ b/src/pages/workspace/accounting/qbo/import/QuickbooksLocationsPage.tsx @@ -1,7 +1,8 @@ -import React from 'react'; +import React, {useEffect} from 'react'; import {View} from 'react-native'; import ConnectionLayout from '@components/ConnectionLayout'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; +import OfflineWithFeedback from '@components/OfflineWithFeedback'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -9,6 +10,7 @@ import * as QuickbooksOnline from '@libs/actions/connections/QuickbooksOnline'; import * as ErrorUtils from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; import * as PolicyUtils from '@libs/PolicyUtils'; +import {shouldShowLocationsLineItemsRestriction, shouldSwitchLocationsToReportFields} from '@pages/workspace/accounting/qbo/utils'; import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; import ToggleSettingOptionRow from '@pages/workspace/workflows/ToggleSettingsOptionRow'; @@ -22,11 +24,16 @@ function QuickbooksLocationsPage({policy}: WithPolicyProps) { const policyID = policy?.id ?? '-1'; const qboConfig = policy?.connections?.quickbooksOnline?.config; const isSwitchOn = !!(qboConfig?.syncLocations && qboConfig?.syncLocations !== CONST.INTEGRATION_ENTITY_MAP_TYPES.NONE); - const canImportLocation = - qboConfig?.reimbursableExpensesExportDestination === CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.JOURNAL_ENTRY && - qboConfig?.nonReimbursableExpensesExportDestination !== CONST.QUICKBOOKS_NON_REIMBURSABLE_EXPORT_ACCOUNT_TYPE.VENDOR_BILL; - const shouldBeDisabled = !canImportLocation && !isSwitchOn; - const isReportFieldsSelected = qboConfig?.syncLocations === CONST.INTEGRATION_ENTITY_MAP_TYPES.REPORT_FIELD; + const isTagsSelected = qboConfig?.syncLocations === CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG; + const shouldShowLineItemsRestriction = shouldShowLocationsLineItemsRestriction(qboConfig); + + // If we previously selected tags but now we have the line items restriction, we need to switch to report fields + useEffect(() => { + if (!shouldSwitchLocationsToReportFields(qboConfig)) { + return; + } + QuickbooksOnline.updateQuickbooksOnlineSyncLocations(policyID, CONST.INTEGRATION_ENTITY_MAP_TYPES.REPORT_FIELD, qboConfig?.syncLocations); + }, [qboConfig, policyID]); return ( <ConnectionLayout @@ -44,11 +51,15 @@ function QuickbooksLocationsPage({policy}: WithPolicyProps) { title={translate('workspace.accounting.import')} switchAccessibilityLabel={translate('workspace.qbo.locations')} isActive={isSwitchOn} - disabled={shouldBeDisabled} onToggle={() => QuickbooksOnline.updateQuickbooksOnlineSyncLocations( policyID, - isSwitchOn ? CONST.INTEGRATION_ENTITY_MAP_TYPES.NONE : CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG, + // eslint-disable-next-line no-nested-ternary + isSwitchOn + ? CONST.INTEGRATION_ENTITY_MAP_TYPES.NONE + : shouldShowLineItemsRestriction + ? CONST.INTEGRATION_ENTITY_MAP_TYPES.REPORT_FIELD + : CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG, qboConfig?.syncLocations, ) } @@ -57,16 +68,24 @@ function QuickbooksLocationsPage({policy}: WithPolicyProps) { pendingAction={PolicyUtils.settingsPendingAction([CONST.QUICKBOOKS_CONFIG.SYNC_LOCATIONS], qboConfig?.pendingFields)} /> {isSwitchOn && ( - <MenuItemWithTopDescription - interactive={false} - title={isReportFieldsSelected ? translate('workspace.common.reportFields') : translate('workspace.common.tags')} - description={translate('workspace.common.displayedAs')} - wrapperStyle={styles.sectionMenuItemTopDescription} - /> + <OfflineWithFeedback pendingAction={PolicyUtils.settingsPendingAction([CONST.QUICKBOOKS_CONFIG.SYNC_LOCATIONS], qboConfig?.pendingFields)}> + <MenuItemWithTopDescription + interactive={!shouldShowLineItemsRestriction} + title={!isTagsSelected ? translate('workspace.common.reportFields') : translate('workspace.common.tags')} + description={translate('workspace.common.displayedAs')} + onPress={() => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_LOCATIONS_DISPLAYED_AS.getRoute(policyID))} + shouldShowRightIcon={!shouldShowLineItemsRestriction} + wrapperStyle={[styles.sectionMenuItemTopDescription, styles.mt4]} + brickRoadIndicator={ + PolicyUtils.areSettingsInErrorFields([CONST.QUICKBOOKS_CONFIG.SYNC_LOCATIONS], qboConfig?.errorFields) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined + } + /> + </OfflineWithFeedback> )} - {shouldBeDisabled && ( + + {shouldShowLineItemsRestriction && isSwitchOn && ( <View style={[styles.flex1, styles.flexRow, styles.alignItemsCenter, styles.gap2, styles.mt3]}> - <Text style={styles.mutedTextLabel}>{translate('workspace.qbo.locationsAdditionalDescription')}</Text> + <Text style={styles.mutedTextLabel}>{translate('workspace.qbo.locationsLineItemsRestrictionDescription')}</Text> </View> )} </ConnectionLayout> diff --git a/src/pages/workspace/accounting/qbo/utils.ts b/src/pages/workspace/accounting/qbo/utils.ts new file mode 100644 index 000000000000..1b5d5b8ed66d --- /dev/null +++ b/src/pages/workspace/accounting/qbo/utils.ts @@ -0,0 +1,15 @@ +import CONST from '@src/CONST'; +import type {QBOConnectionConfig} from '@src/types/onyx/Policy'; + +function shouldShowLocationsLineItemsRestriction(config?: QBOConnectionConfig): boolean { + return !( + config?.reimbursableExpensesExportDestination === CONST.QUICKBOOKS_REIMBURSABLE_ACCOUNT_TYPE.JOURNAL_ENTRY && + config?.nonReimbursableExpensesExportDestination === CONST.QUICKBOOKS_NON_REIMBURSABLE_ACCOUNT_TYPE.CREDIT_CARD + ); +} + +function shouldSwitchLocationsToReportFields(config?: QBOConnectionConfig): boolean { + return config?.syncLocations === CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG && shouldShowLocationsLineItemsRestriction(config); +} + +export {shouldShowLocationsLineItemsRestriction, shouldSwitchLocationsToReportFields}; diff --git a/src/pages/workspace/accounting/xero/XeroMapTrackingCategoryConfigurationPage.tsx b/src/pages/workspace/accounting/xero/XeroMapTrackingCategoryConfigurationPage.tsx index dae46f32dc54..6585e89011e0 100644 --- a/src/pages/workspace/accounting/xero/XeroMapTrackingCategoryConfigurationPage.tsx +++ b/src/pages/workspace/accounting/xero/XeroMapTrackingCategoryConfigurationPage.tsx @@ -41,7 +41,7 @@ function XeroMapTrackingCategoryConfigurationPage({policy}: WithPolicyProps) { () => Object.values(CONST.XERO_CONFIG.TRACKING_CATEGORY_OPTIONS).map((option) => ({ value: option, - text: translate(`workspace.xero.trackingCategoriesOptions.${option.toLowerCase()}` as TranslationPaths), + text: translate(`workspace.xero.trackingCategoriesOptions.${option.toUpperCase()}` as TranslationPaths), keyForList: option, isSelected: option === currentTrackingCategoryValue, })), diff --git a/src/pages/workspace/accounting/xero/XeroTrackingCategoryConfigurationPage.tsx b/src/pages/workspace/accounting/xero/XeroTrackingCategoryConfigurationPage.tsx index 5aa6b2cd4efe..1e9f7382f51f 100644 --- a/src/pages/workspace/accounting/xero/XeroTrackingCategoryConfigurationPage.tsx +++ b/src/pages/workspace/accounting/xero/XeroTrackingCategoryConfigurationPage.tsx @@ -32,7 +32,11 @@ function XeroTrackingCategoryConfigurationPage({policy}: WithPolicyProps) { id: category.id, description: translate('workspace.xero.mapTrackingCategoryTo', {categoryName: category.name}) as TranslationPaths, onPress: () => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_XERO_TRACKING_CATEGORIES_MAP.getRoute(policyID, category.id, category.name)), - title: translate(`workspace.xero.trackingCategoriesOptions.${!StringUtils.isEmptyString(category.value) ? category.value.toLowerCase() : 'default'}` as TranslationPaths), + title: translate( + `workspace.xero.trackingCategoriesOptions.${ + !StringUtils.isEmptyString(category.value) ? category.value.toUpperCase() : CONST.XERO_CONFIG.TRACKING_CATEGORY_OPTIONS.DEFAULT + }` as TranslationPaths, + ), })); }, [translate, policy, policyID]);