From 71543eeba52766c090bbfbb22ded329a5dfc955e Mon Sep 17 00:00:00 2001 From: Rutika Pawar <183392827+twilight2294@users.noreply.github.com> Date: Sat, 1 Mar 2025 07:53:02 +0000 Subject: [PATCH 1/3] New Feature: "When to export" selector for auto-sync for Quickbooks Online --- src/CONST.ts | 1 + src/ROUTES.ts | 8 ++ src/SCREENS.ts | 2 + src/languages/en.ts | 25 +++--- src/languages/es.ts | 25 +++--- ...eQuickbooksOnlineAccountingMethodParams.ts | 9 ++ src/libs/API/parameters/index.ts | 1 + src/libs/API/types.ts | 2 + .../ModalStackNavigators/index.tsx | 3 + .../RELATIONS/WORKSPACE_TO_RHP.ts | 2 + src/libs/Navigation/linkingConfig/config.ts | 6 ++ src/libs/actions/Policy/Policy.ts | 5 ++ .../actions/connections/QuickbooksOnline.ts | 20 ++++- .../advanced/NetSuiteAccountingMethodPage.tsx | 8 +- .../advanced/NetSuiteAdvancedPage.tsx | 4 +- .../advanced/NetSuiteAutoSyncPage.tsx | 6 +- .../QuickbooksAccountingMethodPage.tsx | 82 +++++++++++++++++++ .../qbo/advanced/QuickbooksAdvancedPage.tsx | 35 +++++--- .../qbo/advanced/QuickbooksAutoSyncPage.tsx | 79 ++++++++++++++++++ src/types/onyx/Policy.ts | 3 + 20 files changed, 280 insertions(+), 46 deletions(-) create mode 100644 src/libs/API/parameters/UpdateQuickbooksOnlineAccountingMethodParams.ts create mode 100644 src/pages/workspace/accounting/qbo/advanced/QuickbooksAccountingMethodPage.tsx create mode 100644 src/pages/workspace/accounting/qbo/advanced/QuickbooksAutoSyncPage.tsx diff --git a/src/CONST.ts b/src/CONST.ts index 30077672b5eb1..891322574f583 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -1855,6 +1855,7 @@ const CONST = { AUTO_CREATE_VENDOR: 'autoCreateVendor', REIMBURSEMENT_ACCOUNT_ID: 'reimbursementAccountID', COLLECTION_ACCOUNT_ID: 'collectionAccountID', + ACCOUNTING_METHOD: 'accountingMethod', }, XERO_CONFIG: { diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 7f3d1324b4116..de165cdc58555 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -1131,6 +1131,14 @@ const ROUTES = { route: 'settings/workspaces/:policyID/accounting/quickbooks-online/invoice-account-selector', getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/quickbooks-online/invoice-account-selector` as const, }, + WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_AUTO_SYNC: { + route: 'settings/workspaces/:policyID/connections/quickbooks-online/advanced/autosync', + getRoute: (policyID: string) => `settings/workspaces/${policyID}/connections/quickbooks-online/advanced/autosync` as const, + }, + WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_ACCOUNTING_METHOD: { + route: 'settings/workspaces/:policyID/connections/quickbooks-online/advanced/autosync/accounting-method', + getRoute: (policyID: string) => `settings/workspaces/${policyID}/connections/quickbooks-online/advanced/autosync/accounting-method` as const, + }, WORKSPACE_ACCOUNTING_CARD_RECONCILIATION: { route: 'settings/workspaces/:policyID/accounting/:connection/card-reconciliation', getRoute: (policyID: string, connection?: ValueOf) => diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 5a8b0c75d5c01..82fbebd8596f8 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -360,6 +360,8 @@ const SCREENS = { 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_ONLINE_AUTO_SYNC: 'Policy_Accounting_Quickbooks_Online_Auto_Sync', + QUICKBOOKS_ONLINE_ACCOUNTING_METHOD: 'Policy_Accounting_Quickbooks_Online_Accounting_Method', 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 8016342f090b5..b49bdd441d9b5 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -2888,6 +2888,7 @@ const translations = { locations: 'Locations', customers: 'Customers/projects', accountsDescription: 'Your QuickBooks Online chart of accounts will import into Expensify as categories.', + autoSyncDescription: 'Sync QuickBooks Online and Expensify automatically, every day. Export finalized report in realtime', accountsSwitchTitle: 'Choose to import new accounts as enabled or disabled categories.', accountsSwitchDescription: 'Enabled categories will be available for members to select when creating their expenses.', classesDescription: 'Choose how to handle QuickBooks Online classes in Expensify.', @@ -3222,18 +3223,6 @@ const translations = { [CONST.NETSUITE_REPORTS_APPROVAL_LEVEL.REPORTS_APPROVED_BOTH]: 'Supervisor and accounting approved', }, }, - accountingMethods: { - label: 'When to Export', - description: 'Choose when to export the expenses:', - values: { - [COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.ACCRUAL]: 'Accrual', - [COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.CASH]: 'Cash', - }, - alternateText: { - [COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.ACCRUAL]: 'Out-of-pocket expenses will export when final approved', - [COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.CASH]: 'Out-of-pocket expenses will export when paid', - }, - }, exportVendorBillsTo: { label: 'Vendor bill approval level', description: 'Once a vendor bill is approved in Expensify and exported to NetSuite, you can set an additional level of approval in NetSuite prior to posting.', @@ -3527,6 +3516,18 @@ const translations = { } }, }, + accountingMethods: { + label: 'When to Export', + description: 'Choose when to export the expenses:', + values: { + [COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.ACCRUAL]: 'Accrual', + [COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.CASH]: 'Cash', + }, + alternateText: { + [COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.ACCRUAL]: 'Out-of-pocket expenses will export when final approved', + [COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.CASH]: 'Out-of-pocket expenses will export when paid', + }, + }, multiConnectionSelector: { title: ({connectionName}: ConnectionNameParams) => `${CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY[connectionName]} setup`, description: ({connectionName}: ConnectionNameParams) => `Select your ${CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY[connectionName]} version to continue.`, diff --git a/src/languages/es.ts b/src/languages/es.ts index 0d82fb9fe3997..9c0de3f08b9e3 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -2914,6 +2914,7 @@ const translations = { locations: 'Lugares', customers: 'Clientes/proyectos', accountsDescription: 'Tu plan de cuentas de QuickBooks Online se importará a Expensify como categorías.', + autoSyncDescription: 'Sincroniza QuickBooks Online y Expensify automáticamente, todos los días. Exporta el informe finalizado en tiempo real', accountsSwitchTitle: 'Elige importar cuentas nuevas como categorías activadas o desactivadas.', accountsSwitchDescription: 'Las categorías activas estarán disponibles para ser escogidas cuando se crea un gasto.', classesDescription: 'Elige cómo gestionar las clases de QuickBooks Online en Expensify.', @@ -3260,18 +3261,6 @@ const translations = { [CONST.NETSUITE_REPORTS_APPROVAL_LEVEL.REPORTS_APPROVED_BOTH]: 'Aprobado por supervisor y contabilidad', }, }, - accountingMethods: { - label: 'Cuándo Exportar', - description: 'Elige cuándo exportar los gastos:', - values: { - [COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.ACCRUAL]: 'Devengo', - [COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.CASH]: 'Efectivo', - }, - alternateText: { - [COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.ACCRUAL]: 'Los gastos por cuenta propia se exportarán cuando estén aprobados definitivamente', - [COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.CASH]: 'Los gastos por cuenta propia se exportarán cuando estén pagados', - }, - }, exportVendorBillsTo: { label: 'Nivel de aprobación de facturas de proveedores', description: @@ -3566,6 +3555,18 @@ const translations = { } }, }, + accountingMethods: { + label: 'Cuándo Exportar', + description: 'Elige cuándo exportar los gastos:', + values: { + [COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.ACCRUAL]: 'Devengo', + [COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.CASH]: 'Efectivo', + }, + alternateText: { + [COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.ACCRUAL]: 'Los gastos por cuenta propia se exportarán cuando estén aprobados definitivamente', + [COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.CASH]: 'Los gastos por cuenta propia se exportarán cuando estén pagados', + }, + }, multiConnectionSelector: { title: ({connectionName}: ConnectionNameParams) => `${CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY[connectionName]} configuración`, description: ({connectionName}: ConnectionNameParams) => `Selecciona tu versión de ${CONST.POLICY.CONNECTIONS.NAME_USER_FRIENDLY[connectionName]} para continuar.`, diff --git a/src/libs/API/parameters/UpdateQuickbooksOnlineAccountingMethodParams.ts b/src/libs/API/parameters/UpdateQuickbooksOnlineAccountingMethodParams.ts new file mode 100644 index 0000000000000..617570d5c3656 --- /dev/null +++ b/src/libs/API/parameters/UpdateQuickbooksOnlineAccountingMethodParams.ts @@ -0,0 +1,9 @@ +import type {CONST as COMMON_CONST} from 'expensify-common'; +import type {ValueOf} from 'type-fest'; + +type UpdateQuickbooksOnlineAccountingMethodParams = { + policyID: string; + accountingMethod: ValueOf; +}; + +export default UpdateQuickbooksOnlineAccountingMethodParams; diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts index 38ee3ee710535..1e3511a549689 100644 --- a/src/libs/API/parameters/index.ts +++ b/src/libs/API/parameters/index.ts @@ -20,6 +20,7 @@ export type {default as SyncPolicyToQuickbooksOnlineParams} from './SyncPolicyTo export type {default as SyncPolicyToXeroParams} from './SyncPolicyToXeroParams'; export type {default as SyncPolicyToNetSuiteParams} from './SyncPolicyToNetSuiteParams'; export type {default as UpdateNetSuiteAccountingMethodParams} from './UpdateNetSuiteAccountingMethodParams'; +export type {default as UpdateQuickbooksOnlineAccountingMethodParams} from './UpdateQuickbooksOnlineAccountingMethodParams'; export type {default as SyncPolicyToQuickbooksDesktopParams} from './SyncPolicyToQuickbooksDesktopParams'; export type {default as DeleteContactMethodParams} from './DeleteContactMethodParams'; export type {default as DeletePaymentBankAccountParams} from './DeletePaymentBankAccountParams'; diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index 03b5103a64910..d956070c3b78b 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -267,6 +267,7 @@ const WRITE_COMMANDS = { UPDATE_QUICKBOOKS_ONLINE_SYNC_PEOPLE: 'UpdateQuickbooksOnlineSyncPeople', UPDATE_QUICKBOOKS_ONLINE_REIMBURSEMENT_ACCOUNT_ID: 'UpdateQuickbooksOnlineReimbursementAccountID', UPDATE_QUICKBOOKS_ONLINE_EXPORT: 'UpdateQuickbooksOnlineExport', + UPDATE_QUICKBOOKS_ONLINE_ACCOUNTING_METHOD: 'UpdateQuickbooksOnlineAccountingMethod', UPDATE_QUICKBOOKS_DESKTOP_EXPORT_DATE: 'UpdateQuickbooksDesktopExportDate', UPDATE_MANY_POLICY_CONNECTION_CONFIGS: 'UpdateManyPolicyConnectionConfigurations', UPDATE_QUICKBOOKS_DESKTOP_NON_REIMBURSABLE_EXPENSES_EXPORT_DESTINATION: 'UpdateQuickbooksDesktopNonReimbursableExpensesExportDestination', @@ -747,6 +748,7 @@ type WriteCommandParameters = { [WRITE_COMMANDS.UPDATE_QUICKBOOKS_ONLINE_EXPORT_DATE]: Parameters.UpdateQuickbooksOnlineGenericTypeParams; [WRITE_COMMANDS.UPDATE_QUICKBOOKS_ONLINE_NON_REIMBURSABLE_EXPENSES_ACCOUNT]: Parameters.UpdateQuickbooksOnlineGenericTypeParams; [WRITE_COMMANDS.UPDATE_QUICKBOOKS_ONLINE_COLLECTION_ACCOUNT_ID]: Parameters.UpdateQuickbooksOnlineGenericTypeParams; + [WRITE_COMMANDS.UPDATE_QUICKBOOKS_ONLINE_ACCOUNTING_METHOD]: Parameters.UpdateQuickbooksOnlineAccountingMethodParams; [WRITE_COMMANDS.UPDATE_QUICKBOOKS_DESKTOP_EXPORT_DATE]: Parameters.UpdateQuickbooksDesktopGenericTypeParams; [WRITE_COMMANDS.UPDATE_QUICKBOOKS_DESKTOP_MARK_CHECKS_TO_BE_PRINTED]: Parameters.UpdateQuickbooksDesktopGenericTypeParams; [WRITE_COMMANDS.UPDATE_QUICKBOOKS_DESKTOP_AUTO_CREATE_VENDOR]: Parameters.UpdateQuickbooksDesktopGenericTypeParams; diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 91939c86f07fd..36e509c615e1a 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -343,6 +343,9 @@ const SettingsModalStackNavigator = createModalStackNavigator('@pages/workspace/accounting/qbo/export/QuickbooksCompanyCardExpenseAccountSelectPage').default, [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_COMPANY_CARD_EXPENSE_ACCOUNT_COMPANY_CARD_SELECT]: () => require('../../../../pages/workspace/accounting/qbo/export/QuickbooksCompanyCardExpenseAccountSelectCardPage').default, + [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_AUTO_SYNC]: () => require('../../../../pages/workspace/accounting/qbo/advanced/QuickbooksAutoSyncPage').default, + [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_ACCOUNTING_METHOD]: () => + require('../../../../pages/workspace/accounting/qbo/advanced/QuickbooksAccountingMethodPage').default, [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_COMPANY_CARD_EXPENSE_ACCOUNT]: () => require('../../../../pages/workspace/accounting/qbo/export/QuickbooksCompanyCardExpenseAccountPage').default, [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_EXPORT_PREFERRED_EXPORTER]: () => diff --git a/src/libs/Navigation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP.ts b/src/libs/Navigation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP.ts index a986641b3e5b8..a68ef1ddf9b3c 100755 --- a/src/libs/Navigation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP.ts +++ b/src/libs/Navigation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP.ts @@ -55,6 +55,8 @@ const WORKSPACE_TO_RHP: Partial['config'] = { [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_LOCATIONS_DISPLAYED_AS]: { path: ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_LOCATIONS_DISPLAYED_AS.route, }, + [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_AUTO_SYNC]: { + path: ROUTES.WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_AUTO_SYNC.route, + }, + [SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_ACCOUNTING_METHOD]: { + path: ROUTES.WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_ACCOUNTING_METHOD.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/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 5f965b5e71b4f..dd1a9d88f8b2d 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -696,6 +696,10 @@ function clearNetSuiteAutoSyncErrorField(policyID: string) { Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {connections: {netsuite: {config: {errorFields: {autoSync: null}}}}}); } +function clearQuickbooksOnlineAutoSyncErrorField(policyID: string) { + Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {connections: {quickbooksOnline: {config: {errorFields: {autoSync: null}}}}}); +} + function clearNSQSErrorField(policyID: string, fieldName: string) { Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {connections: {netsuiteQuickStart: {config: {errorFields: {[fieldName]: null}}}}}); } @@ -4962,6 +4966,7 @@ export { clearNetSuiteErrorField, clearNetSuitePendingField, clearNetSuiteAutoSyncErrorField, + clearQuickbooksOnlineAutoSyncErrorField, removeNetSuiteCustomFieldByIndex, clearWorkspaceReimbursementErrors, setWorkspaceCurrencyDefault, diff --git a/src/libs/actions/connections/QuickbooksOnline.ts b/src/libs/actions/connections/QuickbooksOnline.ts index 05b6bb730069d..805f02b7658cf 100644 --- a/src/libs/actions/connections/QuickbooksOnline.ts +++ b/src/libs/actions/connections/QuickbooksOnline.ts @@ -1,7 +1,9 @@ +import type {CONST as COMMON_CONST} from 'expensify-common'; import type {OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; +import {ValueOf} from 'type-fest'; import * as API from '@libs/API'; -import type {ConnectPolicyToAccountingIntegrationParams} from '@libs/API/parameters'; +import type {ConnectPolicyToAccountingIntegrationParams, UpdateQuickbooksOnlineAccountingMethodParams} from '@libs/API/parameters'; import type UpdateQuickbooksOnlineAutoCreateVendorParams from '@libs/API/parameters/UpdateQuickbooksOnlineAutoCreateVendorParams'; import type UpdateQuickbooksOnlineGenericTypeParams from '@libs/API/parameters/UpdateQuickbooksOnlineGenericTypeParams'; import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; @@ -403,6 +405,21 @@ function updateQuickbooksOnlinePreferredExporter, + oldAccountingMethod: ValueOf, +) { + const onyxData = buildOnyxDataForQuickbooksConfiguration(policyID, CONST.QUICKBOOKS_CONFIG.ACCOUNTING_METHOD, accountingMethod, oldAccountingMethod); + + const parameters: UpdateQuickbooksOnlineAccountingMethodParams = { + policyID, + accountingMethod, + }; + + API.write(WRITE_COMMANDS.UPDATE_QUICKBOOKS_ONLINE_ACCOUNTING_METHOD, parameters, onyxData); +} + export { getQuickbooksOnlineSetupLink, updateQuickbooksOnlineEnableNewCategories, @@ -421,4 +438,5 @@ export { updateQuickbooksOnlineSyncClasses, updateQuickbooksOnlineSyncLocations, updateQuickbooksOnlineSyncCustomers, + updateQuickbooksOnlineAccountingMethod, }; diff --git a/src/pages/workspace/accounting/netsuite/advanced/NetSuiteAccountingMethodPage.tsx b/src/pages/workspace/accounting/netsuite/advanced/NetSuiteAccountingMethodPage.tsx index a5c1872158e96..03dcc80889d60 100644 --- a/src/pages/workspace/accounting/netsuite/advanced/NetSuiteAccountingMethodPage.tsx +++ b/src/pages/workspace/accounting/netsuite/advanced/NetSuiteAccountingMethodPage.tsx @@ -31,8 +31,8 @@ function NetSuiteAccountingMethodPage({policy}: WithPolicyConnectionsProps) { const accountingMethod = config?.accountingMethod ?? COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.CASH; const data: MenuListItem[] = Object.values(COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD).map((accountingMethodType) => ({ value: accountingMethodType, - text: translate(`workspace.netsuite.advancedConfig.accountingMethods.values.${accountingMethodType}` as TranslationPaths), - alternateText: translate(`workspace.netsuite.advancedConfig.accountingMethods.alternateText.${accountingMethodType}` as TranslationPaths), + text: translate(`workspace.accountingMethods.values.${accountingMethodType}` as TranslationPaths), + alternateText: translate(`workspace.accountingMethods.alternateText.${accountingMethodType}` as TranslationPaths), keyForList: accountingMethodType, isSelected: accountingMethod === accountingMethodType, })); @@ -43,7 +43,7 @@ function NetSuiteAccountingMethodPage({policy}: WithPolicyConnectionsProps) { const headerContent = useMemo( () => ( - {translate('workspace.netsuite.advancedConfig.accountingMethods.description')} + {translate('workspace.accountingMethods.description')} ), [translate, styles.pb5, styles.ph5], @@ -62,7 +62,7 @@ function NetSuiteAccountingMethodPage({policy}: WithPolicyConnectionsProps) { return ( Navigation.navigate(ROUTES.POLICY_ACCOUNTING_NETSUITE_ACCOUNTING_METHOD.getRoute(policyID))} /> diff --git a/src/pages/workspace/accounting/qbo/advanced/QuickbooksAccountingMethodPage.tsx b/src/pages/workspace/accounting/qbo/advanced/QuickbooksAccountingMethodPage.tsx new file mode 100644 index 0000000000000..70c1fc81e7a65 --- /dev/null +++ b/src/pages/workspace/accounting/qbo/advanced/QuickbooksAccountingMethodPage.tsx @@ -0,0 +1,82 @@ +import {CONST as COMMON_CONST} from 'expensify-common'; +import React, {useCallback, useMemo} from 'react'; +import {View} from 'react-native'; +import type {ValueOf} from 'type-fest'; +import RadioListItem from '@components/SelectionList/RadioListItem'; +import type {ListItem} from '@components/SelectionList/types'; +import SelectionScreen from '@components/SelectionScreen'; +import type {SelectorType} from '@components/SelectionScreen'; +import Text from '@components/Text'; +import useLocalize from '@hooks/useLocalize'; +import useThemeStyles from '@hooks/useThemeStyles'; +import * as Connections from '@libs/actions/connections/QuickbooksOnline'; +import {settingsPendingAction} from '@libs/PolicyUtils'; +import Navigation from '@navigation/Navigation'; +import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections'; +import withPolicyConnections from '@pages/workspace/withPolicyConnections'; +import CONST from '@src/CONST'; +import type {TranslationPaths} from '@src/languages/types'; +import ROUTES from '@src/ROUTES'; + +type MenuListItem = ListItem & { + value: ValueOf; +}; + +function QuickbooksAccountingMethodPage({policy}: WithPolicyConnectionsProps) { + const {translate} = useLocalize(); + const policyID = policy?.id ?? '-1'; + const styles = useThemeStyles(); + const config = policy?.connections?.quickbooksOnline?.config; + const accountingMethod = config?.accountingMethod ?? COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.CASH; + const data: MenuListItem[] = Object.values(COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD).map((accountingMethodType) => ({ + value: accountingMethodType, + text: translate(`workspace.accountingMethods.values.${accountingMethodType}` as TranslationPaths), + alternateText: translate(`workspace.accountingMethods.alternateText.${accountingMethodType}` as TranslationPaths), + keyForList: accountingMethodType, + isSelected: accountingMethod === accountingMethodType, + })); + + const pendingAction = + settingsPendingAction([CONST.QUICKBOOKS_CONFIG.AUTO_SYNC], config?.pendingFields) ?? settingsPendingAction([CONST.QUICKBOOKS_CONFIG.ACCOUNTING_METHOD], config?.pendingFields); + + const headerContent = useMemo( + () => ( + + {translate('workspace.accountingMethods.description')} + + ), + [translate, styles.pb5, styles.ph5], + ); + + const selectExpenseReportApprovalLevel = useCallback( + (row: MenuListItem) => { + if (row.value !== config?.accountingMethod) { + Connections.updateQuickbooksOnlineAccountingMethod(policyID, row.value, config?.accountingMethod ?? COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.CASH); + } + Navigation.goBack(ROUTES.WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_AUTO_SYNC.getRoute(policyID)); + }, + [config?.accountingMethod, policyID], + ); + + return ( + selectExpenseReportApprovalLevel(selection as MenuListItem)} + initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList} + policyID={policyID} + accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN]} + featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED} + onBackButtonPress={() => Navigation.goBack(ROUTES.WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_AUTO_SYNC.getRoute(policyID))} + connectionName={CONST.POLICY.CONNECTIONS.NAME.QBO} + pendingAction={pendingAction} + /> + ); +} + +QuickbooksAccountingMethodPage.displayName = 'QuickbooksAccountingMethodPage'; + +export default withPolicyConnections(QuickbooksAccountingMethodPage); diff --git a/src/pages/workspace/accounting/qbo/advanced/QuickbooksAdvancedPage.tsx b/src/pages/workspace/accounting/qbo/advanced/QuickbooksAdvancedPage.tsx index 14be504611125..278efd8fb78eb 100644 --- a/src/pages/workspace/accounting/qbo/advanced/QuickbooksAdvancedPage.tsx +++ b/src/pages/workspace/accounting/qbo/advanced/QuickbooksAdvancedPage.tsx @@ -1,3 +1,4 @@ +import {CONST as COMMON_CONST} from 'expensify-common'; import React, {useMemo} from 'react'; import {View} from 'react-native'; import Accordion from '@components/Accordion'; @@ -12,12 +13,13 @@ 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 {settingsPendingAction} from '@libs/PolicyUtils'; +import {areSettingsInErrorFields, settingsPendingAction} from '@libs/PolicyUtils'; import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; import ToggleSettingOptionRow from '@pages/workspace/workflows/ToggleSettingsOptionRow'; import {clearQBOErrorField} from '@userActions/Policy/Policy'; import CONST from '@src/CONST'; +import {TranslationPaths} from '@src/languages/types'; import ROUTES from '@src/ROUTES'; const reimbursementOrCollectionAccountIDs = [CONST.QUICKBOOKS_CONFIG.REIMBURSEMENT_ACCOUNT_ID, CONST.QUICKBOOKS_CONFIG.COLLECTION_ACCOUNT_ID]; @@ -30,6 +32,7 @@ function QuickbooksAdvancedPage({policy}: WithPolicyConnectionsProps) { const policyID = policy?.id ?? '-1'; const qboConfig = policy?.connections?.quickbooksOnline?.config; + const accountingMethod = policy?.connections?.quickbooksOnline?.config?.accountingMethod; const {bankAccounts, creditCards, otherCurrentAssetAccounts, vendors} = policy?.connections?.quickbooksOnline?.data ?? {}; const nonReimbursableBillDefaultVendorObject = vendors?.find((vendor) => vendor.id === qboConfig?.nonReimbursableBillDefaultVendor); @@ -88,16 +91,6 @@ function QuickbooksAdvancedPage({policy}: WithPolicyConnectionsProps) { ); const qboToggleSettingItems = [ - { - title: translate('workspace.accounting.autoSync'), - subtitle: translate('workspace.qbo.advancedConfig.autoSyncDescription'), - switchAccessibilityLabel: translate('workspace.qbo.advancedConfig.autoSyncDescription'), - isActive: !!qboConfig?.autoSync?.enabled, - onToggle: () => QuickbooksOnline.updateQuickbooksOnlineAutoSync(policyID, !qboConfig?.autoSync?.enabled), - subscribedSetting: CONST.QUICKBOOKS_CONFIG.AUTO_SYNC, - errors: ErrorUtils.getLatestErrorField(qboConfig, CONST.QUICKBOOKS_CONFIG.AUTO_SYNC), - pendingAction: settingsPendingAction([CONST.QUICKBOOKS_CONFIG.AUTO_SYNC], qboConfig?.pendingFields), - }, { title: translate('workspace.qbo.advancedConfig.inviteEmployees'), subtitle: translate('workspace.qbo.advancedConfig.inviteEmployeesDescription'), @@ -162,6 +155,26 @@ function QuickbooksAdvancedPage({policy}: WithPolicyConnectionsProps) { contentContainerStyle={[styles.pb2, styles.ph5]} connectionName={CONST.POLICY.CONNECTIONS.NAME.QBO} > + + Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_AUTO_SYNC.getRoute(policyID))} + brickRoadIndicator={ + areSettingsInErrorFields([CONST.QUICKBOOKS_CONFIG.AUTO_SYNC, CONST.QUICKBOOKS_CONFIG.ACCOUNTING_METHOD], qboConfig?.errorFields) + ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR + : undefined + } + hintText={(() => { + if (!qboConfig?.autoSync?.enabled) { + return undefined; + } + return translate(`workspace.accountingMethods.alternateText.${accountingMethod ?? COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.CASH}` as TranslationPaths); + })()} + /> + {qboToggleSettingItems.map((item) => ( + + Navigation.goBack(ROUTES.WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_ADVANCED.getRoute(policyID))} + /> + Policy.clearQuickbooksOnlineAutoSyncErrorField(policyID)} + onToggle={(isEnabled) => Connections.updateQuickbooksOnlineAutoSync(policyID, isEnabled)} + pendingAction={pendingAction} + errors={ErrorUtils.getLatestErrorField(config, CONST.QUICKBOOKS_CONFIG.AUTO_SYNC)} + /> + {!!config?.autoSync?.enabled && ( + + Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_ACCOUNTING_METHOD.getRoute(policyID))} + /> + + )} + + + ); +} + +QuickbooksAutoSyncPage.displayName = 'QuickbooksAutoSyncPage'; + +export default withPolicyConnections(QuickbooksAutoSyncPage); diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index 465b744deb0c5..978df16819804 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -476,6 +476,9 @@ type QBOConnectionConfig = OnyxCommon.OnyxValueWithOfflineFeedback<{ /** Credentials of the current QBO connection */ credentials: QBOCredentials; + + /** The accounting Method for NetSuite conenction config */ + accountingMethod?: ValueOf; }>; /** From 55640548153d749968da36354106d6e25f32808d Mon Sep 17 00:00:00 2001 From: Rutika Pawar <183392827+twilight2294@users.noreply.github.com> Date: Fri, 7 Mar 2025 09:20:43 +0000 Subject: [PATCH 2/3] fix lint issues --- src/ROUTES.ts | 6 +++--- src/libs/actions/Policy/Policy.ts | 2 +- src/libs/actions/connections/NetSuiteCommands.ts | 10 ++++++++-- src/libs/actions/connections/QuickbooksOnline.ts | 7 +++++-- .../advanced/NetSuiteAccountingMethodPage.tsx | 6 +++--- .../netsuite/advanced/NetSuiteAutoSyncPage.tsx | 14 +++++++------- .../advanced/QuickbooksAccountingMethodPage.tsx | 6 +++--- .../qbo/advanced/QuickbooksAdvancedPage.tsx | 10 +++++----- 8 files changed, 35 insertions(+), 26 deletions(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index de165cdc58555..c291e85f9719b 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -1133,7 +1133,7 @@ const ROUTES = { }, WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_AUTO_SYNC: { route: 'settings/workspaces/:policyID/connections/quickbooks-online/advanced/autosync', - getRoute: (policyID: string) => `settings/workspaces/${policyID}/connections/quickbooks-online/advanced/autosync` as const, + getRoute: (policyID: string | undefined) => `settings/workspaces/${policyID}/connections/quickbooks-online/advanced/autosync` as const, }, WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_ACCOUNTING_METHOD: { route: 'settings/workspaces/:policyID/connections/quickbooks-online/advanced/autosync/accounting-method', @@ -2023,11 +2023,11 @@ const ROUTES = { }, POLICY_ACCOUNTING_NETSUITE_AUTO_SYNC: { route: 'settings/workspaces/:policyID/connections/netsuite/advanced/autosync', - getRoute: (policyID: string) => `settings/workspaces/${policyID}/connections/netsuite/advanced/autosync` as const, + getRoute: (policyID: string | undefined) => `settings/workspaces/${policyID}/connections/netsuite/advanced/autosync` as const, }, POLICY_ACCOUNTING_NETSUITE_ACCOUNTING_METHOD: { route: 'settings/workspaces/:policyID/connections/netsuite/advanced/autosync/accounting-method', - getRoute: (policyID: string) => `settings/workspaces/${policyID}/connections/netsuite/advanced/autosync/accounting-method` as const, + getRoute: (policyID: string | undefined) => `settings/workspaces/${policyID}/connections/netsuite/advanced/autosync/accounting-method` as const, }, POLICY_ACCOUNTING_NSQS_SETUP: { route: 'settings/workspaces/:policyID/accounting/nsqs/setup', diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index dd1a9d88f8b2d..1ac9ee96da28a 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -692,7 +692,7 @@ function clearSageIntacctErrorField(policyID: string, fieldName: string) { Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {connections: {intacct: {config: {errorFields: {[fieldName]: null}}}}}); } -function clearNetSuiteAutoSyncErrorField(policyID: string) { +function clearNetSuiteAutoSyncErrorField(policyID: string | undefined) { Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {connections: {netsuite: {config: {errorFields: {autoSync: null}}}}}); } diff --git a/src/libs/actions/connections/NetSuiteCommands.ts b/src/libs/actions/connections/NetSuiteCommands.ts index bf5b2be4b4a04..f26885945d55a 100644 --- a/src/libs/actions/connections/NetSuiteCommands.ts +++ b/src/libs/actions/connections/NetSuiteCommands.ts @@ -766,7 +766,10 @@ function updateNetSuiteExportToNextOpenPeriod(policyID: string, value: boolean, API.write(WRITE_COMMANDS.UPDATE_NETSUITE_EXPORT_TO_NEXT_OPEN_PERIOD, parameters, onyxData); } -function updateNetSuiteAutoSync(policyID: string, value: boolean) { +function updateNetSuiteAutoSync(policyID: string | undefined, value: boolean) { + if (!policyID) { + return; + } const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -937,10 +940,13 @@ function updateNetSuiteExportReportsTo( } function updateNetSuiteAccountingMethod( - policyID: string, + policyID: string | undefined, accountingMethod: ValueOf, oldAccountingMethod: ValueOf, ) { + if (!policyID) { + return; + } const onyxData = updateNetSuiteOnyxData(policyID, CONST.NETSUITE_CONFIG.ACCOUNTING_METHOD, accountingMethod, oldAccountingMethod); const parameters = { diff --git a/src/libs/actions/connections/QuickbooksOnline.ts b/src/libs/actions/connections/QuickbooksOnline.ts index 805f02b7658cf..7ad356fd3f40b 100644 --- a/src/libs/actions/connections/QuickbooksOnline.ts +++ b/src/libs/actions/connections/QuickbooksOnline.ts @@ -1,7 +1,7 @@ import type {CONST as COMMON_CONST} from 'expensify-common'; import type {OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; -import {ValueOf} from 'type-fest'; +import type {ValueOf} from 'type-fest'; import * as API from '@libs/API'; import type {ConnectPolicyToAccountingIntegrationParams, UpdateQuickbooksOnlineAccountingMethodParams} from '@libs/API/parameters'; import type UpdateQuickbooksOnlineAutoCreateVendorParams from '@libs/API/parameters/UpdateQuickbooksOnlineAutoCreateVendorParams'; @@ -406,10 +406,13 @@ function updateQuickbooksOnlinePreferredExporter, oldAccountingMethod: ValueOf, ) { + if (!policyID) { + return; + } const onyxData = buildOnyxDataForQuickbooksConfiguration(policyID, CONST.QUICKBOOKS_CONFIG.ACCOUNTING_METHOD, accountingMethod, oldAccountingMethod); const parameters: UpdateQuickbooksOnlineAccountingMethodParams = { diff --git a/src/pages/workspace/accounting/netsuite/advanced/NetSuiteAccountingMethodPage.tsx b/src/pages/workspace/accounting/netsuite/advanced/NetSuiteAccountingMethodPage.tsx index 03dcc80889d60..f08f79895cbb9 100644 --- a/src/pages/workspace/accounting/netsuite/advanced/NetSuiteAccountingMethodPage.tsx +++ b/src/pages/workspace/accounting/netsuite/advanced/NetSuiteAccountingMethodPage.tsx @@ -9,7 +9,7 @@ import type {SelectorType} from '@components/SelectionScreen'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import * as Connections from '@libs/actions/connections/NetSuiteCommands'; +import {updateNetSuiteAccountingMethod} from '@libs/actions/connections/NetSuiteCommands'; import {settingsPendingAction} from '@libs/PolicyUtils'; import Navigation from '@navigation/Navigation'; import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections'; @@ -24,7 +24,7 @@ type MenuListItem = ListItem & { function NetSuiteAccountingMethodPage({policy}: WithPolicyConnectionsProps) { const {translate} = useLocalize(); - const policyID = policy?.id ?? '-1'; + const policyID = policy?.id; const styles = useThemeStyles(); const config = policy?.connections?.netsuite?.options?.config; const autoSyncConfig = policy?.connections?.netsuite?.config; @@ -52,7 +52,7 @@ function NetSuiteAccountingMethodPage({policy}: WithPolicyConnectionsProps) { const selectExpenseReportApprovalLevel = useCallback( (row: MenuListItem) => { if (row.value !== config?.accountingMethod) { - Connections.updateNetSuiteAccountingMethod(policyID, row.value, config?.accountingMethod ?? COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.CASH); + updateNetSuiteAccountingMethod(policyID, row.value, config?.accountingMethod ?? COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.CASH); } Navigation.goBack(ROUTES.POLICY_ACCOUNTING_NETSUITE_AUTO_SYNC.getRoute(policyID)); }, diff --git a/src/pages/workspace/accounting/netsuite/advanced/NetSuiteAutoSyncPage.tsx b/src/pages/workspace/accounting/netsuite/advanced/NetSuiteAutoSyncPage.tsx index 5fc2903adacb0..70a364a3d56a7 100644 --- a/src/pages/workspace/accounting/netsuite/advanced/NetSuiteAutoSyncPage.tsx +++ b/src/pages/workspace/accounting/netsuite/advanced/NetSuiteAutoSyncPage.tsx @@ -8,15 +8,15 @@ import ScreenWrapper from '@components/ScreenWrapper'; import useAccordionAnimation from '@hooks/useAccordionAnimation'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import * as Connections from '@libs/actions/connections/NetSuiteCommands'; -import * as ErrorUtils from '@libs/ErrorUtils'; +import {updateNetSuiteAutoSync} from '@libs/actions/connections/NetSuiteCommands'; +import {getLatestErrorField} from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; import {settingsPendingAction} from '@libs/PolicyUtils'; 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 Policy from '@userActions/Policy/Policy'; +import {clearNetSuiteAutoSyncErrorField} from '@userActions/Policy/Policy'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ROUTES from '@src/ROUTES'; @@ -26,7 +26,7 @@ function NetSuiteAutoSyncPage({policy, route}: WithPolicyConnectionsProps) { const {translate} = useLocalize(); const config = policy?.connections?.netsuite?.options?.config; const autoSyncConfig = policy?.connections?.netsuite?.config; - const policyID = route.params.policyID ?? '-1'; + const policyID = route.params.policyID; const accountingMethod = policy?.connections?.netsuite?.options?.config?.accountingMethod; const pendingAction = settingsPendingAction([CONST.NETSUITE_CONFIG.AUTO_SYNC], autoSyncConfig?.pendingFields) ?? settingsPendingAction([CONST.NETSUITE_CONFIG.ACCOUNTING_METHOD], config?.pendingFields); @@ -57,10 +57,10 @@ function NetSuiteAutoSyncPage({policy, route}: WithPolicyConnectionsProps) { wrapperStyle={[styles.pv2, styles.mh5]} switchAccessibilityLabel={translate('workspace.netsuite.advancedConfig.autoSyncDescription')} shouldPlaceSubtitleBelowSwitch - onCloseError={() => Policy.clearNetSuiteAutoSyncErrorField(policyID)} - onToggle={(isEnabled) => Connections.updateNetSuiteAutoSync(policyID, isEnabled)} + onCloseError={() => clearNetSuiteAutoSyncErrorField(policyID)} + onToggle={(isEnabled) => updateNetSuiteAutoSync(policyID, isEnabled)} pendingAction={pendingAction} - errors={ErrorUtils.getLatestErrorField(autoSyncConfig, CONST.NETSUITE_CONFIG.AUTO_SYNC)} + errors={getLatestErrorField(autoSyncConfig, CONST.NETSUITE_CONFIG.AUTO_SYNC)} /> { if (row.value !== config?.accountingMethod) { - Connections.updateQuickbooksOnlineAccountingMethod(policyID, row.value, config?.accountingMethod ?? COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.CASH); + updateQuickbooksOnlineAccountingMethod(policyID, row.value, config?.accountingMethod ?? COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.CASH); } Navigation.goBack(ROUTES.WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_AUTO_SYNC.getRoute(policyID)); }, diff --git a/src/pages/workspace/accounting/qbo/advanced/QuickbooksAdvancedPage.tsx b/src/pages/workspace/accounting/qbo/advanced/QuickbooksAdvancedPage.tsx index 278efd8fb78eb..c2934769545e1 100644 --- a/src/pages/workspace/accounting/qbo/advanced/QuickbooksAdvancedPage.tsx +++ b/src/pages/workspace/accounting/qbo/advanced/QuickbooksAdvancedPage.tsx @@ -9,7 +9,7 @@ import useAccordionAnimation from '@hooks/useAccordionAnimation'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import useWaitForNavigation from '@hooks/useWaitForNavigation'; -import * as QuickbooksOnline from '@libs/actions/connections/QuickbooksOnline'; +import {updateQuickbooksOnlineAutoCreateVendor, updateQuickbooksOnlineCollectionAccountID, updateQuickbooksOnlineSyncPeople} from '@libs/actions/connections/QuickbooksOnline'; import * as ErrorUtils from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; import * as PolicyUtils from '@libs/PolicyUtils'; @@ -19,7 +19,7 @@ import withPolicyConnections from '@pages/workspace/withPolicyConnections'; import ToggleSettingOptionRow from '@pages/workspace/workflows/ToggleSettingsOptionRow'; import {clearQBOErrorField} from '@userActions/Policy/Policy'; import CONST from '@src/CONST'; -import {TranslationPaths} from '@src/languages/types'; +import type {TranslationPaths} from '@src/languages/types'; import ROUTES from '@src/ROUTES'; const reimbursementOrCollectionAccountIDs = [CONST.QUICKBOOKS_CONFIG.REIMBURSEMENT_ACCOUNT_ID, CONST.QUICKBOOKS_CONFIG.COLLECTION_ACCOUNT_ID]; @@ -96,7 +96,7 @@ function QuickbooksAdvancedPage({policy}: WithPolicyConnectionsProps) { subtitle: translate('workspace.qbo.advancedConfig.inviteEmployeesDescription'), switchAccessibilityLabel: translate('workspace.qbo.advancedConfig.inviteEmployeesDescription'), isActive: !!qboConfig?.syncPeople, - onToggle: () => QuickbooksOnline.updateQuickbooksOnlineSyncPeople(policyID, !qboConfig?.syncPeople), + onToggle: () => updateQuickbooksOnlineSyncPeople(policyID, !qboConfig?.syncPeople), subscribedSetting: CONST.QUICKBOOKS_CONFIG.SYNC_PEOPLE, errors: ErrorUtils.getLatestErrorField(qboConfig, CONST.QUICKBOOKS_CONFIG.SYNC_PEOPLE), pendingAction: settingsPendingAction([CONST.QUICKBOOKS_CONFIG.SYNC_PEOPLE], qboConfig?.pendingFields), @@ -112,7 +112,7 @@ function QuickbooksAdvancedPage({policy}: WithPolicyConnectionsProps) { : CONST.INTEGRATION_ENTITY_MAP_TYPES.NONE; const nonReimbursableVendorCurrentValue = nonReimbursableBillDefaultVendorObject?.id ?? CONST.INTEGRATION_ENTITY_MAP_TYPES.NONE; - QuickbooksOnline.updateQuickbooksOnlineAutoCreateVendor( + updateQuickbooksOnlineAutoCreateVendor( policyID, { [autoCreateVendorConst]: isOn, @@ -134,7 +134,7 @@ function QuickbooksAdvancedPage({policy}: WithPolicyConnectionsProps) { switchAccessibilityLabel: translate('workspace.qbo.advancedConfig.reimbursedReportsDescription'), isActive: isSyncReimbursedSwitchOn, onToggle: () => - QuickbooksOnline.updateQuickbooksOnlineCollectionAccountID( + updateQuickbooksOnlineCollectionAccountID( policyID, isSyncReimbursedSwitchOn ? '' : [...qboAccountOptions, ...invoiceAccountCollectionOptions].at(0)?.id, qboConfig?.collectionAccountID, From 2e17aca0f8f4b257742f60d1f3cdfb7a2e70df78 Mon Sep 17 00:00:00 2001 From: Rutika Pawar <183392827+twilight2294@users.noreply.github.com> Date: Fri, 7 Mar 2025 09:54:32 +0000 Subject: [PATCH 3/3] fix lint: part 2 --- src/ROUTES.ts | 6 +++--- src/libs/actions/Policy/Policy.ts | 2 +- .../actions/connections/QuickbooksOnline.ts | 19 ++++++++++++++----- .../qbo/advanced/QuickbooksAdvancedPage.tsx | 19 +++++++++---------- .../qbo/advanced/QuickbooksAutoSyncPage.tsx | 14 +++++++------- 5 files changed, 34 insertions(+), 26 deletions(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index c291e85f9719b..cfdc03ceb0a19 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -1125,11 +1125,11 @@ const ROUTES = { }, WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_ACCOUNT_SELECTOR: { route: 'settings/workspaces/:policyID/accounting/quickbooks-online/account-selector', - getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/quickbooks-online/account-selector` as const, + getRoute: (policyID: string | undefined) => `settings/workspaces/${policyID}/accounting/quickbooks-online/account-selector` as const, }, WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_INVOICE_ACCOUNT_SELECTOR: { route: 'settings/workspaces/:policyID/accounting/quickbooks-online/invoice-account-selector', - getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/quickbooks-online/invoice-account-selector` as const, + getRoute: (policyID: string | undefined) => `settings/workspaces/${policyID}/accounting/quickbooks-online/invoice-account-selector` as const, }, WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_AUTO_SYNC: { route: 'settings/workspaces/:policyID/connections/quickbooks-online/advanced/autosync', @@ -1137,7 +1137,7 @@ const ROUTES = { }, WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_ACCOUNTING_METHOD: { route: 'settings/workspaces/:policyID/connections/quickbooks-online/advanced/autosync/accounting-method', - getRoute: (policyID: string) => `settings/workspaces/${policyID}/connections/quickbooks-online/advanced/autosync/accounting-method` as const, + getRoute: (policyID: string | undefined) => `settings/workspaces/${policyID}/connections/quickbooks-online/advanced/autosync/accounting-method` as const, }, WORKSPACE_ACCOUNTING_CARD_RECONCILIATION: { route: 'settings/workspaces/:policyID/accounting/:connection/card-reconciliation', diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 1ac9ee96da28a..b73c681f29699 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -696,7 +696,7 @@ function clearNetSuiteAutoSyncErrorField(policyID: string | undefined) { Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {connections: {netsuite: {config: {errorFields: {autoSync: null}}}}}); } -function clearQuickbooksOnlineAutoSyncErrorField(policyID: string) { +function clearQuickbooksOnlineAutoSyncErrorField(policyID: string | undefined) { Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {connections: {quickbooksOnline: {config: {errorFields: {autoSync: null}}}}}); } diff --git a/src/libs/actions/connections/QuickbooksOnline.ts b/src/libs/actions/connections/QuickbooksOnline.ts index 7ad356fd3f40b..1d32887daf991 100644 --- a/src/libs/actions/connections/QuickbooksOnline.ts +++ b/src/libs/actions/connections/QuickbooksOnline.ts @@ -166,7 +166,10 @@ function buildOnyxDataForQuickbooksConfiguration(policyID: string, settingValue: TSettingValue) { +function updateQuickbooksOnlineAutoSync(policyID: string | undefined, settingValue: TSettingValue) { + if (!policyID) { + return; + } const onyxData = buildOnyxDataForQuickbooksConfiguration(policyID, CONST.QUICKBOOKS_CONFIG.AUTO_SYNC, {enabled: settingValue}, {enabled: !settingValue}); const parameters: UpdateQuickbooksOnlineGenericTypeParams = { @@ -189,10 +192,13 @@ function updateQuickbooksOnlineEnableNewCategories>( - policyID: string, + policyID: string | undefined, configUpdate: TConfigUpdate, configCurrentData: TConfigUpdate, ) { + if (!policyID) { + return; + } const onyxData = buildOnyxDataForMultipleQuickbooksConfigurations(policyID, configUpdate, configCurrentData); const parameters: UpdateQuickbooksOnlineAutoCreateVendorParams = { @@ -205,7 +211,10 @@ function updateQuickbooksOnlineAutoCreateVendor(policyID: string, settingValue: TSettingValue) { +function updateQuickbooksOnlineSyncPeople(policyID: string | undefined, settingValue: TSettingValue) { + if (!policyID) { + return; + } const onyxData = buildOnyxDataForQuickbooksConfiguration(policyID, CONST.QUICKBOOKS_CONFIG.SYNC_PEOPLE, settingValue, !settingValue); const parameters: UpdateQuickbooksOnlineGenericTypeParams = { @@ -340,11 +349,11 @@ function updateQuickbooksOnlineNonReimbursableExpensesAccount( - policyID: string, + policyID: string | undefined, settingValue: TSettingValue, oldSettingValue?: TSettingValue, ) { - if (settingValue === oldSettingValue) { + if (settingValue === oldSettingValue || !policyID) { return; } diff --git a/src/pages/workspace/accounting/qbo/advanced/QuickbooksAdvancedPage.tsx b/src/pages/workspace/accounting/qbo/advanced/QuickbooksAdvancedPage.tsx index c2934769545e1..d2ecb144f76f4 100644 --- a/src/pages/workspace/accounting/qbo/advanced/QuickbooksAdvancedPage.tsx +++ b/src/pages/workspace/accounting/qbo/advanced/QuickbooksAdvancedPage.tsx @@ -10,9 +10,8 @@ import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import useWaitForNavigation from '@hooks/useWaitForNavigation'; import {updateQuickbooksOnlineAutoCreateVendor, updateQuickbooksOnlineCollectionAccountID, updateQuickbooksOnlineSyncPeople} from '@libs/actions/connections/QuickbooksOnline'; -import * as ErrorUtils from '@libs/ErrorUtils'; +import {getLatestErrorField} from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; -import * as PolicyUtils from '@libs/PolicyUtils'; import {areSettingsInErrorFields, settingsPendingAction} from '@libs/PolicyUtils'; import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections'; import withPolicyConnections from '@pages/workspace/withPolicyConnections'; @@ -30,7 +29,7 @@ function QuickbooksAdvancedPage({policy}: WithPolicyConnectionsProps) { const waitForNavigate = useWaitForNavigation(); const {translate} = useLocalize(); - const policyID = policy?.id ?? '-1'; + const policyID = policy?.id; const qboConfig = policy?.connections?.quickbooksOnline?.config; const accountingMethod = policy?.connections?.quickbooksOnline?.config?.accountingMethod; const {bankAccounts, creditCards, otherCurrentAssetAccounts, vendors} = policy?.connections?.quickbooksOnline?.data ?? {}; @@ -60,16 +59,16 @@ function QuickbooksAdvancedPage({policy}: WithPolicyConnectionsProps) { description: translate('workspace.qbo.advancedConfig.qboBillPaymentAccount'), onPress: waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_ACCOUNT_SELECTOR.getRoute(policyID))), subscribedSettings: reimbursementOrCollectionAccountIDs, - brickRoadIndicator: PolicyUtils.areSettingsInErrorFields(reimbursementOrCollectionAccountIDs, qboConfig?.errorFields) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, - pendingAction: PolicyUtils.settingsPendingAction(reimbursementOrCollectionAccountIDs, qboConfig?.pendingFields), + brickRoadIndicator: areSettingsInErrorFields(reimbursementOrCollectionAccountIDs, qboConfig?.errorFields) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, + pendingAction: settingsPendingAction(reimbursementOrCollectionAccountIDs, qboConfig?.pendingFields), }, { title: selectedInvoiceCollectionAccountName, description: translate('workspace.qbo.advancedConfig.qboInvoiceCollectionAccount'), onPress: waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_ACCOUNTING_QUICKBOOKS_ONLINE_INVOICE_ACCOUNT_SELECTOR.getRoute(policyID))), subscribedSettings: collectionAccountIDs, - brickRoadIndicator: PolicyUtils.areSettingsInErrorFields(collectionAccountIDs, qboConfig?.errorFields) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, - pendingAction: PolicyUtils.settingsPendingAction(collectionAccountIDs, qboConfig?.pendingFields), + brickRoadIndicator: areSettingsInErrorFields(collectionAccountIDs, qboConfig?.errorFields) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, + pendingAction: settingsPendingAction(collectionAccountIDs, qboConfig?.pendingFields), }, ]; @@ -98,7 +97,7 @@ function QuickbooksAdvancedPage({policy}: WithPolicyConnectionsProps) { isActive: !!qboConfig?.syncPeople, onToggle: () => updateQuickbooksOnlineSyncPeople(policyID, !qboConfig?.syncPeople), subscribedSetting: CONST.QUICKBOOKS_CONFIG.SYNC_PEOPLE, - errors: ErrorUtils.getLatestErrorField(qboConfig, CONST.QUICKBOOKS_CONFIG.SYNC_PEOPLE), + errors: getLatestErrorField(qboConfig, CONST.QUICKBOOKS_CONFIG.SYNC_PEOPLE), pendingAction: settingsPendingAction([CONST.QUICKBOOKS_CONFIG.SYNC_PEOPLE], qboConfig?.pendingFields), }, { @@ -125,7 +124,7 @@ function QuickbooksAdvancedPage({policy}: WithPolicyConnectionsProps) { ); }, subscribedSetting: CONST.QUICKBOOKS_CONFIG.AUTO_CREATE_VENDOR, - errors: ErrorUtils.getLatestErrorField(qboConfig, CONST.QUICKBOOKS_CONFIG.AUTO_CREATE_VENDOR), + errors: getLatestErrorField(qboConfig, CONST.QUICKBOOKS_CONFIG.AUTO_CREATE_VENDOR), pendingAction: settingsPendingAction([CONST.QUICKBOOKS_CONFIG.AUTO_CREATE_VENDOR], qboConfig?.pendingFields), }, { @@ -140,7 +139,7 @@ function QuickbooksAdvancedPage({policy}: WithPolicyConnectionsProps) { qboConfig?.collectionAccountID, ), subscribedSetting: CONST.QUICKBOOKS_CONFIG.COLLECTION_ACCOUNT_ID, - errors: ErrorUtils.getLatestErrorField(qboConfig, CONST.QUICKBOOKS_CONFIG.COLLECTION_ACCOUNT_ID), + errors: getLatestErrorField(qboConfig, CONST.QUICKBOOKS_CONFIG.COLLECTION_ACCOUNT_ID), pendingAction: settingsPendingAction([CONST.QUICKBOOKS_CONFIG.COLLECTION_ACCOUNT_ID], qboConfig?.pendingFields), }, ]; diff --git a/src/pages/workspace/accounting/qbo/advanced/QuickbooksAutoSyncPage.tsx b/src/pages/workspace/accounting/qbo/advanced/QuickbooksAutoSyncPage.tsx index abdfe80616a82..f4a5814342dce 100644 --- a/src/pages/workspace/accounting/qbo/advanced/QuickbooksAutoSyncPage.tsx +++ b/src/pages/workspace/accounting/qbo/advanced/QuickbooksAutoSyncPage.tsx @@ -6,15 +6,15 @@ import OfflineWithFeedback from '@components/OfflineWithFeedback'; import ScreenWrapper from '@components/ScreenWrapper'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; -import * as Connections from '@libs/actions/connections/QuickbooksOnline'; -import * as ErrorUtils from '@libs/ErrorUtils'; +import {updateQuickbooksOnlineAutoSync} from '@libs/actions/connections/QuickbooksOnline'; +import {getLatestErrorField} from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; import {settingsPendingAction} from '@libs/PolicyUtils'; 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 Policy from '@userActions/Policy/Policy'; +import {clearQuickbooksOnlineAutoSyncErrorField} from '@userActions/Policy/Policy'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ROUTES from '@src/ROUTES'; @@ -23,7 +23,7 @@ function QuickbooksAutoSyncPage({policy, route}: WithPolicyConnectionsProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); const config = policy?.connections?.quickbooksOnline?.config; - const policyID = route.params.policyID ?? '-1'; + const policyID = route.params.policyID; const accountingMethod = config?.accountingMethod ?? COMMON_CONST.INTEGRATIONS.ACCOUNTING_METHOD.CASH; const pendingAction = settingsPendingAction([CONST.QUICKBOOKS_CONFIG.AUTO_SYNC], config?.pendingFields) ?? settingsPendingAction([CONST.QUICKBOOKS_CONFIG.ACCOUNTING_METHOD], config?.pendingFields); @@ -50,10 +50,10 @@ function QuickbooksAutoSyncPage({policy, route}: WithPolicyConnectionsProps) { wrapperStyle={[styles.pv2, styles.mh5]} switchAccessibilityLabel={translate('workspace.qbo.advancedConfig.autoSyncDescription')} shouldPlaceSubtitleBelowSwitch - onCloseError={() => Policy.clearQuickbooksOnlineAutoSyncErrorField(policyID)} - onToggle={(isEnabled) => Connections.updateQuickbooksOnlineAutoSync(policyID, isEnabled)} + onCloseError={() => clearQuickbooksOnlineAutoSyncErrorField(policyID)} + onToggle={(isEnabled) => updateQuickbooksOnlineAutoSync(policyID, isEnabled)} pendingAction={pendingAction} - errors={ErrorUtils.getLatestErrorField(config, CONST.QUICKBOOKS_CONFIG.AUTO_SYNC)} + errors={getLatestErrorField(config, CONST.QUICKBOOKS_CONFIG.AUTO_SYNC)} /> {!!config?.autoSync?.enabled && (