Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2092,6 +2092,15 @@ const ROUTES = {
return `workspaces/${policyID}/accounting/quickbooks-online/export/company-card-expense-account/default-vendor-select` as const;
},
},
POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_NON_REIMBURSABLE_CREDIT_CARD_DEFAULT_VENDOR_SELECT: {
route: 'workspaces/:policyID/accounting/quickbooks-online/export/company-card-expense-account/credit-card-default-vendor-select',
getRoute: (policyID: string | undefined) => {
if (!policyID) {
Log.warn('Invalid policyID is used to build the POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_NON_REIMBURSABLE_CREDIT_CARD_DEFAULT_VENDOR_SELECT route');
}
return `workspaces/${policyID}/accounting/quickbooks-online/export/company-card-expense-account/credit-card-default-vendor-select` as const;
},
},
POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_COMPANY_CARD_EXPENSE_SELECT: {
route: 'workspaces/:policyID/accounting/quickbooks-online/export/company-card-expense-account/card-select',
getRoute: (policyID: string | undefined, backTo?: string) => {
Expand Down
1 change: 1 addition & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,7 @@ const SCREENS = {
DYNAMIC_QUICKBOOKS_ONLINE_COMPANY_CARD_EXPENSE_ACCOUNT: 'Dynamic_Workspace_Accounting_Quickbooks_Online_Export_Company_Card_Expense',
DYNAMIC_QUICKBOOKS_ONLINE_COMPANY_CARD_EXPENSE_ACCOUNT_SELECT: 'Dynamic_Workspace_Accounting_Quickbooks_Online_Export_Company_Card_Expense_Account_Select',
QUICKBOOKS_ONLINE_NON_REIMBURSABLE_DEFAULT_VENDOR_SELECT: 'Workspace_Accounting_Quickbooks_Online_Export_Non_Reimbursable_Default_Vendor_Select',
QUICKBOOKS_ONLINE_NON_REIMBURSABLE_CREDIT_CARD_DEFAULT_VENDOR_SELECT: 'Workspace_Accounting_Quickbooks_Online_Export_Non_Reimbursable_Credit_Card_Default_Vendor_Select',
DYNAMIC_QUICKBOOKS_ONLINE_COMPANY_CARD_EXPENSE_ACCOUNT_COMPANY_CARD_SELECT: 'Dynamic_Workspace_Accounting_Quickbooks_Online_Export_Company_Card_Expense_Select',
DYNAMIC_QUICKBOOKS_ONLINE_EXPORT_PREFERRED_EXPORTER: 'Dynamic_Workspace_Accounting_Quickbooks_Online_Export_Preferred_Exporter',
QUICKBOOKS_ONLINE_TRAVEL_INVOICING_CONFIGURATION: 'Workspace_Accounting_Quickbooks_Online_Travel_Invoicing_Configuration',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,8 @@ const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorP
require<ReactComponentModule>('../../../../pages/workspace/accounting/qbo/export/DynamicQuickbooksOutOfPocketExpenseEntitySelectPage').default,
[SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_NON_REIMBURSABLE_DEFAULT_VENDOR_SELECT]: () =>
require<ReactComponentModule>('../../../../pages/workspace/accounting/qbo/export/QuickbooksNonReimbursableDefaultVendorSelectPage').default,
[SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_NON_REIMBURSABLE_CREDIT_CARD_DEFAULT_VENDOR_SELECT]: () =>
require<ReactComponentModule>('../../../../pages/workspace/accounting/qbo/export/QuickbooksNonReimbursableCreditCardDefaultVendorSelectPage').default,
[SCREENS.WORKSPACE.ACCOUNTING.DYNAMIC_QUICKBOOKS_ONLINE_COMPANY_CARD_EXPENSE_ACCOUNT_SELECT]: () =>
require<ReactComponentModule>('@pages/workspace/accounting/qbo/export/DynamicQuickbooksCompanyCardExpenseAccountSelectPage').default,
[SCREENS.WORKSPACE.ACCOUNTING.DYNAMIC_QUICKBOOKS_ONLINE_COMPANY_CARD_EXPENSE_ACCOUNT_COMPANY_CARD_SELECT]: () =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const WORKSPACE_TO_RHP: Partial<Record<keyof WorkspaceSplitNavigatorParamList, s
SCREENS.WORKSPACE.ACCOUNTING.NETSUITE_TRAVEL_INVOICING_PAYABLE_ACCOUNT_SELECT,
SCREENS.WORKSPACE.ACCOUNTING.NETSUITE_TRAVEL_INVOICING_JOURNAL_POSTING_PREFERENCE_SELECT,
SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_NON_REIMBURSABLE_DEFAULT_VENDOR_SELECT,
SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_NON_REIMBURSABLE_CREDIT_CARD_DEFAULT_VENDOR_SELECT,
SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_ADVANCED,
SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_ACCOUNT_SELECTOR,
SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_INVOICE_ACCOUNT_SELECTOR,
Expand Down
3 changes: 3 additions & 0 deletions src/libs/Navigation/linkingConfig/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,9 @@ const config: LinkingOptions<RootNavigatorParamList>['config'] = {
[SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_NON_REIMBURSABLE_DEFAULT_VENDOR_SELECT]: {
path: ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_NON_REIMBURSABLE_DEFAULT_VENDOR_SELECT.route,
},
[SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_NON_REIMBURSABLE_CREDIT_CARD_DEFAULT_VENDOR_SELECT]: {
path: ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_NON_REIMBURSABLE_CREDIT_CARD_DEFAULT_VENDOR_SELECT.route,
},
[SCREENS.WORKSPACE.ACCOUNTING.DYNAMIC_QUICKBOOKS_ONLINE_COMPANY_CARD_EXPENSE_ACCOUNT]:
DYNAMIC_ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_COMPANY_CARD_EXPENSE_ACCOUNT.path,
[SCREENS.WORKSPACE.ACCOUNTING.DYNAMIC_QUICKBOOKS_ONLINE_COMPANY_CARD_EXPENSE_ACCOUNT_COMPANY_CARD_SELECT]:
Expand Down
3 changes: 3 additions & 0 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,9 @@ type SettingsNavigatorParamList = {
[SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_NON_REIMBURSABLE_DEFAULT_VENDOR_SELECT]: {
policyID: string;
};
[SCREENS.WORKSPACE.ACCOUNTING.QUICKBOOKS_ONLINE_NON_REIMBURSABLE_CREDIT_CARD_DEFAULT_VENDOR_SELECT]: {
policyID: string;
};
[SCREENS.WORKSPACE.ACCOUNTING.DYNAMIC_QUICKBOOKS_ONLINE_COMPANY_CARD_EXPENSE_ACCOUNT_SELECT]: {
policyID: string;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ import OfflineWithFeedback from '@components/OfflineWithFeedback';
import useAccordionAnimation from '@hooks/useAccordionAnimation';
import useDynamicBackPath from '@hooks/useDynamicBackPath';
import useLocalize from '@hooks/useLocalize';
import usePermissions from '@hooks/usePermissions';
import useThemeStyles from '@hooks/useThemeStyles';
import {updateManyPolicyConnectionConfigs} from '@libs/actions/connections';
import {getQBONonReimbursableExportAccountType} from '@libs/ConnectionUtils';
import {getLatestErrorField} from '@libs/ErrorUtils';
import createDynamicRoute from '@libs/Navigation/helpers/dynamicRoutesUtils/createDynamicRoute';
import {areSettingsInErrorFields, settingsPendingAction} from '@libs/PolicyUtils';
import {areSettingsInErrorFields, getQBOVendorByID, hasVendorFeature, settingsPendingAction} from '@libs/PolicyUtils';
import Navigation from '@navigation/Navigation';
import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections';
import withPolicyConnections from '@pages/workspace/withPolicyConnections';
Expand All @@ -23,10 +24,13 @@ import ROUTES, {DYNAMIC_ROUTES} from '@src/ROUTES';
function DynamicQuickbooksCompanyCardExpenseAccountPage({policy}: WithPolicyConnectionsProps) {
const {translate} = useLocalize();
const styles = useThemeStyles();
const {isBetaEnabled} = usePermissions();
const policyID = policy?.id;
const qboConfig = policy?.connections?.quickbooksOnline?.config;
const {vendors} = policy?.connections?.quickbooksOnline?.data ?? {};
const nonReimbursableBillDefaultVendorObject = vendors?.find((vendor) => vendor.id === qboConfig?.nonReimbursableBillDefaultVendor);
const nonReimbursableCreditCardDefaultVendorObject = getQBOVendorByID(policy, qboConfig?.nonReimbursableCreditCardDefaultVendor);
const isVendorFeatureAvailable = hasVendorFeature(policy, isBetaEnabled(CONST.BETAS.VENDOR_MATCHING));
const backPath = useDynamicBackPath(DYNAMIC_ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_COMPANY_CARD_EXPENSE_ACCOUNT.path);
const {isAccordionExpanded, shouldAnimateAccordionSection} = useAccordionAnimation(!!qboConfig?.autoCreateVendor);

Expand Down Expand Up @@ -79,6 +83,21 @@ function DynamicQuickbooksCompanyCardExpenseAccountPage({policy}: WithPolicyConn
/>
</OfflineWithFeedback>
))}
{isVendorFeatureAvailable && (
<OfflineWithFeedback pendingAction={settingsPendingAction([CONST.QUICKBOOKS_CONFIG.NON_REIMBURSABLE_CREDIT_CARD_DEFAULT_VENDOR], qboConfig?.pendingFields)}>
<MenuItemWithTopDescription
title={nonReimbursableCreditCardDefaultVendorObject?.name}
description={translate('workspace.accounting.defaultVendor')}
onPress={() => Navigation.navigate(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_NON_REIMBURSABLE_CREDIT_CARD_DEFAULT_VENDOR_SELECT.getRoute(policyID))}
brickRoadIndicator={
areSettingsInErrorFields([CONST.QUICKBOOKS_CONFIG.NON_REIMBURSABLE_CREDIT_CARD_DEFAULT_VENDOR], qboConfig?.errorFields)
? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR
: undefined
}
shouldShowRightIcon
/>
</OfflineWithFeedback>
)}
{qboConfig?.nonReimbursableExpensesExportDestination === CONST.QUICKBOOKS_NON_REIMBURSABLE_EXPORT_ACCOUNT_TYPE.VENDOR_BILL && (
<>
<ToggleSettingOptionRow
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import React, {useCallback, useMemo} from 'react';
import BlockingView from '@components/BlockingViews/BlockingView';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import {updateQuickbooksOnlineNonReimbursableCreditCardDefaultVendor} from '@libs/actions/connections/QuickbooksOnline';
import {getLatestErrorField} from '@libs/ErrorUtils';
import {settingsPendingAction} from '@libs/PolicyUtils';
import Navigation from '@navigation/Navigation';
import type {WithPolicyConnectionsProps} from '@pages/workspace/withPolicyConnections';
import withPolicyConnections from '@pages/workspace/withPolicyConnections';
import variables from '@styles/variables';
import {clearQBOErrorField} from '@userActions/Policy/Policy';
import CONST from '@src/CONST';

type CardListItem = ListItem & {
value: string;
};

function QuickbooksNonReimbursableCreditCardDefaultVendorSelectPage({policy}: WithPolicyConnectionsProps) {
const {translate} = useLocalize();
const styles = useThemeStyles();
const illustrations = useMemoizedLazyIllustrations(['Telescope']);
const {vendors} = policy?.connections?.quickbooksOnline?.data ?? {};
const qboConfig = policy?.connections?.quickbooksOnline?.config;

const policyID = policy?.id ?? CONST.DEFAULT_NUMBER_ID.toString();
const data: CardListItem[] = useMemo(
() =>
vendors?.map((vendor) => ({
value: vendor.id,
text: vendor.name,
keyForList: vendor.name,
isSelected: vendor.id === qboConfig?.nonReimbursableCreditCardDefaultVendor,
})) ?? [],
[qboConfig?.nonReimbursableCreditCardDefaultVendor, vendors],
);

const selectVendor = useCallback(
(row: CardListItem) => {
if (row.value !== qboConfig?.nonReimbursableCreditCardDefaultVendor) {
updateQuickbooksOnlineNonReimbursableCreditCardDefaultVendor(policyID, row.value, qboConfig?.nonReimbursableCreditCardDefaultVendor);
}
Navigation.goBack();
},
[qboConfig?.nonReimbursableCreditCardDefaultVendor, policyID],
);

const listEmptyContent = useMemo(
() => (
<BlockingView
icon={illustrations.Telescope}
iconWidth={variables.emptyListIconWidth}
iconHeight={variables.emptyListIconHeight}
title={translate('workspace.qbo.noAccountsFound')}
subtitle={translate('workspace.qbo.noAccountsFoundDescription')}
containerStyle={styles.pb10}
/>
),
[illustrations.Telescope, translate, styles.pb10],
);

return (
<SelectionScreen
policyID={policyID}
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN]}
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="QuickbooksNonReimbursableCreditCardDefaultVendorSelectPage"
title="workspace.accounting.defaultVendor"
data={data}
onSelectRow={selectVendor}
shouldSingleExecuteRowSelect
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
listEmptyContent={listEmptyContent}
connectionName={CONST.POLICY.CONNECTIONS.NAME.QBO}
onBackButtonPress={() => Navigation.goBack()}
pendingAction={settingsPendingAction([CONST.QUICKBOOKS_CONFIG.NON_REIMBURSABLE_CREDIT_CARD_DEFAULT_VENDOR], qboConfig?.pendingFields)}
errors={getLatestErrorField(qboConfig, CONST.QUICKBOOKS_CONFIG.NON_REIMBURSABLE_CREDIT_CARD_DEFAULT_VENDOR)}
errorRowStyles={[styles.ph5, styles.pv3]}
onClose={() => clearQBOErrorField(policyID, CONST.QUICKBOOKS_CONFIG.NON_REIMBURSABLE_CREDIT_CARD_DEFAULT_VENDOR)}
/>
);
}

export default withPolicyConnections(QuickbooksNonReimbursableCreditCardDefaultVendorSelectPage);
Loading